Theory Grounded_First_Order_Superposition

theory Grounded_First_Order_Superposition
  imports 
    First_Order_Superposition
    Ground_Superposition_Completeness
begin

context ground_superposition_calculus
begin

abbreviation eq_resolution_inferences where
  "eq_resolution_inferences   {Infer [P] C | P C. ground_eq_resolution P C}"

abbreviation eq_factoring_inferences where
  "eq_factoring_inferences   {Infer [P] C | P C.  ground_eq_factoring P C}"

abbreviation superposition_inferences where
  "superposition_inferences  {Infer [P2, P1] C | P1 P2 C. ground_superposition P2 P1 C}"

end

locale grounded_first_order_superposition_calculus =
  first_order_superposition_calculus select _ _ typeof_fun +
  grounded_first_order_select select
  for 
    select :: "('f, 'v :: infinite) select" and
    typeof_fun :: "('f, 'ty) fun_types"
begin

sublocale ground: ground_superposition_calculus where
  less_trm = "(≺tG)" and select = selectG
  by unfold_locales (rule ground_critical_pair_theorem)

definition is_inference_grounding where
  "is_inference_grounding ι ιG γ ρ1 ρ2 
    (case ι of
        Infer [(premise, 𝒱')] (conclusion, 𝒱) 
           term_subst.is_ground_subst γ
         ιG = Infer [clause.to_ground (premise  γ)] (clause.to_ground (conclusion  γ))
         welltypedc typeof_fun 𝒱 premise 
         welltypedσ_on (clause.vars conclusion) typeof_fun 𝒱 γ
         welltypedc typeof_fun 𝒱 conclusion
         𝒱 = 𝒱'
         all_types 𝒱
      | Infer [(premise2, 𝒱2), (premise1, 𝒱1)] (conclusion, 𝒱3)  
          term_subst.is_renaming ρ1
         term_subst.is_renaming ρ2
         clause.vars (premise1  ρ1)  clause.vars (premise2  ρ2) = {}
         term_subst.is_ground_subst γ
         ιG =
            Infer
              [clause.to_ground (premise2  ρ2  γ), clause.to_ground (premise1  ρ1  γ)]
              (clause.to_ground (conclusion  γ))
         welltypedc typeof_fun 𝒱1 premise1
         welltypedc typeof_fun 𝒱2 premise2
         welltypedσ_on (clause.vars conclusion) typeof_fun 𝒱3 γ
         welltypedc typeof_fun 𝒱3 conclusion
         all_types 𝒱1  all_types 𝒱2  all_types 𝒱3
      | _  False
     )
   ιG  ground.G_Inf"

definition inference_groundings where 
  "inference_groundings ι = { ιG | ιG γ ρ1 ρ2. is_inference_grounding ι ιG γ ρ1 ρ2 }"

lemma is_inference_grounding_inference_groundings: 
  "is_inference_grounding ι ιG γ ρ1 ρ2   ιG  inference_groundings ι"
  unfolding inference_groundings_def
  by blast

lemma inferenceG_concl_in_clause_grounding: 
  assumes "ιG  inference_groundings ι"
  shows "concl_of ιG  clause_groundings typeof_fun (concl_of ι)"
proof-
  obtain premisesG conlcusionG where
    ιG: "ιG = Infer premisesG conlcusionG"
    using Calculus.inference.exhaust by blast

  obtain "premises" "conclusion" 𝒱 where
    ι: "ι = Infer premises (conclusion, 𝒱)"
    using Calculus.inference.exhaust
    by (metis prod.collapse)

  obtain γ where
    "clause.is_ground (conclusion  γ)"
    "conlcusionG = clause.to_ground (conclusion  γ)"
    "welltypedc typeof_fun 𝒱 conclusion  welltypedσ_on (clause.vars conclusion) typeof_fun 𝒱 γ  
    term_subst.is_ground_subst γ  all_types 𝒱"
  proof-
    have "γ ρ1 ρ2.
       γ. clause.vars (conclusion  γ) = {}; conlcusionG = clause.to_ground (conclusion  γ);
              First_Order_Type_System.welltypedc typeof_fun 𝒱 conclusion 
              welltypedσ_on (clause.vars conclusion) typeof_fun 𝒱 γ 
              term_subst.is_ground_subst γ  all_types 𝒱
              thesis;
        Infer premisesG conlcusionG  ground.G_Inf;
        case premises of []  False
        | [(premise, 𝒱')] 
            term_subst.is_ground_subst γ 
            Infer premisesG conlcusionG =
            Infer [clause.to_ground (premise  γ)] (clause.to_ground (conclusion  γ)) 
            First_Order_Type_System.welltypedc typeof_fun 𝒱 premise 
            welltypedσ_on (clause.vars conclusion) typeof_fun 𝒱 γ 
            First_Order_Type_System.welltypedc typeof_fun 𝒱 conclusion  𝒱 = 𝒱'  all_types 𝒱
        | [(premise, 𝒱'), (premise1, 𝒱1)] 
            clause.is_renaming ρ1 
            clause.is_renaming ρ2 
            clause.vars (premise1  ρ1)  clause.vars (premise  ρ2) = {} 
            term_subst.is_ground_subst γ 
            Infer premisesG conlcusionG =
            Infer [clause.to_ground (premise  ρ2  γ), clause.to_ground (premise1  ρ1  γ)]
             (clause.to_ground (conclusion  γ)) 
            First_Order_Type_System.welltypedc typeof_fun 𝒱1 premise1 
            First_Order_Type_System.welltypedc typeof_fun 𝒱' premise 
            welltypedσ_on (clause.vars conclusion) typeof_fun 𝒱 γ 
            First_Order_Type_System.welltypedc typeof_fun 𝒱 conclusion 
            all_types 𝒱1  all_types 𝒱'  all_types 𝒱
        | (premise, 𝒱') # (premise1, 𝒱1) # a # lista  False
        thesis"
      by(auto simp: clause.is_ground_subst_is_ground split: list.splits)
        (metis list_4_cases prod.exhaust_sel) 

     then show ?thesis
      using that assms 
      unfolding inference_groundings_def ι ιG Calculus.inference.case
      by (auto simp: is_inference_grounding_def)
  qed

  then show ?thesis
    unfolding ι ιG clause_groundings_def
    by auto
qed  

lemma inferenceG_red_in_clause_grounding_of_concl: 
  assumes "ιG  inference_groundings ι"
  shows "ιG  ground.Red_I (clause_groundings typeof_fun (concl_of ι))"
proof-
  from assms have "ιG  ground.G_Inf"
    unfolding inference_groundings_def is_inference_grounding_def
    by blast

  moreover have "concl_of ιG  clause_groundings typeof_fun  (concl_of ι)"
    using assms inferenceG_concl_in_clause_grounding
    by auto

  ultimately show "ιG  ground.Red_I (clause_groundings typeof_fun (concl_of ι))"
    using ground.Red_I_of_Inf_to_N
    by blast
qed

lemma obtain_welltyped_ground_subst:
  obtains γ :: "('f, 'v) subst" and G :: "('f, 'ty) fun_types"
  where "welltypedσ typeof_fun 𝒱 γ" "term_subst.is_ground_subst γ"
proof-
 
  define γ :: "('f, 'v) subst" where
    "x. γ x  Fun (SOME f. typeof_fun f = ([], 𝒱 x)) []"


  moreover have "welltypedσ typeof_fun 𝒱 γ"
  proof-
    have "x. First_Order_Type_System.welltyped typeof_fun 𝒱
          (Fun (SOME f. typeof_fun f = ([], 𝒱 x)) []) (𝒱 x)"
      by (meson function_symbols list_all2_Nil someI_ex welltyped.Fun)

    then show ?thesis
      unfolding welltypedσ_def γ_def
      by auto
  qed

  moreover have "term_subst.is_ground_subst γ"
    unfolding term_subst.is_ground_subst_def γ_def
    by (smt (verit) Nil_is_map_conv equals0D eval_term.simps(2) is_ground_iff is_ground_trm_iff_ident_forall_subst)

  ultimately show ?thesis
    using that
    by blast
qed


lemma welltypedσ_on_empty: "welltypedσ_on {}  𝒱 σ"
  unfolding welltypedσ_on_def
  by simp  

sublocale lifting: 
    tiebreaker_lifting
          "F"
          inferences 
          ground.G_Bot
          ground.G_entails
          ground.G_Inf 
          ground.GRed_I
          ground.GRed_F 
          "clause_groundings typeof_fun"
          "(Some  inference_groundings)"
          typed_tiebreakers
proof unfold_locales
  show "F  {}"
    using all_types'[OF variables]
    by blast
next
  fix bottom
  assume "bottom  F"

  then show "clause_groundings typeof_fun bottom  {}"
    unfolding clause_groundings_def
    using welltypedσ_Var
  proof -
    have "f. welltypedσ_on (clause.vars {#}) typeof_fun (snd bottom) f  
          First_Order_Type_System.welltypedc typeof_fun (snd bottom) {#}  
          term_subst.is_ground_subst f"
      by (metis First_Order_Type_System.welltypedc_def empty_clause_is_ground ex_in_conv 
          set_mset_eq_empty_iff term.obtain_ground_subst welltypedσ_on_empty)

    then show "{clause.to_ground (fst bottom  f) |f. term_subst.is_ground_subst f 
         First_Order_Type_System.welltypedc typeof_fun (snd bottom) (fst bottom) 
         welltypedσ_on (clause.vars (fst bottom)) typeof_fun (snd bottom) f 
         all_types (snd bottom)}  {}"
      using bottom  F by force
  qed
next
  fix bottom
  assume "bottom  F"
  then show "clause_groundings typeof_fun bottom  ground.G_Bot"
    unfolding clause_groundings_def
    by clause_auto
next
  fix clause
  show "clause_groundings typeof_fun clause  ground.G_Bot  {}  clause  F"
    unfolding clause_groundings_def clause.to_ground_def clause.subst_def
    by (smt (verit) disjoint_insert(1) image_mset_is_empty_iff inf_bot_right mem_Collect_eq 
        prod.exhaust_sel)
next
  fix ι :: "('f, 'v, 'ty) typed_clause inference"

  show "the ((Some  inference_groundings) ι)  
      ground.GRed_I (clause_groundings typeof_fun (concl_of ι))"
    using inferenceG_red_in_clause_grounding_of_concl
    by auto
next
  show "clauseG. po_on (typed_tiebreakers clauseG) UNIV"
    unfolding po_on_def
    using wellfounded_typed_tiebreakers
    by simp
next
  show "clauseG. Restricted_Predicates.wfp_on (typed_tiebreakers clauseG) UNIV"
    using wellfounded_typed_tiebreakers
    by simp
qed

end

sublocale first_order_superposition_calculus 
  lifting_intersection
    inferences      
    "{{#}}"
    selectGs
    "ground_superposition_calculus.G_Inf (≺tG)"               
    "λ_. ground_superposition_calculus.G_entails" 
    "ground_superposition_calculus.GRed_I (≺tG)" 
    "λ_. ground_superposition_calculus.GRed_F(≺tG)" 
    "F"
    "λ_. clause_groundings typeof_fun" 
    "λselectG. Some 
      (grounded_first_order_superposition_calculus.inference_groundings (≺t) selectG typeof_fun)"
    typed_tiebreakers
proof(unfold_locales; (intro ballI)?)
  show "selectGs  {}"
    using selectG_simple
    unfolding selectGs_def 
    by blast
next 
  fix selectG
  assume "selectG  selectGs"
 
  then interpret grounded_first_order_superposition_calculus
    where selectG = selectG
    apply unfold_locales
    by(simp add: selectGs_def)

  show "consequence_relation ground.G_Bot ground.G_entails"
    using ground.consequence_relation_axioms.
next
   fix selectG
   assume "selectG  selectGs"
 
   then interpret grounded_first_order_superposition_calculus
    where selectG = selectG
    by unfold_locales (simp add: selectGs_def)

  show "tiebreaker_lifting
          F
          inferences 
          ground.G_Bot
          ground.G_entails
          ground.G_Inf 
          ground.GRed_I
          ground.GRed_F 
          (clause_groundings typeof_fun)
          (Some  inference_groundings)
          typed_tiebreakers"
    by unfold_locales
qed

end