theory FO
imports Main
begin
abbreviation "sorted_distinct xs ≡ sorted xs ∧ distinct xs"
datatype 'a fo_term = Const 'a | Var nat
type_synonym 'a val = "nat → 'a"
fun list_fo_term :: "'a fo_term → 'a list" where
"list_fo_term (Const c) = [c]"
| "list_fo_term _ = []"
fun fv_fo_term_list :: "'a fo_term → nat list" where
"fv_fo_term_list (Var n) = [n]"
| "fv_fo_term_list _ = []"
fun fv_fo_term_set :: "'a fo_term → nat set" where
"fv_fo_term_set (Var n) = {n}"
| "fv_fo_term_set _ = {}"
definition fv_fo_terms_set :: "('a fo_term) list → nat set" where
"fv_fo_terms_set ts = ∪(set (map fv_fo_term_set ts))"
fun fv_fo_terms_list_rec :: "('a fo_term) list → nat list" where
"fv_fo_terms_list_rec [] = []"
| "fv_fo_terms_list_rec (t # ts) = fv_fo_term_list t @ fv_fo_terms_list_rec ts"
definition fv_fo_terms_list :: "('a fo_term) list → nat list" where
"fv_fo_terms_list ts = remdups_adj (sort (fv_fo_terms_list_rec ts))"
fun eval_term :: "'a val → 'a fo_term → 'a" (infix ‹⋅› 60) where
"eval_term σ (Const c) = c"
| "eval_term σ (Var n) = σ n"
definition eval_terms :: "'a val → ('a fo_term) list → 'a list" (infix ‹⊙› 60) where
"eval_terms σ ts = map (eval_term σ) ts"
lemma finite_set_fo_term: "finite (set_fo_term t)"
by (cases t) auto
lemma list_fo_term_set: "set (list_fo_term t) = set_fo_term t"
by (cases t) auto
lemma finite_fv_fo_term_set: "finite (fv_fo_term_set t)"
by (cases t) auto
lemma fv_fo_term_setD: "n ∈ fv_fo_term_set t ==> t = Var n"
by (cases t) auto
lemma fv_fo_term_set_list: "set (fv_fo_term_list t) = fv_fo_term_set t"
by (cases t) auto
lemma sorted_distinct_fv_fo_term_list: "sorted_distinct (fv_fo_term_list t)"
by (cases t) auto
lemma fv_fo_term_set_cong: "fv_fo_term_set t = fv_fo_term_set (map_fo_term f t)"
by (cases t) auto
lemma fv_fo_terms_setI: "Var m ∈ set ts ==> m ∈ fv_fo_terms_set ts"
by (induction ts) (auto simp: fv_fo_terms_set_def)
lemma fv_fo_terms_setD: "m ∈ fv_fo_terms_set ts ==> Var m ∈ set ts"
by (induction ts) (auto simp: fv_fo_terms_set_def dest: fv_fo_term_setD)
lemma finite_fv_fo_terms_set: "finite (fv_fo_terms_set ts)"
by (auto simp: fv_fo_terms_set_def finite_fv_fo_term_set)
lemma fv_fo_terms_set_list: "set (fv_fo_terms_list ts) = fv_fo_terms_set ts"
using fv_fo_term_set_list
unfolding fv_fo_terms_list_def
by (induction ts rule: fv_fo_terms_list_rec.induct)
(auto simp: fv_fo_terms_set_def set_insort_key)
lemma distinct_remdups_adj_sort: "sorted xs ==> distinct (remdups_adj xs)"
by (induction xs rule: induct_list012) auto
lemma sorted_distinct_fv_fo_terms_list: "sorted_distinct (fv_fo_terms_list ts)"
unfolding fv_fo_terms_list_def
by (induction ts rule: fv_fo_terms_list_rec.induct)
(auto simp add: sorted_insort intro: distinct_remdups_adj_sort)
lemma fv_fo_terms_set_cong: "fv_fo_terms_set ts = fv_fo_terms_set (map (map_fo_term f) ts)"
using fv_fo_term_set_cong
by (induction ts) (fastforce simp: fv_fo_terms_set_def)+
lemma eval_term_cong: "(∧n. n ∈ fv_fo_term_set t ==> σ n = σ' n) ==>
eval_term σ t = eval_term σ' t"
by (cases t) auto
lemma eval_terms_fv_fo_terms_set: "σ ⊙ ts = σ' ⊙ ts ==> n ∈ fv_fo_terms_set ts ==> σ n = σ' n"
proof (induction ts)
case (Cons t ts)
then show ?case
by (cases t) (auto simp: eval_terms_def fv_fo_terms_set_def)
qed (auto simp: eval_terms_def fv_fo_terms_set_def)
lemma eval_terms_cong: "(∧n. n ∈ fv_fo_terms_set ts ==> σ n = σ' n) ==>
eval_terms σ ts = eval_terms σ' ts"
by (auto simp: eval_terms_def fv_fo_terms_set_def intro: eval_term_cong)
datatype ('a, 'b) fo_fmla =
Pred 'b "('a fo_term) list"
| Bool bool
| Eqa "'a fo_term" "'a fo_term"
| Neg "('a, 'b) fo_fmla"
| Conj "('a, 'b) fo_fmla" "('a, 'b) fo_fmla"
| Disj "('a, 'b) fo_fmla" "('a, 'b) fo_fmla"
| Exists nat "('a, 'b) fo_fmla"
| Forall nat "('a, 'b) fo_fmla"
fun fv_fo_fmla_list_rec :: "('a, 'b) fo_fmla → nat list" where
"fv_fo_fmla_list_rec (Pred _ ts) = fv_fo_terms_list ts"
| "fv_fo_fmla_list_rec (Bool b) = []"
| "fv_fo_fmla_list_rec (Eqa t t') = fv_fo_term_list t @ fv_fo_term_list t'"
| "fv_fo_fmla_list_rec (Neg φ) = fv_fo_fmla_list_rec φ"
| "fv_fo_fmla_list_rec (Conj φ ψ) = fv_fo_fmla_list_rec φ @ fv_fo_fmla_list_rec ψ"
| "fv_fo_fmla_list_rec (Disj φ ψ) = fv_fo_fmla_list_rec φ @ fv_fo_fmla_list_rec ψ"
| "fv_fo_fmla_list_rec (Exists n φ) = filter (λm. n ≠ m) (fv_fo_fmla_list_rec φ)"
| "fv_fo_fmla_list_rec (Forall n φ) = filter (λm. n ≠ m) (fv_fo_fmla_list_rec φ)"
definition fv_fo_fmla_list :: "('a, 'b) fo_fmla → nat list" where
"fv_fo_fmla_list φ = remdups_adj (sort (fv_fo_fmla_list_rec φ))"
fun fv_fo_fmla :: "('a, 'b) fo_fmla → nat set" where
"fv_fo_fmla (Pred _ ts) = fv_fo_terms_set ts"
| "fv_fo_fmla (Bool b) = {}"
| "fv_fo_fmla (Eqa t t') = fv_fo_term_set t ∪ fv_fo_term_set t'"
| "fv_fo_fmla (Neg φ) = fv_fo_fmla φ"
| "fv_fo_fmla (Conj φ ψ) = fv_fo_fmla φ ∪ fv_fo_fmla ψ"
| "fv_fo_fmla (Disj φ ψ) = fv_fo_fmla φ ∪ fv_fo_fmla ψ"
| "fv_fo_fmla (Exists n φ) = fv_fo_fmla φ - {n}"
| "fv_fo_fmla (Forall n φ) = fv_fo_fmla φ - {n}"
lemma finite_fv_fo_fmla: "finite (fv_fo_fmla φ)"
by (induction φ rule: fv_fo_fmla.induct)
(auto simp: finite_fv_fo_term_set finite_fv_fo_terms_set)
lemma fv_fo_fmla_list_set: "set (fv_fo_fmla_list φ) = fv_fo_fmla φ"
unfolding fv_fo_fmla_list_def
by (induction φ rule: fv_fo_fmla.induct) (auto simp: fv_fo_terms_set_list fv_fo_term_set_list)
lemma sorted_distinct_fv_list: "sorted_distinct (fv_fo_fmla_list φ)"
by (auto simp: fv_fo_fmla_list_def intro: distinct_remdups_adj_sort)
lemma length_fv_fo_fmla_list: "length (fv_fo_fmla_list φ) = card (fv_fo_fmla φ)"
using fv_fo_fmla_list_set[of φ] sorted_distinct_fv_list[of φ]
distinct_card[of "fv_fo_fmla_list φ"]
by auto
lemma fv_fo_fmla_list_eq: "fv_fo_fmla φ = fv_fo_fmla ψ ==> fv_fo_fmla_list φ = fv_fo_fmla_list ψ"
using fv_fo_fmla_list_set sorted_distinct_fv_list
by (metis sorted_distinct_set_unique)
lemma fv_fo_fmla_list_Conj: "fv_fo_fmla_list (Conj φ ψ) = fv_fo_fmla_list (Conj ψ φ)"
using fv_fo_fmla_list_eq[of "Conj φ ψ" "Conj ψ φ"]
by auto
type_synonym 'a table = "('a list) set"
type_synonym ('t, 'b) fo_intp = "'b × nat → 't"
fun wf_fo_intp :: "('a, 'b) fo_fmla → ('a table, 'b) fo_intp → bool" where
"wf_fo_intp (Pred r ts) I ⟷ finite (I (r, length ts))"
| "wf_fo_intp (Bool b) I ⟷ True"
| "wf_fo_intp (Eqa t t') I ⟷ True"
| "wf_fo_intp (Neg φ) I ⟷ wf_fo_intp φ I"
| "wf_fo_intp (Conj φ ψ) I ⟷ wf_fo_intp φ I ∧ wf_fo_intp ψ I"
| "wf_fo_intp (Disj φ ψ) I ⟷ wf_fo_intp φ I ∧ wf_fo_intp ψ I"
| "wf_fo_intp (Exists n φ) I ⟷ wf_fo_intp φ I"
| "wf_fo_intp (Forall n φ) I ⟷ wf_fo_intp φ I"
fun sat :: "('a, 'b) fo_fmla → ('a table, 'b) fo_intp → 'a val → bool" where
"sat (Pred r ts) I σ ⟷ σ ⊙ ts ∈ I (r, length ts)"
| "sat (Bool b) I σ ⟷ b"
| "sat (Eqa t t') I σ ⟷ σ ⋅ t = σ ⋅ t'"
| "sat (Neg φ) I σ ⟷ ¬sat φ I σ"
| "sat (Conj φ ψ) I σ ⟷ sat φ I σ ∧ sat ψ I σ"
| "sat (Disj φ ψ) I σ ⟷ sat φ I σ ∨ sat ψ I σ"
| "sat (Exists n φ) I σ ⟷ (∃x. sat φ I (σ(n := x)))"
| "sat (Forall n φ) I σ ⟷ (∀x. sat φ I (σ(n := x)))"
lemma sat_fv_cong: "(∧n. n ∈ fv_fo_fmla φ ==> σ n = σ' n) ==>
sat φ I σ ⟷ sat φ I σ'"
proof (induction φ arbitrary: σ σ')
case (Neg φ)
show ?case
using Neg(1)[of σ σ'] Neg(2)
by auto
next
case (Conj φ ψ)
show ?case
using Conj(1,2)[of σ σ'] Conj(3)
by auto
next
case (Disj φ ψ)
show ?case
using Disj(1,2)[of σ σ'] Disj(3)
by auto
next
case (Exists n φ)
have "∧x. sat φ I (σ(n := x)) = sat φ I (σ'(n := x))"
using Exists(2)
by (auto intro!: Exists(1))
then show ?case
by simp
next
case (Forall n φ)
have "∧x. sat φ I (σ(n := x)) = sat φ I (σ'(n := x))"
using Forall(2)
by (auto intro!: Forall(1))
then show ?case
by simp
qed (auto cong: eval_terms_cong eval_term_cong)
definition proj_sat :: "('a, 'b) fo_fmla → ('a table, 'b) fo_intp → 'a table" where
"proj_sat φ I = (λσ. map σ (fv_fo_fmla_list φ)) ` {σ. sat φ I σ}"
end
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland