Theory M
theory M
imports TermsAndClauses Sig
begin
subsection‹Well-typed (well-formed) terms, clauses, literals and problems›
context Signature begin
text‹The type of a term›
fun tpOf where
"tpOf (Var x) = tpOfV x"
|
"tpOf (Fn f Tl) = resOf f"
fun wt where
"wt (Var x) ⟷ True"
|
"wt (Fn f Tl) ⟷
wtFsym f ∧ list_all wt Tl ∧ arOf f = map tpOf Tl"
fun wtA where
"wtA (Eq T1 T2) ⟷ wt T1 ∧ wt T2 ∧ tpOf T1 = tpOf T2"
|
"wtA (Pr p Tl) ⟷
wtPsym p ∧ list_all wt Tl ∧ parOf p = map tpOf Tl"
fun wtL where
"wtL (Pos a) ⟷ wtA a"
|
"wtL (Neg a) ⟷ wtA a"
definition "wtC ≡ list_all wtL"
lemma wtC_append[simp]: "wtC (c1 @ c2) ⟷ wtC c1 ∧ wtC c2"
unfolding wtC_def by simp
definition "wtPB Φ ≡ ∀ c ∈ Φ. wtC c"
lemma wtPB_Un[simp]: "wtPB (Φ1 ∪ Φ2) ⟷ wtPB Φ1 ∧ wtPB Φ2"
unfolding wtPB_def by auto
lemma wtPB_UN[simp]: "wtPB (⋃ i ∈ I. Φ i) ⟷ (∀ i ∈ I. wtPB (Φ i))"
unfolding wtPB_def by auto
lemma wtPB_sappend[simp]:
assumes "wtPB Φ1" and "wtPB Φ2" shows "wtPB (Φ1 @@ Φ2)"
using assms unfolding wtPB_def sappend_def by auto
definition "wtSB π ≡ ∀ x. wt (π x) ∧ tpOf (π x) = tpOfV x"
lemma wtSB_wt[simp]: "wtSB π ⟹ wt (π x)"
unfolding wtSB_def by auto
lemma wtSB_tpOf[simp]: "wtSB π ⟹ tpOf (π x) = tpOfV x"
unfolding wtSB_def by auto
lemma wt_tpOf_subst:
assumes "wtSB π" and "wt T"
shows "wt (subst π T) ∧ tpOf (subst π T) = tpOf T"
using assms apply(induct T) by (auto simp add: list_all_iff)
lemmas wt_subst[simp] = wt_tpOf_subst[THEN conjunct1]
lemmas tpOf_subst[simp] = wt_tpOf_subst[THEN conjunct2]
lemma wtSB_o:
assumes 1: "wtSB π1" and 2: "wtSB π2"
shows "wtSB (subst π1 o π2)"
using 2 unfolding wtSB_def using 1 by auto
definition "getTvars σl ≡ map Var (getVars σl)"
lemma length_getTvars[simp]: "length (getTvars σl) = length σl"
unfolding getTvars_def by auto
lemma wt_getTvars[simp]: "list_all wt (getTvars σl)"
unfolding list_all_length getTvars_def by simp
lemma wt_nth_getTvars[simp]:
"i < length σl ⟹ wt (getTvars σl ! i)"
unfolding getTvars_def by auto
lemma map_tpOf_getTvars[simp]: "map tpOf (getTvars σl) = σl"
unfolding getTvars_def unfolding list_eq_iff by auto
lemma tpOf_nth_getTvars[simp]:
"i < length σl ⟹ tpOf (getTvars σl ! i) = σl ! i"
unfolding getTvars_def by auto
end
subsection ‹Structures›
text‹We split a structre into a ``type structure'' that interprets the types
and the rest of the structure that interprets the function and relation symbols.›
text‹Type structures:›
locale Tstruct =
fixes intT :: "'tp ⇒ 'univ ⇒ bool"
assumes NE_intT: "NE (intT σ)"
text‹Environment:›
type_synonym ('tp,'univ) env = "'tp ⇒ var ⇒ 'univ"
text‹Structures:›
locale Struct = Signature wtFsym wtPsym arOf resOf parOf +
Tstruct intT
for wtFsym and wtPsym
and arOf :: "'fsym ⇒ 'tp list"
and resOf :: "'fsym ⇒ 'tp"
and parOf :: "'psym ⇒ 'tp list"
and intT :: "'tp ⇒ 'univ ⇒ bool"
+
fixes
intF :: "'fsym ⇒ 'univ list ⇒ 'univ"
and intP :: "'psym ⇒ 'univ list ⇒ bool"
assumes
intF: "⟦wtFsym f; list_all2 intT (arOf f) al⟧ ⟹ intT (resOf f) (intF f al)"
and
dummy: "intP = intP"
begin
text‹Well-typed environment:›
definition "wtE ξ ≡ ∀ x. intT (tpOfV x) (ξ x)"
lemma wtTE_intT[simp]: "wtE ξ ⟹ intT (tpOfV x) (ξ x)"
unfolding wtE_def dom_def by auto
definition "pickT σ ≡ SOME a. intT σ a"
lemma pickT[simp]: "intT σ (pickT σ)"
unfolding pickT_def apply(rule someI_ex) using NE_intT by auto
text‹Picking a well-typed environment:›
definition
"pickE (xl::var list) al ≡
SOME ξ. wtE ξ ∧ (∀ i < length xl. ξ (xl!i) = al!i)"
lemma ex_pickE:
assumes "length xl = length al"
and "distinct xl" and "⋀ i. i < length xl ⟹ intT (tpOfV (xl!i)) (al!i)"
shows "∃ ξ. wtE ξ ∧ (∀ i < length xl. ξ (xl!i) = al!i)"
using assms
proof(induct rule: list_induct2)
case Nil show ?case apply(rule exI[of _ "λ x. pickT (tpOfV x)"])
unfolding wtE_def by auto
next
case (Cons x xl a al)
then obtain ξ where 1: "wtE ξ" and 2: "∀ i < length xl. ξ (xl!i) = al!i" by force
define ξ' where "ξ' x' = (if x = x' then a else ξ x')" for x'
show ?case
proof(rule exI[of _ ξ'], unfold wtE_def, safe)
fix x' show "intT (tpOfV x') (ξ' x')"
using 1 Cons.prems(2)[of 0] unfolding ξ'_def by auto
next
fix i assume i: "i < length (x # xl)"
thus "ξ' ((x # xl) ! i) = (a # al) ! i"
proof(cases i)
case (Suc j) hence j: "j < length xl" using i by auto
have "¬ x = (x # xl) ! i" using Suc i Cons.prems(1) by auto
thus ?thesis using Suc using j Cons.prems(1) Cons.hyps 2 unfolding ξ'_def by auto
qed(insert Cons.prems(1) Cons.hyps 2, unfold ξ'_def, simp)
qed
qed
lemma wtE_pickE_pickE:
assumes "length xl = length al"
and "distinct xl" and "⋀ i. i < length xl ⟹ intT (tpOfV (xl!i)) (al!i)"
shows "wtE (pickE xl al) ∧ (∀ i. i < length xl ⟶ pickE xl al (xl!i) = al!i)"
proof-
let ?phi = "λ ξ. wtE ξ ∧ (∀ i < length xl. ξ (xl!i) = al!i)"
show ?thesis unfolding pickE_def apply(rule someI_ex[of ?phi])
using ex_pickE[OF assms] by simp
qed
lemmas wtE_pickE[simp] = wtE_pickE_pickE[THEN conjunct1]
lemma pickE[simp]:
assumes "length xl = length al"
and "distinct xl" and "⋀ i. i < length xl ⟹ intT (tpOfV (xl!i)) (al!i)"
and "i < length xl"
shows "pickE xl al (xl!i) = al!i"
using assms wtE_pickE_pickE by auto
definition "pickAnyE ≡ pickE [] []"
lemma wtE_pickAnyE[simp]: "wtE pickAnyE"
unfolding pickAnyE_def by (rule wtE_pickE) auto
fun int where
"int ξ (Var x) = ξ x"
|
"int ξ (Fn f Tl) = intF f (map (int ξ) Tl)"
fun satA where
"satA ξ (Eq T1 T2) ⟷ int ξ T1 = int ξ T2"
|
"satA ξ (Pr p Tl) ⟷ intP p (map (int ξ) Tl)"
fun satL where
"satL ξ (Pos a) ⟷ satA ξ a"
|
"satL ξ (Neg a) ⟷ ¬ satA ξ a"
definition "satC ξ ≡ list_ex (satL ξ)"
lemma satC_append[simp]: "satC ξ (c1 @ c2) ⟷ satC ξ c1 ∨ satC ξ c2"
unfolding satC_def by auto
lemma satC_iff_set: "satC ξ c ⟷ (∃ l ∈ set c. satL ξ l)"
unfolding satC_def Bex_set[symmetric] ..
definition "satPB ξ Φ ≡ ∀ c ∈ Φ. satC ξ c"
lemma satPB_Un[simp]: "satPB ξ (Φ1 ∪ Φ2) ⟷ satPB ξ Φ1 ∧ satPB ξ Φ2"
unfolding satPB_def by auto
lemma satPB_UN[simp]: "satPB ξ (⋃ i ∈ I. Φ i) ⟷ (∀ i ∈ I. satPB ξ (Φ i))"
unfolding satPB_def by auto
lemma satPB_sappend[simp]: "satPB ξ (Φ1 @@ Φ2) ⟷ satPB ξ Φ1 ∨ satPB ξ Φ2"
unfolding satPB_def sappend_def by (fastforce simp: satC_append)
definition "SAT Φ ≡ ∀ ξ. wtE ξ ⟶ satPB ξ Φ"
lemma SAT_UN[simp]: "SAT (⋃ i ∈ I. Φ i) ⟷ (∀ i ∈ I. SAT (Φ i))"
unfolding SAT_def by auto
text‹Soundness of typing w.r.t. interpretation:›
lemma wt_int:
assumes wtE: "wtE ξ" and wt: "wt T"
shows "intT (tpOf T) (int ξ T)"
using wt apply(induct T) using wtE
by (auto intro!: intF simp add: list_all2_map_map)
lemma int_cong:
assumes "⋀x. x ∈ vars T ⟹ ξ1 x = ξ2 x"
shows "int ξ1 T = int ξ2 T"
using assms proof(induct T)
case (Fn f Tl)
hence 1: "map (int ξ1) Tl = map (int ξ2) Tl"
unfolding list_all_iff by (auto intro: map_ext)
show ?case apply simp by (metis 1)
qed auto
lemma satA_cong:
assumes "⋀x. x ∈ varsA at ⟹ ξ1 x = ξ2 x"
shows "satA ξ1 at ⟷ satA ξ2 at"
using assms int_cong[of _ ξ1 ξ2]
apply(cases at) apply(fastforce intro!: int_cong[of _ ξ1 ξ2])
apply simp by (metis (opaque_lifting, mono_tags) map_eq_conv)
lemma satL_cong:
assumes "⋀ x. x ∈ varsL l ⟹ ξ1 x = ξ2 x"
shows "satL ξ1 l ⟷ satL ξ2 l"
using assms satA_cong[of _ ξ1 ξ2] by (cases l, auto)
lemma satC_cong:
assumes "⋀ x. x ∈ varsC c ⟹ ξ1 x = ξ2 x"
shows "satC ξ1 c ⟷ satC ξ2 c"
using assms satL_cong[of _ ξ1 ξ2] unfolding satC_def varsC_def
apply (induct c) by (fastforce intro!: satL_cong[of _ ξ1 ξ2])+
lemma satPB_cong:
assumes "⋀ x. x ∈ varsPB Φ ⟹ ξ1 x = ξ2 x"
shows "satPB ξ1 Φ ⟷ satPB ξ2 Φ"
by (force simp: satPB_def varsPB_def intro!: satC_cong ball_cong assms)
lemma int_o:
"int (int ξ o ρ) T = int ξ (subst ρ T)"
apply(induct T) apply simp_all unfolding list_all_iff o_def
using map_ext by (metis (lifting, no_types))
lemmas int_subst = int_o[symmetric]
lemma int_o_subst:
"int ξ o subst ρ = int (int ξ o ρ)"
apply(rule ext) apply(subst comp_def) unfolding int_o[symmetric] ..
lemma satA_o:
"satA (int ξ o ρ) at = satA ξ (substA ρ at)"
by (cases at, simp_all add: int_o_subst int_o[of ξ ρ])
lemmas satA_subst = satA_o[symmetric]
lemma satA_o_subst:
"satA ξ o substA ρ = satA (int ξ o ρ)"
apply(rule ext) apply(subst comp_def) unfolding satA_o[symmetric] ..
lemma satL_o:
"satL (int ξ o ρ) l = satL ξ (substL ρ l)"
using satA_o[of ξ ρ] by (cases l, simp_all)
lemmas satL_subst = satL_o[symmetric]
lemma satL_o_subst:
"satL ξ o substL ρ = satL (int ξ o ρ)"
apply(rule ext) apply(subst comp_def) unfolding satL_o[symmetric] ..
lemma satC_o:
"satC (int ξ o ρ) c = satC ξ (substC ρ c)"
using satL_o[of ξ ρ] unfolding satC_def substC_def by (induct c, auto)
lemmas satC_subst = satC_o[symmetric]
lemma satC_o_subst:
"satC ξ o substC ρ = satC (int ξ o ρ)"
apply(rule ext) apply(subst comp_def) unfolding satC_o[symmetric] ..
lemma satPB_o:
"satPB (int ξ o ρ) Φ = satPB ξ (substPB ρ Φ)"
using satC_o[of ξ ρ] unfolding satPB_def substPB_def by auto
lemmas satPB_subst = satPB_o[symmetric]
lemma satPB_o_subst:
"satPB ξ o substPB ρ = satPB (int ξ o ρ)"
apply(rule ext) apply(subst comp_def) unfolding satPB_o[symmetric] ..
lemma wtE_o:
assumes 1: "wtE ξ" and 2: "wtSB ρ"
shows "wtE (int ξ o ρ)"
unfolding wtE_def proof
fix x have 0: "tpOfV x = tpOf (ρ x)" using 2 by auto
show "intT (tpOfV x) ((int ξ ∘ ρ) x)" apply(subst 0) unfolding comp_def
apply(rule wt_int[OF 1]) using 2 by auto
qed
definition "compE ρ ξ x ≡ int ξ (ρ x)"
lemma wtE_compE:
assumes "wtSB ρ" and "wtE ξ" shows "wtE (compE ρ ξ)"
unfolding wtE_def using assms wt_int
unfolding wtSB_def compE_def by fastforce
lemma compE_upd: "compE (ρ (x := T)) ξ = (compE ρ ξ) (x := int ξ T)"
unfolding compE_def[abs_def] by auto
end
context Signature begin
fun fsyms where
"fsyms (Var x) = {}"
|
"fsyms (Fn f Tl) = {f} ∪ ⋃ (set (map fsyms Tl))"
fun fsymsA where
"fsymsA (Eq T1 T2) = fsyms T1 ∪ fsyms T2"
|
"fsymsA (Pr p Tl) = ⋃ (set (map fsyms Tl))"
fun fsymsL where
"fsymsL (Pos at) = fsymsA at"
|
"fsymsL (Neg at) = fsymsA at"
definition "fsymsC c = ⋃ (set (map fsymsL c))"
definition "fsymsPB Φ = ⋃ {fsymsC c | c. c ∈ Φ}"
lemma fsyms_int_cong:
assumes S1: "Struct wtFsym wtPsym arOf resOf intT intF1 intP"
and S2: "Struct wtFsym wtPsym arOf resOf intT intF2 intP"
and 0: "⋀ f. f ∈ fsyms T ⟹ intF1 f = intF2 f"
shows "Struct.int intF1 ξ T = Struct.int intF2 ξ T"
using 0 proof(induct T)
case (Fn f Tl)
hence 1: "map (Struct.int intF1 ξ) Tl = map (Struct.int intF2 ξ) Tl"
unfolding list_all_iff map_ext by auto
show ?case
using Fn Struct.int.simps[OF S1, of ξ] Struct.int.simps[OF S2, of ξ] apply simp
using 1 by metis
qed (auto simp: Struct.int.simps[OF S1, of ξ] Struct.int.simps[OF S2, of ξ])
lemma fsyms_satA_cong:
assumes S1: "Struct wtFsym wtPsym arOf resOf intT intF1 intP"
and S2: "Struct wtFsym wtPsym arOf resOf intT intF2 intP"
and 0: "⋀ f. f ∈ fsymsA at ⟹ intF1 f = intF2 f"
shows "Struct.satA intF1 intP ξ at ⟷ Struct.satA intF2 intP ξ at"
using 0 fsyms_int_cong[OF S1 S2]
apply(cases at)
apply(fastforce intro!: fsyms_int_cong[OF S1 S2, of _ ξ]
simp: Struct.satA.simps[OF S1, of ξ] Struct.satA.simps[OF S2, of ξ])
apply (simp add: Struct.satA.simps[OF S1, of ξ] Struct.satA.simps[OF S2, of ξ])
by (metis (opaque_lifting, mono_tags) map_eq_conv)
lemma fsyms_satL_cong:
assumes S1: "Struct wtFsym wtPsym arOf resOf intT intF1 intP"
and S2: "Struct wtFsym wtPsym arOf resOf intT intF2 intP"
and 0: "⋀ f. f ∈ fsymsL l ⟹ intF1 f = intF2 f"
shows "Struct.satL intF1 intP ξ l ⟷ Struct.satL intF2 intP ξ l"
using 0 fsyms_satA_cong[OF S1 S2]
by (cases l, auto simp: Struct.satL.simps[OF S1, of ξ] Struct.satL.simps[OF S2, of ξ])
lemma fsyms_satC_cong:
assumes S1: "Struct wtFsym wtPsym arOf resOf intT intF1 intP"
and S2: "Struct wtFsym wtPsym arOf resOf intT intF2 intP"
and 0: "⋀ f. f ∈ fsymsC c ⟹ intF1 f = intF2 f"
shows "Struct.satC intF1 intP ξ c ⟷ Struct.satC intF2 intP ξ c"
using 0 fsyms_satL_cong[OF S1 S2]
unfolding Struct.satC_def[OF S1] Struct.satC_def[OF S2] fsymsC_def
apply (induct c) by (fastforce intro!: fsyms_satL_cong[OF S1 S2])+
lemma fsyms_satPB_cong:
assumes S1: "Struct wtFsym wtPsym arOf resOf intT intF1 intP"
and S2: "Struct wtFsym wtPsym arOf resOf intT intF2 intP"
and 0: "⋀ f. f ∈ fsymsPB Φ ⟹ intF1 f = intF2 f"
shows "Struct.satPB intF1 intP ξ Φ ⟷ Struct.satPB intF2 intP ξ Φ"
by (force simp: Struct.satPB_def[OF S1] Struct.satPB_def[OF S2] fsymsPB_def
intro!: fsyms_satC_cong[OF S1 S2] ball_cong 0)
lemma fsymsPB_Un[simp]: "fsymsPB (Φ1 ∪ Φ2) = fsymsPB Φ1 ∪ fsymsPB Φ2"
unfolding fsymsPB_def by auto
lemma fsymsC_append[simp]: "fsymsC (c1 @ c2) = fsymsC c1 ∪ fsymsC c2"
unfolding fsymsC_def by auto
lemma fsymsPB_sappend_incl[simp]:
"fsymsPB (Φ1 @@ Φ2) ⊆ fsymsPB Φ1 ∪ fsymsPB Φ2"
by (unfold fsymsPB_def sappend_def, fastforce)
lemma fsymsPB_sappend[simp]:
assumes 1: "Φ1 ≠ {}" and 2: "Φ2 ≠ {}"
shows "fsymsPB (Φ1 @@ Φ2) = fsymsPB Φ1 ∪ fsymsPB Φ2"
proof safe
fix x
{assume "x ∈ fsymsPB Φ1"
then obtain c1 c2 where "x ∈ fsymsC c1" and "c1 ∈ Φ1" and "c2 ∈ Φ2"
using 2 unfolding fsymsPB_def by auto
thus "x ∈ fsymsPB (Φ1 @@ Φ2)" unfolding sappend_def fsymsPB_def by fastforce
}
{assume "x ∈ fsymsPB Φ2"
then obtain c1 c2 where "x ∈ fsymsC c2" and "c1 ∈ Φ1" and "c2 ∈ Φ2"
using 1 unfolding fsymsPB_def by auto
thus "x ∈ fsymsPB (Φ1 @@ Φ2)" unfolding sappend_def fsymsPB_def by fastforce
}
qed(unfold fsymsPB_def sappend_def, fastforce)
lemma Struct_upd:
assumes "Struct wtFsym wtPsym arOf resOf intT intF intP"
and "⋀ al. list_all2 intT (arOf ef) al ⟹ intT (resOf ef) (EF al)"
shows "Struct wtFsym wtPsym arOf resOf intT (intF (ef := EF)) intP"
apply standard using assms
unfolding Struct_def Struct_axioms_def Tstruct_def by auto
end
subsection‹Problems›
text‹A problem is a potentially infinitary formula in clausal form, i.e.,
a potentially infinite conjunction of clauses.›
locale Problem = Signature wtFsym wtPsym arOf resOf parOf
for wtFsym wtPsym
and arOf :: "'fsym ⇒ 'tp list"
and resOf :: "'fsym ⇒ 'tp"
and parOf :: "'psym ⇒ 'tp list"
+
fixes Φ :: "('fsym, 'psym) prob"
assumes wt_Φ: "wtPB Φ"
subsection‹Models of a problem›
text‹Model of a problem:›
locale Model = Problem + Struct +
assumes SAT: "SAT Φ"
begin
lemma sat_Φ: "wtE ξ ⟹ satPB ξ Φ"
using SAT unfolding SAT_def by auto
end
end