Theory First_Order_Superposition_Completeness
theory First_Order_Superposition_Completeness
imports
Ground_Superposition_Completeness
Grounded_First_Order_Superposition
"HOL-ex.Sketch_and_Explore"
begin
lemma welltyped⇩σ_on_term:
assumes "welltyped⇩σ_on (term.vars term) ℱ 𝒱 γ"
shows "welltyped ℱ 𝒱 term τ ⟷ welltyped ℱ 𝒱 (term ⋅t γ) τ"
by (simp add: assms welltyped⇩σ_on_welltyped)
context grounded_first_order_superposition_calculus
begin
lemma eq_resolution_lifting:
fixes
premise⇩G conclusion⇩G :: "'f gatom clause" and
premise "conclusion" :: "('f, 'v) atom clause" and
γ :: "('f, 'v) subst"
defines
premise⇩G [simp]: "premise⇩G ≡ clause.to_ground (premise ⋅ γ)" and
conclusion⇩G [simp]: "conclusion⇩G ≡ clause.to_ground (conclusion ⋅ γ)"
assumes
premise_grounding: "clause.is_ground (premise ⋅ γ)" and
conclusion_grounding: "clause.is_ground (conclusion ⋅ γ)" and
select: "clause.from_ground (select⇩G premise⇩G) = (select premise) ⋅ γ" and
ground_eq_resolution: "ground.ground_eq_resolution premise⇩G conclusion⇩G" and
typing:
"welltyped⇩c typeof_fun 𝒱 premise"
"term_subst.is_ground_subst γ"
"welltyped⇩σ_on (clause.vars premise) typeof_fun 𝒱 γ"
"all_types 𝒱"
obtains conclusion'
where
"eq_resolution (premise, 𝒱) (conclusion', 𝒱)"
"Infer [premise⇩G] conclusion⇩G ∈ inference_groundings (Infer [(premise, 𝒱)] (conclusion', 𝒱))"
"conclusion' ⋅ γ = conclusion ⋅ γ"
using ground_eq_resolution
proof(cases premise⇩G conclusion⇩G rule: ground.ground_eq_resolution.cases)
case (ground_eq_resolutionI literal⇩G premise⇩G' term⇩G)
have premise_not_empty: "premise ≠ {#}"
using
ground_eq_resolutionI(1)
empty_not_add_mset
clause_subst_empty
unfolding premise⇩G
by (metis clause_from_ground_empty_mset clause.from_ground_inverse)
have "premise ⋅ γ = clause.from_ground (add_mset literal⇩G (clause.to_ground (conclusion ⋅ γ)))"
using
ground_eq_resolutionI(1)[THEN arg_cong, of clause.from_ground]
clause.to_ground_inverse[OF premise_grounding]
ground_eq_resolutionI(4)
unfolding premise⇩G conclusion⇩G
by metis
also have "... = add_mset (literal.from_ground literal⇩G) (conclusion ⋅ γ)"
unfolding clause_from_ground_add_mset
by (simp add: conclusion_grounding)
finally have premise_γ: "premise ⋅ γ = add_mset (literal.from_ground literal⇩G) (conclusion ⋅ γ)".
let ?select⇩G_empty = "select⇩G premise⇩G = {#}"
let ?select⇩G_not_empty = "select⇩G premise⇩G ≠ {#}"
obtain max_literal where max_literal:
"is_maximal⇩l max_literal premise"
"is_maximal⇩l (max_literal ⋅l γ) (premise ⋅ γ)"
using is_maximal⇩l_ground_subst_stability[OF premise_not_empty premise_grounding]
by blast
moreover then have "max_literal ∈# premise"
using maximal⇩l_in_clause by fastforce
moreover have max_literal_γ: "max_literal ⋅l γ = literal.from_ground (term⇩G !≈ term⇩G)"
if ?select⇩G_empty
proof-
have "ground.is_maximal_lit literal⇩G premise⇩G"
using ground_eq_resolutionI(3) that maximal_lit_in_clause
by (metis empty_iff set_mset_empty)
then show ?thesis
using max_literal(2) unique_maximal_in_ground_clause[OF premise_grounding]
unfolding
ground_eq_resolutionI(2)
is_maximal_lit_iff_is_maximal⇩l
premise⇩G
clause.to_ground_inverse[OF premise_grounding]
by blast
qed
moreover obtain selected_literal where
"selected_literal ⋅l γ = literal.from_ground (term⇩G !≈ term⇩G)" and
"is_maximal⇩l selected_literal (select premise)"
if ?select⇩G_not_empty
proof-
have "ground.is_maximal_lit literal⇩G (select⇩G premise⇩G)" if ?select⇩G_not_empty
using ground_eq_resolutionI(3) that
by blast
then show ?thesis
using
that
select
unique_maximal_in_ground_clause[OF select_subst(1)[OF premise_grounding]]
is_maximal⇩l_ground_subst_stability[OF _ select_subst(1)[OF premise_grounding]]
unfolding
ground_eq_resolutionI(2)
premise⇩G
is_maximal_lit_iff_is_maximal⇩l
by (metis (full_types) clause_subst_empty(2) clause.from_ground_inverse clause_to_ground_empty_mset)
qed
moreover then have "selected_literal ∈# premise" if ?select⇩G_not_empty
by (meson that maximal⇩l_in_clause mset_subset_eqD select_subset)
ultimately obtain literal where
literal_γ: "literal ⋅l γ = literal.from_ground (term⇩G !≈ term⇩G)" and
literal_in_premise: "literal ∈# premise" and
literal_selected: "?select⇩G_not_empty ⟹ is_maximal⇩l literal (select premise)" and
literal_max: "?select⇩G_empty ⟹ is_maximal⇩l literal premise"
by blast
have literal_grounding: "literal.is_ground (literal ⋅l γ)"
using literal_γ
by simp
from literal_γ obtain "term" term' where
literal: "literal = term !≈ term'"
using subst_polarity_stable literal_from_ground_polarity_stable
by (metis literal.collapse(2) literal.disc(2) uprod_exhaust)
have literal⇩G:
"literal.from_ground literal⇩G = (term !≈ term') ⋅l γ"
"literal⇩G = literal.to_ground ((term !≈ term') ⋅l γ)"
using literal_γ literal ground_eq_resolutionI(2)
by simp_all
obtain conclusion' where conclusion': "premise = add_mset literal conclusion'"
using multi_member_split[OF literal_in_premise]
by blast
have "term ⋅t γ = term' ⋅t γ"
using literal_γ
unfolding literal subst_literal(2) atom.subst_def literal.from_ground_def atom.from_ground_def
by simp
moreover obtain τ where "welltyped typeof_fun 𝒱 term τ" "welltyped typeof_fun 𝒱 term' τ"
using typing(1)
unfolding conclusion' literal welltyped⇩c_def welltyped⇩l_def welltyped⇩a_def
by auto
ultimately obtain μ σ where μ:
"term_subst.is_imgu μ {{term, term'}}"
"γ = μ ⊙ σ"
"welltyped_imgu' typeof_fun 𝒱 term term' μ"
using welltyped_imgu'_exists
by meson
have conclusion'_γ: "conclusion' ⋅ γ = conclusion ⋅ γ"
using premise_γ
unfolding conclusion' ground_eq_resolutionI(2) literal_γ[symmetric] subst_clause_add_mset
by simp
have eq_resolution: "eq_resolution (premise, 𝒱) (conclusion' ⋅ μ, 𝒱)"
proof (rule eq_resolutionI)
show "premise = add_mset literal conclusion'"
using conclusion'.
next
show "literal = term !≈ term'"
using literal.
next
show "term_subst.is_imgu μ {{term, term'}}"
using μ(1).
next
show "select premise = {#} ∧ is_maximal⇩l (literal ⋅l μ) (premise ⋅ μ)
∨ is_maximal⇩l (literal ⋅l μ) ((select premise) ⋅ μ)"
proof(cases ?select⇩G_empty)
case select⇩G_empty: True
then have "max_literal ⋅l γ = literal ⋅l γ"
by (simp add: max_literal_γ literal_γ)
then have literal_γ_is_maximal: "is_maximal⇩l (literal ⋅l γ) (premise ⋅ γ)"
using max_literal(2) by simp
have literal_μ_in_premise: "literal ⋅l μ ∈# premise ⋅ μ"
by (simp add: clause.subst_in_to_set_subst literal_in_premise)
have "is_maximal⇩l (literal ⋅l μ) (premise ⋅ μ)"
using is_maximal⇩l_ground_subst_stability'[OF
literal_μ_in_premise
premise_grounding[unfolded μ(2) clause.subst_comp_subst]
literal_γ_is_maximal[unfolded μ(2) clause.subst_comp_subst literal.subst_comp_subst]
].
then show ?thesis
using select select⇩G_empty
by clause_auto
next
case False
have selected_grounding: "clause.is_ground (select premise ⋅ μ ⋅ σ)"
using select_subst(1)[OF premise_grounding]
unfolding μ(2) clause.subst_comp_subst.
note selected_subst =
literal_selected[OF False, THEN maximal⇩l_in_clause, THEN clause.subst_in_to_set_subst]
have "is_maximal⇩l (literal ⋅l γ) (select premise ⋅ γ)"
using False ground_eq_resolutionI(3)
unfolding ground_eq_resolutionI(2) is_maximal_lit_iff_is_maximal⇩l literal_γ select
by presburger
then have "is_maximal⇩l (literal ⋅l μ) (select premise ⋅ μ)"
unfolding μ(2) clause.subst_comp_subst literal.subst_comp_subst
using is_maximal⇩l_ground_subst_stability'[OF selected_subst selected_grounding]
by argo
with False show ?thesis
by blast
qed
next
show "welltyped_imgu' typeof_fun 𝒱 term term' μ"
using μ(3).
next
show "conclusion' ⋅ μ = conclusion' ⋅ μ" ..
qed
have "term_subst.is_idem μ"
using μ(1)
by (simp add: term_subst.is_imgu_iff_is_idem_and_is_mgu)
then have μ_γ: "μ ⊙ γ = γ"
unfolding μ(2) term_subst.is_idem_def
by (metis subst_compose_assoc)
have vars_conclusion': "clause.vars (conclusion' ⋅ μ) ⊆ clause.vars premise"
using vars_clause_imgu[OF μ(1)]
unfolding conclusion' literal
by clause_auto
have "conclusion' ⋅ μ ⋅ γ = conclusion ⋅ γ"
using conclusion'_γ
unfolding clause.subst_comp_subst[symmetric] μ_γ.
moreover have
"Infer [premise⇩G] conclusion⇩G ∈ inference_groundings (Infer [(premise, 𝒱)] (conclusion' ⋅ μ, 𝒱))"
unfolding inference_groundings_def mem_Collect_eq
proof -
have "Infer [premise⇩G] conclusion⇩G ∈ ground.G_Inf"
unfolding ground.G_Inf_def
using ground_eq_resolution by blast
then have "∃ρ⇩1 ρ⇩2. is_inference_grounding
(Infer [(premise, 𝒱)] (conclusion' ⋅ μ, 𝒱))
(Infer [premise⇩G] conclusion⇩G) γ ρ⇩1 ρ⇩2"
unfolding is_inference_grounding_def Calculus.inference.case list.case prod.case
using typing
by (smt (verit) calculation conclusion⇩G eq_resolution eq_resolution_preserves_typing premise⇩G
vars_conclusion' welltyped⇩σ_on_subset)
thus "∃ι⇩G γ ρ⇩1 ρ⇩2. Infer [premise⇩G] conclusion⇩G = ι⇩G ∧
is_inference_grounding (Infer [(premise, 𝒱)] (conclusion' ⋅ μ, 𝒱)) ι⇩G γ ρ⇩1 ρ⇩2"
by iprover
qed
ultimately show ?thesis
using that[OF eq_resolution]
by blast
qed
lemma eq_factoring_lifting:
fixes
premise⇩G conclusion⇩G :: "'f gatom clause" and
premise "conclusion" :: "('f, 'v) atom clause" and
γ :: "('f, 'v) subst"
defines
premise⇩G [simp]: "premise⇩G ≡ clause.to_ground (premise ⋅ γ)" and
conclusion⇩G [simp]: "conclusion⇩G ≡ clause.to_ground (conclusion ⋅ γ)"
assumes
premise_grounding: "clause.is_ground (premise ⋅ γ)" and
conclusion_grounding: "clause.is_ground (conclusion ⋅ γ)" and
select: "clause.from_ground (select⇩G premise⇩G) = (select premise) ⋅ γ" and
ground_eq_factoring: "ground.ground_eq_factoring premise⇩G conclusion⇩G" and
typing:
"welltyped⇩c typeof_fun 𝒱 premise"
"term_subst.is_ground_subst γ"
"welltyped⇩σ_on (clause.vars premise) typeof_fun 𝒱 γ"
"all_types 𝒱"
obtains conclusion'
where
"eq_factoring (premise, 𝒱) (conclusion', 𝒱)"
"Infer [premise⇩G] conclusion⇩G ∈ inference_groundings (Infer [(premise, 𝒱)] (conclusion', 𝒱))"
"conclusion' ⋅ γ = conclusion ⋅ γ"
using ground_eq_factoring
proof(cases premise⇩G conclusion⇩G rule: ground.ground_eq_factoring.cases)
case (ground_eq_factoringI literal⇩G⇩1 literal⇩G⇩2 premise'⇩G term⇩G⇩1 term⇩G⇩2 term⇩G⇩3)
have premise_not_empty: "premise ≠ {#}"
using ground_eq_factoringI(1) empty_not_add_mset clause_subst_empty premise⇩G
by (metis clause_from_ground_empty_mset clause.from_ground_inverse)
have select_empty: "select premise = {#}"
using ground_eq_factoringI(4) select clause_subst_empty
by clause_auto
have premise_γ: "premise ⋅ γ = clause.from_ground (add_mset literal⇩G⇩1 (add_mset literal⇩G⇩2 premise'⇩G))"
using ground_eq_factoringI(1) premise⇩G
by (metis premise_grounding clause.to_ground_inverse)
obtain literal⇩1 where literal⇩1_maximal:
"is_maximal⇩l literal⇩1 premise"
"is_maximal⇩l (literal⇩1 ⋅l γ) (premise ⋅ γ)"
using is_maximal⇩l_ground_subst_stability[OF premise_not_empty premise_grounding]
by blast
have max_ground_literal: "is_maximal⇩l (literal.from_ground (term⇩G⇩1 ≈ term⇩G⇩2)) (premise ⋅ γ)"
using ground_eq_factoringI(5)
unfolding
is_maximal_lit_iff_is_maximal⇩l
ground_eq_factoringI(2)
premise⇩G
clause.to_ground_inverse[OF premise_grounding].
have literal⇩1_γ: "literal⇩1 ⋅l γ = literal.from_ground literal⇩G⇩1"
using
unique_maximal_in_ground_clause[OF premise_grounding literal⇩1_maximal(2) max_ground_literal]
ground_eq_factoringI(2)
by blast
then have "is_pos literal⇩1"
unfolding ground_eq_factoringI(2)
using literal_from_ground_stable subst_pos_stable
by (metis literal.disc(1))
with literal⇩1_γ obtain term⇩1 term⇩1' where
literal⇩1_terms: "literal⇩1 = term⇩1 ≈ term⇩1'" and
term⇩G⇩1_term⇩1: "term.from_ground term⇩G⇩1 = term⇩1 ⋅t γ"
unfolding ground_eq_factoringI(2)
by clause_simp
obtain premise'' where premise'': "premise = add_mset literal⇩1 premise''"
using maximal⇩l_in_clause[OF literal⇩1_maximal(1)]
by (meson multi_member_split)
then have premise''_γ: "premise'' ⋅ γ = add_mset (literal.from_ground literal⇩G⇩2) (clause.from_ground premise'⇩G)"
using premise_γ
unfolding clause_from_ground_add_mset literal⇩1_γ[symmetric]
by (simp add: subst_clause_add_mset)
then obtain literal⇩2 where literal⇩2:
"literal⇩2 ⋅l γ = literal.from_ground literal⇩G⇩2"
"literal⇩2 ∈# premise''"
unfolding clause.subst_def
using msed_map_invR by force
then have "is_pos literal⇩2"
unfolding ground_eq_factoringI(3)
using literal_from_ground_stable subst_pos_stable
by (metis literal.disc(1))
with literal⇩2 obtain term⇩2 term⇩2' where
literal⇩2_terms: "literal⇩2 = term⇩2 ≈ term⇩2'" and
term⇩G⇩1_term⇩2: "term.from_ground term⇩G⇩1 = term⇩2 ⋅t γ"
unfolding ground_eq_factoringI(3)
by clause_simp
have term⇩G⇩2_term⇩1': "term.from_ground term⇩G⇩2 = term⇩1' ⋅t γ"
using literal⇩1_γ term⇩G⇩1_term⇩1
unfolding
literal⇩1_terms
ground_eq_factoringI(2)
apply clause_simp
by auto
have term⇩G⇩3_term⇩2': "term.from_ground term⇩G⇩3 = term⇩2' ⋅t γ"
using literal⇩2 term⇩G⇩1_term⇩2
unfolding
literal⇩2_terms
ground_eq_factoringI(3)
by clause_auto
obtain premise' where premise: "premise = add_mset literal⇩1 (add_mset literal⇩2 premise')"
using literal⇩2(2) maximal⇩l_in_clause[OF literal⇩1_maximal(1)] premise''
by (metis multi_member_split)
then have premise'_γ: "premise' ⋅ γ = clause.from_ground premise'⇩G"
using premise''_γ premise''
unfolding literal⇩2(1)[symmetric]
by (simp add: subst_clause_add_mset)
have term⇩1_term⇩2: "term⇩1 ⋅t γ = term⇩2 ⋅t γ"
using term⇩G⇩1_term⇩1 term⇩G⇩1_term⇩2
by argo
moreover obtain τ where "welltyped typeof_fun 𝒱 term⇩1 τ" "welltyped typeof_fun 𝒱 term⇩2 τ"
proof-
have "welltyped⇩c typeof_fun 𝒱 (premise ⋅ γ)"
using typing
using welltyped⇩σ_on_welltyped⇩c by blast
then obtain τ where "welltyped typeof_fun 𝒱 (term.from_ground term⇩G⇩1) τ"
unfolding premise_γ ground_eq_factoringI
by clause_simp
then have "welltyped typeof_fun 𝒱 (term⇩1 ⋅t γ) τ" "welltyped typeof_fun 𝒱 (term⇩2 ⋅t γ) τ"
using term⇩G⇩1_term⇩1 term⇩G⇩1_term⇩2
by metis+
then have "welltyped typeof_fun 𝒱 term⇩1 τ" "welltyped typeof_fun 𝒱 term⇩2 τ"
using typing(3) welltyped⇩σ_on_term
unfolding welltyped⇩σ_on_def premise literal⇩1_terms literal⇩2_terms
apply clause_simp
by (metis UnCI welltyped⇩σ_on_def welltyped⇩σ_on_term)+
then show ?thesis
using that
by blast
qed
ultimately obtain μ σ where μ:
"term_subst.is_imgu μ {{term⇩1, term⇩2}}"
"γ = μ ⊙ σ"
"welltyped_imgu' typeof_fun 𝒱 term⇩1 term⇩2 μ"
using welltyped_imgu'_exists
by meson
let ?conclusion' = "add_mset (term⇩1 ≈ term⇩2') (add_mset (term⇩1' !≈ term⇩2') premise')"
have eq_factoring: "eq_factoring (premise, 𝒱) (?conclusion' ⋅ μ, 𝒱)"
proof (rule eq_factoringI)
show "premise = add_mset literal⇩1 (add_mset literal⇩2 premise')"
using premise.
next
show "literal⇩1 = term⇩1 ≈ term⇩1'"
using literal⇩1_terms.
next
show "literal⇩2 = term⇩2 ≈ term⇩2'"
using literal⇩2_terms.
next
show "select premise = {#}"
using select_empty.
next
have literal⇩1_μ_in_premise: "literal⇩1 ⋅l μ ∈# premise ⋅ μ"
using literal⇩1_maximal(1) clause.subst_in_to_set_subst maximal⇩l_in_clause by blast
have "is_maximal⇩l (literal⇩1 ⋅l μ) (premise ⋅ μ)"
using is_maximal⇩l_ground_subst_stability'[OF
literal⇩1_μ_in_premise
premise_grounding[unfolded μ(2) clause.subst_comp_subst]
literal⇩1_maximal(2)[unfolded μ(2) clause.subst_comp_subst literal.subst_comp_subst]
].
then show "is_maximal⇩l (literal⇩1 ⋅l μ) (premise ⋅ μ)"
by blast
next
have term_groundings: "term.is_ground (term⇩1' ⋅t μ ⋅t σ)" "term.is_ground (term⇩1 ⋅t μ ⋅t σ)"
unfolding
term_subst.subst_comp_subst[symmetric]
μ(2)[symmetric]
term⇩G⇩1_term⇩1[symmetric]
term⇩G⇩2_term⇩1'[symmetric]
using term.ground_is_ground
by simp_all
have "term⇩1' ⋅t μ ⋅t σ ≺⇩t term⇩1 ⋅t μ ⋅t σ"
using ground_eq_factoringI(6)[unfolded
less⇩t⇩G_def
term⇩G⇩1_term⇩1
term⇩G⇩2_term⇩1'
μ(2)
term_subst.subst_comp_subst
].
then show "¬ term⇩1 ⋅t μ ≼⇩t term⇩1' ⋅t μ"
using less⇩t_less_eq⇩t_ground_subst_stability[OF term_groundings]
by blast
next
show "term_subst.is_imgu μ {{term⇩1, term⇩2}}"
using μ(1).
next
show "welltyped_imgu' typeof_fun 𝒱 term⇩1 term⇩2 μ"
using μ(3).
next
show "?conclusion' ⋅ μ = ?conclusion' ⋅ μ"
..
qed
have "term_subst.is_idem μ"
using μ(1)
by (simp add: term_subst.is_imgu_iff_is_idem_and_is_mgu)
then have μ_γ: "μ ⊙ γ = γ"
unfolding μ(2) term_subst.is_idem_def
by (metis subst_compose_assoc)
have vars_conclusion': "clause.vars (?conclusion' ⋅ μ) ⊆ clause.vars premise"
using vars_clause_imgu[OF μ(1)] vars_term_imgu[OF μ(1)]
unfolding premise literal⇩1_terms literal⇩2_terms
by clause_auto
have "conclusion ⋅ γ =
add_mset (term.from_ground term⇩G⇩2 !≈ term.from_ground term⇩G⇩3)
(add_mset (term.from_ground term⇩G⇩1 ≈ term.from_ground term⇩G⇩3) (clause.from_ground premise'⇩G))"
using ground_eq_factoringI(7) clause.to_ground_inverse[OF conclusion_grounding]
unfolding atom_from_ground_term_from_ground[symmetric]
literal_from_ground_atom_from_ground[symmetric] clause_from_ground_add_mset[symmetric]
by simp
then have conclusion_γ:
"conclusion ⋅ γ = add_mset (term⇩1 ≈ term⇩2') (add_mset (term⇩1' !≈ term⇩2') premise') ⋅ γ"
unfolding
term⇩G⇩2_term⇩1'
term⇩G⇩3_term⇩2'
term⇩G⇩1_term⇩1
premise'_γ[symmetric]
by(clause_simp simp: add_mset_commute)
then have "?conclusion' ⋅ μ ⋅ γ = conclusion ⋅ γ"
by (metis μ_γ clause.subst_comp_subst)
moreover have
"Infer [premise⇩G] conclusion⇩G ∈ inference_groundings (Infer [(premise, 𝒱)] (?conclusion' ⋅ μ, 𝒱))"
unfolding inference_groundings_def mem_Collect_eq
proof -
have "Infer [premise⇩G] conclusion⇩G ∈ ground.G_Inf"
unfolding ground.G_Inf_def
using ground_eq_factoring conclusion_grounding premise_grounding
by blast
then have "∃ρ⇩1 ρ⇩2. is_inference_grounding
(Infer [(premise, 𝒱)] (?conclusion' ⋅ μ, 𝒱))
(Infer [premise⇩G] conclusion⇩G) γ ρ⇩1 ρ⇩2"
unfolding is_inference_grounding_def Calculus.inference.case list.case prod.case
using typing
by (smt (verit) calculation conclusion⇩G eq_factoring eq_factoring_preserves_typing premise⇩G
vars_conclusion' welltyped⇩σ_on_subset)
thus "∃ι⇩G γ ρ⇩1 ρ⇩2. Infer [premise⇩G] conclusion⇩G = ι⇩G ∧
is_inference_grounding (Infer [(premise, 𝒱)] (?conclusion' ⋅ μ, 𝒱)) ι⇩G γ ρ⇩1 ρ⇩2"
by iprover
qed
ultimately show ?thesis
using that[OF eq_factoring]
by blast
qed
lemma if_subst_sth [clause_simp]: "(if b then Pos else Neg) atom ⋅l ρ =
(if b then Pos else Neg) (atom ⋅a ρ)"
by clause_auto
lemma superposition_lifting:
fixes
premise⇩G⇩1 premise⇩G⇩2 conclusion⇩G :: "'f gatom clause" and
premise⇩1 premise⇩2 "conclusion" :: "('f, 'v) atom clause" and
γ ρ⇩1 ρ⇩2 :: "('f, 'v) subst" and
𝒱⇩1 𝒱⇩2
defines
premise⇩G⇩1 [simp]: "premise⇩G⇩1 ≡ clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)" and
premise⇩G⇩2 [simp]: "premise⇩G⇩2 ≡ clause.to_ground (premise⇩2 ⋅ ρ⇩2 ⋅ γ)" and
conclusion⇩G [simp]: "conclusion⇩G ≡ clause.to_ground (conclusion ⋅ γ)" and
premise_groundings [simp]:
"premise_groundings ≡ clause_groundings typeof_fun (premise⇩1, 𝒱⇩1) ∪
clause_groundings typeof_fun (premise⇩2, 𝒱⇩2)" and
ι⇩G [simp]: "ι⇩G ≡ Infer [premise⇩G⇩2, premise⇩G⇩1] conclusion⇩G"
assumes
renaming:
"term_subst.is_renaming ρ⇩1"
"term_subst.is_renaming ρ⇩2"
"clause.vars (premise⇩1 ⋅ ρ⇩1) ∩ clause.vars (premise⇩2 ⋅ ρ⇩2) = {}" and
premise⇩1_grounding: "clause.is_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)" and
premise⇩2_grounding: "clause.is_ground (premise⇩2 ⋅ ρ⇩2 ⋅ γ)" and
conclusion_grounding: "clause.is_ground (conclusion ⋅ γ)" and
select:
"clause.from_ground (select⇩G premise⇩G⇩1) = (select premise⇩1) ⋅ ρ⇩1 ⋅ γ"
"clause.from_ground (select⇩G premise⇩G⇩2) = (select premise⇩2) ⋅ ρ⇩2 ⋅ γ" and
ground_superposition: "ground.ground_superposition premise⇩G⇩2 premise⇩G⇩1 conclusion⇩G" and
non_redundant: "ι⇩G ∉ ground.Red_I premise_groundings" and
typing:
"welltyped⇩c typeof_fun 𝒱⇩1 premise⇩1"
"welltyped⇩c typeof_fun 𝒱⇩2 premise⇩2"
"term_subst.is_ground_subst γ"
"welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 (ρ⇩1 ⊙ γ)"
"welltyped⇩σ_on (clause.vars premise⇩2) typeof_fun 𝒱⇩2 (ρ⇩2 ⊙ γ)"
"welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 ρ⇩1"
"welltyped⇩σ_on (clause.vars premise⇩2) typeof_fun 𝒱⇩2 ρ⇩2"
"all_types 𝒱⇩1" "all_types 𝒱⇩2"
obtains conclusion' 𝒱⇩3
where
"superposition (premise⇩2, 𝒱⇩2) (premise⇩1, 𝒱⇩1) (conclusion', 𝒱⇩3)"
"ι⇩G ∈ inference_groundings (Infer [(premise⇩2, 𝒱⇩2), (premise⇩1, 𝒱⇩1)] (conclusion', 𝒱⇩3))"
"conclusion' ⋅ γ = conclusion ⋅ γ"
using ground_superposition
proof(cases premise⇩G⇩2 premise⇩G⇩1 conclusion⇩G rule: ground.ground_superposition.cases)
case (ground_superpositionI
literal⇩G⇩1
premise⇩G⇩1'
literal⇩G⇩2
premise⇩G⇩2'
𝒫⇩G
context⇩G
term⇩G⇩1
term⇩G⇩2
term⇩G⇩3
)
have premise⇩1_not_empty: "premise⇩1 ≠ {#}"
using ground_superpositionI(1) empty_not_add_mset clause_subst_empty premise⇩G⇩1
by (metis clause_from_ground_empty_mset clause.from_ground_inverse)
have premise⇩2_not_empty: "premise⇩2 ≠ {#}"
using ground_superpositionI(2) empty_not_add_mset clause_subst_empty premise⇩G⇩2
by (metis clause_from_ground_empty_mset clause.from_ground_inverse)
have premise⇩1_γ: "premise⇩1 ⋅ ρ⇩1 ⋅ γ = clause.from_ground (add_mset literal⇩G⇩1 premise⇩G⇩1')"
using ground_superpositionI(1) premise⇩G⇩1
by (metis premise⇩1_grounding clause.to_ground_inverse)
have premise⇩2_γ: "premise⇩2 ⋅ ρ⇩2 ⋅ γ = clause.from_ground (add_mset literal⇩G⇩2 premise⇩G⇩2')"
using ground_superpositionI(2) premise⇩G⇩2
by (metis premise⇩2_grounding clause.to_ground_inverse)
let ?select⇩G_empty = "select⇩G (clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)) = {#}"
let ?select⇩G_not_empty = "select⇩G (clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)) ≠ {#}"
have pos_literal⇩G⇩1_is_strictly_maximal⇩l:
"is_strictly_maximal⇩l (literal.from_ground literal⇩G⇩1) (premise⇩1 ⋅ ρ⇩1 ⊙ γ)" if "𝒫⇩G = Pos"
using ground_superpositionI(9) that
unfolding is_strictly_maximal⇩G⇩l_iff_is_strictly_maximal⇩l
by(simp add: premise⇩1_grounding)
have neg_literal⇩G⇩1_is_maximal⇩l:
"is_maximal⇩l (literal.from_ground literal⇩G⇩1) (premise⇩1 ⋅ ρ⇩1 ⊙ γ)" if ?select⇩G_empty
using
that
ground_superpositionI(9)
is_maximal⇩l_if_is_strictly_maximal⇩l
is_maximal⇩l_empty
premise⇩1_γ
unfolding
is_maximal_lit_iff_is_maximal⇩l
is_strictly_maximal⇩G⇩l_iff_is_strictly_maximal⇩l
ground_superpositionI(1)
apply clause_auto
by (metis premise⇩1_γ clause_from_ground_empty_mset clause.from_ground_inverse)
obtain pos_literal⇩1 where
"is_strictly_maximal⇩l pos_literal⇩1 premise⇩1"
"pos_literal⇩1 ⋅l ρ⇩1 ⊙ γ = literal.from_ground literal⇩G⇩1"
if "𝒫⇩G = Pos"
using is_strictly_maximal⇩l_ground_subst_stability[OF
premise⇩1_grounding[folded clause.subst_comp_subst]
pos_literal⇩G⇩1_is_strictly_maximal⇩l
]
by blast
moreover then have "pos_literal⇩1 ∈# premise⇩1" if "𝒫⇩G = Pos"
using that strictly_maximal⇩l_in_clause by fastforce
moreover obtain neg_max_literal⇩1 where
"is_maximal⇩l neg_max_literal⇩1 premise⇩1"
"neg_max_literal⇩1 ⋅l ρ⇩1 ⊙ γ = literal.from_ground literal⇩G⇩1"
if "𝒫⇩G = Neg" ?select⇩G_empty
using
is_maximal⇩l_ground_subst_stability[OF
premise⇩1_not_empty
premise⇩1_grounding[folded clause.subst_comp_subst]
]
neg_literal⇩G⇩1_is_maximal⇩l
by (metis (no_types, opaque_lifting) assms(9) clause.comp_subst.left.monoid_action_compatibility unique_maximal_in_ground_clause)
moreover then have "neg_max_literal⇩1 ∈# premise⇩1" if "𝒫⇩G = Neg" ?select⇩G_empty
using that maximal⇩l_in_clause by fastforce
moreover obtain neg_selected_literal⇩1 where
"is_maximal⇩l neg_selected_literal⇩1 (select premise⇩1)"
"neg_selected_literal⇩1 ⋅l ρ⇩1 ⊙ γ = literal.from_ground literal⇩G⇩1"
if "𝒫⇩G = Neg" ?select⇩G_not_empty
proof-
have "ground.is_maximal_lit literal⇩G⇩1 (select⇩G premise⇩G⇩1)" if "𝒫⇩G = Neg" ?select⇩G_not_empty
using ground_superpositionI(9) that
by simp
then show ?thesis
using
that
select(1)
unique_maximal_in_ground_clause
is_maximal⇩l_ground_subst_stability
unfolding premise⇩G⇩1 is_maximal_lit_iff_is_maximal⇩l
by (metis (mono_tags, lifting) clause.comp_subst.monoid_action_compatibility
clause_subst_empty(2) clause.ground_is_ground image_mset_is_empty_iff
clause.from_ground_def)
qed
moreover then have "neg_selected_literal⇩1 ∈# premise⇩1" if "𝒫⇩G = Neg" ?select⇩G_not_empty
using that
by (meson maximal⇩l_in_clause mset_subset_eqD select_subset)
ultimately obtain literal⇩1 where
literal⇩1_γ: "literal⇩1 ⋅l ρ⇩1 ⊙ γ = literal.from_ground literal⇩G⇩1" and
literal⇩1_in_premise⇩1: "literal⇩1 ∈# premise⇩1" and
literal⇩1_is_strictly_maximal: "𝒫⇩G = Pos ⟹ is_strictly_maximal⇩l literal⇩1 premise⇩1" and
literal⇩1_is_maximal: "𝒫⇩G = Neg ⟹ ?select⇩G_empty ⟹ is_maximal⇩l literal⇩1 premise⇩1" and
literal⇩1_selected: "𝒫⇩G = Neg ⟹ ?select⇩G_not_empty ⟹ is_maximal⇩l literal⇩1 (select premise⇩1)"
by (metis ground_superpositionI(9) literals_distinct(1))
then have literal⇩1_grounding: "literal.is_ground (literal⇩1 ⋅l ρ⇩1 ⊙ γ)"
by simp
have literal⇩G⇩2_is_strictly_maximal⇩l:
"is_strictly_maximal⇩l (literal.from_ground literal⇩G⇩2) (premise⇩2 ⋅ ρ⇩2 ⊙ γ)"
using ground_superpositionI(11)
unfolding is_strictly_maximal⇩G⇩l_iff_is_strictly_maximal⇩l
by (simp add: premise⇩2_grounding)
obtain literal⇩2 where
literal⇩2_strictly_maximal: "is_strictly_maximal⇩l literal⇩2 premise⇩2" and
literal⇩2_γ: "literal⇩2 ⋅l ρ⇩2 ⊙ γ = literal.from_ground literal⇩G⇩2"
using is_strictly_maximal⇩l_ground_subst_stability[OF
premise⇩2_grounding[folded clause.subst_comp_subst]
literal⇩G⇩2_is_strictly_maximal⇩l
].
then have literal⇩2_in_premise⇩2: "literal⇩2 ∈# premise⇩2"
using strictly_maximal⇩l_in_clause by blast
have literal⇩2_grounding: "literal.is_ground (literal⇩2 ⋅l ρ⇩2 ⊙ γ)"
using literal⇩2_γ by simp
obtain premise⇩1' where premise⇩1: "premise⇩1 = add_mset literal⇩1 premise⇩1'"
by (meson literal⇩1_in_premise⇩1 multi_member_split)
then have premise⇩1'_γ: "premise⇩1' ⋅ ρ⇩1 ⋅ γ = clause.from_ground premise⇩G⇩1'"
using premise⇩1_γ
unfolding clause_from_ground_add_mset literal⇩1_γ[symmetric]
by (simp add: subst_clause_add_mset)
obtain premise⇩2' where premise⇩2: "premise⇩2 = add_mset literal⇩2 premise⇩2'"
by (meson literal⇩2_in_premise⇩2 multi_member_split)
then have premise⇩2'_γ: "premise⇩2' ⋅ ρ⇩2 ⋅ γ = clause.from_ground premise⇩G⇩2'"
using premise⇩2_γ
unfolding clause_from_ground_add_mset literal⇩2_γ[symmetric]
by (simp add: subst_clause_add_mset)
let ?𝒫 = "if 𝒫⇩G = Pos then Pos else Neg"
have [simp]: "𝒫⇩G ≠ Pos ⟷ 𝒫⇩G = Neg"
using ground_superpositionI(4)
by auto
have "literal⇩1 ⋅l ρ⇩1 ⋅l γ =
?𝒫 (Upair (context.from_ground context⇩G)⟨term.from_ground term⇩G⇩1⟩ (term.from_ground term⇩G⇩2))"
using literal⇩1_γ
unfolding ground_superpositionI(5)
by (simp add: literal_from_ground_atom_from_ground atom_from_ground_term_from_ground
ground_term_with_context(3))
then obtain term⇩1_with_context term⇩1' where
literal⇩1: "literal⇩1 = ?𝒫 (Upair term⇩1_with_context term⇩1')" and
term⇩1'_γ: "term⇩1' ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩2" and
term⇩1_with_context_γ:
"term⇩1_with_context ⋅t ρ⇩1 ⋅t γ = (context.from_ground context⇩G)⟨term.from_ground term⇩G⇩1⟩"
by (smt (verit) obtain_from_literal_subst)
from literal⇩2_γ have "literal⇩2 ⋅l ρ⇩2 ⋅l γ = term.from_ground term⇩G⇩1 ≈ term.from_ground term⇩G⇩3"
unfolding ground_superpositionI(6) atom_from_ground_term_from_ground
literal_from_ground_atom_from_ground(2) literal.subst_comp_subst.
then obtain term⇩2 term⇩2' where
literal⇩2: "literal⇩2 = term⇩2 ≈ term⇩2'" and
term⇩2_γ: "term⇩2 ⋅t ρ⇩2 ⋅t γ = term.from_ground term⇩G⇩1" and
term⇩2'_γ: "term⇩2' ⋅t ρ⇩2 ⋅t γ = term.from_ground term⇩G⇩3"
using obtain_from_pos_literal_subst
by metis
let ?inference_into_var = "∄context⇩1 term⇩1.
term⇩1_with_context = context⇩1⟨term⇩1⟩ ∧
term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1 ∧
context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G ∧
is_Fun term⇩1"
have inference_into_var_is_redundant:
"?inference_into_var ⟹ ground.redundant_infer premise_groundings ι⇩G"
proof-
assume inference_into_var: ?inference_into_var
obtain term⇩x context⇩x context⇩x' where
term⇩1_with_context: "term⇩1_with_context = context⇩x⟨term⇩x⟩" and
is_Var_term⇩x: "is_Var term⇩x" and
"context.from_ground context⇩G = (context⇩x ⋅t⇩c ρ⇩1 ⋅t⇩c γ) ∘⇩c context⇩x'"
proof-
from inference_into_var term⇩1_with_context_γ
have
"∃term⇩x context⇩x context⇩x'.
term⇩1_with_context = context⇩x⟨term⇩x⟩ ∧
is_Var term⇩x ∧
context.from_ground context⇩G = (context⇩x ⋅t⇩c ρ⇩1 ⋅t⇩c γ) ∘⇩c context⇩x'"
proof(induction term⇩1_with_context arbitrary: context⇩G)
case (Var x)
show ?case
proof(intro exI conjI)
show
"Var x = □⟨Var x⟩"
"is_Var (Var x)"
"context.from_ground context⇩G = (□ ⋅t⇩c ρ⇩1 ⋅t⇩c γ) ∘⇩c context.from_ground context⇩G"
by simp_all
qed
next
case (Fun f terms)
then have "context⇩G ≠ GHole"
by (metis ctxt_of_gctxt.simps(1) vars_term_of_gterm
vars_ctxt_of_gctxt[of "gctxt_of_ctxt (□ ∘⇩c □)"]
gctxt_ident_iff_eq_GHole[of "□⇩G" term⇩G⇩1]
gctxt_ident_iff_eq_GHole[of "□⇩G" undefined]
ctxt_eq[of "□" "Fun f terms" "□⟨Fun f terms⟩"]
ground_term_with_context3[of context⇩G term⇩G⇩1]
ground_term_with_context3[of "□⇩G" undefined]
actxt.map(1)[of "λx. x" "λuua. uua ⋅t ρ⇩1"]
actxt.map(1)[of "λx. x" "λuua. uua ⋅t γ"]
intp_actxt_compose[of Fun "□" "□" "Fun f terms"]
intp_actxt_compose[of Fun "□" "□" "term_of_gterm undefined"]
gctxt_of_ctxt_inv[of "□ ∘⇩c □"]
term.discI(2)[of "Fun f terms" f terms]
less⇩t_ground_subterm_property[of "term.from_ground undefined" "□ ∘⇩c □"]
term_of_gterm_ctxt_apply_ground(1)[of undefined "□ ∘⇩c □" "term_of_gterm undefined"]
term_order.less_imp_not_eq[of "term.from_ground _" "term.from_ground _"])
then obtain terms⇩G⇩1 context⇩G' terms⇩G⇩2 where
context⇩G: "context⇩G = GMore f terms⇩G⇩1 context⇩G' terms⇩G⇩2"
using Fun(3)
by(cases context⇩G) auto
have terms_γ:
"map (λterm. term ⋅t ρ⇩1 ⋅t γ) terms =
map term.from_ground terms⇩G⇩1 @ (context.from_ground context⇩G')⟨term.from_ground term⇩G⇩1⟩ #
map term.from_ground terms⇩G⇩2"
using Fun(3)
unfolding context⇩G
by(simp add: comp_def)
then obtain terms⇩1 "term" terms⇩2 where
terms: "terms = terms⇩1 @ term # terms⇩2" and
terms⇩1_γ: "map (λterm. term ⋅t ρ⇩1 ⋅t γ) terms⇩1 = map term.from_ground terms⇩G⇩1" and
terms⇩2_γ: "map (λterm. term ⋅t ρ⇩1 ⋅t γ) terms⇩2 = map term.from_ground terms⇩G⇩2"
by (smt (z3) append_eq_map_conv map_eq_Cons_D)
with terms_γ
have term_γ: "term ⋅t ρ⇩1 ⋅t γ = (context.from_ground context⇩G')⟨term.from_ground term⇩G⇩1⟩"
by simp
show ?case
proof(cases "term.is_ground term")
case True
with term_γ
obtain term⇩1 context⇩1 where
"term = context⇩1⟨term⇩1⟩"
"term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1"
"context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G'"
"is_Fun term⇩1"
by (metis Term.ground_vars_term_empty context.ground_is_ground ground_subst_apply
term.ground_is_ground context.subst_ident_if_ground gterm_is_fun)
moreover then have "Fun f terms = (More f terms⇩1 context⇩1 terms⇩2)⟨term⇩1⟩"
unfolding terms
by auto
ultimately have
"∃context⇩1 term⇩1.
Fun f terms = context⇩1⟨term⇩1⟩ ∧
term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1 ∧
context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G ∧
is_Fun term⇩1"
by (auto
intro: exI[of _ "More f terms⇩1 context⇩1 terms⇩2"] exI[of _ term⇩1]
simp: comp_def terms⇩1_γ terms⇩2_γ context⇩G)
then show ?thesis
using Fun(2)
by argo
next
case False
moreover have "term ∈ set terms"
using terms by auto
moreover have
"∄context⇩1 term⇩1. term = context⇩1⟨term⇩1⟩ ∧
term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1 ∧
context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G' ∧
is_Fun term⇩1"
proof(rule notI)
assume
"∃context⇩1 term⇩1.
term = context⇩1⟨term⇩1⟩ ∧
term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1 ∧
context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G' ∧
is_Fun term⇩1"
then obtain context⇩1 term⇩1 where
"term": "term = context⇩1⟨term⇩1⟩"
"term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1"
"context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G'"
"is_Fun term⇩1"
by blast
then have
"∃context⇩1 term⇩1.
Fun f terms = context⇩1⟨term⇩1⟩ ∧
term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1 ∧
context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G ∧
is_Fun term⇩1"
by(auto
intro: exI[of _ "(More f terms⇩1 context⇩1 terms⇩2)"] exI[of _ term⇩1]
simp: "term" terms terms⇩1_γ terms⇩2_γ context⇩G comp_def)
then show False
using Fun(2)
by argo
qed
ultimately obtain term⇩x context⇩x context⇩x' where
"term = context⇩x⟨term⇩x⟩"
"is_Var term⇩x"
"context.from_ground context⇩G' = (context⇩x ⋅t⇩c ρ⇩1 ⋅t⇩c γ) ∘⇩c context⇩x'"
using Fun(1) term_γ by blast
then have
"Fun f terms = (More f terms⇩1 context⇩x terms⇩2)⟨term⇩x⟩"
"is_Var term⇩x"
"context.from_ground context⇩G = (More f terms⇩1 context⇩x terms⇩2 ⋅t⇩c ρ⇩1 ⋅t⇩c γ) ∘⇩c context⇩x'"
by(auto simp: terms terms⇩1_γ terms⇩2_γ context⇩G comp_def)
then show ?thesis
by blast
qed
qed
then show ?thesis
using that
by blast
qed
then have context⇩G: "context.from_ground context⇩G = context⇩x ∘⇩c context⇩x' ⋅t⇩c ρ⇩1 ⋅t⇩c γ"
using ground_context_subst[OF context.ground_is_ground] ctxt_compose_subst_compose_distrib
by metis
obtain τ⇩x where τ⇩x: "welltyped typeof_fun 𝒱⇩1 term⇩x τ⇩x"
using term⇩1_with_context typing(1)
unfolding premise⇩1 welltyped⇩c_def literal⇩1 welltyped⇩l_def welltyped⇩a_def
by (metis welltyped.simps is_Var_term⇩x term.collapse(1))
have ι⇩G_parts:
"set (side_prems_of ι⇩G) = {premise⇩G⇩2}"
"main_prem_of ι⇩G = premise⇩G⇩1"
"concl_of ι⇩G = conclusion⇩G"
unfolding ι⇩G
by simp_all
from is_Var_term⇩x
obtain var⇩x where var⇩x: "Var var⇩x = term⇩x ⋅t ρ⇩1"
using renaming(1)[unfolded term_subst_is_renaming_iff]
by (cases term⇩x) auto
have τ⇩x_var⇩x: "welltyped typeof_fun 𝒱⇩1 (Var var⇩x) τ⇩x"
using τ⇩x typing(6)
unfolding welltyped⇩σ_on_def var⇩x premise⇩1 literal⇩1 term⇩1_with_context
by(clause_auto simp: welltyped⇩σ_on_def welltyped⇩σ_on_welltyped)
show ?thesis
proof(unfold ground.redundant_infer_def ι⇩G_parts, intro exI conjI)
let ?update = "(context⇩x' ⋅t⇩c ρ⇩1 ⋅t⇩c γ)⟨term.from_ground term⇩G⇩3⟩"
define γ' where
γ': "γ' ≡ γ(var⇩x := ?update)"
have update_grounding: "term.is_ground ?update"
proof-
have "context.is_ground ((context⇩x ⋅t⇩c ρ⇩1 ⋅t⇩c γ) ∘⇩c (context⇩x' ⋅t⇩c ρ⇩1 ⋅t⇩c γ))"
using context.ground_is_ground[of context⇩G] context⇩G
by fastforce
then show ?thesis
using context_is_ground_context_compose1(2)
by auto
qed
let ?context⇩x'_γ = "context.to_ground (context⇩x' ⋅t⇩c ρ⇩1 ⋅t⇩c γ)"
note term_from_ground_context =
ground_term_with_context1[OF _ term.ground_is_ground, unfolded term.from_ground_inverse]
have term⇩x_γ: "term.to_ground (term⇩x ⋅t ρ⇩1 ⋅t γ) = ?context⇩x'_γ⟨term⇩G⇩1⟩⇩G"
using term⇩1_with_context_γ update_grounding
unfolding term⇩1_with_context context⇩G
by(auto simp: term_from_ground_context)
have term⇩x_γ': "term.to_ground (term⇩x ⋅t ρ⇩1 ⋅t γ') = ?context⇩x'_γ⟨term⇩G⇩3⟩⇩G"
using update_grounding
unfolding var⇩x[symmetric] γ'
by(auto simp: term_from_ground_context)
have aux: "term⇩x ⋅t ρ⇩1 ⋅t γ = (context⇩x' ⋅t⇩c ρ⇩1 ⋅t⇩c γ)⟨term.from_ground term⇩G⇩1⟩"
using term⇩x_γ
by (metis ground_term_with_context2 term_subst.is_ground_subst_is_ground
term_with_context_is_ground term.to_ground_inverse typing(3) update_grounding)
have "welltyped⇩c typeof_fun 𝒱⇩2 (clause.from_ground premise⇩G⇩2)"
by (metis ground_superpositionI(2) premise⇩2_γ
clause.comp_subst.left.monoid_action_compatibility typing(2) typing(5)
welltyped⇩σ_on_welltyped⇩c)
then have "∃τ. welltyped typeof_fun 𝒱⇩2 (term.from_ground term⇩G⇩1) τ ∧
welltyped typeof_fun 𝒱⇩2 (term.from_ground term⇩G⇩3) τ"
unfolding ground_superpositionI
by clause_simp
then have aux': "∃τ. welltyped typeof_fun 𝒱⇩1 (term.from_ground term⇩G⇩1) τ ∧
welltyped typeof_fun 𝒱⇩1 (term.from_ground term⇩G⇩3) τ"
by (meson term.ground_is_ground welltyped_is_ground)
have "welltyped typeof_fun 𝒱⇩1 (term⇩x ⋅t ρ⇩1 ⋅t γ) τ⇩x"
proof-
have "
⟦∀x∈context.vars context⇩x ∪ term.vars term⇩x ∪ term.vars term⇩1' ∪ clause.vars premise⇩1'.
First_Order_Type_System.welltyped typeof_fun 𝒱⇩1 ((ρ⇩1 ⊙ γ) x) (𝒱⇩1 x);
First_Order_Type_System.welltyped typeof_fun 𝒱⇩1 term⇩x τ⇩x⟧
⟹ First_Order_Type_System.welltyped typeof_fun 𝒱⇩1 (term⇩x ⋅t ρ⇩1 ⋅t γ) τ⇩x"
by (metis UnI2 sup.commute term_subst.subst_comp_subst welltyped⇩σ_on_def welltyped⇩σ_on_term)
then show ?thesis
using typing(4) τ⇩x
unfolding welltyped⇩σ_on_def var⇩x premise⇩1 literal⇩1 term⇩1_with_context
by clause_simp
qed
then have τ⇩x_update: "welltyped typeof_fun 𝒱⇩1 ?update τ⇩x"
unfolding aux
using aux'
by (meson welltyped⇩κ)
let ?premise⇩1_γ' = "clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ')"
have premise⇩1_γ'_grounding: "clause.is_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ')"
using clause.ground_subst_upd[OF update_grounding premise⇩1_grounding]
unfolding γ'
by blast
have γ'_ground: "term_subst.is_ground_subst (ρ⇩1 ⊙ γ')"
by (metis γ' term.ground_subst_upd term_subst.comp_subst.left.monoid_action_compatibility
term_subst.is_ground_subst_def typing(3) update_grounding)
have γ'_wt: "welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 (ρ⇩1 ⊙ γ')"
using welltyped⇩σ_on_subst_upd[OF τ⇩x_var⇩x τ⇩x_update typing(4)]
unfolding γ' welltyped⇩σ_on_def subst_compose
using First_Order_Type_System.welltyped.simps τ⇩x τ⇩x_update eval_term.simps(1)
eval_with_fresh_var fun_upd_same is_Var_term⇩x renaming(1) subst_compose_def
term.collapse(1) term.distinct(1) term.set_cases(2) term_subst_is_renaming_iff
the_inv_f_f typing(4) var⇩x welltyped⇩σ_on_def
by (smt (verit, del_insts))
show "{?premise⇩1_γ'} ⊆ premise_groundings"
using premise⇩1_γ'_grounding typing γ'_wt γ'_ground
unfolding clause.subst_comp_subst[symmetric] premise⇩1 premise_groundings
clause_groundings_def
by auto
show "finite {?premise⇩1_γ'}"
by simp
show "ground.G_entails ({?premise⇩1_γ'} ∪ {premise⇩G⇩2}) {conclusion⇩G}"
proof(unfold ground.G_entails_def, intro allI impI)
fix I :: "'f gterm rel"
let ?I = "upair ` I"
assume
refl: "refl I" and
trans: "trans I" and
sym: "sym I" and
compatible_with_gctxt: "compatible_with_gctxt I" and
premise: "?I ⊫s {?premise⇩1_γ'} ∪ {premise⇩G⇩2}"
have var⇩x_γ_ground: "term.is_ground (Var var⇩x ⋅t γ)"
using term⇩1_with_context_γ
unfolding term⇩1_with_context var⇩x
by(clause_simp simp: term_subst.is_ground_subst_is_ground typing(3))
show "?I ⊫s { conclusion⇩G }"
proof(cases "?I ⊫ premise⇩G⇩2'")
case True
then show ?thesis
unfolding ground_superpositionI(12)
by auto
next
case False
then have literal⇩G⇩2: "?I ⊫l literal⇩G⇩2"
using premise
unfolding ground_superpositionI(2)
by blast
then have "?I ⊫l ?context⇩x'_γ⟨term⇩G⇩1⟩⇩G ≈ ?context⇩x'_γ⟨term⇩G⇩3⟩⇩G"
unfolding ground_superpositionI(6)
using compatible_with_gctxt compatible_with_gctxt_def sym
by auto
then have "?I ⊫l term.to_ground (term⇩x ⋅t ρ⇩1 ⋅t γ) ≈ term.to_ground (term⇩x ⋅t ρ⇩1 ⋅t γ')"
using term⇩x_γ term⇩x_γ'
by argo
moreover then have "?I ⊫ ?premise⇩1_γ'"
using premise by fastforce
ultimately have "?I ⊫ premise⇩G⇩1"
using
interpretation_clause_congruence[OF
trans sym compatible_with_gctxt update_grounding var⇩x_γ_ground premise⇩1_grounding
]
var⇩x
unfolding γ'
by simp
then have "?I ⊫ add_mset (𝒫⇩G (Upair context⇩G⟨term⇩G⇩1⟩⇩G term⇩G⇩2)) premise⇩G⇩1'"
using ground_superpositionI(1) ground_superpositionI(5) by auto
then have "?I ⊫ add_mset (𝒫⇩G (Upair context⇩G⟨term⇩G⇩3⟩⇩G term⇩G⇩2)) premise⇩G⇩1'"
using
literal⇩G⇩2
interpretation_context_congruence[OF trans sym compatible_with_gctxt]
interpretation_context_congruence'[OF trans sym compatible_with_gctxt]
ground_superpositionI(4)
unfolding ground_superpositionI(6)
by(cases "𝒫⇩G = Pos")(auto simp: sym)
then show ?thesis
unfolding ground_superpositionI(12)
by blast
qed
qed
show "∀clause⇩G ∈ {?premise⇩1_γ'}. clause⇩G ≺⇩c⇩G premise⇩G⇩1"
proof-
have var⇩x_γ: "γ var⇩x = term⇩x ⋅t ρ⇩1 ⋅t γ"
using var⇩x
by simp
have context⇩x_grounding: "context.is_ground (context⇩x ⋅t⇩c ρ⇩1 ⋅t⇩c γ)"
using context⇩G
unfolding subst_compose_ctxt_compose_distrib
by (metis context.ground_is_ground context_is_ground_context_compose1(1))
have term⇩x_grounding: "term.is_ground (term⇩x ⋅t ρ⇩1 ⋅t γ)"
using term⇩1_with_context_γ
unfolding term⇩1_with_context
by(clause_simp simp: term_subst.is_ground_subst_is_ground typing(3))
have
"(context⇩x ∘⇩c context⇩x' ⋅t⇩c ρ⇩1 ⋅t⇩c γ)⟨term.from_ground term⇩G⇩3⟩ ≺⇩t context⇩x⟨term⇩x⟩ ⋅t ρ⇩1 ⋅t γ"
using ground_superpositionI(8)
unfolding
less⇩t⇩G_def
context⇩G[symmetric]
term⇩1_with_context[symmetric]
term⇩1_with_context_γ
less⇩t_ground_context_compatible_iff[OF
context.ground_is_ground term.ground_is_ground term.ground_is_ground].
then have update_smaller: "?update ≺⇩t γ var⇩x"
unfolding
var⇩x_γ
subst_apply_term_ctxt_apply_distrib
subst_compose_ctxt_compose_distrib
Subterm_and_Context.ctxt_ctxt_compose
by(rule less⇩t_ground_context_compatible'[OF
context⇩x_grounding update_grounding term⇩x_grounding])
have var⇩x_in_literal⇩1: "var⇩x ∈ literal.vars (literal⇩1 ⋅l ρ⇩1)"
unfolding literal⇩1 term⇩1_with_context literal.vars_def atom.vars_def
using var⇩x
by(auto simp: subst_literal subst_atom)
have literal⇩1_smaller: "literal⇩1 ⋅l ρ⇩1 ⋅l γ' ≺⇩l literal⇩1 ⋅l ρ⇩1 ⋅l γ"
unfolding γ'
using less⇩l_subst_upd[OF
update_grounding
update_smaller
literal⇩1_grounding[unfolded literal.subst_comp_subst]
var⇩x_in_literal⇩1
].
have premise⇩1'_grounding: "clause.is_ground (premise⇩1' ⋅ ρ⇩1 ⋅ γ)"
using premise⇩1'_γ
by simp
have premise⇩1'_smaller: "premise⇩1' ⋅ ρ⇩1 ⋅ γ' ≼⇩c premise⇩1' ⋅ ρ⇩1 ⋅ γ"
unfolding γ'
using less⇩c_subst_upd[of _ γ, OF update_grounding update_smaller premise⇩1'_grounding]
by(cases "var⇩x ∈ clause.vars (premise⇩1' ⋅ ρ⇩1)") simp_all
have "?premise⇩1_γ' ≺⇩c⇩G premise⇩G⇩1"
using less⇩c_add_mset[OF literal⇩1_smaller premise⇩1'_smaller]
unfolding
less⇩c⇩G_less⇩c
premise⇩G⇩1
subst_clause_add_mset[symmetric]
clause.to_ground_inverse[OF premise⇩1_γ'_grounding]
clause.to_ground_inverse[OF premise⇩1_grounding]
unfolding premise⇩1.
then show ?thesis
by blast
qed
qed
qed
obtain context⇩1 term⇩1 where
term⇩1_with_context: "term⇩1_with_context = context⇩1⟨term⇩1⟩" and
term⇩1_γ: "term⇩1 ⋅t ρ⇩1 ⋅t γ = term.from_ground term⇩G⇩1" and
context⇩1_γ: "context⇩1 ⋅t⇩c ρ⇩1 ⋅t⇩c γ = context.from_ground context⇩G" and
term⇩1_not_Var: "¬ is_Var term⇩1"
using non_redundant ground_superposition inference_into_var_is_redundant
unfolding
ground.Red_I_def
ground.G_Inf_def
premise_groundings
ι⇩G
conclusion⇩G
ground_superpositionI(1, 2)
premise_groundings
by blast
obtain term⇩2'_with_context where
term⇩2'_with_context_γ:
"term⇩2'_with_context ⋅t γ = (context.from_ground context⇩G)⟨term.from_ground term⇩G⇩3⟩" and
term⇩2'_with_context: "term⇩2'_with_context = (context⇩1 ⋅t⇩c ρ⇩1)⟨term⇩2' ⋅t ρ⇩2⟩"
unfolding term⇩2'_γ[symmetric] context⇩1_γ[symmetric]
by force
define 𝒱⇩3 where
"⋀x. 𝒱⇩3 x ≡
if x ∈ clause.vars (premise⇩1 ⋅ ρ⇩1)
then 𝒱⇩1 (the_inv ρ⇩1 (Var x))
else 𝒱⇩2 (the_inv ρ⇩2 (Var x))"
have wt_γ:
"welltyped⇩σ_on (clause.vars (premise⇩1 ⋅ ρ⇩1) ∪ clause.vars (premise⇩2 ⋅ ρ⇩2)) typeof_fun 𝒱⇩3 γ"
proof(unfold welltyped⇩σ_on_def, intro ballI)
fix x
assume x_in_vars: "x ∈ clause.vars (premise⇩1 ⋅ ρ⇩1) ∪ clause.vars (premise⇩2 ⋅ ρ⇩2)"
obtain f ts where γ_x: "γ x = Fun f ts"
using obtain_ground_fun term_subst.is_ground_subst_is_ground[OF typing(3)]
by (metis eval_term.simps(1))
have "welltyped typeof_fun 𝒱⇩3 (γ x) (𝒱⇩3 x)"
proof(cases "x ∈ clause.vars (premise⇩1 ⋅ ρ⇩1)")
case True
then have "Var x ∈ ρ⇩1 ` clause.vars premise⇩1"
by (metis image_eqI renaming(1) renaming_vars_clause)
then have y_in_vars: "the_inv ρ⇩1 (Var x) ∈ clause.vars premise⇩1"
by (metis (no_types, lifting) image_iff renaming(1) term_subst_is_renaming_iff the_inv_f_f)
define y where "y ≡ the_inv ρ⇩1 (Var x)"
have "term.is_ground (Var y ⋅t ρ⇩1 ⋅t γ)"
using term_subst.is_ground_subst_is_ground typing(3) by blast
moreover have "welltyped typeof_fun 𝒱⇩1 (Var y ⋅t ρ⇩1 ⋅t γ) (𝒱⇩1 y)"
using typing(4) y_in_vars
unfolding welltyped⇩σ_on_def y_def
by (simp add: subst_compose)
ultimately have "welltyped typeof_fun 𝒱⇩3 (Var y ⋅t ρ⇩1 ⋅t γ) (𝒱⇩1 y)"
by (meson welltyped_is_ground)
moreover have "ρ⇩1 (the_inv ρ⇩1 (Var x)) = Var x"
by (metis ‹Var x ∈ ρ⇩1 ` clause.vars premise⇩1› image_iff renaming(1) term_subst_is_renaming_iff the_inv_f_f)
ultimately show ?thesis
using True
unfolding 𝒱⇩3_def y_def
by simp
next
case False
then have "Var x ∈ ρ⇩2 ` clause.vars premise⇩2"
using x_in_vars
by (metis Un_iff image_eqI renaming(2) renaming_vars_clause)
then have y_in_vars: "the_inv ρ⇩2 (Var x) ∈ clause.vars premise⇩2"
by (metis (no_types, lifting) image_iff renaming(2) term_subst_is_renaming_iff the_inv_f_f)
define y where "y ≡ the_inv ρ⇩2 (Var x)"
have "term.is_ground (Var y ⋅t ρ⇩2 ⋅t γ)"
using term_subst.is_ground_subst_is_ground typing(3) by blast
moreover have "welltyped typeof_fun 𝒱⇩2 (Var y ⋅t ρ⇩2 ⋅t γ) (𝒱⇩2 y)"
using typing(5) y_in_vars
unfolding welltyped⇩σ_on_def y_def
by (simp add: subst_compose)
ultimately have "welltyped typeof_fun 𝒱⇩3 (Var y ⋅t ρ⇩2 ⋅t γ) (𝒱⇩2 y)"
by (meson welltyped_is_ground)
moreover have "ρ⇩2 (the_inv ρ⇩2 (Var x)) = Var x"
by (metis ‹Var x ∈ ρ⇩2 ` clause.vars premise⇩2› image_iff renaming(2)
term_subst_is_renaming_iff the_inv_f_f)
ultimately show ?thesis
using False
unfolding 𝒱⇩3_def y_def
by simp
qed
then show "welltyped typeof_fun 𝒱⇩3 (γ x) (𝒱⇩3 x)"
unfolding γ_x.
qed
have "term⇩1 ⋅t ρ⇩1 ⋅t γ = term⇩2 ⋅t ρ⇩2 ⋅t γ"
unfolding term⇩1_γ term⇩2_γ ..
moreover have
"∃τ. welltyped typeof_fun 𝒱⇩3 (term⇩1 ⋅t ρ⇩1) τ ∧ welltyped typeof_fun 𝒱⇩3 (term⇩2 ⋅t ρ⇩2) τ"
proof-
have "welltyped⇩c typeof_fun 𝒱⇩2 (premise⇩2 ⋅ ρ⇩2 ⋅ γ)"
using typing
by (metis clause.subst_comp_subst welltyped⇩σ_on_welltyped⇩c)
then obtain τ where
"welltyped typeof_fun 𝒱⇩2 (term.from_ground term⇩G⇩1) τ"
unfolding premise⇩2_γ ground_superpositionI
by clause_simp
then have
"welltyped typeof_fun 𝒱⇩3 (term.from_ground term⇩G⇩1) τ"
using welltyped_is_ground
by (metis term.ground_is_ground)+
then have
"welltyped typeof_fun 𝒱⇩3 (term.from_ground term⇩G⇩1) τ"
by auto
then have
"welltyped typeof_fun 𝒱⇩3 (term⇩1 ⋅t ρ⇩1 ⋅t γ) τ" "welltyped typeof_fun 𝒱⇩3 (term⇩2 ⋅t ρ⇩2 ⋅t γ) τ"
using term⇩1_γ term⇩2_γ
by presburger+
moreover have
"term.vars (term⇩1 ⋅t ρ⇩1) ⊆ clause.vars (premise⇩1 ⋅ ρ⇩1)"
"term.vars (term⇩2 ⋅t ρ⇩2) ⊆ clause.vars (premise⇩2 ⋅ ρ⇩2)"
unfolding premise⇩1 literal⇩1 subst_clause_add_mset term⇩1_with_context premise⇩2 literal⇩2
by clause_simp
ultimately have
"welltyped typeof_fun 𝒱⇩3 (term⇩1 ⋅t ρ⇩1) τ" "welltyped typeof_fun 𝒱⇩3 (term⇩2 ⋅t ρ⇩2) τ"
using wt_γ
unfolding welltyped⇩σ_on_def
by (meson sup_ge1 sup_ge2 welltyped⇩σ_on_subset welltyped⇩σ_on_term wt_γ)+
then show ?thesis
by blast
qed
ultimately obtain μ σ where μ:
"term_subst.is_imgu μ {{term⇩1 ⋅t ρ⇩1, term⇩2 ⋅t ρ⇩2}}"
"γ = μ ⊙ σ"
"welltyped_imgu' typeof_fun 𝒱⇩3 (term⇩1 ⋅t ρ⇩1) (term⇩2 ⋅t ρ⇩2) μ"
using welltyped_imgu'_exists
by (smt (verit, del_insts))
define conclusion' where
conclusion': "conclusion' ≡
add_mset (?𝒫 (Upair term⇩2'_with_context (term⇩1' ⋅t ρ⇩1))) (premise⇩1' ⋅ ρ⇩1 + premise⇩2' ⋅ ρ⇩2) ⋅ μ"
show ?thesis
proof(rule that)
show "superposition (premise⇩2, 𝒱⇩2) (premise⇩1, 𝒱⇩1) (conclusion', 𝒱⇩3)"
proof(rule superpositionI)
show "term_subst.is_renaming ρ⇩1"
using renaming(1).
next
show "term_subst.is_renaming ρ⇩2"
using renaming(2).
next
show "premise⇩1 = add_mset literal⇩1 premise⇩1'"
using premise⇩1.
next
show "premise⇩2 = add_mset literal⇩2 premise⇩2'"
using premise⇩2.
next
show "?𝒫 ∈ {Pos, Neg}"
by simp
next
show "literal⇩1 = ?𝒫 (Upair context⇩1⟨term⇩1⟩ term⇩1')"
unfolding literal⇩1 term⇩1_with_context..
next
show "literal⇩2 = term⇩2 ≈ term⇩2'"
using literal⇩2.
next
show "is_Fun term⇩1"
using term⇩1_not_Var.
next
show "term_subst.is_imgu μ {{term⇩1 ⋅t ρ⇩1, term⇩2 ⋅t ρ⇩2}}"
using μ(1).
next
note premises_clause_to_ground_inverse = assms(9, 10)[THEN clause.to_ground_inverse]
note premise_groundings = assms(10, 9)[unfolded μ(2) clause.subst_comp_subst]
have "premise⇩2 ⋅ ρ⇩2 ⋅ μ ⋅ σ ≺⇩c premise⇩1 ⋅ ρ⇩1 ⋅ μ ⋅ σ"
using ground_superpositionI(3)
unfolding premise⇩G⇩1 premise⇩G⇩2 less⇩c⇩G_less⇩c premises_clause_to_ground_inverse
unfolding μ(2) clause.subst_comp_subst
by blast
then show "¬ premise⇩1 ⋅ ρ⇩1 ⋅ μ ≼⇩c premise⇩2 ⋅ ρ⇩2 ⋅ μ"
using less⇩c_less_eq⇩c_ground_subst_stability[OF premise_groundings]
by blast
next
show "?𝒫 = Pos
∧ select premise⇩1 = {#}
∧ is_strictly_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ) (premise⇩1 ⋅ ρ⇩1 ⋅ μ)
∨ ?𝒫 = Neg
∧ (select premise⇩1 = {#} ∧ is_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ) (premise⇩1 ⋅ ρ⇩1 ⋅ μ)
∨ is_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ) ((select premise⇩1) ⋅ ρ⇩1 ⋅ μ))"
proof(cases "?𝒫 = Pos")
case True
moreover then have select_empty: "select premise⇩1 = {#}"
using clause_subst_empty select(1) ground_superpositionI(9)
by clause_auto
moreover have "is_strictly_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ ⋅l σ) (premise⇩1 ⋅ ρ⇩1 ⋅ μ ⋅ σ)"
using True pos_literal⇩G⇩1_is_strictly_maximal⇩l
unfolding literal⇩1_γ[symmetric] μ(2)
by force
moreover then have "is_strictly_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ) (premise⇩1 ⋅ ρ⇩1 ⋅ μ)"
using
is_strictly_maximal⇩l_ground_subst_stability'[OF
_
premise⇩1_grounding[unfolded μ(2) clause.subst_comp_subst]
]
clause.subst_in_to_set_subst
literal⇩1_in_premise⇩1
by blast
ultimately show ?thesis
by auto
next
case 𝒫_not_Pos: False
then have 𝒫⇩G_Neg: "𝒫⇩G = Neg"
using ground_superpositionI(4)
by fastforce
show ?thesis
proof(cases ?select⇩G_empty)
case select⇩G_empty: True
then have "select premise⇩1 = {#}"
using clause_subst_empty select(1) ground_superpositionI(9) 𝒫⇩G_Neg
by clause_auto
moreover have "is_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ ⋅l σ) (premise⇩1 ⋅ ρ⇩1 ⋅ μ ⋅ σ)"
using neg_literal⇩G⇩1_is_maximal⇩l[OF select⇩G_empty]
unfolding literal⇩1_γ[symmetric] μ(2)
by simp
moreover then have "is_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ) (premise⇩1 ⋅ ρ⇩1 ⋅ μ)"
using
is_maximal⇩l_ground_subst_stability'[OF
_
premise⇩1_grounding[unfolded μ(2) clause.subst_comp_subst]
]
clause.subst_in_to_set_subst
literal⇩1_in_premise⇩1
by blast
ultimately show ?thesis
using 𝒫⇩G_Neg
by simp
next
case select⇩G_not_empty: False
have selected_grounding: "clause.is_ground (select premise⇩1 ⋅ ρ⇩1 ⋅ μ ⋅ σ)"
using select_subst(1)[OF premise⇩1_grounding] select(1)
unfolding μ(2) clause.subst_comp_subst
by (metis clause.ground_is_ground)
note selected_subst =
literal⇩1_selected[
OF 𝒫⇩G_Neg select⇩G_not_empty,
THEN maximal⇩l_in_clause,
THEN clause.subst_in_to_set_subst]
have "is_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l γ) (select premise⇩1 ⋅ ρ⇩1 ⋅ γ)"
using select⇩G_not_empty ground_superpositionI(9) 𝒫⇩G_Neg
unfolding is_maximal_lit_iff_is_maximal⇩l literal⇩1_γ[symmetric] select(1)
by simp
then have "is_maximal⇩l (literal⇩1 ⋅l ρ⇩1 ⋅l μ) ((select premise⇩1) ⋅ ρ⇩1 ⋅ μ)"
using is_maximal⇩l_ground_subst_stability'[OF _ selected_grounding] selected_subst
by (metis μ(2) clause.subst_comp_subst literal.subst_comp_subst)
with select⇩G_not_empty 𝒫⇩G_Neg show ?thesis
by simp
qed
qed
next
show "select premise⇩2 = {#}"
using ground_superpositionI(10) select(2)
by clause_auto
next
have "is_strictly_maximal⇩l (literal⇩2 ⋅l ρ⇩2 ⋅l μ ⋅l σ) (premise⇩2 ⋅ ρ⇩2 ⋅ μ ⋅ σ)"
using literal⇩G⇩2_is_strictly_maximal⇩l
unfolding literal⇩2_γ[symmetric] μ(2)
by simp
then show "is_strictly_maximal⇩l (literal⇩2 ⋅l ρ⇩2 ⋅l μ) (premise⇩2 ⋅ ρ⇩2 ⋅ μ)"
using
is_strictly_maximal⇩l_ground_subst_stability'[OF
_ premise⇩2_grounding[unfolded μ(2) clause.subst_comp_subst]]
literal⇩2_in_premise⇩2
clause.subst_in_to_set_subst
by blast
next
have term_groundings:
"term.is_ground (term⇩1' ⋅t ρ⇩1 ⋅t μ ⋅t σ)"
"term.is_ground (context⇩1⟨term⇩1⟩ ⋅t ρ⇩1 ⋅t μ ⋅t σ)"
unfolding
term⇩1_with_context[symmetric]
term⇩1_with_context_γ[unfolded μ(2) term_subst.subst_comp_subst]
term⇩1'_γ[unfolded μ(2) term_subst.subst_comp_subst]
by simp_all
have "term⇩1' ⋅t ρ⇩1 ⋅t μ ⋅t σ ≺⇩t context⇩1⟨term⇩1⟩ ⋅t ρ⇩1 ⋅t μ ⋅t σ"
using ground_superpositionI(7)
unfolding
term⇩1'_γ[unfolded μ(2) term_subst.subst_comp_subst]
term⇩1_with_context[symmetric]
term⇩1_with_context_γ[unfolded μ(2) term_subst.subst_comp_subst]
less⇩t⇩G_def
ground_term_with_context(3).
then show "¬ context⇩1⟨term⇩1⟩ ⋅t ρ⇩1 ⋅t μ ≼⇩t term⇩1' ⋅t ρ⇩1 ⋅t μ"
using less⇩t_less_eq⇩t_ground_subst_stability[OF term_groundings]
by blast
next
have term_groundings:
"term.is_ground (term⇩2' ⋅t ρ⇩2 ⋅t μ ⋅t σ)"
"term.is_ground (term⇩2 ⋅t ρ⇩2 ⋅t μ ⋅t σ)"
unfolding
term⇩2_γ[unfolded μ(2) term_subst.subst_comp_subst]
term⇩2'_γ[unfolded μ(2) term_subst.subst_comp_subst]
by simp_all
have "term⇩2' ⋅t ρ⇩2 ⋅t μ ⋅t σ ≺⇩t term⇩2 ⋅t ρ⇩2 ⋅t μ ⋅t σ"
using ground_superpositionI(8)
unfolding
term⇩2_γ[unfolded μ(2) term_subst.subst_comp_subst]
term⇩2'_γ[unfolded μ(2) term_subst.subst_comp_subst]
less⇩t⇩G_def.
then show "¬ term⇩2 ⋅t ρ⇩2 ⋅t μ ≼⇩t term⇩2' ⋅t ρ⇩2 ⋅t μ"
using less⇩t_less_eq⇩t_ground_subst_stability[OF term_groundings]
by blast
next
show
"conclusion' = add_mset (?𝒫 (Upair (context⇩1 ⋅t⇩c ρ⇩1)⟨term⇩2' ⋅t ρ⇩2⟩ (term⇩1' ⋅t ρ⇩1)))
(premise⇩1' ⋅ ρ⇩1 + premise⇩2' ⋅ ρ⇩2) ⋅ μ"
unfolding term⇩2'_with_context conclusion'..
show "welltyped_imgu' typeof_fun 𝒱⇩3 (term⇩1 ⋅t ρ⇩1) (term⇩2 ⋅t ρ⇩2) μ"
using μ(3) by blast
show "clause.vars (premise⇩1 ⋅ ρ⇩1) ∩ clause.vars (premise⇩2 ⋅ ρ⇩2) = {}"
using renaming(3).
show "∀x∈clause.vars (premise⇩1 ⋅ ρ⇩1). 𝒱⇩1 (the_inv ρ⇩1 (Var x)) = 𝒱⇩3 x"
unfolding 𝒱⇩3_def
by meson
show "∀x∈clause.vars (premise⇩2 ⋅ ρ⇩2). 𝒱⇩2 (the_inv ρ⇩2 (Var x)) = 𝒱⇩3 x"
unfolding 𝒱⇩3_def
using renaming(3)
by (meson disjoint_iff)
show "welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 ρ⇩1"
using typing(6).
show "welltyped⇩σ_on (clause.vars premise⇩2) typeof_fun 𝒱⇩2 ρ⇩2"
using typing(7).
have "∃τ. welltyped typeof_fun 𝒱⇩2 term⇩2 τ ∧ welltyped typeof_fun 𝒱⇩2 term⇩2' τ"
using typing(2)
unfolding premise⇩2 literal⇩2 welltyped⇩c_def welltyped⇩l_def welltyped⇩a_def
by auto
then show "⋀τ τ'. ⟦has_type typeof_fun 𝒱⇩2 term⇩2 τ; has_type typeof_fun 𝒱⇩2 term⇩2' τ'⟧ ⟹ τ = τ'"
by (metis welltyped_right_unique has_type_welltyped right_uniqueD)
show "all_types 𝒱⇩1" "all_types 𝒱⇩2"
using typing
by auto
qed
have "term_subst.is_idem μ"
using μ(1)
by (simp add: term_subst.is_imgu_iff_is_idem_and_is_mgu)
then have μ_γ: "μ ⊙ γ = γ"
unfolding μ(2) term_subst.is_idem_def
by (metis subst_compose_assoc)
have conclusion'_γ: "conclusion' ⋅ γ = conclusion ⋅ γ"
proof-
have "conclusion ⋅ γ =
add_mset (?𝒫 (Upair (context.from_ground context⇩G)⟨term.from_ground term⇩G⇩3⟩ (term.from_ground term⇩G⇩2)))
(clause.from_ground premise⇩G⇩1' + clause.from_ground premise⇩G⇩2')"
proof-
have "⟦
conclusion⇩G = add_mset (context⇩G⟨term⇩G⇩3⟩⇩G ≈ term⇩G⇩2) (premise⇩G⇩1' + premise⇩G⇩2');
clause.from_ground (clause.to_ground (conclusion ⋅ γ)) = conclusion ⋅ γ; 𝒫⇩G = Pos⟧
⟹ conclusion ⋅ γ =
add_mset
((if Pos = Pos then Pos else Neg)
(Upair (term.from_ground context⇩G⟨term⇩G⇩3⟩⇩G) (term.from_ground term⇩G⇩2)))
(clause.from_ground premise⇩G⇩1' + clause.from_ground premise⇩G⇩2')"
by (simp add: literal_from_ground_atom_from_ground(2) clause_from_ground_add_mset
atom_from_ground_term_from_ground)
moreover have "⟦
conclusion⇩G = add_mset (context⇩G⟨term⇩G⇩3⟩⇩G !≈ term⇩G⇩2) (premise⇩G⇩1' + premise⇩G⇩2');
clause.from_ground (clause.to_ground (conclusion ⋅ γ)) = conclusion ⋅ γ; 𝒫⇩G = Neg⟧
⟹ conclusion ⋅ γ =
add_mset
((if Neg = Pos then Pos else Neg)
(Upair (term.from_ground context⇩G⟨term⇩G⇩3⟩⇩G) (term.from_ground term⇩G⇩2)))
(clause.from_ground premise⇩G⇩1' + clause.from_ground premise⇩G⇩2')"
by (simp add: literal_from_ground_atom_from_ground(1) clause_from_ground_add_mset
atom_from_ground_term_from_ground)
ultimately show ?thesis
using ground_superpositionI(4, 12) clause.to_ground_inverse[OF conclusion_grounding]
unfolding ground_term_with_context(3)
by clause_simp
qed
then show ?thesis
unfolding
conclusion'
term⇩2'_with_context_γ[symmetric]
premise⇩1'_γ[symmetric]
premise⇩2'_γ[symmetric]
term⇩1'_γ[symmetric]
subst_clause_plus[symmetric]
subst_apply_term_ctxt_apply_distrib[symmetric]
subst_atom[symmetric]
unfolding
clause.subst_comp_subst[symmetric]
μ_γ
by(simp add: subst_clause_add_mset subst_literal)
qed
have vars_conclusion':
"clause.vars conclusion' ⊆ clause.vars (premise⇩1 ⋅ ρ⇩1) ∪ clause.vars (premise⇩2 ⋅ ρ⇩2)"
proof
fix x
assume "x ∈ clause.vars conclusion'"
then consider
(term⇩2'_with_context) "x ∈ term.vars (term⇩2'_with_context ⋅t μ)"
| (term⇩1') "x ∈ term.vars (term⇩1' ⋅t ρ⇩1 ⋅t μ)"
| (premise⇩1') "x ∈ clause.vars (premise⇩1' ⋅ ρ⇩1 ⋅ μ)"
| (premise⇩2') "x ∈ clause.vars (premise⇩2' ⋅ ρ⇩2 ⋅ μ)"
unfolding conclusion' subst_clause_add_mset subst_clause_plus subst_literal
by clause_simp
then show "x ∈ clause.vars (premise⇩1 ⋅ ρ⇩1) ∪ clause.vars (premise⇩2 ⋅ ρ⇩2)"
proof(cases)
case t: term⇩2'_with_context
then show ?thesis
using vars_context_imgu[OF μ(1)] vars_term_imgu[OF μ(1)]
unfolding premise⇩1 literal⇩1 term⇩1_with_context premise⇩2 literal⇩2 term⇩2'_with_context
apply clause_simp
by blast
next
case term⇩1'
then show ?thesis
using vars_term_imgu[OF μ(1)]
unfolding premise⇩1 subst_clause_add_mset literal⇩1 term⇩1_with_context premise⇩2 literal⇩2
by clause_simp
next
case premise⇩1'
then show ?thesis
using vars_clause_imgu[OF μ(1)]
unfolding premise⇩1 subst_clause_add_mset literal⇩1 term⇩1_with_context premise⇩2 literal⇩2
by clause_simp
next
case premise⇩2'
then show ?thesis
using vars_clause_imgu[OF μ(1)]
unfolding premise⇩1 subst_clause_add_mset literal⇩1 term⇩1_with_context premise⇩2 literal⇩2
by clause_simp
qed
qed
have surjx: "surj (λx. the_inv ρ⇩2 (Var x))"
using surj_the_inv[OF renaming(2)].
have yy:
"⋀P Q b ty. {x. (if b x then P x else Q x) = ty } =
{x. b x ∧ P x = ty} ∪ {x. ¬b x ∧ Q x = ty}"
by auto
have qq: "⋀ty. infinite {x. 𝒱⇩2 (the_inv ρ⇩2 (Var x)) = ty}"
using needed[OF surjx typing(9)[unfolded all_types_def, rule_format]].
have zz:
"⋀ty. {x. x ∉ clause.vars (premise⇩1 ⋅ ρ⇩1) ∧ 𝒱⇩2 (the_inv ρ⇩2 (Var x)) = ty} =
{x. 𝒱⇩2 (the_inv ρ⇩2 (Var x)) = ty} - {x. x ∈ clause.vars (premise⇩1 ⋅ ρ⇩1)}"
by auto
have "⋀ty. infinite {x. x ∉ clause.vars (premise⇩1 ⋅ ρ⇩1) ∧ 𝒱⇩2 (the_inv ρ⇩2 (Var x)) = ty}"
unfolding zz
using qq
by auto
then have all_types_𝒱⇩3: "all_types 𝒱⇩3"
unfolding 𝒱⇩3_def all_types_def yy
by auto
show "ι⇩G ∈ inference_groundings (Infer [(premise⇩2, 𝒱⇩2), (premise⇩1, 𝒱⇩1)] (conclusion', 𝒱⇩3))"
proof-
have " ⟦conclusion' ⋅ γ = conclusion ⋅ γ;
ground.ground_superposition (clause.to_ground (premise⇩2 ⋅ ρ⇩2 ⋅ γ))
(clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)) (clause.to_ground (conclusion ⋅ γ));
welltyped⇩σ_on (clause.vars conclusion') typeof_fun 𝒱⇩3 γ; all_types 𝒱⇩3⟧
⟹ First_Order_Type_System.welltyped⇩c typeof_fun 𝒱⇩3 conclusion'"
using ‹superposition (premise⇩2, 𝒱⇩2) (premise⇩1, 𝒱⇩1) (conclusion', 𝒱⇩3)›
superposition_preserves_typing typing(1) typing(2) by blast
then have
"is_inference_grounding (Infer [(premise⇩2, 𝒱⇩2), (premise⇩1, 𝒱⇩1)] (conclusion', 𝒱⇩3)) ι⇩G γ ρ⇩1 ρ⇩2"
using
conclusion'_γ ground_superposition
welltyped⇩σ_on_subset[OF wt_γ vars_conclusion']
all_types_𝒱⇩3
unfolding is_inference_grounding_def
unfolding ground.G_Inf_def ι⇩G
by(auto simp: typing renaming premise⇩1_grounding premise⇩2_grounding conclusion_grounding)
then show ?thesis
using is_inference_grounding_inference_groundings
by blast
qed
show "conclusion' ⋅ γ = conclusion ⋅ γ"
using conclusion'_γ.
qed
qed
lemma eq_resolution_ground_instance:
assumes
"ι⇩G ∈ ground.eq_resolution_inferences"
"ι⇩G ∈ ground.Inf_from_q select⇩G (⋃(clause_groundings typeof_fun ` premises))"
"subst_stability_on typeof_fun premises"
obtains ι where
"ι ∈ Inf_from premises"
"ι⇩G ∈ inference_groundings ι"
proof-
obtain premise⇩G conclusion⇩G where
ι⇩G : "ι⇩G = Infer [premise⇩G] conclusion⇩G" and
ground_eq_resolution: "ground.ground_eq_resolution premise⇩G conclusion⇩G"
using assms(1)
by blast
have premise⇩G_in_groundings: "premise⇩G ∈ ⋃(clause_groundings typeof_fun ` premises)"
using assms(2)
unfolding ι⇩G ground.Inf_from_q_def ground.Inf_from_def
by simp
obtain premise "conclusion" γ 𝒱 where
"clause.from_ground premise⇩G = premise ⋅ γ" and
"clause.from_ground conclusion⇩G = conclusion ⋅ γ" and
select: "clause.from_ground (select⇩G premise⇩G) = select premise ⋅ γ" and
premise_in_premises: "(premise, 𝒱) ∈ premises" and
typing: "welltyped⇩c typeof_fun 𝒱 premise"
"term_subst.is_ground_subst γ"
"welltyped⇩σ_on (clause.vars premise) typeof_fun 𝒱 γ"
"all_types 𝒱"
proof-
have x: "⋀a b. ⟦⋀premise γ conclusion 𝒱.
⟦clause.from_ground premise⇩G = premise ⋅ γ;
clause.from_ground conclusion⇩G = conclusion ⋅ γ;
clause.from_ground (select⇩G premise⇩G) = select premise ⋅ γ;
(premise, 𝒱) ∈ premises;
First_Order_Type_System.welltyped⇩c typeof_fun 𝒱 premise;
term_subst.is_ground_subst γ;
welltyped⇩σ_on (clause.vars premise) typeof_fun 𝒱 γ; all_types 𝒱⟧
⟹ thesis;
∀y∈premises.
∀premise⇩G∈clause_groundings typeof_fun y.
∃x∈premises.
case x of
(premise, 𝒱) ⇒
∃γ. premise ⋅ γ = clause.from_ground premise⇩G ∧
select⇩G (clause.to_ground (premise ⋅ γ)) =
clause.to_ground (select premise ⋅ γ) ∧
First_Order_Type_System.welltyped⇩c typeof_fun 𝒱 premise ∧
welltyped⇩σ_on (clause.vars premise) typeof_fun 𝒱 γ ∧
term_subst.is_ground_subst γ ∧ all_types 𝒱;
Infer [premise⇩G] conclusion⇩G ∈ ground.G_Inf; (a, b) ∈ premises;
premise⇩G ∈ clause_groundings typeof_fun (a, b)⟧
⟹ thesis"
by (smt (verit, del_insts) case_prodE clause.ground_is_ground select_subst1
clause.subst_ident_if_ground clause.from_ground_inverse clause.to_ground_inverse)
then show ?thesis
using assms(2, 3) premise⇩G_in_groundings that
unfolding ι⇩G ground.Inf_from_q_def ground.Inf_from_def
by auto
qed
then have
premise_grounding: "clause.is_ground (premise ⋅ γ)" and
premise⇩G: "premise⇩G = clause.to_ground (premise ⋅ γ)" and
conclusion_grounding: "clause.is_ground (conclusion ⋅ γ)" and
conclusion⇩G: "conclusion⇩G = clause.to_ground (conclusion ⋅ γ)"
using clause.ground_is_ground clause.from_ground_inverse
by(smt(verit))+
obtain conclusion' where
eq_resolution: "eq_resolution (premise, 𝒱) (conclusion', 𝒱)" and
ι⇩G: "ι⇩G = Infer [clause.to_ground (premise ⋅ γ)] (clause.to_ground (conclusion' ⋅ γ))" and
inference_groundings: "ι⇩G ∈ inference_groundings (Infer [(premise, 𝒱)] (conclusion', 𝒱))" and
conclusion'_conclusion: "conclusion' ⋅ γ = conclusion ⋅ γ"
using
eq_resolution_lifting[OF
premise_grounding
conclusion_grounding
select[unfolded premise⇩G]
ground_eq_resolution[unfolded premise⇩G conclusion⇩G]
typing
]
unfolding premise⇩G conclusion⇩G ι⇩G
by metis
let ?ι = "Infer [(premise, 𝒱)] (conclusion', 𝒱)"
show ?thesis
proof(rule that)
show "?ι ∈ Inf_from premises"
using premise_in_premises eq_resolution
unfolding Inf_from_def inferences_def inference_system.Inf_from_def
by auto
show "ι⇩G ∈ inference_groundings ?ι"
using inference_groundings.
qed
qed
lemma eq_factoring_ground_instance:
assumes
"ι⇩G ∈ ground.eq_factoring_inferences"
"ι⇩G ∈ ground.Inf_from_q select⇩G (⋃(clause_groundings typeof_fun ` premises))"
"subst_stability_on typeof_fun premises"
obtains ι where
"ι ∈ Inf_from premises"
"ι⇩G ∈ inference_groundings ι"
proof-
obtain premise⇩G conclusion⇩G where
ι⇩G : "ι⇩G = Infer [premise⇩G] conclusion⇩G" and
ground_eq_factoring: "ground.ground_eq_factoring premise⇩G conclusion⇩G"
using assms(1)
by blast
have premise⇩G_in_groundings: "premise⇩G ∈ ⋃(clause_groundings typeof_fun ` premises)"
using assms(2)
unfolding ι⇩G ground.Inf_from_q_def ground.Inf_from_def
by simp
obtain premise "conclusion" γ 𝒱 where
"clause.from_ground premise⇩G = premise ⋅ γ" and
"clause.from_ground conclusion⇩G = conclusion ⋅ γ" and
select: "clause.from_ground (select⇩G (clause.to_ground (premise ⋅ γ))) = select premise ⋅ γ" and
premise_in_premises: "(premise, 𝒱) ∈ premises" and
typing:
"welltyped⇩c typeof_fun 𝒱 premise"
"term_subst.is_ground_subst γ"
"welltyped⇩σ_on (clause.vars premise) typeof_fun 𝒱 γ"
"all_types 𝒱"
using assms(2, 3) premise⇩G_in_groundings
unfolding ι⇩G ground.Inf_from_q_def ground.Inf_from_def
by (smt (verit) clause.subst_ident_if_ground clause.ground_is_ground
old.prod.case old.prod.exhaust select_subst1 clause.to_ground_inverse)
then have
premise_grounding: "clause.is_ground (premise ⋅ γ)" and
premise⇩G: "premise⇩G = clause.to_ground (premise ⋅ γ)" and
conclusion_grounding: "clause.is_ground (conclusion ⋅ γ)" and
conclusion⇩G: "conclusion⇩G = clause.to_ground (conclusion ⋅ γ)"
by (smt(verit) clause.ground_is_ground clause.from_ground_inverse)+
obtain conclusion' where
eq_factoring: "eq_factoring (premise, 𝒱) (conclusion', 𝒱)" and
inference_groundings: "ι⇩G ∈ inference_groundings (Infer [(premise, 𝒱)] (conclusion', 𝒱))" and
conclusion'_conclusion: "conclusion' ⋅ γ = conclusion ⋅ γ"
using
eq_factoring_lifting[OF
premise_grounding
conclusion_grounding
select
ground_eq_factoring[unfolded premise⇩G conclusion⇩G]
]
typing
unfolding premise⇩G conclusion⇩G ι⇩G
by metis
let ?ι = "Infer [(premise, 𝒱)] (conclusion', 𝒱)"
show ?thesis
proof(rule that)
show "?ι ∈ Inf_from premises"
using premise_in_premises eq_factoring
unfolding Inf_from_def inferences_def inference_system.Inf_from_def
by auto
show "ι⇩G ∈ inference_groundings ?ι"
using inference_groundings.
qed
qed
lemma subst_compose_if: "σ ⊙ (λvar. if var ∈ range_vars' σ then σ⇩1 var else σ⇩2 var) = σ ⊙ σ⇩1"
unfolding subst_compose_def range_vars'_def
using term_subst_eq_conv
by fastforce
lemma subst_compose_if':
assumes "range_vars' σ ∩ range_vars' σ' = {}"
shows "σ ⊙ (λvar. if var ∈ range_vars' σ' then σ⇩1 var else σ⇩2 var) = σ ⊙ σ⇩2"
proof-
have "⋀x. σ x ⋅t (λvar. if var ∈ range_vars' σ' then σ⇩1 var else σ⇩2 var) = σ x ⋅t σ⇩2"
proof-
fix x
have "⋀xa. ⟦σ x = Var xa; xa ∈ range_vars' σ'⟧ ⟹ σ⇩1 xa = σ⇩2 xa"
by (metis IntI assms emptyE subst_compose_def term.set_intros(3)
term_subst.comp_subst.left.right_neutral vars_term_range_vars')
moreover have "⋀x1a x2 xa.
⟦σ x = Fun x1a x2; xa ∈ set x2⟧
⟹ xa ⋅t (λvar. if var ∈ range_vars' σ' then σ⇩1 var else σ⇩2 var) = xa ⋅t σ⇩2"
by (smt (verit, ccfv_threshold) UNIV_I UN_iff assms disjoint_iff image_iff range_vars'_def
term.set_intros(4) term_subst_eq_conv)
ultimately show "σ x ⋅t (λvar. if var ∈ range_vars' σ' then σ⇩1 var else σ⇩2 var) = σ x ⋅t σ⇩2"
by(induction "σ x") auto
qed
then show ?thesis
unfolding subst_compose_def
by presburger
qed
lemma is_ground_subst_if:
assumes "term_subst.is_ground_subst γ⇩1" "term_subst.is_ground_subst γ⇩2"
shows "term_subst.is_ground_subst (λvar. if b var then γ⇩1 var else γ⇩2 var)"
using assms
unfolding term_subst.is_ground_subst_def
by (simp add: is_ground_iff)
lemma superposition_ground_instance:
assumes
"ι⇩G ∈ ground.superposition_inferences"
"ι⇩G ∈ ground.Inf_from_q select⇩G (⋃ (clause_groundings typeof_fun ` premises))"
"ι⇩G ∉ ground.GRed_I (⋃ (clause_groundings typeof_fun ` premises))"
"subst_stability_on typeof_fun premises"
obtains ι where
"ι ∈ Inf_from premises"
"ι⇩G ∈ inference_groundings ι"
proof-
obtain premise⇩G⇩1 premise⇩G⇩2 conclusion⇩G where
ι⇩G : "ι⇩G = Infer [premise⇩G⇩2, premise⇩G⇩1] conclusion⇩G" and
ground_superposition: "ground.ground_superposition premise⇩G⇩2 premise⇩G⇩1 conclusion⇩G"
using assms(1)
by blast
have
premise⇩G⇩1_in_groundings: "premise⇩G⇩1 ∈ ⋃ (clause_groundings typeof_fun ` premises)" and
premise⇩G⇩2_in_groundings: "premise⇩G⇩2 ∈ ⋃ (clause_groundings typeof_fun ` premises)"
using assms(2)
unfolding ι⇩G ground.Inf_from_q_def ground.Inf_from_def
by simp_all
obtain premise⇩1 𝒱⇩1 premise⇩2 𝒱⇩2 γ⇩1 γ⇩2 where
premise⇩1_γ⇩1: "premise⇩1 ⋅ γ⇩1 = clause.from_ground premise⇩G⇩1" and
premise⇩2_γ⇩2: "premise⇩2 ⋅ γ⇩2 = clause.from_ground premise⇩G⇩2" and
select:
"clause.from_ground (select⇩G (clause.to_ground (premise⇩1 ⋅ γ⇩1))) = select premise⇩1 ⋅ γ⇩1"
"clause.from_ground (select⇩G (clause.to_ground (premise⇩2 ⋅ γ⇩2))) = select premise⇩2 ⋅ γ⇩2" and
premise⇩1_in_premises: "(premise⇩1, 𝒱⇩1) ∈ premises" and
premise⇩2_in_premises: "(premise⇩2, 𝒱⇩2) ∈ premises" and
wt:
"welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 γ⇩1"
"welltyped⇩σ_on (clause.vars premise⇩2) typeof_fun 𝒱⇩2 γ⇩2"
"term_subst.is_ground_subst γ⇩1"
"term_subst.is_ground_subst γ⇩2"
"welltyped⇩c typeof_fun 𝒱⇩1 premise⇩1"
"welltyped⇩c typeof_fun 𝒱⇩2 premise⇩2"
"all_types 𝒱⇩1"
"all_types 𝒱⇩2"
using assms(2, 4) premise⇩G⇩1_in_groundings premise⇩G⇩2_in_groundings
unfolding ι⇩G ground.Inf_from_q_def ground.Inf_from_def
by (smt (verit, ccfv_threshold) case_prod_conv clause.ground_is_ground select_subst1
surj_pair clause.to_ground_inverse)
obtain ρ⇩1 ρ⇩2 :: "('f, 'v) subst" where
renaming:
"term_subst.is_renaming ρ⇩1"
"term_subst.is_renaming ρ⇩2"
"ρ⇩1 ` (clause.vars premise⇩1) ∩ ρ⇩2 ` (clause.vars premise⇩2) = {}" and
wt_ρ:
"welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 ρ⇩1"
"welltyped⇩σ_on (clause.vars premise⇩2) typeof_fun 𝒱⇩2 ρ⇩2"
using welltyped_on_renaming_exists'[OF _ _ wt(7,8)[unfolded all_types_def, rule_format]]
by (metis clause.finite_vars(1))
have renaming_distinct: "clause.vars (premise⇩1 ⋅ ρ⇩1) ∩ clause.vars (premise⇩2 ⋅ ρ⇩2) = {}"
using renaming(3)
unfolding renaming(1,2)[THEN renaming_vars_clause, symmetric]
by blast
from renaming obtain ρ⇩1_inv ρ⇩2_inv where
ρ⇩1_inv: "ρ⇩1 ⊙ ρ⇩1_inv = Var" and
ρ⇩2_inv: "ρ⇩2 ⊙ ρ⇩2_inv = Var"
unfolding term_subst.is_renaming_def
by blast
have "select premise⇩1 ⊆# premise⇩1" "select premise⇩2 ⊆# premise⇩2"
by (simp_all add: select_subset)
then have select_subset:
"select premise⇩1 ⋅ ρ⇩1 ⊆# premise⇩1 ⋅ ρ⇩1"
"select premise⇩2 ⋅ ρ⇩2 ⊆# premise⇩2 ⋅ ρ⇩2"
by (simp_all add: image_mset_subseteq_mono clause.subst_def)
define γ where
γ: "⋀var. γ var ≡
if var ∈ clause.vars (premise⇩1 ⋅ ρ⇩1)
then (ρ⇩1_inv ⊙ γ⇩1) var
else (ρ⇩2_inv ⊙ γ⇩2) var"
have γ⇩1: "∀x∈ clause.vars premise⇩1. (ρ⇩1 ⊙ γ) x = γ⇩1 x"
proof(intro ballI)
fix x
assume x_in_vars: "x ∈ clause.vars premise⇩1"
obtain y where y: "ρ⇩1 x = Var y"
by (meson is_Var_def renaming(1) term_subst_is_renaming_iff)
then have "y ∈ clause.vars (premise⇩1 ⋅ ρ⇩1)"
using x_in_vars renaming(1) renaming_vars_clause by fastforce
then have "γ y = ρ⇩1_inv y ⋅t γ⇩1"
by (simp add: γ subst_compose)
then show "(ρ⇩1 ⊙ γ) x = γ⇩1 x"
by (metis y ρ⇩1_inv eval_term.simps(1) subst_compose)
qed
have γ⇩2: "∀x∈ clause.vars premise⇩2. (ρ⇩2 ⊙ γ) x = γ⇩2 x"
proof(intro ballI)
fix x
assume x_in_vars: "x ∈ clause.vars premise⇩2"
obtain y where y: "ρ⇩2 x = Var y"
by (meson is_Var_def renaming(2) term_subst_is_renaming_iff)
then have "y ∈ clause.vars (premise⇩2 ⋅ ρ⇩2)"
using x_in_vars renaming(2) renaming_vars_clause by fastforce
then have "γ y = ρ⇩2_inv y ⋅t γ⇩2"
using γ renaming_distinct subst_compose by fastforce
then show "(ρ⇩2 ⊙ γ) x = γ⇩2 x"
by (metis y ρ⇩2_inv eval_term.simps(1) subst_compose)
qed
have γ⇩1_is_ground: "∀x∈clause.vars premise⇩1. term.is_ground (γ⇩1 x)"
by (metis Term.term.simps(17) insert_iff is_ground_iff term_subst.is_ground_subst_def wt(3))
have γ⇩2_is_ground: "∀x∈clause.vars premise⇩2. term.is_ground (γ⇩2 x)"
by (metis Term.term.simps(17) insert_iff is_ground_iff term_subst.is_ground_subst_def wt(4))
have wt_γ:
"welltyped⇩σ_on (clause.vars premise⇩1) typeof_fun 𝒱⇩1 (ρ⇩1 ⊙ γ)"
"welltyped⇩σ_on (clause.vars premise⇩2) typeof_fun 𝒱⇩2 (ρ⇩2 ⊙ γ)"
using wt(1,2) welltyped⇩σ_on_subset welltyped⇩σ_welltyped⇩σ_on γ⇩1 γ⇩2
unfolding welltyped⇩σ_on_def
by auto
have "term_subst.is_ground_subst (ρ⇩1_inv ⊙ γ⇩1)" "term_subst.is_ground_subst (ρ⇩2_inv ⊙ γ⇩2)"
using term_subst.is_ground_subst_comp_right wt by blast+
then have is_ground_subst_γ: "term_subst.is_ground_subst γ"
unfolding γ
using is_ground_subst_if
by fast
have premise⇩1_γ: "premise⇩1 ⋅ ρ⇩1 ⋅ γ = clause.from_ground premise⇩G⇩1"
proof -
have "premise⇩1 ⋅ ρ⇩1 ⊙ (ρ⇩1_inv ⊙ γ⇩1) = clause.from_ground premise⇩G⇩1"
by (metis ρ⇩1_inv premise⇩1_γ⇩1 subst_monoid_mult.mult.left_neutral subst_monoid_mult.mult_assoc)
then show ?thesis
using γ⇩1 premise⇩1_γ⇩1 clause.subst_eq by fastforce
qed
have premise⇩2_γ: "premise⇩2 ⋅ ρ⇩2 ⋅ γ = clause.from_ground premise⇩G⇩2"
proof -
have "premise⇩2 ⋅ ρ⇩2 ⊙ (ρ⇩2_inv ⊙ γ⇩2) = clause.from_ground premise⇩G⇩2"
by (metis ρ⇩2_inv premise⇩2_γ⇩2 subst_monoid_mult.mult.left_neutral subst_monoid_mult.mult_assoc)
then show ?thesis
using γ⇩2 premise⇩2_γ⇩2 clause.subst_eq by force
qed
have "premise⇩1 ⋅ ρ⇩1 ⋅ γ = premise⇩1 ⋅ γ⇩1"
by (simp add: premise⇩1_γ premise⇩1_γ⇩1)
moreover have "select premise⇩1 ⋅ ρ⇩1 ⋅ γ = select premise⇩1 ⋅ γ⇩1"
proof-
have "clause.vars (select premise⇩1 ⋅ ρ⇩1) ⊆ clause.vars (premise⇩1 ⋅ ρ⇩1)"
using select_subset(1) clause_submset_vars_clause_subset by blast
then show ?thesis
unfolding γ
by (smt (verit, best) ρ⇩1_inv clause.subst_eq subsetD
clause.comp_subst.left.monoid_action_compatibility
term_subst.comp_subst.left.right_neutral)
qed
ultimately have select⇩1:
"clause.from_ground (select⇩G (clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ))) = select premise⇩1 ⋅ ρ⇩1 ⋅ γ"
using select(1)
by argo
have "premise⇩2 ⋅ ρ⇩2 ⋅ γ = premise⇩2 ⋅ γ⇩2"
by (simp add: premise⇩2_γ premise⇩2_γ⇩2)
moreover have "select premise⇩2 ⋅ ρ⇩2 ⋅ γ = select premise⇩2 ⋅ γ⇩2"
proof-
have "clause.vars (select premise⇩2 ⋅ ρ⇩2) ⊆ clause.vars (premise⇩2 ⋅ ρ⇩2)"
using select_subset(2) clause_submset_vars_clause_subset by blast
then show ?thesis
unfolding γ
by (smt (verit, best) γ⇩2 γ ‹select premise⇩2 ⊆# premise⇩2› clause_submset_vars_clause_subset
clause.subst_eq subset_iff clause.comp_subst.left.monoid_action_compatibility)
qed
ultimately have select⇩2:
"clause.from_ground (select⇩G (clause.to_ground (premise⇩2 ⋅ ρ⇩2 ⋅ γ))) = select premise⇩2 ⋅ ρ⇩2 ⋅ γ"
using select(2)
by argo
obtain "conclusion" where
conclusion_γ: "conclusion ⋅ γ = clause.from_ground conclusion⇩G"
by (meson clause.ground_is_ground clause.subst_ident_if_ground)
then have
premise⇩1_grounding: "clause.is_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)" and
premise⇩2_grounding: "clause.is_ground (premise⇩2 ⋅ ρ⇩2 ⋅ γ)" and
premise⇩G⇩1: "premise⇩G⇩1 = clause.to_ground (premise⇩1 ⋅ ρ⇩1 ⋅ γ)" and
premise⇩G⇩2: "premise⇩G⇩2 = clause.to_ground (premise⇩2 ⋅ ρ⇩2 ⋅ γ)" and
conclusion_grounding: "clause.is_ground (conclusion ⋅ γ)" and
conclusion⇩G: "conclusion⇩G = clause.to_ground (conclusion ⋅ γ)"
by (simp_all add: premise⇩1_γ premise⇩2_γ)
have "clause_groundings typeof_fun (premise⇩1, 𝒱⇩1) ∪ clause_groundings typeof_fun (premise⇩2, 𝒱⇩2)
⊆ ⋃ (clause_groundings typeof_fun ` premises)"
using premise⇩1_in_premises premise⇩2_in_premises by blast
then have ι⇩G_not_redunant:
"ι⇩G ∉ ground.GRed_I (clause_groundings typeof_fun (premise⇩1, 𝒱⇩1) ∪ clause_groundings typeof_fun (premise⇩2, 𝒱⇩2))"
using assms(3) ground.Red_I_of_subset
by blast
then obtain conclusion' 𝒱⇩3 where
superposition: "superposition (premise⇩2, 𝒱⇩2) (premise⇩1, 𝒱⇩1) (conclusion', 𝒱⇩3)" and
inference_groundings:
"ι⇩G ∈ inference_groundings (Infer [(premise⇩2, 𝒱⇩2), (premise⇩1, 𝒱⇩1)] (conclusion', 𝒱⇩3))" and
conclusion'_γ_conclusion_γ: "conclusion' ⋅ γ = conclusion ⋅ γ"
using
superposition_lifting[OF
renaming(1,2)
renaming_distinct
premise⇩1_grounding
premise⇩2_grounding
conclusion_grounding
select⇩1
select⇩2
ground_superposition[unfolded premise⇩G⇩2 premise⇩G⇩1 conclusion⇩G]
ι⇩G_not_redunant[unfolded ι⇩G premise⇩G⇩2 premise⇩G⇩1 conclusion⇩G]
wt(5, 6)
is_ground_subst_γ
wt_γ
wt_ρ
wt(7, 8)
]
unfolding ι⇩G conclusion⇩G premise⇩G⇩1 premise⇩G⇩2
by blast
let ?ι = "Infer [(premise⇩2, 𝒱⇩2), (premise⇩1, 𝒱⇩1)] (conclusion', 𝒱⇩3)"
show ?thesis
proof(rule that)
show "?ι ∈ Inf_from premises"
using premise⇩1_in_premises premise⇩2_in_premises superposition
unfolding Inf_from_def inferences_def inference_system.Inf_from_def
by auto
show "ι⇩G ∈ inference_groundings ?ι"
using inference_groundings.
qed
qed
lemma ground_instances:
assumes
"ι⇩G ∈ ground.Inf_from_q select⇩G (⋃ (clause_groundings typeof_fun ` premises))"
"ι⇩G ∉ ground.Red_I (⋃ (clause_groundings typeof_fun ` premises))"
"subst_stability_on typeof_fun premises"
obtains ι where
"ι ∈ Inf_from premises"
"ι⇩G ∈ inference_groundings ι"
proof-
have "ι⇩G ∈ ground.superposition_inferences ∨
ι⇩G ∈ ground.eq_resolution_inferences ∨
ι⇩G ∈ ground.eq_factoring_inferences"
using assms(1)
unfolding
ground.Inf_from_q_def
ground.Inf_from_def
ground.G_Inf_def
inference_system.Inf_from_def
by fastforce
then show ?thesis
proof(elim disjE)
assume "ι⇩G ∈ ground.superposition_inferences"
then show ?thesis
using that superposition_ground_instance assms
by blast
next
assume "ι⇩G ∈ ground.eq_resolution_inferences"
then show ?thesis
using that eq_resolution_ground_instance assms
by blast
next
assume "ι⇩G ∈ ground.eq_factoring_inferences"
then show ?thesis
using that eq_factoring_ground_instance assms
by blast
qed
qed
end
context first_order_superposition_calculus
begin
lemma overapproximation:
obtains select⇩G where
"ground_Inf_overapproximated select⇩G premises"
"is_grounding select⇩G"
proof-
obtain select⇩G where
subst_stability: "select_subst_stability_on typeof_fun select select⇩G premises" and
"is_grounding select⇩G"
using obtain_subst_stable_on_select_grounding
by blast
then interpret grounded_first_order_superposition_calculus
where select⇩G = select⇩G
by unfold_locales
have overapproximation: "ground_Inf_overapproximated select⇩G premises"
using ground_instances[OF _ _ subst_stability]
by auto
show thesis
using that[OF overapproximation select⇩G].
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 select⇩G
assume "select⇩G ∈ select⇩G⇩s"
then interpret grounded_first_order_superposition_calculus
where select⇩G = select⇩G
by unfold_locales (simp add: select⇩G⇩s_def)
show "statically_complete_calculus
ground.G_Bot
ground.G_Inf
ground.G_entails
ground.Red_I
ground.Red_F"
using ground.statically_complete_calculus_axioms.
next
fix clauses
have "⋀clauses. ∃select⇩G ∈ select⇩G⇩s. ground_Inf_overapproximated select⇩G clauses"
using overapproximation
unfolding select⇩G⇩s_def
by (smt (verit, best) mem_Collect_eq)
then show "empty_ord.saturated clauses ⟹
∃select⇩G ∈ select⇩G⇩s. ground_Inf_overapproximated select⇩G clauses".
qed
end
end