Theory Superposition_Completeness

theory Superposition_Completeness
  imports
    Grounded_Superposition
    Ground_Superposition_Completeness
    Superposition_Welltypedness_Preservation

    First_Order_Clause.Nonground_Entailment
begin

section ‹Completeness›

context grounded_superposition_calculus
begin

subsection ‹Liftings›

lemma eq_resolution_lifting:
  fixes
    DG CG :: "'f ground_atom clause" and
    D C :: "('f, 'v) atom clause" and
    γ :: "('f, 'v) subst"
  defines
    [simp]: "DG  clause.to_ground (D  γ)" and
    [simp]: "CG  clause.to_ground (C  γ)"
  assumes
    ground_eq_resolution: "ground.eq_resolution DG CG" and
    D_grounding: "clause.is_ground (D  γ)" and
    C_grounding: "clause.is_ground (C  γ)" and
    select: "clause.from_ground (selectG DG) = (select D)  γ" and
    D_is_welltyped: "clause.is_welltyped 𝒱 D" and
    γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱 γ" and
    𝒱: "infinite_variables_per_type 𝒱"
  obtains C'
  where
    "eq_resolution (D, 𝒱) (C', 𝒱)"
    "Infer [DG] CG  inference_ground_instances (Infer [(D, 𝒱)] (C', 𝒱))"
    "C'  γ = C  γ"
  using ground_eq_resolution
proof(cases DG CG rule: ground.eq_resolution.cases)
  case ground_eq_resolutionI: (eq_resolutionI lG DG' tG)

  let ?selectG_empty = "selectG DG = {#}"
  let ?selectG_not_empty = "selectG DG  {#}"

  obtain l where
    l_γ: "l ⋅l γ = term.from_ground tG !≈ term.from_ground tG" and
    l_in_D: "l ∈# D" and
    l_selected: "?selectG_not_empty  is_maximal l (select D)" and
    l_γ_selected: "?selectG_not_empty  is_maximal (l ⋅l γ) (select D  γ)" and
    l_is_maximal: "?selectG_empty  is_maximal l D" and
    l_γ_is_maximal: "?selectG_empty  is_maximal (l ⋅l γ) (D  γ)"
  proof-
    obtain max_l where
      "is_maximal max_l D" and
      is_max_in_D_γ: "is_maximal (max_l ⋅l γ) (D  γ)"
    proof-
      have "D  {#}"
        using ground_eq_resolutionI(1)
        by auto

      then show ?thesis
        using that D_grounding obtain_maximal_literal
        by blast
    qed

    moreover then have "max_l ∈# D"
      unfolding is_maximal_def
      by blast

    moreover have "max_l ⋅l γ = term.from_ground tG !≈ term.from_ground tG" if ?selectG_empty
    proof(rule unique_maximal_in_ground_clause[OF D_grounding is_max_in_D_γ])
      have "ground_is_maximal lG DG"
        using ground_eq_resolutionI(3) that
        unfolding is_maximal_def
        by simp

      then show "is_maximal (term.from_ground tG !≈ term.from_ground tG) (D  γ)"
        using D_grounding
        unfolding ground_eq_resolutionI(2)
        by simp
    qed

    moreover obtain selected_l where
      "selected_l ⋅l γ = term.from_ground tG !≈ term.from_ground tG" and
      "is_maximal selected_l (select D)"
      "is_maximal (selected_l ⋅l γ) (select D  γ)"
    if ?selectG_not_empty
    proof-
      have "is_maximal (term.from_ground tG !≈ term.from_ground tG) (select D  γ)"
        if ?selectG_not_empty
        using ground_eq_resolutionI(3) that select
        unfolding ground_eq_resolutionI(2)
        by simp

      then show ?thesis
        using
          that
          obtain_maximal_literal[OF _ select_ground_subst[OF D_grounding]]
          unique_maximal_in_ground_clause[OF select_ground_subst[OF D_grounding]]
        by (metis is_maximal_not_empty clause.magma_subst_empty)
    qed

    moreover then have "selected_l ∈# D" if ?selectG_not_empty
      by (meson that maximal_in_clause mset_subset_eqD select_subset)

    ultimately show ?thesis
      using that
      by blast
  qed

  obtain C' where D: "D = add_mset l C'"
    using multi_member_split[OF l_in_D]
    by blast

  obtain t t' where l: "l = t !≈ t'"
    using l_γ obtain_from_neg_literal_subst
    by meson

  obtain μ σ where γ: "γ = μ  σ" and imgu: "welltyped_imgu_on (clause.vars D) 𝒱 t t' μ"
  proof-
    have unified: "t ⋅t γ = t' ⋅t γ"
      using l_γ
      unfolding l
      by simp

    moreover obtain τ where welltyped: "welltyped 𝒱 t τ" "welltyped 𝒱 t' τ"
      using D_is_welltyped
      unfolding D l
      by auto

    show ?thesis
      using obtain_welltyped_imgu_on[OF unified welltyped] that
      by metis
  qed

  show ?thesis
  proof(rule that)

    show eq_resolution: "eq_resolution (D, 𝒱) (C'  μ, 𝒱)"
    proof (rule eq_resolutionI, rule imgu)

      show "select D = {#}  is_maximal (l ⋅l μ) (D  μ)"
      proof -
        assume "select D = {#}"

        then have "?selectG_empty"
          using select 
          by auto

        moreover have "l ⋅l μ ∈# D  μ"
          using l_in_D
          by blast

        ultimately show "is_maximal (l ⋅l μ) (D  μ)"
          using l_γ_is_maximal is_maximal_if_grounding_is_maximal D_grounding
          unfolding γ
          by simp
      qed

      show "select D  {#}  is_maximal (l ⋅l μ) (select D  μ)"
      proof -
        assume "select D  {#}"

        then have "¬?selectG_empty"
          using select 
          by auto

        moreover then have "l ⋅l μ ∈# select D  μ"
          using l_selected maximal_in_clause
          by blast

        ultimately show ?thesis
          using
            select_ground_subst[OF D_grounding]
            l_γ_selected
            is_maximal_if_grounding_is_maximal
          unfolding γ
          by auto
      qed
    qed (rule D, rule l, rule refl)

    show C'_μ_γ: "C'  μ  γ = C  γ"
    proof-
      have "term.is_idem μ"
        using imgu
        unfolding term_subst.is_imgu_iff_is_idem_and_is_mgu
        by blast

      then have μ_γ: "μ  γ = γ"
        unfolding γ term_subst.is_idem_def subst_compose_assoc[symmetric]
        by argo

      have "D  γ = add_mset (l ⋅l γ) (C  γ)"
      proof-
        have "clause.to_ground (D  γ) = clause.to_ground (add_mset (l ⋅l γ) (C  γ))"
          using ground_eq_resolutionI(1)
          unfolding ground_eq_resolutionI(2) l_γ ground_eq_resolutionI(4)[symmetric]
          by simp

        moreover have "clause.is_ground (add_mset (l ⋅l γ) (C  γ))"
          using C_grounding clause.to_set_is_ground_subst[OF l_in_D D_grounding]
          by simp

        ultimately show ?thesis
          using clause.to_ground_eq[OF D_grounding]
          by blast
      qed

      then have "C'  γ = C  γ"
        unfolding D
        by simp

      then show ?thesis
        unfolding clause.subst_comp_subst[symmetric] μ_γ.
    qed

    show "Infer [DG] CG  inference_ground_instances (Infer [(D, 𝒱)] (C'  μ, 𝒱))"
    proof (rule is_inference_ground_instance_one_premise)

      show "is_inference_ground_instance_one_premise (D, 𝒱) (C'  μ, 𝒱) (Infer [DG] CG) γ"
      proof(unfold split, intro conjI; (rule D_is_welltyped refl 𝒱)?)
        show "inference.is_ground (Infer [D] (C'  μ) ⋅ι γ)"
          using D_grounding C_grounding C'_μ_γ
          by auto
      next
        show "Infer [DG] CG = inference.to_ground (Infer [D] (C'  μ) ⋅ι γ)"
          using C'_μ_γ
          by simp
      next
        have "clause.vars (C'  μ)  clause.vars D"
          using clause.variables_in_base_imgu imgu
          unfolding D l
          by auto

        then show "term.subst.is_welltyped_on (clause.vars (C'  μ)) 𝒱 γ"
          using D_is_welltyped γ_is_welltyped
          by blast
      next
        show "clause.is_welltyped 𝒱 (C'  μ)"
          using D_is_welltyped eq_resolution eq_resolution_preserves_typing
          by blast
      qed

      show "Infer [DG] CG  ground.G_Inf"
        unfolding ground.G_Inf_def
        using ground_eq_resolution
        by blast
    qed
  qed
qed

lemma eq_factoring_lifting:
  fixes
    DG CG :: "'f ground_atom clause" and
    D C :: "('f, 'v) atom clause" and
    γ :: "('f, 'v) subst"
  defines
    [simp]: "DG  clause.to_ground (D  γ)" and
    [simp]: "CG  clause.to_ground (C  γ)"
  assumes
    ground_eq_factoring: "ground.eq_factoring DG CG" and
    D_grounding: "clause.is_ground (D  γ)" and
    C_grounding: "clause.is_ground (C  γ)" and
    select: "clause.from_ground (selectG DG) = (select D)  γ" and
    D_is_welltyped: "clause.is_welltyped 𝒱 D" and
    γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱 γ" and
    𝒱: "infinite_variables_per_type 𝒱"
  obtains C'
  where
    "eq_factoring (D, 𝒱) (C', 𝒱)"
    "Infer [DG] CG  inference_ground_instances (Infer [(D, 𝒱)] (C', 𝒱))"
    "C'  γ = C  γ"
  using ground_eq_factoring
proof(cases DG CG rule: ground.eq_factoring.cases)
  case ground_eq_factoringI: (eq_factoringI lG1 lG2 DG' tG1 tG2 tG3)

  have "D  {#}"
    using ground_eq_factoringI(1)
    by auto

  then obtain l1 where
    l1_is_maximal: "is_maximal l1 D" and
    l1_γ_is_maximal: "is_maximal (l1 ⋅l γ) (D  γ)"
    using that obtain_maximal_literal D_grounding
    by blast

  obtain t1 t1' where
    l1: "l1 = t1  t1'" and
    l1: "l1 ⋅l γ = term.from_ground tG1  term.from_ground tG2" and
    t1: "t1 ⋅t γ = term.from_ground tG1" and
    t1'_γ: "t1' ⋅t γ = term.from_ground tG2"
  proof-
    have "is_maximal (literal.from_ground lG1) (D  γ)"
      using ground_eq_factoringI(5) D_grounding
      by simp

    then have "l1 ⋅l γ = term.from_ground tG1  term.from_ground tG2"
      unfolding  ground_eq_factoringI(2)
      using unique_maximal_in_ground_clause[OF D_grounding l1_γ_is_maximal]
      by simp

    then show ?thesis
      using that
      unfolding ground_eq_factoringI(2)
      by (metis obtain_from_pos_literal_subst)
  qed

  obtain l2 D' where
    l2: "l2 ⋅l γ = term.from_ground tG1  term.from_ground tG3" and
    D: "D = add_mset l1 (add_mset l2 D')"
  proof-
    obtain D'' where D: "D = add_mset l1 D''"
      using maximal_in_clause[OF l1_is_maximal]
      by (meson multi_member_split)

    moreover have "D  γ = clause.from_ground (add_mset lG1 (add_mset lG2 DG'))"
      using ground_eq_factoringI(1) DG_def
      by (metis D_grounding clause.to_ground_inverse)

    ultimately have "D''  γ =  add_mset (literal.from_ground lG2) (clause.from_ground DG')"
      using  l1
      by (simp add: ground_eq_factoringI(2))

    then obtain l2 where "l2 ⋅l γ = term.from_ground tG1  term.from_ground tG3" "l2 ∈# D''"
      unfolding clause.subst_def ground_eq_factoringI
      using msed_map_invR
      by force

    then show ?thesis
      using that
      unfolding D
      by (metis mset_add)
  qed

  then obtain t2 t2' where
    l2: "l2 = t2  t2'" and
    t2: "t2 ⋅t γ = term.from_ground tG1" and
    t2'_γ: "t2' ⋅t γ = term.from_ground tG3"
    unfolding ground_eq_factoringI(3)
    using obtain_from_pos_literal_subst
    by metis

  have D'_γ: "D'  γ = clause.from_ground DG'"
    using D D_grounding ground_eq_factoringI(1,2,3) l1 l2
    by force

  obtain μ σ where γ: "γ = μ  σ" and imgu: "welltyped_imgu_on (clause.vars D) 𝒱 t1 t2 μ"
  proof-
    have unified: "t1 ⋅t γ = t2 ⋅t γ"
      unfolding t1 t2 ..

    then obtain τ where "welltyped 𝒱 (t1 ⋅t γ) τ" "welltyped 𝒱 (t2 ⋅t γ) τ"
      using D_is_welltyped γ_is_welltyped
      unfolding D l1 l2
      by auto

    then have welltyped: "welltyped 𝒱 t1 τ" "welltyped 𝒱 t2 τ"
      using γ_is_welltyped
      unfolding D l1 l2
      by simp_all

    then show ?thesis
      using obtain_welltyped_imgu_on[OF unified welltyped] that
      by metis
  qed

  let ?C'' = "add_mset (t1  t2') (add_mset (t1' !≈ t2') D')"
  let ?C' = "?C''  μ"

  show ?thesis
  proof(rule that)

    show eq_factoring: "eq_factoring (D, 𝒱) (?C', 𝒱)"
    proof (rule eq_factoringI; (rule D l1 l2 imgu refl 𝒱)?)
      show "select D = {#}"
        using ground_eq_factoringI(4) select
        by simp
    next
      have "l1 ⋅l μ ∈# D  μ"
        using l1_is_maximal clause.subst_in_to_set_subst maximal_in_clause
        by blast

      then show "is_maximal (l1 ⋅l μ) (D  μ)"
        using is_maximal_if_grounding_is_maximal D_grounding l1_γ_is_maximal
        unfolding γ
        by auto
    next
      have groundings: "term.is_ground (t1' ⋅t μ ⋅t σ)" "term.is_ground (t1 ⋅t μ ⋅t σ)"
        using t1'_γ t1
        unfolding γ
        by simp_all

      have "t1' ⋅t γ t t1 ⋅t γ"
        using ground_eq_factoringI(6)
        unfolding t1'_γ t1 term.order.lessG_def.

      then show "¬ t1 ⋅t μ t t1' ⋅t μ"
        unfolding γ
        using term.order.ground_less_not_less_eq[OF groundings]
        by simp
    qed

    show C'_γ: "?C'  γ = C  γ"
    proof-
      have "term.is_idem μ"
        using imgu
        unfolding term_subst.is_imgu_iff_is_idem_and_is_mgu
        by blast

      then have μ_γ: "μ  γ = γ"
        unfolding γ term_subst.is_idem_def subst_compose_assoc[symmetric]
        by argo

      have "C  γ = clause.from_ground (add_mset (tG2 !≈ tG3) (add_mset (tG1  tG3) DG'))"
        using ground_eq_factoringI(7) clause.to_ground_eq[OF C_grounding clause.ground_is_ground]
        unfolding CG_def
        by (metis clause.from_ground_inverse)

      also have "... = ?C''  γ"
        using t1 t1'_γ t2'_γ D'_γ
        by simp

      also have "... = ?C'  γ"
        unfolding clause.subst_comp_subst[symmetric] μ_γ ..

      finally show ?thesis ..
    qed

    show "Infer [DG] CG  inference_ground_instances (Infer [(D, 𝒱)] (?C', 𝒱))"
    proof (rule is_inference_ground_instance_one_premise)

      show "is_inference_ground_instance_one_premise (D, 𝒱) (?C', 𝒱) (Infer [DG] CG) γ"
      proof(unfold split, intro conjI; (rule D_is_welltyped refl 𝒱)?)

        show "inference.is_ground (Infer [D] ?C' ⋅ι γ)"
          using C_grounding D_grounding C'_γ
          by auto
      next

        show "Infer [DG] CG = inference.to_ground (Infer [D] ?C' ⋅ι γ)"
          using C'_γ
          by simp
      next

        have imgu: "term.is_imgu μ {{t1, t2}}"
          using imgu
          by blast

        have "clause.vars ?C'  clause.vars D"
          using clause.variables_in_base_imgu[OF imgu, of ?C'']
          unfolding D l1 l2
          by auto

        then show "term.subst.is_welltyped_on (clause.vars ?C') 𝒱 γ"
          using D_is_welltyped γ_is_welltyped
          by blast
      next

        show "clause.is_welltyped 𝒱 ?C'"
          using D_is_welltyped eq_factoring eq_factoring_preserves_typing
          by blast
      qed

      show "Infer [DG] CG  ground.G_Inf"
        unfolding ground.G_Inf_def
        using ground_eq_factoring
        by blast
    qed
  qed
qed

lemma superposition_lifting:
  fixes
    EG DG CG :: "'f ground_atom clause" and
    E D C :: "('f, 'v) atom clause" and
    γ ρ1 ρ2 :: "('f, 'v) subst" and
    𝒱1 𝒱2 :: "('v, 'ty) var_types"
  defines
    [simp]: "EG  clause.to_ground (E  ρ1  γ)" and
    [simp]: "DG  clause.to_ground (D  ρ2  γ)" and
    [simp]: "CG  clause.to_ground (C  γ)" and
    [simp]: "NG  clause.welltyped_ground_instances (E, 𝒱1) 
                    clause.welltyped_ground_instances (D, 𝒱2)" and
    [simp]: "ιG  Infer [DG, EG] CG"
  assumes
    ground_superposition: "ground.superposition DG EG CG" and
    ρ1: "term_subst.is_renaming ρ1" and
    ρ2: "term_subst.is_renaming ρ2" and
    rename_apart: "clause.vars (E  ρ1)  clause.vars (D  ρ2) = {}" and
    E_grounding: "clause.is_ground (E  ρ1  γ)" and
    D_grounding: "clause.is_ground (D  ρ2  γ)" and
    C_grounding: "clause.is_ground (C  γ)" and
    select_from_E: "clause.from_ground (selectG EG) = (select E)  ρ1  γ" and
    select_from_D: "clause.from_ground (selectG DG) = (select D)  ρ2  γ" and
    E_is_welltyped: "clause.is_welltyped 𝒱1 E" and
    D_is_welltyped: "clause.is_welltyped 𝒱2 D" and
    ρ1_γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars E) 𝒱1 (ρ1  γ)" and
    ρ2_γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱2 (ρ2  γ)" and
    ρ1_is_welltyped: "term.subst.is_welltyped_on (clause.vars E) 𝒱1 ρ1" and
    ρ2_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱2 ρ2" and
    𝒱1: "infinite_variables_per_type 𝒱1" and
    𝒱2: "infinite_variables_per_type 𝒱2" and
    not_redundant: "ιG  ground.Red_I NG"
  obtains C' 𝒱3
  where
    "superposition (D, 𝒱2) (E, 𝒱1) (C', 𝒱3)"
    "ιG  inference_ground_instances (Infer [(D, 𝒱2), (E, 𝒱1)] (C', 𝒱3))"
    "C'  γ = C  γ"
  using ground_superposition
proof(cases DG EG CG rule: ground.superposition.cases)
  case ground_superpositionI: (superpositionI lG1 EG' lG2 DG' 𝒫G cG tG1 tG2 tG3)

  have E_γ: "E  ρ1  γ = clause.from_ground (add_mset lG1 EG')"
    using ground_superpositionI(1)
    unfolding EG_def
    by (metis E_grounding clause.to_ground_inverse)

  have D_γ: "D  ρ2  γ = clause.from_ground (add_mset lG2 DG')"
    using ground_superpositionI(2) DG_def
    by (metis D_grounding clause.to_ground_inverse)

  let ?selectG_empty = "selectG (clause.to_ground (E  ρ1  γ)) = {#}"
  let ?selectG_not_empty = "selectG (clause.to_ground (E  ρ1  γ))  {#}"

  obtain l1 where
    l1: "l1 ⋅l ρ1  γ = literal.from_ground lG1" and
    l1_is_strictly_maximal: "𝒫G = Pos  is_strictly_maximal l1 E" and
    l1_is_maximal: "𝒫G = Neg  ?selectG_empty  is_maximal l1 E" and
    l1_selected: "𝒫G = Neg  ?selectG_not_empty  is_maximal l1 (select E)" and
    l1_in_E: "l1 ∈# E"
  proof-

    have E_not_empty: "E  {#}"
      using ground_superpositionI(1)
      by auto

    have "is_strictly_maximal (literal.from_ground lG1) (E  ρ1  γ)" if "𝒫G = Pos"
      using ground_superpositionI(9) that E_grounding
      by simp

    then obtain positive_l1 where
      "is_strictly_maximal positive_l1 E"
      "positive_l1 ⋅l ρ1  γ = literal.from_ground lG1"
    if "𝒫G = Pos"
      using obtain_strictly_maximal_literal[OF E_grounding]
      by metis

    moreover then have "positive_l1 ∈# E" if "𝒫G = Pos"
      using that strictly_maximal_in_clause
      by blast

    moreover then have "is_maximal (literal.from_ground lG1) (E  ρ1  γ)" if ?selectG_empty
      using that ground_superpositionI(9) is_maximal_not_empty E_grounding
      by auto

    then obtain negative_maximal_l1 where
      "is_maximal negative_maximal_l1 E"
      "negative_maximal_l1 ⋅l ρ1  γ = literal.from_ground lG1"
    if "𝒫G = Neg" ?selectG_empty
      using
        obtain_maximal_literal[OF E_not_empty E_grounding[folded clause.subst_comp_subst]]
        unique_maximal_in_ground_clause[OF E_grounding[folded clause.subst_comp_subst]]
      by metis

    moreover then have "negative_maximal_l1 ∈# E" if "𝒫G = Neg" ?selectG_empty
      using that maximal_in_clause
      by blast

    moreover have "ground_is_maximal lG1 (selectG EG)" if "𝒫G = Neg" ?selectG_not_empty
      using ground_superpositionI(9) that
      by simp

    then obtain negative_selected_l1 where
      "is_maximal negative_selected_l1 (select E)"
      "negative_selected_l1 ⋅l ρ1  γ = literal.from_ground lG1"
    if "𝒫G = Neg" ?selectG_not_empty
      using
        select_from_E
        unique_maximal_in_ground_clause
        obtain_maximal_literal
      unfolding EG_def
      by (metis (no_types, lifting) clause.ground_is_ground clause.from_ground_empty'
          clause.magma_subst_empty)

    moreover then have "negative_selected_l1 ∈# E" if "𝒫G = Neg" ?selectG_not_empty
      using that
      by (meson maximal_in_clause mset_subset_eqD select_subset)

    ultimately show ?thesis
      using that ground_superpositionI(9)
      by (metis literals_distinct(1))
  qed

  obtain E' where E: "E = add_mset l1 E'"
    by (meson l1_in_E multi_member_split)

  then have E'_γ: "E'  ρ1  γ = clause.from_ground EG'"
    using l1 E_γ
    by auto

  let ?𝒫 = "if 𝒫G = Pos then Pos else Neg"

  have [simp]: "𝒫G  Pos  𝒫G = Neg" "𝒫G  Neg  𝒫G = Pos"
    using ground_superpositionI(4)
    by auto

  have [simp]: "a σ. ?𝒫 a ⋅l σ = ?𝒫 (a ⋅a σ)"
    by auto

  have [simp]: "𝒱 a. literal.is_welltyped 𝒱 (?𝒫 a)  atom.is_welltyped 𝒱 a"
    by (auto simp: literal_is_welltyped_iff_atm_of)

  have [simp]: "a. literal.vars (?𝒫 a) = atom.vars a"
    by auto

  have l1:
    "l1 ⋅l ρ1  γ = ?𝒫 (Upair (context.from_ground cG)term.from_ground tG1 (term.from_ground tG2))"
    unfolding ground_superpositionI l1
    by simp

  obtain c1 t1 t1' where
    l1: "l1 = ?𝒫 (Upair c1t1 t1')" and
    t1'_γ: "t1' ⋅t ρ1  γ = term.from_ground tG2" and
    t1: "t1 ⋅t ρ1  γ = term.from_ground tG1" and
    c1: "c1 ⋅tc ρ1  γ = context.from_ground cG" and
    t1_is_Fun: "is_Fun t1"
  proof-

    obtain c1_t1 t1' where
      l1: "l1 = ?𝒫 (Upair c1_t1 t1')" and
      t1'_γ: "t1' ⋅t ρ1  γ = term.from_ground tG2" and
      c1_t1: "c1_t1 ⋅t ρ1  γ = (context.from_ground cG)term.from_ground tG1"
      using l1
      by (smt (verit) obtain_from_literal_subst)

    let ?inference_into_Fun =
      "c1 t1.
        c1_t1 = c1t1 
        t1 ⋅t ρ1  γ = term.from_ground tG1 
        c1 ⋅tc ρ1  γ = context.from_ground cG 
        is_Fun t1"

    have "¬ ?inference_into_Fun  ground.redundant_infer NG ιG"
    proof-
      assume "¬ ?inference_into_Fun"

      with c1_t1
      obtain t1 c1 cG' where
        c1_t1: "c1_t1 = c1t1" and
        t1_is_Var: "is_Var t1" and
        cG: "cG = context.to_ground (c1 ⋅tc ρ1  γ) c cG'"
      proof(induction c1_t1 arbitrary: cG thesis)
        case (Var x)

        show ?case
        proof(rule Var.prems)
          show "Var x = Var x"
            by simp

          show "is_Var (Var x)"
            by simp

          show "cG = context.to_ground ( ⋅tc ρ1  γ) c cG"
            by (simp add: context.to_ground_def)
        qed
      next
        case (Fun f ts)

        have "cG  "
          using Fun.prems(2,3)
          unfolding context.from_ground_def
          by (metis actxt.simps(8) intp_actxt.simps(1) is_FunI)

        then obtain tsG1 cG' tsG2 where
          cG: "cG = More f tsG1 cG' tsG2"
          using Fun.prems
          by (cases cG) (auto simp: context.from_ground_def)

        have
          "map (λt. t ⋅t ρ1  γ) ts =
            map term.from_ground tsG1 @ (context.from_ground cG')term.from_ground tG1 #
            map term.from_ground tsG2"
          using Fun(3)
          unfolding cG context.from_ground_def
          by simp

        moreover then obtain ts1 t ts2 where
          ts: "ts = ts1 @ t # ts2" and
          ts1: "map (λterm. term ⋅t ρ1  γ) ts1 = map term.from_ground tsG1" and
          ts2: "map (λterm. term ⋅t ρ1  γ) ts2 = map term.from_ground tsG2"
          by (smt append_eq_map_conv map_eq_Cons_D)

        ultimately have t_γ: "t ⋅t ρ1  γ = (context.from_ground cG')term.from_ground tG1"
          by simp

        obtain t1 c1 cG'' where
          "t = c1t1" and
          "is_Var t1" and
          "cG' = context.to_ground (c1 ⋅tc ρ1  γ) c cG''"
        proof-
          have "t  set ts"
            by (simp add: ts)

          moreover have
            "c1 t1. t = c1t1 
                t1 ⋅t ρ1  γ = term.from_ground tG1 
                c1 ⋅tc ρ1  γ = context.from_ground cG' 
                is_Fun t1"
          proof(rule notI, elim exE conjE)
            fix c1 t1
            assume
              "t = c1t1"
              "t1 ⋅t ρ1  γ = term.from_ground tG1"
              "c1 ⋅tc ρ1  γ = context.from_ground cG'"
              "is_Fun t1"

            moreover then have
              "Fun f ts = (More f ts1 c1 ts2)t1"
              "(More f ts1 c1 ts2) ⋅tc ρ1  γ = context.from_ground cG"
              unfolding context.from_ground_def cG ts
              using ts1 ts2
              by auto

            ultimately show False
              using Fun.prems(3)
              by blast
          qed

          ultimately show ?thesis
            using Fun(1) t_γ that
            by blast
        qed

        moreover then have
          "Fun f ts = (More f ts1 c1 ts2)t1"
          "cG = context.to_ground (More f ts1 c1 ts2 ⋅tc ρ1  γ) c cG''"
          using ts1 ts2
          unfolding context.to_ground_def cG ts
          by auto

        ultimately show ?case
          using Fun.prems(1)
          by blast
      qed

      obtain x where t11: "t1 ⋅t ρ1 = Var x"
        using t1_is_Var term.id_subst_rename[OF ρ1]
        unfolding is_Var_def
        by auto

      have ιG_parts:
        "set (side_prems_of ιG) = {DG}"
        "main_prem_of ιG = EG"
        "concl_of ιG = CG"
        by simp_all

      show ?thesis
      proof(rule ground.redundant_infer_singleton, unfold ιG_parts, intro bexI conjI)

        let ?tG = "(context.from_ground cG')term.from_ground tG3"

        define γ' where
          "γ'  γ(x := ?tG)"

        let ?EG' = "clause.to_ground (E  ρ1  γ')"

        have t1: "t1 ⋅t ρ1  γ = (context.from_ground cG')term.from_ground tG1"
        proof -

          have "context.is_ground (c1 ⋅tc ρ1  γ)"
            using c1_t1
            unfolding c1_t1 context.safe_unfolds
            by (metis context.ground_is_ground context.term_with_context_is_ground
                term.ground_is_ground)

          then show ?thesis
            using c1_t1
            unfolding c1_t1 c1_t1 cG
            by auto
        qed

        have t1_γ': "t1 ⋅t ρ1  γ' = (context.from_ground cG')term.from_ground tG3"
          unfolding γ'_def
          using t11
          by simp

        show "?EG'  NG"
        proof-

          have "?EG'  clause.welltyped_ground_instances (E, 𝒱1)"
          proof(unfold clause.welltyped_ground_instances_def mem_Collect_eq fst_conv snd_conv,
              intro exI conjI E_is_welltyped 𝒱1,
              rule refl)

            show "clause.is_ground (E  ρ1  γ')"
              unfolding γ'_def
              using E_grounding
              by simp

            show "term.subst.is_welltyped_on (clause.vars E) 𝒱1 (ρ1  γ')"
            proof(intro term.welltyped.typed_subst_compose ρ1_is_welltyped)

              have "welltyped 𝒱1 ?tG (𝒱1 x)"
              proof-

                have "welltyped 𝒱1 (context.from_ground cG')term.from_ground tG1 (𝒱1 x)"
                proof-

                  have "welltyped 𝒱1 (t1 ⋅t ρ1) (𝒱1 x)"
                    using t11
                    by auto

                  then have "welltyped 𝒱1 (t1 ⋅t ρ1  γ) (𝒱1 x)"
                    using ρ1_is_welltyped ρ1_γ_is_welltyped
                    unfolding E c1_t1 l1 subst_compose_def
                    by simp

                  moreover have "context.is_ground (c1 ⋅tc ρ1  γ)"
                    using c1_t1
                    unfolding c1_t1 context.safe_unfolds
                    by (metis context.ground_is_ground context.term_with_context_is_ground
                        term.ground_is_ground)

                  then have "t1 ⋅t ρ1  γ = (context.from_ground cG')term.from_ground tG1"
                    using c1_t1
                    unfolding c1_t1 c1_t1 cG
                    by auto

                  ultimately show ?thesis
                    by argo
                qed

                moreover obtain τ where
                  "welltyped 𝒱1 (term.from_ground tG1) τ"
                  "welltyped 𝒱1 (term.from_ground tG3) τ"
                proof-
                  have "clause.is_welltyped 𝒱2 (clause.from_ground DG)"
                    using D_is_welltyped
                    unfolding
                      DG_def
                      clause.to_ground_inverse[OF D_grounding]
                      clause.is_welltyped.subst_stability[OF ρ2_γ_is_welltyped].

                  then obtain τ where
                    "welltyped 𝒱2 (term.from_ground tG1) τ"
                    "welltyped 𝒱2 (term.from_ground tG3) τ"
                    unfolding ground_superpositionI
                    by auto

                  then show ?thesis
                    using that term.welltyped.explicit_replace_𝒱_iff[of _ 𝒱2 𝒱1]
                    by simp
                qed

                 ultimately show ?thesis
                  by auto
              qed

              moreover have "term.subst.is_welltyped_on ( (term.vars ` ρ1 ` clause.vars E)) 𝒱1 γ"
                by (intro term.welltyped.renaming_subst_compose ρ1_γ_is_welltyped ρ1_is_welltyped ρ1)

              ultimately show
                "term.subst.is_welltyped_on ( (term.vars ` ρ1 ` clause.vars E)) 𝒱1 γ'"
                unfolding γ'_def
                by simp
            qed
          qed

          then show ?thesis
            by simp
        qed

        show "ground.G_entails {?EG', DG} {CG}"
        proof(unfold ground.G_entails_def, intro allI impI)
          fix I :: "'f gterm rel"
          let ?I = "upair ` I"

          assume
            refl_I: "refl I" and
            trans_I: "trans I" and
            sym_I: "sym I" and
            compatible_with_gctxt_I: "compatible_with_gctxt I" and
            premise: "?I ⊫s {?EG', DG}"

           then interpret clause_entailment I
             by unfold_locales

          have γ_x_is_ground: "term.is_ground (γ x)"
            using t1 t11
            by auto

          show "?I ⊫s {CG}"
          proof(cases "?I  DG'")
            case True

            then show ?thesis
              unfolding ground_superpositionI
              by auto
          next
            case False

            then have tG1_tG3: "Upair tG1 tG3  ?I"
              using premise sym
              unfolding ground_superpositionI
              by auto

            have "?I ⊫l cG'tG1G  cG'tG3G"
              using upair_compatible_with_gctxtI[OF tG1_tG3]
              by auto

            then have "?I ⊫l term.to_ground (t1 ⋅t ρ1  γ)  term.to_ground (t1 ⋅t ρ1  γ')"
              unfolding t1 t1_γ'
              by simp

            then have "(term.to_ground (γ x), cG'tG3G)  I"
              unfolding γ'_def
              using t11
              by (auto simp: sym)

            moreover have "?I  ?EG'"
              using premise
              by simp

            ultimately have "?I  EG"
              unfolding γ'_def
              using
                clause.symmetric_congruence[of _ γ, OF _ γ_x_is_ground]
                E_grounding
              by simp

            then have "?I  add_mset (𝒫G (Upair cGtG3G tG2)) EG'"
              unfolding ground_superpositionI
              using symmetric_literal_context_congruence[OF tG1_tG3]
              by (cases "𝒫G = Pos") simp_all

            then show ?thesis
              unfolding ground_superpositionI
              by blast
          qed
        qed

        show "?EG' cG EG"
        proof-

          have "γ x = t1 ⋅t ρ1  γ"
            using t11
            by simp

          then have tG_smaller: "?tG t γ x"
            using ground_superpositionI(8)
            unfolding t1 term.order.lessG_def
            by simp

          have "add_mset (l1 ⋅l ρ1  γ') (E'  ρ1  γ') c add_mset (l1 ⋅l ρ1  γ) (E'  ρ1  γ)"
          proof(rule lessc_add_mset)

            have "x  literal.vars (l1 ⋅l ρ1)"
              unfolding l1 c1_t1 literal.vars_def atom.vars_def
              using t11
              by auto

            moreover have "literal.is_ground (l1 ⋅l ρ1  γ)"
              using E_grounding
              unfolding E
              by simp

            ultimately show "l1 ⋅l ρ1  γ' l l1 ⋅l ρ1  γ"
              unfolding γ'_def
              using literal.order.subst_update_stability tG_smaller
              by simp
          next

            have "clause.is_ground (E'  ρ1  γ)"
              using E'_γ
              by simp

            then show "E'  ρ1  γ' c E'  ρ1  γ"
              unfolding γ'_def
              using clause.order.subst_update_stability tG_smaller
              by (cases "x  clause.vars (E'  ρ1)") simp_all
          qed

          then have "E  ρ1  γ' c E  ρ1  γ"
            unfolding E
            by simp

          moreover have "clause.is_ground (E  ρ1  γ')"
            unfolding γ'_def
            using E_grounding
            by simp

          ultimately show ?thesis
            using E_grounding
            unfolding clause.order.lessG_def
            by simp
        qed
      qed
    qed

    then show ?thesis
      using not_redundant ground_superposition that l1 t1'_γ c1_t1
      unfolding ground.Red_I_def ground.G_Inf_def
      by auto
  qed

  obtain l2 where
    l2: "l2 ⋅l ρ2  γ = literal.from_ground lG2" and
    l2_is_strictly_maximal: "is_strictly_maximal l2 D"
  proof-
    have "is_strictly_maximal (literal.from_ground lG2) (D  ρ2  γ)"
      using ground_superpositionI(11) D_grounding
      by simp

    then show ?thesis
      using obtain_strictly_maximal_literal[OF D_grounding] that
      by metis
  qed

  then have l2_in_D: "l2 ∈# D"
    using strictly_maximal_in_clause
    by blast

  from l2 have l2: "l2 ⋅l ρ2  γ = term.from_ground tG1  term.from_ground tG3"
    unfolding ground_superpositionI
    by simp

  then obtain t2 t2' where
    l2: "l2 = t2  t2'" and
    t2: "t2 ⋅t ρ2  γ = term.from_ground tG1" and
    t2'_γ: "t2' ⋅t ρ2  γ = term.from_ground tG3"
    using obtain_from_pos_literal_subst
    by metis

  obtain D' where D: "D = add_mset l2 D'"
    by (meson l2_in_D multi_member_split)

  then have D'_γ: "D'  ρ2  γ = clause.from_ground DG'"
    using D_γ l2
    unfolding ground_superpositionI
    by auto

  obtain 𝒱3 where
    𝒱3: "infinite_variables_per_type 𝒱3" and
    𝒱1_𝒱3: "xclause.vars E. 𝒱1 x = 𝒱3 (term.rename ρ1 x)" and
    𝒱2_𝒱3: "xclause.vars D. 𝒱2 x = 𝒱3 (term.rename ρ2 x)"
    using clause.obtain_merged_𝒱[OF ρ1 ρ2 rename_apart clause.finite_vars clause.finite_vars 
                                 infinite_UNIV] .

  have γ_is_welltyped:
    "term.subst.is_welltyped_on (clause.vars (E  ρ1)  clause.vars (D  ρ2)) 𝒱3 γ"
  proof(unfold Set.ball_Un, intro conjI)

    show "term.subst.is_welltyped_on (clause.vars (E  ρ1)) 𝒱3 γ"
      using clause.is_welltyped.renaming_grounding[OF ρ1 ρ1_γ_is_welltyped E_grounding 𝒱1_𝒱3].
  next

    show "term.subst.is_welltyped_on (clause.vars (D  ρ2)) 𝒱3 γ"
      using clause.is_welltyped.renaming_grounding[OF ρ2 ρ2_γ_is_welltyped D_grounding 𝒱2_𝒱3].
  qed

  obtain μ σ where
    γ: "γ = μ  σ" and
    imgu: "welltyped_imgu_on (clause.vars (E  ρ1)  clause.vars (D  ρ2)) 𝒱3 (t1 ⋅t ρ1) (t2 ⋅t ρ2) μ"
  proof-

    have unified: "t1 ⋅t ρ1 ⋅t γ = t2 ⋅t ρ2 ⋅t γ"
      using t1 t2
      by simp

    obtain τ where welltyped: "welltyped 𝒱3 (t1 ⋅t ρ1) τ" "welltyped 𝒱3 (t2 ⋅t ρ2) τ"
    proof-
      have "clause.is_welltyped 𝒱2 (D  ρ2  γ)"
        using ρ2_γ_is_welltyped D_is_welltyped
        by (metis clause.is_welltyped.subst_stability)

      then obtain τ where
        "welltyped 𝒱2 (term.from_ground tG1) τ"
        unfolding D_γ ground_superpositionI
        by auto

      then have "welltyped 𝒱3 (term.from_ground tG1) τ"
        using term.welltyped.is_ground_typed
        by (meson term.ground_is_ground term.welltyped.explicit_is_ground_typed)

      then have "welltyped 𝒱3 (t1 ⋅t ρ1  γ) τ" "welltyped 𝒱3 (t2 ⋅t ρ2  γ) τ"
        using t1 t2
        by presburger+

      moreover have
        "term.vars (t1 ⋅t ρ1)  clause.vars (E  ρ1)"
        "term.vars (t2 ⋅t ρ2)  clause.vars (D  ρ2)"
        unfolding E l1 clause.add_subst D l2
        by auto

      ultimately have "welltyped 𝒱3 (t1 ⋅t ρ1) τ" "welltyped 𝒱3 (t2 ⋅t ρ2) τ"
        using γ_is_welltyped
        by (simp_all add: subsetD)

      then show ?thesis
        using that
        by blast
    qed

    show ?thesis
      using obtain_welltyped_imgu_on[OF unified welltyped] that
      by metis
  qed

  define C' where
    C': "C' = add_mset (?𝒫 (Upair (c1 ⋅tc ρ1)t2' ⋅t ρ2 (t1' ⋅t ρ1))) (E'  ρ1 + D'  ρ2)  μ"

  show ?thesis
  proof(rule that)

    show superposition: "superposition (D, 𝒱2) (E, 𝒱1) (C', 𝒱3)"
    proof(rule superpositionI;
           ((rule ρ1 ρ2 E D l1 l2 t1_is_Fun imgu rename_apart ρ1_is_welltyped ρ2_is_welltyped 𝒱1 𝒱2 C'
               𝒱1_𝒱3 𝒱2_𝒱3)+)?)

      show "?𝒫  {Pos, Neg}"
        by simp
    next

      show "¬ E  ρ1  μ c D  ρ2  μ"
      proof(rule clause.order.ground_less_not_less_eq)

        show "clause.vars (D  ρ2  μ  σ) = {}"
          using D_grounding
          unfolding γ
          by simp

        show "clause.vars (E  ρ1  μ  σ) = {}"
          using E_grounding
          unfolding γ
          by simp

        show "D  ρ2  μ  σ c E  ρ1  μ  σ"
          using ground_superpositionI(3) D_grounding E_grounding
          unfolding EG_def DG_def clause.order.lessG_def γ
          by simp
      qed
    next
      assume "?𝒫 = Pos"

      then show "select E = {#}"
        using ground_superpositionI(9) select_from_E
        by fastforce

    next
      assume Pos: "?𝒫 = Pos"

      show "is_strictly_maximal (l1 ⋅l ρ1  μ) (E  ρ1  μ)"
      proof(rule is_strictly_maximal_if_grounding_is_strictly_maximal)

        show "l1 ⋅l ρ1  μ ∈# E  ρ1  μ"
          using l1_in_E
          by blast

        show "clause.is_ground (E  ρ1  μ  σ)"
          using E_grounding[unfolded γ]
          by simp

        show "is_strictly_maximal (l1 ⋅l ρ1  μ ⋅l σ) (E  ρ1  μ  σ)"
          using Pos l1 E_γ ground_superpositionI(9)
          unfolding γ ground_superpositionI
          by fastforce
      qed
    next
      assume Neg: "?𝒫 = Neg" "select E = {#}"

      show "is_maximal (l1 ⋅l ρ1  μ) (E  ρ1  μ)"
      proof(rule is_maximal_if_grounding_is_maximal)

          show "l1 ⋅l ρ1  μ ∈# E  ρ1  μ"
            using l1_in_E
            by blast
        next

          show "clause.is_ground (E  ρ1  μ  σ)"
            using E_grounding γ
            by auto
        next

          show "is_maximal (l1 ⋅l ρ1  μ ⋅l σ) (E  ρ1  μ  σ) "
            using l1 γ E_γ ground_superpositionI(5,9) is_maximal_not_empty Neg select_from_E
            by auto
        qed
    next
      assume Neg: "?𝒫 = Neg" "select E  {#}"

      show "is_maximal (l1 ⋅l ρ1  μ) ((select E)  ρ1  μ)"
      proof(rule is_maximal_if_grounding_is_maximal)

        show "l1 ⋅l ρ1  μ ∈# select E  ρ1  μ"
          using ground_superpositionI(9) l1_selected maximal_in_clause Neg select_from_E
          by force
      next

        show "clause.is_ground (select E  ρ1  μ  σ)"
          using select_ground_subst[OF E_grounding]
          unfolding γ
          by simp
      next
        show "is_maximal (l1 ⋅l ρ1  μ ⋅l σ) (select E  ρ1  μ  σ)"
          using γ ground_superpositionI(5,9) l1 that select_from_E Neg
          by fastforce
      qed
    next

      show "select D = {#}"
        using ground_superpositionI(10) select_from_D
        by simp
    next

      show "is_strictly_maximal (l2 ⋅l ρ2  μ) (D  ρ2  μ)"
      proof(rule is_strictly_maximal_if_grounding_is_strictly_maximal)

        show "l2 ⋅l ρ2  μ ∈# D  ρ2  μ"
          using l2_in_D
          by blast
      next

        show "clause.is_ground (D  ρ2  μ  σ)"
          using D_grounding
          unfolding γ
          by simp
      next

        show "is_strictly_maximal (l2 ⋅l ρ2  μ ⋅l σ) (D  ρ2  μ  σ)"
          using l2 γ D_γ ground_superpositionI(6,11)
          by auto
      qed
    next

      show "¬ c1t1 ⋅t ρ1  μ t t1' ⋅t ρ1  μ"
      proof(rule term.order.ground_less_not_less_eq)

        show "term.is_ground (t1' ⋅t ρ1  μ ⋅t σ)"
          using t1'_γ γ
          by simp
      next

        show "term.is_ground (c1t1 ⋅t ρ1  μ ⋅t σ)"
          using t1 c1 γ
          by simp
      next

        show "t1' ⋅t ρ1  μ ⋅t σ t c1t1 ⋅t ρ1  μ ⋅t σ"
          using ground_superpositionI(7) c1 t1'_γ t1
          unfolding term.order.lessG_def γ
          by auto
      qed
    next

      show "¬ t2 ⋅t ρ2  μ t t2' ⋅t ρ2  μ"
      proof(rule term.order.ground_less_not_less_eq)

        show "term.is_ground (t2' ⋅t ρ2  μ ⋅t σ)"
          using t2'_γ γ
          by simp
      next

        show "term.is_ground (t2 ⋅t ρ2  μ ⋅t σ)"
          using t2 γ
          by simp
      next

        show "t2' ⋅t ρ2  μ ⋅t σ t t2 ⋅t ρ2  μ ⋅t σ"
          using ground_superpositionI(8) t2 t2'_γ
          unfolding γ term.order.lessG_def
          by simp
      qed
    next

      have "τ. welltyped 𝒱2 t2 τ  welltyped 𝒱2 t2' τ"
        using D_is_welltyped
        unfolding D l2
        by auto

      then show "τ τ'. typed 𝒱2 t2 τ; typed 𝒱2 t2' τ'  τ = τ'"
        using term.typed_if_welltyped
        by blast
    qed

    show C'_γ: "C'  γ = C  γ"
    proof-

      have "term_subst.is_idem μ"
        using imgu term.is_imgu_iff_is_idem_and_is_mgu
        by blast

      then have μ_γ: "μ  γ = γ"
        unfolding γ term_subst.is_idem_def
        by (metis subst_compose_assoc)

      have "C  γ =
              add_mset
                (?𝒫 (Upair (context.from_ground cG)term.from_ground tG3 (term.from_ground tG2)))
                  (clause.from_ground EG' + clause.from_ground DG')"
        using ground_superpositionI(4, 12) clause.to_ground_inverse[OF C_grounding]
        by auto

      then show ?thesis
        unfolding
          C'
          E'_γ[symmetric]
          D'_γ[symmetric]
          t1'_γ[symmetric]
          t2'_γ[symmetric]
          c1[symmetric]
          clause.subst_comp_subst[symmetric]
          μ_γ
        by simp
    qed

    show "ιG  inference_ground_instances (Infer [(D, 𝒱2), (E, 𝒱1)] (C', 𝒱3))"
    proof (rule is_inference_ground_instance_two_premises)

      show "is_inference_ground_instance_two_premises (D, 𝒱2) (E, 𝒱1) (C', 𝒱3) ιG γ ρ1 ρ2"
      proof(unfold split, intro conjI;
            (rule ρ1 ρ2 rename_apart D_is_welltyped E_is_welltyped refl 𝒱1 𝒱2 𝒱3)?)

        show "inference.is_ground (Infer [D  ρ2, E  ρ1] C' ⋅ι γ)"
          using  D_grounding E_grounding C_grounding C'_γ
          by auto
      next

        show "ιG = inference.to_ground (Infer [D  ρ2, E  ρ1] C' ⋅ι γ)"
          using C'_γ
          by simp
      next

        show "clause.is_welltyped 𝒱3 C'"
          using superposition superposition_preserves_typing E_is_welltyped D_is_welltyped
          by blast
      next

        show "term.subst.is_welltyped_on (clause.vars C') 𝒱3 γ"
        proof(rule term.is_welltyped_on_subset[OF γ_is_welltyped])

          show "clause.vars C'  clause.vars (E  ρ1)  clause.vars (D  ρ2)"
          proof (unfold subset_eq, intro ballI)
            fix x

            have is_imgu: "term.is_imgu μ {{t1 ⋅t ρ1, t2 ⋅t ρ2}}"
              using imgu
              by blast

            assume "x  clause.vars C'"

            then consider
              (t2') "x  term.vars (t2' ⋅t ρ2  μ)" |
              (c1) "x  context.vars (c1 ⋅tc ρ1  μ)" |
              (t1') "x  term.vars (t1' ⋅t ρ1  μ)" |
              (E') "x  clause.vars (E'  ρ1  μ)" |
              (D') "x  clause.vars (D'  ρ2  μ)"
              unfolding C'
              by auto

            then show "x  clause.vars (E  ρ1)  clause.vars (D  ρ2)"
            proof cases
              case t2'

              then show ?thesis
                using term.variables_in_base_imgu[OF is_imgu]
                unfolding E l1 D l2
                by auto
            next
              case c1

              then show ?thesis
                using context.variables_in_base_imgu[OF is_imgu]
                unfolding E l1 D l2
                by force
            next
              case t1'

              then show ?thesis
                using term.variables_in_base_imgu[OF is_imgu]
                unfolding E clause.add_subst l1 D l2
                by auto
            next
              case E'

              then show ?thesis
                using clause.variables_in_base_imgu[OF is_imgu]
                unfolding E l1 D l2
                by auto
            next
              case D'

              then show ?thesis
                using clause.variables_in_base_imgu[OF is_imgu]
                unfolding E l1 D l2
                by auto
            qed
          qed
        qed
      qed

      show "ιG  ground.G_Inf"
        unfolding ground.G_Inf_def
        using ground_superposition
        by simp
    qed
  qed
qed

subsection ‹Ground instances›

context
  fixes ιG N
  assumes
    subst_stability: "subst_stability_on N" and
    ιG_Inf_from: "ιG  ground.Inf_from_q selectG ((clause.welltyped_ground_instances ` N))"
begin

lemma single_premise_ground_instance:
  assumes
    ground_inference: "ιG   {Infer [D] C | D C. ground_inference D C}" and
    lifting: "D γ C 𝒱 thesis. 
    ground_inference (clause.to_ground (D  γ)) (clause.to_ground (C  γ));
    clause.is_ground (D  γ);
    clause.is_ground (C  γ);
    clause.from_ground (selectG (clause.to_ground (D  γ))) = select D  γ;
    clause.is_welltyped 𝒱 D; 
    term.subst.is_welltyped_on (clause.vars D) 𝒱 γ;
    infinite_variables_per_type 𝒱;
    C'. 
        inference (D, 𝒱) (C', 𝒱);
        Infer [clause.to_ground (D  γ)] (clause.to_ground (C  γ))
         inference_ground_instances (Infer [(D, 𝒱)] (C', 𝒱));
        C'  γ = C  γ  thesis
        thesis" and
    inference_eq: "inference = eq_factoring  inference = eq_resolution"
  obtains ι where
    "ι  Inf_from N"
    "ιG  inference_ground_instances ι"
proof-
  obtain DG CG where
    ιG: "ιG = Infer [DG] CG" and
    ground_inference: "ground_inference DG CG"
    using ground_inference
    by blast

  have DG_in_groundings: "DG  (clause.welltyped_ground_instances ` N)"
    using ιG_Inf_from
    unfolding ιG ground.Inf_from_q_def ground.Inf_from_def
    by simp

  obtain D γ 𝒱 where
    D_grounding: "clause.is_ground (D  γ)" and
    D_is_welltyped: "clause.is_welltyped 𝒱 D" and
    γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱 γ" and
    𝒱: "infinite_variables_per_type 𝒱" and
    D_in_N: "(D, 𝒱)N" and
    "selectG DG = clause.to_ground (select D  γ)"
    "D  γ = clause.from_ground DG"
    using subst_stability[rule_format, OF DG_in_groundings]
    by blast

  then have
    DG: "DG = clause.to_ground (D  γ)" and
    select: "clause.from_ground (selectG DG) = select D  γ"
    by (simp_all add: select_ground_subst)

  obtain C where
    CG: "CG = clause.to_ground (C  γ)" and
    C_grounding: "clause.is_ground (C  γ)"
    by (metis clause.all_subst_ident_iff_ground clause.from_ground_inverse
        clause.ground_is_ground)

  obtain C' where
    inference: "inference (D, 𝒱) (C', 𝒱)" and
    inference_ground_instances: "ιG  inference_ground_instances (Infer [(D, 𝒱)] (C', 𝒱))" and
    C'_C: "C'  γ = C  γ"
    using
      lifting[OF
        ground_inference[unfolded DG CG]
        D_grounding
        C_grounding
        select[unfolded DG]
        D_is_welltyped
        γ_is_welltyped
        𝒱]
    unfolding DG CG ιG.

  let  = "Infer [(D, 𝒱)] (C', 𝒱)"

  show ?thesis
  proof(rule that[OF _ inference_ground_instances])

    show "  Inf_from N"
      using D_in_N inference inference_eq
      unfolding Inf_from_def inferences_def inference_system.Inf_from_def
      by auto
  qed
qed

lemma eq_resolution_ground_instance:
  assumes ground_eq_resolution: "ιG  ground.eq_resolution_inferences"
  obtains ι where
    "ι  Inf_from N"
    "ιG  inference_ground_instances ι"
  using eq_resolution_lifting single_premise_ground_instance[OF ground_eq_resolution]
  by blast

lemma eq_factoring_ground_instance:
  assumes ground_eq_factoring: "ιG  ground.eq_factoring_inferences"
  obtains ι where
    "ι  Inf_from N"
    "ιG  inference_ground_instances ι"
  using eq_factoring_lifting single_premise_ground_instance[OF ground_eq_factoring]
  by blast

lemma superposition_ground_instance:
  assumes
    ground_superposition: "ιG  ground.superposition_inferences" and
    not_redundant: "ιG  ground.GRed_I ( (clause.welltyped_ground_instances ` N))"
  obtains ι where
    "ι  Inf_from N"
    "ιG  inference_ground_instances ι"
proof-
  obtain EG DG CG where
    ιG : "ιG = Infer [DG, EG] CG" and
    ground_superposition: "ground.superposition DG EG CG"
    using assms(1)
    by blast

  have
    EG_in_groundings: "EG   (clause.welltyped_ground_instances ` N)" and
    DG_in_groundings: "DG   (clause.welltyped_ground_instances ` N)"
    using ιG_Inf_from
    unfolding ιG ground.Inf_from_q_def ground.Inf_from_def
    by simp_all

  obtain E 𝒱1 γ1 where
    E_grounding: "clause.is_ground (E  γ1)" and
    E_is_welltyped: "clause.is_welltyped 𝒱1 E" and
    γ1_is_welltyped: "term.subst.is_welltyped_on (clause.vars E) 𝒱1 γ1" and
    𝒱1: "infinite_variables_per_type 𝒱1" and
    E_in_N: "(E, 𝒱1)N" and
    "selectG EG = clause.to_ground (select E  γ1)"
    "E  γ1 = clause.from_ground EG"
    using subst_stability[rule_format, OF EG_in_groundings]
    by blast

  then have
    EG: "EG = clause.to_ground (E  γ1)" and
    select_from_E: "clause.from_ground (selectG EG) = select E  γ1"
    by (simp_all add: select_ground_subst)

  obtain D 𝒱2 γ2 where
    D_grounding: "clause.is_ground (D  γ2)" and
    D_is_welltyped: "clause.is_welltyped 𝒱2 D" and
    γ2_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱2 γ2" and
    𝒱2: "infinite_variables_per_type 𝒱2" and
    D_in_N: "(D, 𝒱2)N" and
    "selectG DG = clause.to_ground (select D  γ2)"
    "D  γ2 = clause.from_ground DG"
    using subst_stability[rule_format, OF DG_in_groundings]
    by blast

  then have
    DG: "DG = clause.to_ground (D  γ2)" and
    select_from_D: "clause.from_ground (selectG DG) = select D  γ2"
    by (simp_all add: select_ground_subst)

  obtain ρ1 ρ2 γ :: "('f, 'v) subst" where
    ρ1: "term_subst.is_renaming ρ1" and
    ρ2: "term_subst.is_renaming ρ2" and
    rename_apart: "clause.vars (E  ρ1)  clause.vars (D  ρ2) = {}" and
    ρ1_is_welltyped: "term.subst.is_welltyped_on (clause.vars E) 𝒱1 ρ1" and
    ρ2_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱2 ρ2" and
    γ1: "x  clause.vars E. γ1 x = (ρ1  γ) x" and
    γ2: "x  clause.vars D. γ2 x = (ρ2  γ) x"
    using clause.is_welltyped.obtain_merged_grounding[OF
            γ1_is_welltyped γ2_is_welltyped E_grounding D_grounding 𝒱2 clause.finite_vars].

  have E_grounding: "clause.is_ground (E  ρ1  γ)"
    using clause.subst_eq γ1 E_grounding
    by fastforce

  have EG: "EG = clause.to_ground (E  ρ1  γ)"
    using clause.subst_eq γ1 EG
    by fastforce

  have D_grounding: "clause.is_ground (D  ρ2  γ)"
    using clause.subst_eq γ2 D_grounding
    by fastforce

  have DG: "DG = clause.to_ground (D  ρ2  γ)"
    using clause.subst_eq γ2 DG
    by fastforce

  have ρ1_γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars E) 𝒱1 (ρ1  γ)"
    using γ1_is_welltyped γ1
    by fastforce

  have ρ2_γ_is_welltyped: "term.subst.is_welltyped_on (clause.vars D) 𝒱2 (ρ2  γ)"
    using γ2_is_welltyped γ2
    by fastforce

  have select_from_E:
    "clause.from_ground (selectG (clause.to_ground (E  ρ1  γ))) = select E  ρ1  γ"
  proof-
    have "E  γ1 = E  ρ1  γ"
      using γ1 clause.subst_eq
      by fast

    moreover have "select E  γ1 = select E  ρ1  γ"
      using clause.subst_eq γ1 select_vars_subset
      by (metis (no_types, lifting) clause.comp_subst.left.monoid_action_compatibility in_mono)

    ultimately show ?thesis
      using select_from_E
      unfolding EG
      by simp
  qed

  have select_from_D:
    "clause.from_ground (selectG (clause.to_ground (D  ρ2  γ))) = select D  ρ2  γ"
  proof-
    have "D  γ2 = D  ρ2  γ"
      using γ2 clause.subst_eq
      by fast

    moreover have "select D  γ2 = select D  ρ2  γ"
      using clause.subst_eq γ2 select_vars_subset[of D]
      by (metis (no_types, lifting) clause.comp_subst.left.monoid_action_compatibility in_mono)

    ultimately show ?thesis
      using select_from_D
      unfolding DG
      by simp
  qed

  obtain C where
    C_grounding: "clause.is_ground (C  γ)" and
    CG: "CG = clause.to_ground (C  γ)"
    by (metis clause.all_subst_ident_if_ground clause.from_ground_inverse clause.ground_is_ground)

  have "clause.welltyped_ground_instances (E, 𝒱1)  clause.welltyped_ground_instances (D, 𝒱2) 
           (clause.welltyped_ground_instances ` N)"
    using E_in_N D_in_N
    by blast

  then have ιG_not_redundant:
    "ιG  ground.GRed_I
          (clause.welltyped_ground_instances (E, 𝒱1)  clause.welltyped_ground_instances (D, 𝒱2))"
    using not_redundant ground.Red_I_of_subset
    by blast

  obtain C' 𝒱3 where
    superposition: "superposition (D, 𝒱2) (E, 𝒱1) (C', 𝒱3)" and
    inference_groundings: "ιG  inference_ground_instances (Infer [(D, 𝒱2), (E, 𝒱1)] (C', 𝒱3))" and
    C'_γ_C_γ: "C'  γ = C  γ"
    using
      superposition_lifting[OF
        ground_superposition[unfolded DG EG CG]
        ρ1 ρ2
        rename_apart
        E_grounding D_grounding C_grounding
        select_from_E select_from_D
        E_is_welltyped D_is_welltyped
        ρ1_γ_is_welltyped ρ2_γ_is_welltyped
        ρ1_is_welltyped ρ2_is_welltyped
        𝒱1 𝒱2
        ιG_not_redundant[unfolded ιG DG EG CG]]
    unfolding ιG CG EG DG .

  let  = "Infer [(D, 𝒱2), (E, 𝒱1)] (C', 𝒱3)"

  show ?thesis
  proof(rule that[OF _ inference_groundings])

    show "  Inf_from N"
      using E_in_N D_in_N superposition
      unfolding Inf_from_def inferences_def inference_system.Inf_from_def
      by auto
  qed
qed

lemma ground_instances:
  assumes not_redundant: "ιG  ground.Red_I ( (clause.welltyped_ground_instances ` N))"
  obtains ι where
    "ι  Inf_from N"
    "ιG  inference_ground_instances ι"
proof-
  consider
    (superposition) "ιG  ground.superposition_inferences" |
    (eq_resolution) "ιG  ground.eq_resolution_inferences" |
    (eq_factoring) "ιG  ground.eq_factoring_inferences"
    using ιG_Inf_from
    unfolding
      ground.Inf_from_q_def
      ground.G_Inf_def
      inference_system.Inf_from_def
    by fastforce

  then show ?thesis
  proof cases
    case superposition

    then show ?thesis
      using that superposition_ground_instance not_redundant
      by blast
  next
    case eq_resolution

    then show ?thesis
      using that eq_resolution_ground_instance
      by blast
  next
    case eq_factoring

    then show ?thesis
      using that eq_factoring_ground_instance
      by blast
  qed
qed

end

end

context superposition_calculus
begin

lemma overapproximation:
  obtains selectG where
    "ground_Inf_overapproximated selectG premises"
    "is_grounding selectG"
proof-
  obtain selectG where
    subst_stability: "select_subst_stability_on select selectG premises" and
    "is_grounding selectG"
    using obtain_subst_stable_on_select_grounding
    by blast

  then interpret grounded_superposition_calculus
    where selectG = selectG
    by unfold_locales

  show thesis
  proof(rule that[OF _ selectG])

    show "ground_Inf_overapproximated selectG premises"
      using ground_instances[OF subst_stability]
      by auto
  qed
qed

sublocale statically_complete_calculus "F" inferences entails_𝒢 Red_I_𝒢 Red_F_𝒢
proof(unfold static_empty_ord_inter_equiv_static_inter,
    rule stat_ref_comp_to_non_ground_fam_inter,
    rule ballI)
  fix selectG
  assume "selectG  selectGs"
  then interpret grounded_superposition_calculus
    where selectG = selectG
    by unfold_locales (simp add: selectGs_def)

  show "statically_complete_calculus
          ground.G_Bot
          ground.G_Inf
          ground.G_entails
          ground.Red_I
          ground.Red_F"
    by unfold_locales
next

  show "N. selectG  selectGs. ground_Inf_overapproximated selectG N"
    using overapproximation
    unfolding selectGs_def
    by (smt (verit, best) mem_Collect_eq)
qed

end

end