Theory Stateful_Typing
section ‹Extending the Typing Result to Stateful Constraints›
theory Stateful_Typing
imports Typing_Result Stateful_Strands
begin
text ‹\label{sec:Stateful-Typing}Locale setup›
locale stateful_typed_model = typed_model arity public Ana Γ
for arity::"'fun ⇒ nat"
and public::"'fun ⇒ bool"
and Ana::"('fun,'var) term ⇒ (('fun,'var) term list × ('fun,'var) term list)"
and Γ::"('fun,'var) term ⇒ ('fun,'atom::finite) term_type"
+
fixes Pair::"'fun"
assumes Pair_arity: "arity Pair = 2"
and Ana_subst': "⋀f T δ K M. Ana (Fun f T) = (K,M) ⟹ Ana (Fun f T ⋅ δ) = (K ⋅⇩l⇩i⇩s⇩t δ,M ⋅⇩l⇩i⇩s⇩t δ)"
begin
lemma Ana_invar_subst'[simp]: "Ana_invar_subst 𝒮"
using Ana_subst' unfolding Ana_invar_subst_def by force
definition pair where
"pair d ≡ case d of (t,t') ⇒ Fun Pair [t,t']"
fun tr⇩p⇩a⇩i⇩r⇩s::
"(('fun,'var) term × ('fun,'var) term) list ⇒
('fun,'var) dbstatelist ⇒
(('fun,'var) term × ('fun,'var) term) list list"
where
"tr⇩p⇩a⇩i⇩r⇩s [] D = [[]]"
| "tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) D =
concat (map (λd. map ((#) (pair (s,t), pair d)) (tr⇩p⇩a⇩i⇩r⇩s F D)) D)"
text ‹
A translation/reduction ‹tr› from stateful constraints to (lists of) "non-stateful" constraints.
The output represents a finite disjunction of constraints whose models constitute exactly the
models of the input constraint. The typing result for "non-stateful" constraints is later lifted
to the stateful setting through this reduction procedure.
›
fun tr::"('fun,'var) stateful_strand ⇒ ('fun,'var) dbstatelist ⇒ ('fun,'var) strand list"
where
"tr [] D = [[]]"
| "tr (send⟨ts⟩#A) D = map ((#) (send⟨ts⟩⇩s⇩t)) (tr A D)"
| "tr (receive⟨ts⟩#A) D = map ((#) (receive⟨ts⟩⇩s⇩t)) (tr A D)"
| "tr (⟨ac: t ≐ t'⟩#A) D = map ((#) (⟨ac: t ≐ t'⟩⇩s⇩t)) (tr A D)"
| "tr (insert⟨t,s⟩#A) D = tr A (List.insert (t,s) D)"
| "tr (delete⟨t,s⟩#A) D =
concat (map (λDi. map (λB. (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])@B)
(tr A [d←D. d ∉ set Di]))
(subseqs D))"
| "tr (⟨ac: t ∈ s⟩#A) D =
concat (map (λB. map (λd. ⟨ac: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t#B) D) (tr A D))"
| "tr (∀X⟨∨≠: F ∨∉: F'⟩#A) D =
map ((@) (map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))) (tr A D)"
text ‹Type-flaw resistance of stateful constraint steps›
fun tfr⇩s⇩s⇩t⇩p where
"tfr⇩s⇩s⇩t⇩p (Equality _ t t') = ((∃δ. Unifier δ t t') ⟶ Γ t = Γ t')"
| "tfr⇩s⇩s⇩t⇩p (NegChecks X F F') = (
(F' = [] ∧ (∀x ∈ fv⇩p⇩a⇩i⇩r⇩s F-set X. ∃a. Γ (Var x) = TAtom a)) ∨
(∀f T. Fun f T ∈ subterms⇩s⇩e⇩t (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F') ⟶
T = [] ∨ (∃s ∈ set T. s ∉ Var ` set X)))"
| "tfr⇩s⇩s⇩t⇩p _ = True"
text ‹Type-flaw resistance of stateful constraints›
definition tfr⇩s⇩s⇩t where "tfr⇩s⇩s⇩t S ≡ tfr⇩s⇩e⇩t (trms⇩s⇩s⇩t S ∪ pair ` setops⇩s⇩s⇩t S) ∧ list_all tfr⇩s⇩s⇩t⇩p S"
subsection ‹Minor Lemmata›
lemma pair_in_pair_image_iff:
"pair (s,t) ∈ pair ` P ⟷ (s,t) ∈ P"
unfolding pair_def by fast
lemma subst_apply_pairs_pair_image_subst:
"pair ` set (F ⋅⇩p⇩a⇩i⇩r⇩s θ) = pair ` set F ⋅⇩s⇩e⇩t θ"
unfolding subst_apply_pairs_def pair_def by (induct F) auto
lemma Ana_subst_subterms_cases:
fixes θ::"('fun,'var) subst"
assumes t: "t ⊑⇩s⇩e⇩t M ⋅⇩s⇩e⇩t θ"
and s: "s ∈ set (snd (Ana t))"
shows "(∃u ∈ subterms⇩s⇩e⇩t M. t = u ⋅ θ ∧ s ∈ set (snd (Ana u)) ⋅⇩s⇩e⇩t θ) ∨ (∃x ∈ fv⇩s⇩e⇩t M. t ⊑ θ x)"
proof (cases "t ∈ subterms⇩s⇩e⇩t M ⋅⇩s⇩e⇩t θ")
case True
then obtain u where u: "u ∈ subterms⇩s⇩e⇩t M" "t = u ⋅ θ" by blast
show ?thesis
proof (cases u)
case (Var x)
hence "x ∈ fv⇩s⇩e⇩t M" using fv_subset_subterms[OF u(1)] by simp
thus ?thesis using u(2) Var by fastforce
next
case (Fun f T)
hence "set (snd (Ana t)) = set (snd (Ana u)) ⋅⇩s⇩e⇩t θ"
using Ana_subst'[of f T _ _ θ] u(2) by (cases "Ana u") auto
thus ?thesis using s u by blast
qed
qed (use s t subterms⇩s⇩e⇩t_subst in blast)
lemma Ana_snd_subst_nth_inv:
fixes θ::"('fun,'var) subst" and f ts
defines "R ≡ snd (Ana (Fun f ts ⋅ θ))"
assumes r: "r = R ! i" "i < length R"
shows "r = snd (Ana (Fun f ts)) ! i ⋅ θ"
proof -
obtain K R where "Ana (Fun f ts) = (K,R)" by (metis surj_pair)
thus ?thesis using Ana_subst'[of f ts K R θ] r unfolding R_def by auto
qed
lemma Ana_snd_subst_inv:
fixes θ::"('fun,'var) subst"
assumes r: "r ∈ set (snd (Ana (Fun f ts ⋅ θ)))"
shows "∃t ∈ set (snd (Ana (Fun f ts))). r = t ⋅ θ"
proof -
obtain K R where "Ana (Fun f ts) = (K,R)" by (metis surj_pair)
thus ?thesis using Ana_subst'[of f ts K R θ] r by auto
qed
lemma fun_pair_eq[dest]: "pair d = pair d' ⟹ d = d'"
proof -
obtain t s t' s' where "d = (t,s)" "d' = (t',s')" by atomize_elim auto
thus "pair d = pair d' ⟹ d = d'" unfolding pair_def by simp
qed
lemma fun_pair_subst: "pair d ⋅ δ = pair (d ⋅⇩p δ)"
using surj_pair[of d] unfolding pair_def by force
lemma fun_pair_subst_set: "pair ` M ⋅⇩s⇩e⇩t δ = pair ` (M ⋅⇩p⇩s⇩e⇩t δ)"
proof
show "pair ` M ⋅⇩s⇩e⇩t δ ⊆ pair ` (M ⋅⇩p⇩s⇩e⇩t δ)"
using fun_pair_subst[of _ δ] by fastforce
show "pair ` (M ⋅⇩p⇩s⇩e⇩t δ) ⊆ pair ` M ⋅⇩s⇩e⇩t δ"
proof
fix t assume t: "t ∈ pair ` (M ⋅⇩p⇩s⇩e⇩t δ)"
then obtain p where p: "p ∈ M" "t = pair (p ⋅⇩p δ)" by blast
thus "t ∈ pair ` M ⋅⇩s⇩e⇩t δ" using fun_pair_subst[of p δ] by force
qed
qed
lemma fun_pair_eq_subst: "pair d ⋅ δ = pair d' ⋅ θ ⟷ d ⋅⇩p δ = d' ⋅⇩p θ"
by (metis fun_pair_subst fun_pair_eq[of "d ⋅⇩p δ" "d' ⋅⇩p θ"])
lemma setops⇩s⇩s⇩t_pair_image_cons[simp]:
"pair ` setops⇩s⇩s⇩t (x#S) = pair ` setops⇩s⇩s⇩t⇩p x ∪ pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (send⟨ts⟩#S) = pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (receive⟨ts⟩#S) = pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (⟨ac: t ≐ t'⟩#S) = pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (insert⟨t,s⟩#S) = {pair (t,s)} ∪ pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (delete⟨t,s⟩#S) = {pair (t,s)} ∪ pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (⟨ac: t ∈ s⟩#S) = {pair (t,s)} ∪ pair ` setops⇩s⇩s⇩t S"
"pair ` setops⇩s⇩s⇩t (∀X⟨∨≠: F ∨∉: G⟩#S) = pair ` set G ∪ pair ` setops⇩s⇩s⇩t S"
unfolding setops⇩s⇩s⇩t_def by auto
lemma setops⇩s⇩s⇩t_pair_image_subst_cons[simp]:
"pair ` setops⇩s⇩s⇩t (x#S ⋅⇩s⇩s⇩t θ) = pair ` setops⇩s⇩s⇩t⇩p (x ⋅⇩s⇩s⇩t⇩p θ) ∪ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (send⟨ts⟩#S ⋅⇩s⇩s⇩t θ) = pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (receive⟨ts⟩#S ⋅⇩s⇩s⇩t θ) = pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (⟨ac: t ≐ t'⟩#S ⋅⇩s⇩s⇩t θ) = pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (insert⟨t,s⟩#S ⋅⇩s⇩s⇩t θ) = {pair (t,s) ⋅ θ} ∪ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (delete⟨t,s⟩#S ⋅⇩s⇩s⇩t θ) = {pair (t,s) ⋅ θ} ∪ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (⟨ac: t ∈ s⟩#S ⋅⇩s⇩s⇩t θ) = {pair (t,s) ⋅ θ} ∪ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
"pair ` setops⇩s⇩s⇩t (∀X⟨∨≠: F ∨∉: G⟩#S ⋅⇩s⇩s⇩t θ) =
pair ` set (G ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) θ) ∪ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
using subst_sst_cons[of _ S θ] unfolding setops⇩s⇩s⇩t_def pair_def by auto
lemma setops⇩s⇩s⇩t_are_pairs: "t ∈ pair ` setops⇩s⇩s⇩t A ⟹ ∃s s'. t = pair (s,s')"
proof (induction A)
case (Cons a A) thus ?case
by (cases a) (auto simp add: setops⇩s⇩s⇩t_def)
qed (simp add: setops⇩s⇩s⇩t_def)
lemma fun_pair_wf⇩t⇩r⇩m: "wf⇩t⇩r⇩m t ⟹ wf⇩t⇩r⇩m t' ⟹ wf⇩t⇩r⇩m (pair (t,t'))"
using Pair_arity unfolding wf⇩t⇩r⇩m_def pair_def by auto
lemma wf⇩t⇩r⇩m⇩s_pairs: "wf⇩t⇩r⇩m⇩s (trms⇩p⇩a⇩i⇩r⇩s F) ⟹ wf⇩t⇩r⇩m⇩s (pair ` set F)"
using fun_pair_wf⇩t⇩r⇩m by blast
lemma wf_fun_pair_ineqs_map:
assumes "wf⇩s⇩t X A"
shows "wf⇩s⇩t X (map (λd. ∀Y⟨∨≠: [(pair (t, s), pair d)]⟩⇩s⇩t) D@A)"
using assms by (induct D) auto
lemma wf_fun_pair_negchecks_map:
assumes "wf⇩s⇩t X A"
shows "wf⇩s⇩t X (map (λG. ∀Y⟨∨≠: (F@G)⟩⇩s⇩t) M@A)"
using assms by (induct M) auto
lemma wf_fun_pair_eqs_ineqs_map:
fixes A::"('fun,'var) strand"
assumes "wf⇩s⇩t X A" "Di ∈ set (subseqs D)" "∀(t,t') ∈ set D. fv t ∪ fv t' ⊆ X"
shows "wf⇩s⇩t X ((map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])@A)"
proof -
let ?c1 = "map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di"
let ?c2 = "map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di]"
have 1: "wf⇩s⇩t X (?c2@A)" using wf_fun_pair_ineqs_map[OF assms(1)] by simp
have 2: "∀(t,t') ∈ set Di. fv t ∪ fv t' ⊆ X"
using assms(2,3) by (meson contra_subsetD subseqs_set_subset(1))
have "wf⇩s⇩t X (?c1@B)" when "wf⇩s⇩t X B" for B::"('fun,'var) strand"
using 2 that by (induct Di) auto
thus ?thesis using 1 by simp
qed
lemma trms⇩s⇩s⇩t_wt_subst_ex:
assumes θ: "wt⇩s⇩u⇩b⇩s⇩t θ" "wf⇩t⇩r⇩m⇩s (subst_range θ)"
and t: "t ∈ trms⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
shows "∃s δ. s ∈ trms⇩s⇩s⇩t S ∧ wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ) ∧ t = s ⋅ δ"
using t
proof (induction S)
case (Cons s S) thus ?case
proof (cases "t ∈ trms⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)")
case False
hence "t ∈ trms⇩s⇩s⇩t⇩p (s ⋅⇩s⇩s⇩t⇩p θ)"
using Cons.prems trms⇩s⇩s⇩t_subst_cons[of s S θ]
by auto
then obtain u where u: "u ∈ trms⇩s⇩s⇩t⇩p s" "t = u ⋅ rm_vars (set (bvars⇩s⇩s⇩t⇩p s)) θ"
using trms⇩s⇩s⇩t⇩p_subst'' by blast
thus ?thesis
using trms⇩s⇩s⇩t_subst_cons[of s S θ]
wt_subst_rm_vars[OF θ(1), of "set (bvars⇩s⇩s⇩t⇩p s)"]
wf_trms_subst_rm_vars'[OF θ(2), of "set (bvars⇩s⇩s⇩t⇩p s)"]
by fastforce
qed auto
qed simp
lemma setops⇩s⇩s⇩t_wt_subst_ex:
assumes θ: "wt⇩s⇩u⇩b⇩s⇩t θ" "wf⇩t⇩r⇩m⇩s (subst_range θ)"
and t: "t ∈ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
shows "∃s δ. s ∈ pair ` setops⇩s⇩s⇩t S ∧ wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ) ∧ t = s ⋅ δ"
using t
proof (induction S)
case (Cons x S) thus ?case
proof (cases x)
case (Insert t' s)
hence "t = pair (t',s) ⋅ θ ∨ t ∈ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
using Cons.prems subst_sst_cons[of _ S θ]
unfolding pair_def by (force simp add: setops⇩s⇩s⇩t_def)
thus ?thesis
using Insert Cons.IH θ by (cases "t = pair (t', s) ⋅ θ") (fastforce, auto)
next
case (Delete t' s)
hence "t = pair (t',s) ⋅ θ ∨ t ∈ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
using Cons.prems subst_sst_cons[of _ S θ]
unfolding pair_def by (force simp add: setops⇩s⇩s⇩t_def)
thus ?thesis
using Delete Cons.IH θ by (cases "t = pair (t', s) ⋅ θ") (fastforce, auto)
next
case (InSet ac t' s)
hence "t = pair (t',s) ⋅ θ ∨ t ∈ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
using Cons.prems subst_sst_cons[of _ S θ]
unfolding pair_def by (force simp add: setops⇩s⇩s⇩t_def)
thus ?thesis
using InSet Cons.IH θ by (cases "t = pair (t', s) ⋅ θ") (fastforce, auto)
next
case (NegChecks X F F')
hence "t ∈ pair ` set (F' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) θ) ∨ t ∈ pair ` setops⇩s⇩s⇩t (S ⋅⇩s⇩s⇩t θ)"
using Cons.prems subst_sst_cons[of _ S θ]
unfolding pair_def by (force simp add: setops⇩s⇩s⇩t_def)
thus ?thesis
proof
assume "t ∈ pair ` set (F' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) θ)"
then obtain s where s: "t = s ⋅ rm_vars (set X) θ" "s ∈ pair ` set F'"
using subst_apply_pairs_pair_image_subst[of F' "rm_vars (set X) θ"] by auto
thus ?thesis
using NegChecks setops⇩s⇩s⇩t_pair_image_cons(8)[of X F F' S]
wt_subst_rm_vars[OF θ(1), of "set X"]
wf_trms_subst_rm_vars'[OF θ(2), of "set X"]
by fast
qed (use Cons.IH in auto)
qed (auto simp add: setops⇩s⇩s⇩t_def subst_sst_cons[of _ S θ])
qed (simp add: setops⇩s⇩s⇩t_def)
lemma setops⇩s⇩s⇩t_wf⇩t⇩r⇩m⇩s:
"wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A) ⟹ wf⇩t⇩r⇩m⇩s (pair ` setops⇩s⇩s⇩t A)"
"wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A) ⟹ wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A)"
proof -
show "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A) ⟹ wf⇩t⇩r⇩m⇩s (pair ` setops⇩s⇩s⇩t A)"
proof (induction A)
case (Cons a A)
hence 0: "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t⇩p a)" "wf⇩t⇩r⇩m⇩s (pair ` setops⇩s⇩s⇩t A)" by auto
thus ?case
proof (cases a)
case (NegChecks X F F')
hence "wf⇩t⇩r⇩m⇩s (trms⇩p⇩a⇩i⇩r⇩s F')" using 0 by simp
thus ?thesis using NegChecks wf⇩t⇩r⇩m⇩s_pairs[of F'] 0 by (auto simp add: setops⇩s⇩s⇩t_def)
qed (auto simp add: setops⇩s⇩s⇩t_def dest: fun_pair_wf⇩t⇩r⇩m)
qed (auto simp add: setops⇩s⇩s⇩t_def)
thus "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A) ⟹ wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A)" by fast
qed
lemma SMP_MP_split:
assumes "t ∈ SMP M"
and M: "∀m ∈ M. is_Fun m"
shows "(∃δ. wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ) ∧ t ∈ M ⋅⇩s⇩e⇩t δ) ∨
t ∈ SMP ((subterms⇩s⇩e⇩t M ∪ ⋃((set ∘ fst ∘ Ana) ` M)) - M)"
(is "?P t ∨ ?Q t")
using assms(1)
proof (induction t rule: SMP.induct)
case (MP t)
have "wt⇩s⇩u⇩b⇩s⇩t Var" "wf⇩t⇩r⇩m⇩s (subst_range Var)" "M ⋅⇩s⇩e⇩t Var = M" by simp_all
thus ?case using MP by metis
next
case (Subterm t t')
show ?case using Subterm.IH
proof
assume "?P t"
then obtain s δ where s: "s ∈ M" "t = s ⋅ δ" and δ: "wt⇩s⇩u⇩b⇩s⇩t δ" "wf⇩t⇩r⇩m⇩s (subst_range δ)" by auto
then obtain f T where fT: "s = Fun f T" using M by fast
have "(∃s'. s' ⊑ s ∧ t' = s' ⋅ δ) ∨ (∃x ∈ fv s. t' ⊏ δ x)"
using subterm_subst_unfold[OF Subterm.hyps(2)[unfolded s(2)]] by blast
thus ?thesis
proof
assume "∃s'. s' ⊑ s ∧ t' = s' ⋅ δ"
then obtain s' where s': "s' ⊑ s" "t' = s' ⋅ δ" by fast
show ?thesis
proof (cases "s' ∈ M")
case True thus ?thesis using s' δ by blast
next
case False
hence "s' ∈ (subterms⇩s⇩e⇩t M ∪ ⋃((set ∘ fst ∘ Ana) ` M)) - M" using s'(1) s(1) by force
thus ?thesis using SMP.Substitution[OF SMP.MP[of s'] δ] s' by presburger
qed
next
assume "∃x ∈ fv s. t' ⊏ δ x"
then obtain x where x: "x ∈ fv s" "t' ⊏ δ x" by fast
have "Var x ∉ M" using M by blast
hence "Var x ∈ (subterms⇩s⇩e⇩t M ∪ ⋃((set ∘ fst ∘ Ana) ` M)) - M"
using s(1) var_is_subterm[OF x(1)] by blast
hence "δ x ∈ SMP ((subterms⇩s⇩e⇩t M ∪ ⋃((set ∘ fst ∘ Ana) ` M)) - M)"
using SMP.Substitution[OF SMP.MP[of "Var x"] δ] by auto
thus ?thesis using SMP.Subterm x(2) by presburger
qed
qed (metis SMP.Subterm[OF _ Subterm.hyps(2)])
next
case (Substitution t δ)
show ?case using Substitution.IH
proof
assume "?P t"
then obtain θ where "wt⇩s⇩u⇩b⇩s⇩t θ" "wf⇩t⇩r⇩m⇩s (subst_range θ)" "t ∈ M ⋅⇩s⇩e⇩t θ" by fast
hence "wt⇩s⇩u⇩b⇩s⇩t (θ ∘⇩s δ)" "wf⇩t⇩r⇩m⇩s (subst_range (θ ∘⇩s δ))" "t ⋅ δ ∈ M ⋅⇩s⇩e⇩t (θ ∘⇩s δ)"
using wt_subst_compose[of θ, OF _ Substitution.hyps(2)]
wf_trm_subst_compose[of θ _ δ, OF _ wf_trm_subst_rangeD[OF Substitution.hyps(3)]]
wf_trm_subst_range_iff
by (argo, blast, auto)
thus ?thesis by blast
next
assume "?Q t" thus ?thesis using SMP.Substitution[OF _ Substitution.hyps(2,3)] by meson
qed
next
case (Ana t K T k)
show ?case using Ana.IH
proof
assume "?P t"
then obtain θ where θ: "wt⇩s⇩u⇩b⇩s⇩t θ" "wf⇩t⇩r⇩m⇩s (subst_range θ)" "t ∈ M ⋅⇩s⇩e⇩t θ" by fast
then obtain s where s: "s ∈ M" "t = s ⋅ θ" by auto
then obtain f S where fT: "s = Fun f S" using M by (cases s) auto
obtain K' T' where s_Ana: "Ana s = (K', T')" by (metis surj_pair)
hence "set K = set K' ⋅⇩s⇩e⇩t θ" "set T = set T' ⋅⇩s⇩e⇩t θ"
using Ana_subst'[of f S K' T'] fT Ana.hyps(2) s(2) by auto
then obtain k' where k': "k' ∈ set K'" "k = k' ⋅ θ" using Ana.hyps(3) by fast
show ?thesis
proof (cases "k' ∈ M")
case True thus ?thesis using k' θ(1,2) by blast
next
case False
hence "k' ∈ (subterms⇩s⇩e⇩t M ∪ ⋃((set ∘ fst ∘ Ana) ` M)) - M" using k'(1) s_Ana s(1) by force
thus ?thesis using SMP.Substitution[OF SMP.MP[of k'] θ(1,2)] k'(2) by presburger
qed
next
assume "?Q t" thus ?thesis using SMP.Ana[OF _ Ana.hyps(2,3)] by meson
qed
qed
lemma setops_subterm_trms:
assumes t: "t ∈ pair ` setops⇩s⇩s⇩t S"
and s: "s ⊏ t"
shows "s ∈ subterms⇩s⇩e⇩t (trms⇩s⇩s⇩t S)"
proof -
obtain u u' where u: "pair (u,u') ∈ pair ` setops⇩s⇩s⇩t S" "t = pair (u,u')"
using t setops⇩s⇩s⇩t_are_pairs[of _ S] by blast
hence "s ⊑ u ∨ s ⊑ u'" using s unfolding pair_def by auto
thus ?thesis using u setops⇩s⇩s⇩t_member_iff[of u u' S] unfolding trms⇩s⇩s⇩t_def by force
qed
lemma setops_subterms_cases:
assumes t: "t ∈ subterms⇩s⇩e⇩t (pair ` setops⇩s⇩s⇩t S)"
shows "t ∈ subterms⇩s⇩e⇩t (trms⇩s⇩s⇩t S) ∨ t ∈ pair ` setops⇩s⇩s⇩t S"
proof -
obtain s s' where s: "pair (s,s') ∈ pair ` setops⇩s⇩s⇩t S" "t ⊑ pair (s,s')"
using t setops⇩s⇩s⇩t_are_pairs[of _ S] by blast
hence "t ∈ pair ` setops⇩s⇩s⇩t S ∨ t ⊑ s ∨ t ⊑ s'" unfolding pair_def by auto
thus ?thesis using s setops⇩s⇩s⇩t_member_iff[of s s' S] unfolding trms⇩s⇩s⇩t_def by force
qed
lemma setops_SMP_cases:
assumes "t ∈ SMP (pair ` setops⇩s⇩s⇩t S)"
and "∀p. Ana (pair p) = ([], [])"
shows "(∃δ. wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ) ∧ t ∈ pair ` setops⇩s⇩s⇩t S ⋅⇩s⇩e⇩t δ) ∨ t ∈ SMP (trms⇩s⇩s⇩t S)"
proof -
have 0: "⋃((set ∘ fst ∘ Ana) ` pair ` setops⇩s⇩s⇩t S) = {}"
proof (induction S)
case (Cons x S) thus ?case
using assms(2) by (cases x) (auto simp add: setops⇩s⇩s⇩t_def)
qed (simp add: setops⇩s⇩s⇩t_def)
have 1: "∀m ∈ pair ` setops⇩s⇩s⇩t S. is_Fun m"
proof (induction S)
case (Cons x S) thus ?case
unfolding pair_def by (cases x) (auto simp add: assms(2) setops⇩s⇩s⇩t_def)
qed (simp add: setops⇩s⇩s⇩t_def)
have 2:
"subterms⇩s⇩e⇩t (pair ` setops⇩s⇩s⇩t S) ∪
⋃((set ∘ fst ∘ Ana) ` (pair ` setops⇩s⇩s⇩t S)) - pair ` setops⇩s⇩s⇩t S
⊆ subterms⇩s⇩e⇩t (trms⇩s⇩s⇩t S)"
using 0 setops_subterms_cases by fast
show ?thesis
using SMP_MP_split[OF assms(1) 1] SMP_mono[OF 2] SMP_subterms_eq[of "trms⇩s⇩s⇩t S"]
by blast
qed
lemma constraint_model_priv_const_in_constr_prefix:
assumes A: "wf⇩s⇩s⇩t A"
and I: "I ⊨⇩s A"
"interpretation⇩s⇩u⇩b⇩s⇩t I"
"wf⇩t⇩r⇩m⇩s (subst_range I)"
"wt⇩s⇩u⇩b⇩s⇩t I"
and c: "¬public c"
"arity c = 0"
"Fun c [] ⊑⇩s⇩e⇩t ik⇩s⇩s⇩t A ⋅⇩s⇩e⇩t I"
shows "Fun c [] ⊑⇩s⇩e⇩t trms⇩s⇩s⇩t A"
using const_subterms_subst_cases[OF c(3)]
proof
assume "Fun c [] ⊑⇩s⇩e⇩t ik⇩s⇩s⇩t A" thus ?thesis using ik⇩s⇩s⇩t_trms⇩s⇩s⇩t_subset by blast
next
assume "∃x ∈ fv⇩s⇩e⇩t (ik⇩s⇩s⇩t A). x ∈ subst_domain I ∧ Fun c [] ⊑ I x"
then obtain x where x: "x ∈ fv⇩s⇩e⇩t (ik⇩s⇩s⇩t A)" "Fun c [] ⊑ I x" by blast
have 0: "wf⇩t⇩r⇩m (I x)" "wf'⇩s⇩s⇩t {} A" "Fun c [] ⋅ I = Fun c []"
using I A by simp_all
have 1: "x ∈ wfrestrictedvars⇩s⇩s⇩t A"
using x(1) in_ik⇩s⇩s⇩t_iff[of _ A] unfolding wfrestrictedvars⇩s⇩s⇩t_def by force
hence 2: "∃v ∈ wfrestrictedvars⇩s⇩s⇩t A. Fun c [] ⋅ I ⊑ I v" using 0(3) x(2) by force
obtain A⇩p⇩r⇩e A⇩s⇩u⇩f where A': "¬(∃w ∈ wfrestrictedvars⇩s⇩s⇩t A⇩p⇩r⇩e. Fun c [] ⊑ I w)"
"(∃ts. A = A⇩p⇩r⇩e@send⟨ts⟩#A⇩s⇩u⇩f ∧ Fun c [] ⊑⇩s⇩e⇩t set ts ⋅⇩s⇩e⇩t I) ∨
(∃s u. A = A⇩p⇩r⇩e@⟨assign: s ≐ u⟩#A⇩s⇩u⇩f ∧ Fun c [] ⊑ s ⋅ I ∧ ¬(Fun c [] ⊑⇩s⇩e⇩t (I ` fv u))) ∨
(∃s u. A = A⇩p⇩r⇩e@⟨assign: s ∈ u⟩#A⇩s⇩u⇩f ∧ (Fun c [] ⊑ s ⋅ I ∨ Fun c [] ⊑ u ⋅ I))"
(is "?X ∨ ?Y ∨ ?Z")
using wf⇩s⇩s⇩t_strand_first_Send_var_split[OF 0(2) 2] by force
show ?thesis using A'(2)
proof (elim disjE)
assume ?X
then obtain ts where ts: "A = A⇩p⇩r⇩e@send⟨ts⟩#A⇩s⇩u⇩f" "Fun c [] ⊑⇩s⇩e⇩t set ts ⋅⇩s⇩e⇩t I" by blast
hence "I ⊨⇩s (A⇩p⇩r⇩e@[send⟨ts⟩])"
using I(1) strand_sem_append_stateful[of "{}" "{}" "A⇩p⇩r⇩e@[send⟨ts⟩]" A⇩s⇩u⇩f I] by auto
hence "(ik⇩s⇩s⇩t A⇩p⇩r⇩e) ⋅⇩s⇩e⇩t I ⊢ t ⋅ I" when "t ∈ set ts" for t
using that strand_sem_append_stateful[of "{}" "{}" A⇩p⇩r⇩e "[send⟨ts⟩]" I]
strand_sem_stateful.simps(2)[of _ _ ts "[]"]
unfolding list_all_iff by force
hence "Fun c [] ⊑⇩s⇩e⇩t ik⇩s⇩s⇩t A⇩p⇩r⇩e ⋅⇩s⇩e⇩t I"
using ts(2) c(1) private_fun_deduct_in_ik by fast
hence "Fun c [] ⊑⇩s⇩e⇩t ik⇩s⇩s⇩t A⇩p⇩r⇩e"
using A'(1) const_subterms_subst_cases[of c I "ik⇩s⇩s⇩t A⇩p⇩r⇩e"]
ik⇩s⇩s⇩t_fv_subset_wfrestrictedvars⇩s⇩s⇩t[of A⇩p⇩r⇩e]
by fast
thus ?thesis
using ik⇩s⇩s⇩t_trms⇩s⇩s⇩t_subset[of "A⇩p⇩r⇩e"] unfolding ts(1) by fastforce
next
assume ?Y
then obtain s u where su:
"A = A⇩p⇩r⇩e@⟨assign: s ≐ u⟩#A⇩s⇩u⇩f" "Fun c [] ⊑ s ⋅ I" "¬(Fun c [] ⊑⇩s⇩e⇩t I ` fv u)"
by fast
hence "s ⋅ I = u ⋅ I"
using I(1) strand_sem_append_stateful[of "{}" "{}" "A⇩p⇩r⇩e@[⟨assign: s ≐ u⟩]" A⇩s⇩u⇩f I]
strand_sem_append_stateful[of _ _ A⇩p⇩r⇩e "[⟨assign: s ≐ u⟩]" I]
by auto
hence "Fun c [] ⊑ u" using su(2,3) const_subterm_subst_var_obtain[of c u I] by auto
thus ?thesis unfolding su(1) by auto
next
assume ?Z
then obtain s u where su:
"A = A⇩p⇩r⇩e@⟨assign: s ∈ u⟩#A⇩s⇩u⇩f" "Fun c [] ⊑ s ⋅ I ∨ Fun c [] ⊑ u ⋅ I"
by fast
hence "(s,u) ⋅⇩p I ∈ dbupd⇩s⇩s⇩t A⇩p⇩r⇩e I {}"
using I(1) strand_sem_append_stateful[of "{}" "{}" "A⇩p⇩r⇩e@[⟨assign: s ∈ u⟩]" A⇩s⇩u⇩f I]
strand_sem_append_stateful[of _ _ A⇩p⇩r⇩e "[⟨assign: s ∈ u⟩]" I]
unfolding db⇩s⇩s⇩t_def by auto
then obtain s' u' where su': "insert⟨s',u'⟩ ∈ set A⇩p⇩r⇩e" "s ⋅ I = s' ⋅ I" "u ⋅ I = u' ⋅ I"
using db⇩s⇩s⇩t_in_cases[of "s ⋅ I" "u ⋅ I" A⇩p⇩r⇩e I "[]"] db⇩s⇩s⇩t_set_is_dbupd⇩s⇩s⇩t[of A⇩p⇩r⇩e I "[]"]
by fastforce
have "fv s' ∪ fv u' ⊆ wfrestrictedvars⇩s⇩s⇩t A⇩p⇩r⇩e"
using su'(1) unfolding wfrestrictedvars⇩s⇩s⇩t_def by force
hence "Fun c [] ⊑ s' ∨ Fun c [] ⊑ u'"
using su(2) A'(1) su'(2,3)
const_subterm_subst_cases[of c s' I]
const_subterm_subst_cases[of c u' I]
by auto
thus ?thesis using su'(1) unfolding su(1) by force
qed
qed
lemma tr⇩p⇩a⇩i⇩r⇩s_empty_case:
assumes "tr⇩p⇩a⇩i⇩r⇩s F D = []"
shows "D = []" "F ≠ []"
proof -
show "F ≠ []" using assms by (auto intro: ccontr)
have "tr⇩p⇩a⇩i⇩r⇩s F (a#A) ≠ []" for a A
by (induct F "a#A" rule: tr⇩p⇩a⇩i⇩r⇩s.induct) fastforce+
thus "D = []" using assms by (cases D) simp_all
qed
lemma tr⇩p⇩a⇩i⇩r⇩s_elem_length_eq:
assumes "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)"
shows "length G = length F"
using assms by (induct F D arbitrary: G rule: tr⇩p⇩a⇩i⇩r⇩s.induct) auto
lemma tr⇩p⇩a⇩i⇩r⇩s_index:
assumes "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)" "i < length F"
shows "∃d ∈ set D. G ! i = (pair (F ! i), pair d)"
using assms
proof (induction F D arbitrary: i G rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F D)
obtain d G' where G:
"d ∈ set D" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)"
"G = (pair (s,t), pair d)#G'"
using "2.prems"(1) by atomize_elim auto
show ?case
using "2.IH"[OF G(1,2)] "2.prems"(2) G(1,3)
by (cases i) auto
qed simp
lemma tr⇩p⇩a⇩i⇩r⇩s_cons:
assumes "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)" "d ∈ set D"
shows "(pair (s,t), pair d)#G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) D)"
using assms by auto
lemma tr⇩p⇩a⇩i⇩r⇩s_has_pair_lists:
assumes "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)" "g ∈ set G"
shows "∃f ∈ set F. ∃d ∈ set D. g = (pair f, pair d)"
using assms
proof (induction F D arbitrary: G rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F D)
obtain d G' where G:
"d ∈ set D" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)"
"G = (pair (s,t), pair d)#G'"
using "2.prems"(1) by atomize_elim auto
show ?case
using "2.IH"[OF G(1,2)] "2.prems"(2) G(1,3)
by (cases "g ∈ set G'") auto
qed simp
lemma tr⇩p⇩a⇩i⇩r⇩s_is_pair_lists:
assumes "f ∈ set F" "d ∈ set D"
shows "∃G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D). (pair f, pair d) ∈ set G"
(is "?P F D f d")
proof -
have "∀f ∈ set F. ∀d ∈ set D. ?P F D f d"
proof (induction F D rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F D)
hence IH: "∀f ∈ set F. ∀d ∈ set D. ?P F D f d" by metis
moreover have "∀d ∈ set D. ?P ((s,t)#F) D (s,t) d"
proof
fix d assume d: "d ∈ set D"
then obtain G where G: "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)"
using tr⇩p⇩a⇩i⇩r⇩s_empty_case(1) by force
hence "(pair (s, t), pair d)#G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) D)"
using d by auto
thus "?P ((s,t)#F) D (s,t) d" using d G by auto
qed
ultimately show ?case by fastforce
qed simp
thus ?thesis by (metis assms)
qed
lemma tr⇩p⇩a⇩i⇩r⇩s_db_append_subset:
"set (tr⇩p⇩a⇩i⇩r⇩s F D) ⊆ set (tr⇩p⇩a⇩i⇩r⇩s F (D@E))" (is ?A)
"set (tr⇩p⇩a⇩i⇩r⇩s F E) ⊆ set (tr⇩p⇩a⇩i⇩r⇩s F (D@E))" (is ?B)
proof -
show ?A
proof (induction F D rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F D)
show ?case
proof
fix G assume "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) D)"
then obtain d G' where G':
"d ∈ set D" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)" "G = (pair (s,t), pair d)#G'"
by atomize_elim auto
have "d ∈ set (D@E)" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F (D@E))" using "2.IH"[OF G'(1)] G'(1,2) by auto
thus "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) (D@E))" using G'(3) by auto
qed
qed simp
show ?B
proof (induction F E rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F E)
show ?case
proof
fix G assume "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) E)"
then obtain d G' where G':
"d ∈ set E" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F E)" "G = (pair (s,t), pair d)#G'"
by atomize_elim auto
have "d ∈ set (D@E)" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F (D@E))" using "2.IH"[OF G'(1)] G'(1,2) by auto
thus "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F) (D@E))" using G'(3) by auto
qed
qed simp
qed
lemma tr⇩p⇩a⇩i⇩r⇩s_trms_subset:
"G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D) ⟹ trms⇩p⇩a⇩i⇩r⇩s G ⊆ pair ` set F ∪ pair ` set D"
proof (induction F D arbitrary: G rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F D G)
obtain d G' where G:
"d ∈ set D" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)" "G = (pair (s,t), pair d)#G'"
using "2.prems"(1) by atomize_elim auto
show ?case using "2.IH"[OF G(1,2)] G(1,3) by auto
qed simp
lemma tr⇩p⇩a⇩i⇩r⇩s_trms_subset':
"⋃(trms⇩p⇩a⇩i⇩r⇩s ` set (tr⇩p⇩a⇩i⇩r⇩s F D)) ⊆ pair ` set F ∪ pair ` set D"
using tr⇩p⇩a⇩i⇩r⇩s_trms_subset by blast
lemma tr⇩p⇩a⇩i⇩r⇩s_vars_subset:
"G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D) ⟹ fv⇩p⇩a⇩i⇩r⇩s G ⊆ fv⇩p⇩a⇩i⇩r⇩s F ∪ fv⇩p⇩a⇩i⇩r⇩s D"
proof (induction F D arbitrary: G rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F D G)
obtain d G' where G:
"d ∈ set D" "G' ∈ set (tr⇩p⇩a⇩i⇩r⇩s F D)" "G = (pair (s,t), pair d)#G'"
using "2.prems"(1) by atomize_elim auto
show ?case using "2.IH"[OF G(1,2)] G(1,3) unfolding pair_def by auto
qed simp
lemma tr⇩p⇩a⇩i⇩r⇩s_vars_subset': "⋃(fv⇩p⇩a⇩i⇩r⇩s ` set (tr⇩p⇩a⇩i⇩r⇩s F D)) ⊆ fv⇩p⇩a⇩i⇩r⇩s F ∪ fv⇩p⇩a⇩i⇩r⇩s D"
using tr⇩p⇩a⇩i⇩r⇩s_vars_subset[of _ F D] by blast
lemma tr_trms_subset:
"A' ∈ set (tr A D) ⟹ trms⇩s⇩t A' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D"
proof (induction A D arbitrary: A' rule: tr.induct)
case 1 thus ?case by simp
next
case (2 t A D)
then obtain A'' where A'': "A' = send⟨t⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)" by atomize_elim auto
hence "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D" by (metis "2.IH")
thus ?case using A'' by (auto simp add: setops⇩s⇩s⇩t_def)
next
case (3 t A D)
then obtain A'' where A'': "A' = receive⟨t⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)" by atomize_elim auto
hence "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D" by (metis "3.IH")
thus ?case using A'' by (auto simp add: setops⇩s⇩s⇩t_def)
next
case (4 ac t t' A D)
then obtain A'' where A'': "A' = ⟨ac: t ≐ t'⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)" by atomize_elim auto
hence "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D" by (metis "4.IH")
thus ?case using A'' by (auto simp add: setops⇩s⇩s⇩t_def)
next
case (5 t s A D)
hence "A' ∈ set (tr A (List.insert (t,s) D))" by simp
hence "trms⇩s⇩t A' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set (List.insert (t, s) D)"
by (metis "5.IH")
thus ?case by (auto simp add: setops⇩s⇩s⇩t_def)
next
case (6 t s A D)
from 6 obtain Di A'' B C where A'':
"Di ∈ set (subseqs D)" "A'' ∈ set (tr A [d←D. d ∉ set Di])" "A' = (B@C)@A''"
"B = map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di"
"C = map (λd. Inequality [] [(pair (t,s) , pair d)]) [d←D. d ∉ set Di]"
by atomize_elim auto
hence "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set [d←D. d ∉ set Di]"
by (metis "6.IH")
hence "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t (Delete t s#A) ∪ pair ` setops⇩s⇩s⇩t (Delete t s#A) ∪ pair ` set D"
by (auto simp add: setops⇩s⇩s⇩t_def)
moreover have "trms⇩s⇩t (B@C) ⊆ insert (pair (t,s)) (pair ` set D)"
using A''(4,5) subseqs_set_subset[OF A''(1)] by auto
moreover have "pair (t,s) ∈ pair ` setops⇩s⇩s⇩t (Delete t s#A)" by (simp add: setops⇩s⇩s⇩t_def)
ultimately show ?case using A''(3) trms⇩s⇩t_append[of "B@C" A'] by auto
next
case (7 ac t s A D)
from 7 obtain d A'' where A'':
"d ∈ set D" "A'' ∈ set (tr A D)"
"A' = ⟨ac: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t#A''"
by atomize_elim auto
hence "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D" by (metis "7.IH")
moreover have "trms⇩s⇩t A' = {pair (t,s), pair d} ∪ trms⇩s⇩t A''"
using A''(1,3) by auto
ultimately show ?case using A''(1) by (auto simp add: setops⇩s⇩s⇩t_def)
next
case (8 X F F' A D)
from 8 obtain A'' where A'':
"A'' ∈ set (tr A D)" "A' = (map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))@A''"
by atomize_elim auto
define B where "B ≡ ⋃(trms⇩p⇩a⇩i⇩r⇩s ` set (tr⇩p⇩a⇩i⇩r⇩s F' D))"
have "trms⇩s⇩t A'' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D" by (metis A''(1) "8.IH")
hence "trms⇩s⇩t A' ⊆ B ∪ trms⇩p⇩a⇩i⇩r⇩s F ∪ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D"
using A'' B_def by auto
moreover have "B ⊆ pair ` set F' ∪ pair ` set D"
using tr⇩p⇩a⇩i⇩r⇩s_trms_subset'[of F' D] B_def by simp
moreover have "pair ` setops⇩s⇩s⇩t (∀X⟨∨≠: F ∨∉: F'⟩#A) = pair ` set F' ∪ pair ` setops⇩s⇩s⇩t A"
by (auto simp add: setops⇩s⇩s⇩t_def)
ultimately show ?case by auto
qed
lemma tr_vars_subset:
assumes "A' ∈ set (tr A D)"
shows "fv⇩s⇩t A' ⊆ fv⇩s⇩s⇩t A ∪ (⋃(t,t') ∈ set D. fv t ∪ fv t')" (is ?P)
and "bvars⇩s⇩t A' ⊆ bvars⇩s⇩s⇩t A" (is ?Q)
proof -
show ?P using assms
proof (induction A arbitrary: A' D rule: strand_sem_stateful_induct)
case (ConsIn A' D ac t s A)
then obtain A'' d where *:
"d ∈ set D" "A' = ⟨ac: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t#A''"
"A'' ∈ set (tr A D)"
by atomize_elim auto
hence "fv⇩s⇩t A'' ⊆ fv⇩s⇩s⇩t A ∪ (⋃(t,t')∈set D. fv t ∪ fv t')" by (metis ConsIn.IH)
thus ?case using * unfolding pair_def by auto
next
case (ConsDel A' D t s A)
define Dfv where "Dfv ≡ λD::('fun,'var) dbstatelist. (⋃(t,t')∈set D. fv t ∪ fv t')"
define fltD where "fltD ≡ λDi. filter (λd. d ∉ set Di) D"
define constr where
"constr ≡ λDi. (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) (fltD Di))"
from ConsDel obtain A'' Di where *:
"Di ∈ set (subseqs D)" "A' = (constr Di)@A''" "A'' ∈ set (tr A (fltD Di))"
unfolding constr_def fltD_def by atomize_elim auto
hence "fv⇩s⇩t A'' ⊆ fv⇩s⇩s⇩t A ∪ Dfv (fltD Di)"
unfolding Dfv_def constr_def fltD_def by (metis ConsDel.IH)
moreover have "Dfv (fltD Di) ⊆ Dfv D" unfolding Dfv_def constr_def fltD_def by auto
moreover have "Dfv Di ⊆ Dfv D"
using subseqs_set_subset(1)[OF *(1)] unfolding Dfv_def constr_def fltD_def by fast
moreover have "fv⇩s⇩t (constr Di) ⊆ fv t ∪ fv s ∪ (Dfv Di ∪ Dfv (fltD Di))"
unfolding Dfv_def constr_def fltD_def pair_def by auto
moreover have "fv⇩s⇩s⇩t (Delete t s#A) = fv t ∪ fv s ∪ fv⇩s⇩s⇩t A" by auto
moreover have "fv⇩s⇩t A' = fv⇩s⇩t (constr Di) ∪ fv⇩s⇩t A''" using * by force
ultimately have "fv⇩s⇩t A' ⊆ fv⇩s⇩s⇩t (Delete t s#A) ∪ Dfv D" by auto
thus ?case unfolding Dfv_def fltD_def constr_def by simp
next
case (ConsNegChecks A' D X F F' A)
then obtain A'' where A'':
"A'' ∈ set (tr A D)" "A' = (map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))@A''"
by atomize_elim auto
define B where "B ≡ ⋃(fv⇩p⇩a⇩i⇩r⇩s ` set (tr⇩p⇩a⇩i⇩r⇩s F' D))"
have 1: "fv⇩s⇩t (map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D)) ⊆ (B ∪ fv⇩p⇩a⇩i⇩r⇩s F) - set X"
unfolding B_def by auto
have 2: "B ⊆ fv⇩p⇩a⇩i⇩r⇩s F' ∪ fv⇩p⇩a⇩i⇩r⇩s D"
using tr⇩p⇩a⇩i⇩r⇩s_vars_subset'[of F' D]
unfolding B_def by simp
have "fv⇩s⇩t A' ⊆ ((fv⇩p⇩a⇩i⇩r⇩s F' ∪ fv⇩p⇩a⇩i⇩r⇩s D ∪ fv⇩p⇩a⇩i⇩r⇩s F) - set X) ∪ fv⇩s⇩t A''"
using 1 2 A''(2) by fastforce
thus ?case using ConsNegChecks.IH[OF A''(1)] by auto
qed fastforce+
show ?Q using assms by (induct A arbitrary: A' D rule: strand_sem_stateful_induct) fastforce+
qed
lemma tr_vars_disj:
assumes "A' ∈ set (tr A D)" "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
and "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}"
shows "fv⇩s⇩t A' ∩ bvars⇩s⇩t A' = {}"
using assms tr_vars_subset by fast
lemma tfr⇩s⇩s⇩t⇩p_alt_def:
"list_all tfr⇩s⇩s⇩t⇩p S =
((∀ac t t'. Equality ac t t' ∈ set S ∧ (∃δ. Unifier δ t t') ⟶ Γ t = Γ t') ∧
(∀X F F'. NegChecks X F F' ∈ set S ⟶ (
(F' = [] ∧ (∀x ∈ fv⇩p⇩a⇩i⇩r⇩s F-set X. ∃a. Γ (Var x) = TAtom a)) ∨
(∀f T. Fun f T ∈ subterms⇩s⇩e⇩t (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F') ⟶
T = [] ∨ (∃s ∈ set T. s ∉ Var ` set X)))))"
(is "?P S = ?Q S")
proof
show "?P S ⟹ ?Q S"
proof (induction S)
case (Cons x S) thus ?case by (cases x) auto
qed simp
show "?Q S ⟹ ?P S"
proof (induction S)
case (Cons x S) thus ?case by (cases x) auto
qed simp
qed
lemma tfr⇩s⇩s⇩t_Nil[simp]: "tfr⇩s⇩s⇩t []"
by (simp add: tfr⇩s⇩s⇩t_def setops⇩s⇩s⇩t_def)
lemma tfr⇩s⇩s⇩t_append: "tfr⇩s⇩s⇩t (A@B) ⟹ tfr⇩s⇩s⇩t A"
proof -
assume assms: "tfr⇩s⇩s⇩t (A@B)"
let ?M = "trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A"
let ?N = "trms⇩s⇩s⇩t (A@B) ∪ pair ` setops⇩s⇩s⇩t (A@B)"
let ?P = "λt t'. ∀x ∈ fv t ∪ fv t'. ∃a. Γ (Var x) = Var a"
let ?Q = "λX t t'. X = [] ∨ (∀x ∈ (fv t ∪ fv t')-set X. ∃a. Γ (Var x) = Var a)"
have *: "SMP ?M - Var`𝒱 ⊆ SMP ?N - Var`𝒱" "?M ⊆ ?N"
using SMP_mono[of ?M ?N] setops⇩s⇩s⇩t_append[of A B]
by auto
{ fix s t assume **: "tfr⇩s⇩e⇩t ?N" "s ∈ SMP ?M - Var`𝒱" "t ∈ SMP ?M - Var`𝒱" "(∃δ. Unifier δ s t)"
hence "s ∈ SMP ?N - Var`𝒱" "t ∈ SMP ?N - Var`𝒱" using * by auto
hence "Γ s = Γ t" using **(1,4) unfolding tfr⇩s⇩e⇩t_def by blast
} moreover have "∀t ∈ ?N. wf⇩t⇩r⇩m t ⟹ ∀t ∈ ?M. wf⇩t⇩r⇩m t" using * by blast
ultimately have "tfr⇩s⇩e⇩t ?N ⟹ tfr⇩s⇩e⇩t ?M" unfolding tfr⇩s⇩e⇩t_def by blast
hence "tfr⇩s⇩e⇩t ?M" using assms unfolding tfr⇩s⇩s⇩t_def by metis
thus "tfr⇩s⇩s⇩t A" using assms unfolding tfr⇩s⇩s⇩t_def by simp
qed
lemma tfr⇩s⇩s⇩t_append': "tfr⇩s⇩s⇩t (A@B) ⟹ tfr⇩s⇩s⇩t B"
proof -
assume assms: "tfr⇩s⇩s⇩t (A@B)"
let ?M = "trms⇩s⇩s⇩t B ∪ pair ` setops⇩s⇩s⇩t B"
let ?N = "trms⇩s⇩s⇩t (A@B) ∪ pair ` setops⇩s⇩s⇩t (A@B)"
let ?P = "λt t'. ∀x ∈ fv t ∪ fv t'. ∃a. Γ (Var x) = Var a"
let ?Q = "λX t t'. X = [] ∨ (∀x ∈ (fv t ∪ fv t')-set X. ∃a. Γ (Var x) = Var a)"
have *: "SMP ?M - Var`𝒱 ⊆ SMP ?N - Var`𝒱" "?M ⊆ ?N"
using SMP_mono[of ?M ?N] setops⇩s⇩s⇩t_append[of A B]
by auto
{ fix s t assume **: "tfr⇩s⇩e⇩t ?N" "s ∈ SMP ?M - Var`𝒱" "t ∈ SMP ?M - Var`𝒱" "(∃δ. Unifier δ s t)"
hence "s ∈ SMP ?N - Var`𝒱" "t ∈ SMP ?N - Var`𝒱" using * by auto
hence "Γ s = Γ t" using **(1,4) unfolding tfr⇩s⇩e⇩t_def by blast
} moreover have "∀t ∈ ?N. wf⇩t⇩r⇩m t ⟹ ∀t ∈ ?M. wf⇩t⇩r⇩m t" using * by blast
ultimately have "tfr⇩s⇩e⇩t ?N ⟹ tfr⇩s⇩e⇩t ?M" unfolding tfr⇩s⇩e⇩t_def by blast
hence "tfr⇩s⇩e⇩t ?M" using assms unfolding tfr⇩s⇩s⇩t_def by metis
thus "tfr⇩s⇩s⇩t B" using assms unfolding tfr⇩s⇩s⇩t_def by simp
qed
lemma tfr⇩s⇩s⇩t_cons: "tfr⇩s⇩s⇩t (a#A) ⟹ tfr⇩s⇩s⇩t A"
using tfr⇩s⇩s⇩t_append'[of "[a]" A] by simp
lemma tfr⇩s⇩s⇩t⇩p_subst:
assumes s: "tfr⇩s⇩s⇩t⇩p s"
and θ: "wt⇩s⇩u⇩b⇩s⇩t θ" "wf⇩t⇩r⇩m⇩s (subst_range θ)" "set (bvars⇩s⇩s⇩t⇩p s) ∩ range_vars θ = {}"
shows "tfr⇩s⇩s⇩t⇩p (s ⋅⇩s⇩s⇩t⇩p θ)"
proof (cases s)
case (Equality a t t')
thus ?thesis
proof (cases "∃δ. Unifier δ (t ⋅ θ) (t' ⋅ θ)")
case True
hence "∃δ. Unifier δ t t'" by (metis subst_subst_compose[of _ θ])
moreover have "Γ t = Γ (t ⋅ θ)" "Γ t' = Γ (t' ⋅ θ)" by (metis wt_subst_trm''[OF assms(2)])+
ultimately have "Γ (t ⋅ θ) = Γ (t' ⋅ θ)" using s Equality by simp
thus ?thesis using Equality True by simp
qed simp
next
case (NegChecks X F G)
let ?P = "λF G. G = [] ∧ (∀x ∈ fv⇩p⇩a⇩i⇩r⇩s F-set X. ∃a. Γ (Var x) = TAtom a)"
let ?Q = "λF G. ∀f T. Fun f T ∈ subterms⇩s⇩e⇩t (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set G) ⟶
T = [] ∨ (∃s ∈ set T. s ∉ Var ` set X)"
let ?θ = "rm_vars (set X) θ"
have "?P F G ∨ ?Q F G" using NegChecks assms(1) by simp
hence "?P (F ⋅⇩p⇩a⇩i⇩r⇩s ?θ) (G ⋅⇩p⇩a⇩i⇩r⇩s ?θ) ∨ ?Q (F ⋅⇩p⇩a⇩i⇩r⇩s ?θ) (G ⋅⇩p⇩a⇩i⇩r⇩s ?θ)"
proof
assume *: "?P F G"
have "G ⋅⇩p⇩a⇩i⇩r⇩s ?θ = []" using * by simp
moreover have "∃a. Γ (Var x) = TAtom a" when x: "x ∈ fv⇩p⇩a⇩i⇩r⇩s (F ⋅⇩p⇩a⇩i⇩r⇩s ?θ) - set X" for x
proof -
obtain t t' where t: "(t,t') ∈ set (F ⋅⇩p⇩a⇩i⇩r⇩s ?θ)" "x ∈ fv t ∪ fv t' - set X"
using x(1) by auto
then obtain u u' where u: "(u,u') ∈ set F" "u ⋅ ?θ = t" "u' ⋅ ?θ = t'"
unfolding subst_apply_pairs_def by auto
obtain y where y: "y ∈ fv u ∪ fv u' - set X" "x ∈ fv (?θ y)"
using t(2) u(2,3) rm_vars_fv_obtain by fast
hence a: "∃a. Γ (Var y) = TAtom a" using u * by auto
have a': "Γ (Var y) = Γ (?θ y)"
using wt_subst_trm''[OF wt_subst_rm_vars[OF θ(1), of "set X"], of "Var y"]
by simp
have "(∃z. ?θ y = Var z) ∨ (∃c. ?θ y = Fun c [])"
proof (cases "?θ y ∈ subst_range θ")
case True thus ?thesis
using a a' θ(2) const_type_inv_wf
by (cases "?θ y") fastforce+
qed fastforce
hence "?θ y = Var x" using y(2) by fastforce
hence "Γ (Var x) = Γ (Var y)" using a' by simp
thus ?thesis using a by presburger
qed
ultimately show ?thesis by simp
next
assume *: "?Q F G"
have **: "set X ∩ range_vars ?θ = {}"
using θ(3) NegChecks rm_vars_img_fv_subset[of "set X" θ] by auto
have "?Q (F ⋅⇩p⇩a⇩i⇩r⇩s ?θ) (G ⋅⇩p⇩a⇩i⇩r⇩s ?θ)"
using ineq_subterm_inj_cond_subst[OF ** *]
trms⇩p⇩a⇩i⇩r⇩s_subst[of F "rm_vars (set X) θ"]
subst_apply_pairs_pair_image_subst[of G "rm_vars (set X) θ"]
by (metis (no_types, lifting) image_Un)
thus ?thesis by simp
qed
thus ?thesis using NegChecks by simp
qed simp_all
lemma tfr⇩s⇩s⇩t⇩p_all_wt_subst_apply:
assumes S: "list_all tfr⇩s⇩s⇩t⇩p S"
and θ: "wt⇩s⇩u⇩b⇩s⇩t θ" "wf⇩t⇩r⇩m⇩s (subst_range θ)" "bvars⇩s⇩s⇩t S ∩ range_vars θ = {}"
shows "list_all tfr⇩s⇩s⇩t⇩p (S ⋅⇩s⇩s⇩t θ)"
proof -
have "set (bvars⇩s⇩s⇩t⇩p s) ∩ range_vars θ = {}" when "s ∈ set S" for s
using that θ(3) unfolding bvars⇩s⇩s⇩t_def range_vars_alt_def by fastforce
thus ?thesis
using tfr⇩s⇩s⇩t⇩p_subst[OF _ θ(1,2)] S
unfolding list_all_iff
by (auto simp add: subst_apply_stateful_strand_def)
qed
lemma tfr_setops_if_tfr_trms:
assumes "Pair ∉ ⋃(funs_term ` SMP (trms⇩s⇩s⇩t S))"
and "∀p. Ana (pair p) = ([], [])"
and "∀s ∈ pair ` setops⇩s⇩s⇩t S. ∀t ∈ pair ` setops⇩s⇩s⇩t S. (∃δ. Unifier δ s t) ⟶ Γ s = Γ t"
and "∀s ∈ pair ` setops⇩s⇩s⇩t S. ∀t ∈ pair ` setops⇩s⇩s⇩t S.
(∃σ θ ρ. wt⇩s⇩u⇩b⇩s⇩t σ ∧ wt⇩s⇩u⇩b⇩s⇩t θ ∧ wf⇩t⇩r⇩m⇩s (subst_range σ) ∧ wf⇩t⇩r⇩m⇩s (subst_range θ) ∧
Unifier ρ (s ⋅ σ) (t ⋅ θ))
⟶ (∃δ. Unifier δ s t)"
and tfr: "tfr⇩s⇩e⇩t (trms⇩s⇩s⇩t S)"
shows "tfr⇩s⇩e⇩t (trms⇩s⇩s⇩t S ∪ pair ` setops⇩s⇩s⇩t S)"
proof -
have 0: "t ∈ SMP (trms⇩s⇩s⇩t S) - range Var ∨ t ∈ SMP (pair ` setops⇩s⇩s⇩t S) - range Var"
when "t ∈ SMP (trms⇩s⇩s⇩t S ∪ pair ` setops⇩s⇩s⇩t S) - range Var" for t
using that SMP_union by blast
have 1: "s ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
when st: "s ∈ SMP (pair ` setops⇩s⇩s⇩t S) - range Var"
"t ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
"∃δ. Unifier δ s t"
for s t
proof -
have "(∃δ. s ∈ pair ` setops⇩s⇩s⇩t S ⋅⇩s⇩e⇩t δ) ∨ s ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
using st setops_SMP_cases[of s S] assms(2) by blast
moreover {
fix δ assume δ: "s ∈ pair ` setops⇩s⇩s⇩t S ⋅⇩s⇩e⇩t δ"
then obtain s' where s': "s' ∈ pair ` setops⇩s⇩s⇩t S" "s = s' ⋅ δ" by blast
then obtain u u' where u: "s' = Fun Pair [u,u']"
using setops⇩s⇩s⇩t_are_pairs[of s'] unfolding pair_def by fast
hence *: "s = Fun Pair [u ⋅ δ, u' ⋅ δ]" using δ s' by simp
obtain f T where fT: "t = Fun f T" using st(2) by (cases t) auto
hence "f ≠ Pair" using st(2) assms(1) by auto
hence False using st(3) * fT s' u by fast
} ultimately show ?thesis by meson
qed
have 2: "Γ s = Γ t"
when "s ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
"t ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
"∃δ. Unifier δ s t"
for s t
using that tfr unfolding tfr⇩s⇩e⇩t_def by blast
have 3: "Γ s = Γ t"
when st: "s ∈ SMP (pair ` setops⇩s⇩s⇩t S) - range Var"
"t ∈ SMP (pair ` setops⇩s⇩s⇩t S) - range Var"
"∃δ. Unifier δ s t"
for s t
proof -
let ?P = "λs δ. wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ) ∧ s ∈ pair ` setops⇩s⇩s⇩t S ⋅⇩s⇩e⇩t δ"
have "(∃δ. ?P s δ) ∨ s ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
"(∃δ. ?P t δ) ∨ t ∈ SMP (trms⇩s⇩s⇩t S) - range Var"
using setops_SMP_cases[of _ S] assms(2) st(1,2) by auto
hence "(∃δ δ'. ?P s δ ∧ ?P t δ') ∨ Γ s = Γ t" by (metis 1 2 st)
moreover {
fix δ δ' assume *: "?P s δ" "?P t δ'"
then obtain s' t' where **:
"s' ∈ pair ` setops⇩s⇩s⇩t S" "t' ∈ pair ` setops⇩s⇩s⇩t S" "s = s' ⋅ δ" "t = t' ⋅ δ'"
by blast
hence "∃θ. Unifier θ s' t'" using st(3) assms(4) * by blast
hence "Γ s' = Γ t'" using assms(3) ** by blast
hence "Γ s = Γ t" using * **(3,4) wt_subst_trm''[of δ s'] wt_subst_trm''[of δ' t'] by argo
} ultimately show ?thesis by blast
qed
show ?thesis using 0 1 2 3 unfolding tfr⇩s⇩e⇩t_def by metis
qed
end
subsection ‹The Typing Result for Stateful Constraints›
subsubsection ‹Correctness of the Constraint Reduction›
context stateful_typed_model
begin
context
begin
private lemma tr_wf':
assumes "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
and "∀(t,t') ∈ set D. fv t ∪ fv t' ⊆ X"
and "wf'⇩s⇩s⇩t X A" "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}"
and "A' ∈ set (tr A D)"
shows "wf⇩s⇩t X A'"
proof -
define P where
"P = (λ(D::('fun,'var) dbstatelist) (A::('fun,'var) stateful_strand).
(∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}) ∧ fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {})"
have "P D A" using assms(1,4) by (simp add: P_def)
with assms(5,3,2) show ?thesis
proof (induction A arbitrary: A' D X rule: wf'⇩s⇩s⇩t.induct)
case 1 thus ?case by simp
next
case (2 X ts A A')
then obtain A'' where A'': "A' = receive⟨ts⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)" "fv⇩s⇩e⇩t (set ts) ⊆ X"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t X A" "∀(s,s') ∈ set D. fv s ∪ fv s' ⊆ X" "P D A"
using 2(1,2,3,4) apply (force, force)
using 2(5) unfolding P_def by force
show ?case using "2.IH"[OF A''(2) *] A''(1,3) by simp
next
case (3 X ts A A')
then obtain A'' where A'': "A' = send⟨ts⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t (X ∪ fv⇩s⇩e⇩t (set ts)) A"
"∀(s,s') ∈ set D. fv s ∪ fv s' ⊆ X ∪ fv⇩s⇩e⇩t (set ts)" "P D A"
using 3(1,2,3,4) apply (force, force)
using 3(5) unfolding P_def by force
show ?case using "3.IH"[OF A''(2) *] A''(1) by simp
next
case (4 X t t' A A')
then obtain A'' where A'': "A' = ⟨assign: t ≐ t'⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)" "fv t' ⊆ X"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t (X ∪ fv t) A" "∀(s,s') ∈ set D. fv s ∪ fv s' ⊆ X ∪ fv t" "P D A"
using 4(1,2,3,4) apply (force, force)
using 4(5) unfolding P_def by force
show ?case using "4.IH"[OF A''(2) *] A''(1,3) by simp
next
case (5 X t t' A A')
then obtain A'' where A'': "A' = ⟨check: t ≐ t'⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t X A" "P D A"
using 5(3) apply force
using 5(5) unfolding P_def by force
show ?case using "5.IH"[OF A''(2) *(1) 5(4) *(2)] A''(1) by simp
next
case (6 X t s A A')
hence A': "A' ∈ set (tr A (List.insert (t,s) D))" "fv t ⊆ X" "fv s ⊆ X" by auto
have *: "wf'⇩s⇩s⇩t X A" "∀(s,s') ∈ set (List.insert (t,s) D). fv s ∪ fv s' ⊆ X" using 6 by auto
have **: "P (List.insert (t,s) D) A" using 6(5) unfolding P_def by force
show ?case using "6.IH"[OF A'(1) * **] A'(2,3) by simp
next
case (7 X t s A A')
let ?constr = "λDi. (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])"
from 7 obtain Di A'' where A'':
"A' = ?constr Di@A''" "A'' ∈ set (tr A [d←D. d ∉ set Di])"
"Di ∈ set (subseqs D)"
by atomize_elim force
have *: "wf'⇩s⇩s⇩t X A" "∀(t',s') ∈ set [d←D. d ∉ set Di]. fv t' ∪ fv s' ⊆ X"
using 7 by auto
have **: "P [d←D. d ∉ set Di] A" using 7 unfolding P_def by force
have ***: "∀(t, t') ∈ set D. fv t ∪ fv t' ⊆ X" using 7 by auto
show ?case
using "7.IH"[OF A''(2) * **] A''(1) wf_fun_pair_eqs_ineqs_map[OF _ A''(3) ***]
by simp
next
case (8 X t s A A')
then obtain d A'' where A'':
"A' = ⟨assign: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t#A''"
"A'' ∈ set (tr A D)" "d ∈ set D"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t (X ∪ fv t ∪ fv s) A" "∀(t',s')∈set D. fv t' ∪ fv s' ⊆ X ∪ fv t ∪ fv s" "P D A"
using 8(1,2,3,4) apply (force, force)
using 8(5) unfolding P_def by force
have **: "fv (pair d) ⊆ X" using A''(3) "8.prems"(3) unfolding pair_def by fastforce
have ***: "fv (pair (t,s)) = fv s ∪ fv t" unfolding pair_def by auto
show ?case using "8.IH"[OF A''(2) *] A''(1) ** *** unfolding pair_def by (simp add: Un_assoc)
next
case (9 X t s A A')
then obtain d A'' where A'':
"A' = ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t#A''"
"A'' ∈ set (tr A D)" "d ∈ set D"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t X A""P D A"
using 9(3) apply force
using 9(5) unfolding P_def by force
have **: "fv (pair d) ⊆ X" using A''(3) "9.prems"(3) unfolding pair_def by fastforce
have ***: "fv (pair (t,s)) = fv s ∪ fv t" unfolding pair_def by auto
show ?case using "9.IH"[OF A''(2) *(1) 9(4) *(2)] A''(1) ** *** by (simp add: Un_assoc)
next
case (10 X Y F F' A A')
from 10 obtain A'' where A'':
"A' = (map (λG. ∀Y⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))@A''" "A'' ∈ set (tr A D)"
by atomize_elim auto
have *: "wf'⇩s⇩s⇩t X A" "∀(t',s') ∈ set D. fv t' ∪ fv s' ⊆ X" using 10 by auto
have "bvars⇩s⇩s⇩t A ⊆ bvars⇩s⇩s⇩t (∀Y⟨∨≠: F ∨∉: F'⟩#A)" "fv⇩s⇩s⇩t A ⊆ fv⇩s⇩s⇩t (∀Y⟨∨≠: F ∨∉: F'⟩#A)" by auto
hence **: "P D A" using 10 unfolding P_def by blast
show ?case using "10.IH"[OF A''(2) * **] A''(1) wf_fun_pair_negchecks_map by simp
qed
qed
private lemma tr_wf⇩t⇩r⇩m⇩s:
assumes "A' ∈ set (tr A [])" "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A)"
shows "wf⇩t⇩r⇩m⇩s (trms⇩s⇩t A')"
using tr_trms_subset[OF assms(1)] setops⇩s⇩s⇩t_wf⇩t⇩r⇩m⇩s(2)[OF assms(2)]
by auto
lemma tr_wf:
assumes "A' ∈ set (tr A [])"
and "wf⇩s⇩s⇩t A"
and "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t A)"
shows "wf⇩s⇩t {} A'"
and "wf⇩t⇩r⇩m⇩s (trms⇩s⇩t A')"
and "fv⇩s⇩t A' ∩ bvars⇩s⇩t A' = {}"
using tr_wf'[OF _ _ _ _ assms(1)]
tr_wf⇩t⇩r⇩m⇩s[OF assms(1,3)]
tr_vars_disj[OF assms(1)]
assms(2)
by fastforce+
private lemma fun_pair_ineqs:
assumes "d ⋅⇩p δ ⋅⇩p θ ≠ d' ⋅⇩p ℐ"
shows "pair d ⋅ δ ⋅ θ ≠ pair d' ⋅ ℐ"
proof -
have "d ⋅⇩p (δ ∘⇩s θ) ≠ d' ⋅⇩p ℐ" using assms subst_pair_compose by metis
hence "pair d ⋅ (δ ∘⇩s θ) ≠ pair d' ⋅ ℐ" using fun_pair_eq_subst by metis
thus ?thesis by simp
qed
private lemma tr_Delete_constr_iff_aux1:
assumes "∀d ∈ set Di. (t,s) ⋅⇩p ℐ = d ⋅⇩p ℐ"
and "∀d ∈ set D - set Di. (t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ"
shows "⟦M; (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])⟧⇩d ℐ"
proof -
from assms(2) have
"⟦M; map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di]⟧⇩d ℐ"
proof (induction D)
case (Cons d D)
hence IH: "⟦M; map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D . d ∉ set Di]⟧⇩d ℐ" by auto
thus ?case
proof (cases "d ∈ set Di")
case False
hence "(t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ" using Cons by simp
hence "pair (t,s) ⋅ ℐ ≠ pair d ⋅ ℐ" using fun_pair_eq_subst by metis
moreover have "⋀t (δ::('fun,'var) subst). subst_domain δ = {} ⟹ t ⋅ δ = t" by auto
ultimately have "∀δ. subst_domain δ = {} ⟶ pair (t,s) ⋅ δ ⋅ ℐ ≠ pair d ⋅ δ ⋅ ℐ" by metis
thus ?thesis using IH by (simp add: ineq_model_def)
qed simp
qed simp
moreover {
fix B assume "⟦M; B⟧⇩d ℐ"
with assms(1) have "⟦M; (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@B⟧⇩d ℐ"
unfolding pair_def by (induction Di) auto
} ultimately show ?thesis by metis
qed
private lemma tr_Delete_constr_iff_aux2:
assumes "ground M"
and "⟦M; (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])⟧⇩d ℐ"
shows "(∀d ∈ set Di. (t,s) ⋅⇩p ℐ = d ⋅⇩p ℐ) ∧ (∀d ∈ set D - set Di. (t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ)"
proof -
let ?c1 = "map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di"
let ?c2 = "map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di]"
have "M ⋅⇩s⇩e⇩t ℐ = M" using assms(1) subst_all_ground_ident by metis
moreover have "ik⇩s⇩t ?c1 = {}" by auto
ultimately have *:
"⟦M; map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di⟧⇩d ℐ"
"⟦M; map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di]⟧⇩d ℐ"
using strand_sem_split(3,4)[of M ?c1 ?c2 ℐ] assms(2) by auto
from *(1) have 1: "∀d ∈ set Di. (t,s) ⋅⇩p ℐ = d ⋅⇩p ℐ" unfolding pair_def by (induct Di) auto
from *(2) have 2: "∀d ∈ set D - set Di. (t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ"
proof (induction D arbitrary: Di)
case (Cons d D) thus ?case
proof (cases "d ∈ set Di")
case False
hence IH: "∀d ∈ set D - set Di. (t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ" using Cons by force
have "⋀t (δ::('fun,'var) subst). subst_domain δ = {} ∧ ground (subst_range δ) ⟷ δ = Var"
by auto
moreover have "ineq_model ℐ [] [((pair (t,s)), (pair d))]"
using False Cons.prems by simp
ultimately have "pair (t,s) ⋅ ℐ ≠ pair d ⋅ ℐ" by (simp add: ineq_model_def)
thus ?thesis using IH unfolding pair_def by force
qed simp
qed simp
show ?thesis by (metis 1 2)
qed
private lemma tr_Delete_constr_iff:
fixes ℐ::"('fun,'var) subst"
assumes "ground M"
shows "set Di ⋅⇩p⇩s⇩e⇩t ℐ ⊆ {(t,s) ⋅⇩p ℐ} ∧ (t,s) ⋅⇩p ℐ ∉ (set D - set Di) ⋅⇩p⇩s⇩e⇩t ℐ ⟷
⟦M; (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])⟧⇩d ℐ"
proof -
let ?constr = "(map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di])"
{ assume "set Di ⋅⇩p⇩s⇩e⇩t ℐ ⊆ {(t,s) ⋅⇩p ℐ}" "(t,s) ⋅⇩p ℐ ∉ (set D - set Di) ⋅⇩p⇩s⇩e⇩t ℐ"
hence "∀d ∈ set Di. (t,s) ⋅⇩p ℐ = d ⋅⇩p ℐ" "∀d ∈ set D - set Di. (t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ"
by auto
hence "⟦M; ?constr⟧⇩d ℐ" using tr_Delete_constr_iff_aux1 by simp
} moreover {
assume "⟦M; ?constr⟧⇩d ℐ"
hence "∀d ∈ set Di. (t,s) ⋅⇩p ℐ = d ⋅⇩p ℐ" "∀d ∈ set D - set Di. (t,s) ⋅⇩p ℐ ≠ d ⋅⇩p ℐ"
using assms tr_Delete_constr_iff_aux2 by auto
hence "set Di ⋅⇩p⇩s⇩e⇩t ℐ ⊆ {(t,s) ⋅⇩p ℐ} ∧ (t,s) ⋅⇩p ℐ ∉ (set D - set Di) ⋅⇩p⇩s⇩e⇩t ℐ" by force
} ultimately show ?thesis by metis
qed
private lemma tr_NotInSet_constr_iff:
fixes ℐ::"('fun,'var) subst"
assumes "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ set X = {}"
shows "(∀δ. subst_domain δ = set X ∧ ground (subst_range δ) ⟶ (t,s) ⋅⇩p δ ⋅⇩p ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ)
⟷ ⟦M; map (λd. ∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) D⟧⇩d ℐ"
proof -
{ assume "∀δ. subst_domain δ = set X ∧ ground (subst_range δ) ⟶ (t,s) ⋅⇩p δ ⋅⇩p ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ"
with assms have "⟦M; map (λd. ∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) D⟧⇩d ℐ"
proof (induction D)
case (Cons d D)
obtain t' s' where d: "d = (t',s')" by atomize_elim auto
have "⟦M; map (λd. ∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) D⟧⇩d ℐ"
"map (λd. ∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) (d#D) =
∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t#map (λd. ∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) D"
using Cons by auto
moreover have
"∀δ. subst_domain δ = set X ∧ ground (subst_range δ) ⟶ pair (t, s) ⋅ δ ⋅ ℐ ≠ pair d ⋅ ℐ"
using fun_pair_ineqs[of ℐ _ "(t,s)" ℐ d] Cons.prems(2) by auto
moreover have "(fv t' ∪ fv s') ∩ set X = {}" using Cons.prems(1) d by auto
hence "∀δ. subst_domain δ = set X ⟶ pair d ⋅ δ = pair d" using d unfolding pair_def by auto
ultimately show ?case by (simp add: ineq_model_def)
qed simp
} moreover {
fix δ::"('fun,'var) subst"
assume "⟦M; map (λd. ∀X⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) D⟧⇩d ℐ"
and δ: "subst_domain δ = set X" "ground (subst_range δ)"
with assms have "(t,s) ⋅⇩p δ ⋅⇩p ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ"
proof (induction D)
case (Cons d D)
obtain t' s' where d: "d = (t',s')" by atomize_elim auto
have "(t,s) ⋅⇩p δ ⋅⇩p ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ"
"pair (t,s) ⋅ δ ⋅ ℐ ≠ pair d ⋅ δ ⋅ ℐ"
using Cons d by (auto simp add: ineq_model_def simp del: subst_range.simps)
moreover have "pair d ⋅ δ = pair d"
using Cons.prems(1) fun_pair_subst[of d δ] d δ(1) unfolding pair_def by auto
ultimately show ?case unfolding pair_def by force
qed simp
} ultimately show ?thesis by metis
qed
lemma tr_NegChecks_constr_iff:
"(∀G∈set L. ineq_model ℐ X (F@G)) ⟷ ⟦M; map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) L⟧⇩d ℐ" (is ?A)
"negchecks_model ℐ D X F F' ⟷ ⟦M; D; [∀X⟨∨≠: F ∨∉: F'⟩]⟧⇩s ℐ" (is ?B)
proof -
show ?A by (induct L) auto
show ?B by simp
qed
lemma tr⇩p⇩a⇩i⇩r⇩s_sem_equiv:
fixes ℐ::"('fun,'var) subst"
assumes "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ set X = {}"
shows "negchecks_model ℐ (set D ⋅⇩p⇩s⇩e⇩t ℐ) X F F' ⟷
(∀G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D). ineq_model ℐ X (F@G))"
proof -
define P where
"P ≡ λδ::('fun,'var) subst. subst_domain δ = set X ∧ ground (subst_range δ)"
define Ineq where
"Ineq ≡ λ(δ::('fun,'var) subst) F. ∃(s,t) ∈ set F. s ⋅ δ ∘⇩s ℐ ≠ t ⋅ δ ∘⇩s ℐ"
define Ineq' where
"Ineq' ≡ λ(δ::('fun,'var) subst) F. ∃(s,t) ∈ set F. s ⋅ δ ∘⇩s ℐ ≠ t ⋅ ℐ"
define Notin where
"Notin ≡ λ(δ::('fun,'var) subst) D F'. ∃(s,t) ∈ set F'. (s,t) ⋅⇩p δ ∘⇩s ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ"
have sublmm:
"((s,t) ⋅⇩p δ ∘⇩s ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ) ⟷ (list_all (λd. Ineq' δ [(pair (s,t),pair d)]) D)"
for s t δ D
unfolding pair_def by (induct D) (auto simp add: Ineq'_def)
have "Notin δ D F' ⟷ (∀G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D). Ineq' δ G)"
(is "?A ⟷ ?B")
when "P δ" for δ
proof
show "?A ⟹ ?B"
proof (induction F' D rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F' D)
show ?case
proof (cases "Notin δ D F'")
case False
hence "(s,t) ⋅⇩p δ ∘⇩s ℐ ∉ set D ⋅⇩p⇩s⇩e⇩t ℐ"
using "2.prems"
by (auto simp add: Notin_def)
hence "pair (s,t) ⋅ δ ∘⇩s ℐ ≠ pair d ⋅ ℐ" when "d ∈ set D" for d
using that sublmm Ball_set[of D "λd. Ineq' δ [(pair (s,t), pair d)]"]
by (simp add: Ineq'_def)
moreover have "∃d ∈ set D. ∃G'. G = (pair (s,t), pair d)#G'"
when "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s ((s,t)#F') D)" for G
using that tr⇩p⇩a⇩i⇩r⇩s_index[OF that, of 0] by force
ultimately show ?thesis by (simp add: Ineq'_def)
qed (auto dest: "2.IH" simp add: Ineq'_def)
qed (simp add: Notin_def)
have "¬?A ⟹ ¬?B"
proof (induction F' D rule: tr⇩p⇩a⇩i⇩r⇩s.induct)
case (2 s t F' D)
hence "¬Notin δ D F'" "D ≠ []" unfolding Notin_def by auto
then obtain G where G: "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D)" "¬Ineq' δ G"
using "2.IH" by (cases D) auto
obtain d where d: "d ∈ set D" "pair (s,t) ⋅ δ ∘⇩s ℐ = pair d ⋅ ℐ"
using "2.prems"
unfolding pair_def by (auto simp add: Notin_def)
thus ?case
using G(2) tr⇩p⇩a⇩i⇩r⇩s_cons[OF G(1) d(1)]
by (auto simp add: Ineq'_def)
qed (simp add: Ineq'_def)
thus "?B ⟹ ?A" by metis
qed
hence *: "(∀δ. P δ ⟶ Ineq δ F ∨ Notin δ D F') ⟷
(∀G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D). ∀δ. P δ ⟶ Ineq δ F ∨ Ineq' δ G)"
by auto
have "t ⋅ δ = t"
when "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D)" "(s,t) ∈ set G" "P δ"
for δ s t G
using assms that(3) tr⇩p⇩a⇩i⇩r⇩s_has_pair_lists[OF that(1,2)]
unfolding pair_def by (fastforce simp add: P_def)
hence **: "Ineq' δ G = Ineq δ G"
when "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D)" "P δ"
for δ G
using that unfolding Ineq_def Ineq'_def by force
have ***: "negchecks_model ℐ (set D ⋅⇩p⇩s⇩e⇩t ℐ) X F F' ⟷ (∀δ. P δ ⟶ Ineq δ F ∨ Notin δ D F')"
unfolding P_def Ineq_def Notin_def negchecks_model_def by blast
have "ineq_model ℐ X (F@G) ⟷ (∀δ. P δ ⟶ Ineq δ (F@G))" for G
unfolding P_def Ineq_def ineq_model_def by blast
hence ****: "ineq_model ℐ X (F@G) ⟷ (∀δ. P δ ⟶ Ineq δ F ∨ Ineq δ G)" for G
unfolding Ineq_def by fastforce
show ?thesis
using * ** *** **** by simp
qed
lemma tr_sem_equiv':
assumes "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
and "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}"
and "ground M"
and ℐ: "interpretation⇩s⇩u⇩b⇩s⇩t ℐ"
shows "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ ⟷ (∃A' ∈ set (tr A D). ⟦M; A'⟧⇩d ℐ)" (is "?P ⟷ ?Q")
proof
have ℐ_grounds: "⋀t. fv (t ⋅ ℐ) = {}" by (rule interpretation_grounds[OF ℐ])
have "∃A' ∈ set (tr A D). ⟦M; A'⟧⇩d ℐ" when ?P using that assms(1,2,3)
proof (induction A arbitrary: D rule: strand_sem_stateful_induct)
case (ConsRcv M D ts A)
have "⟦(set ts ⋅⇩s⇩e⇩t ℐ) ∪ M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground ((set ts ⋅⇩s⇩e⇩t ℐ) ∪ M)"
using ℐ ConsRcv.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
then obtain A' where A': "A' ∈ set (tr A D)" "⟦(set ts ⋅⇩s⇩e⇩t ℐ) ∪ M; A'⟧⇩d ℐ" by (metis ConsRcv.IH)
thus ?case by auto
next
case (ConsSnd M D ts A)
have "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
and *: "∀t ∈ set ts. M ⊢ t ⋅ ℐ"
using ℐ ConsSnd.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
then obtain A' where A': "A' ∈ set (tr A D)" "⟦M; A'⟧⇩d ℐ" by (metis ConsSnd.IH)
thus ?case using * by auto
next
case (ConsEq M D ac t t' A)
have "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
and *: "t ⋅ ℐ = t' ⋅ ℐ"
using ℐ ConsEq.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
then obtain A' where A': "A' ∈ set (tr A D)" "⟦M; A'⟧⇩d ℐ" by (metis ConsEq.IH)
thus ?case using * by auto
next
case (ConsIns M D t s A)
have "⟦M; set (List.insert (t,s) D) ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
"∀(t,t') ∈ set (List.insert (t,s) D). (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
using ConsIns.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
then obtain A' where A': "A' ∈ set (tr A (List.insert (t,s) D))" "⟦M; A'⟧⇩d ℐ"
by (metis ConsIns.IH)
thus ?case by auto
next
case (ConsDel M D t s A)
have *: "⟦M; (set D ⋅⇩p⇩s⇩e⇩t ℐ) - {(t,s) ⋅⇩p ℐ}; A⟧⇩s ℐ"
"∀(t,t')∈set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
using ConsDel.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
then obtain Di where Di:
"Di ⊆ set D" "Di ⋅⇩p⇩s⇩e⇩t ℐ ⊆ {(t,s) ⋅⇩p ℐ}" "(t,s) ⋅⇩p ℐ ∉ (set D - Di) ⋅⇩p⇩s⇩e⇩t ℐ"
using subset_subst_pairs_diff_exists'[of "set D"] by atomize_elim auto
hence **: "(set D ⋅⇩p⇩s⇩e⇩t ℐ) - {(t,s) ⋅⇩p ℐ} = (set D - Di) ⋅⇩p⇩s⇩e⇩t ℐ" by blast
obtain Di' where Di': "set Di' = Di" "Di' ∈ set (subseqs D)"
using subset_sublist_exists[OF Di(1)] by atomize_elim auto
hence ***: "(set D ⋅⇩p⇩s⇩e⇩t ℐ) - {(t,s) ⋅⇩p ℐ} = (set [d←D. d ∉ set Di'] ⋅⇩p⇩s⇩e⇩t ℐ)"
using Di ** by auto
define constr where "constr ≡
map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di'@
map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di']"
have ****: "∀(t,t')∈set [d←D. d ∉ set Di']. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
using *(2) Di(1) Di'(1) subseqs_set_subset[OF Di'(2)] by simp
have "set D - Di = set [d←D. d ∉ set Di']" using Di Di' by auto
hence *****: "⟦M; set [d←D. d ∉ set Di'] ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
using *(1) ** by metis
obtain A' where A': "A' ∈ set (tr A [d←D. d ∉ set Di'])" "⟦M; A'⟧⇩d ℐ"
using ConsDel.IH[OF ***** **** *(3,4)] by atomize_elim auto
hence constr_sat: "⟦M; constr⟧⇩d ℐ"
using Di Di' *(1) *** tr_Delete_constr_iff[OF *(4), of ℐ Di' t s D]
unfolding constr_def by auto
have "constr@A' ∈ set (tr (Delete t s#A) D)" using A'(1) Di' unfolding constr_def by auto
moreover have "ik⇩s⇩t constr = {}" unfolding constr_def by auto
hence "⟦M ⋅⇩s⇩e⇩t ℐ; constr⟧⇩d ℐ" "⟦M ∪ (ik⇩s⇩t constr ⋅⇩s⇩e⇩t ℐ); A'⟧⇩d ℐ"
using constr_sat A'(2) subst_all_ground_ident[OF *(4)] by simp_all
ultimately show ?case
using strand_sem_append(2)[of _ _ ℐ]
subst_all_ground_ident[OF *(4), of ℐ]
by metis
next
case (ConsIn M D ac t s A)
have "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
and *: "(t,s) ⋅⇩p ℐ ∈ set D ⋅⇩p⇩s⇩e⇩t ℐ"
using ℐ ConsIn.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
then obtain A' where A': "A' ∈ set (tr A D)" "⟦M; A'⟧⇩d ℐ" by (metis ConsIn.IH)
moreover obtain d where "d ∈ set D" "pair (t,s) ⋅ ℐ = pair d ⋅ ℐ"
using * unfolding pair_def by auto
ultimately show ?case using * by auto
next
case (ConsNegChecks M D X F F' A)
let ?ineqs = "(map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))"
have 1: "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ" "ground M" using ConsNegChecks by auto
have 2: "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}" "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}"
using ConsNegChecks.prems(2,3) ℐ unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by fastforce+
have 3: "negchecks_model ℐ (set D ⋅⇩p⇩s⇩e⇩t ℐ) X F F'" using ConsNegChecks.prems(1) by simp
from 1 2 obtain A' where A': "A' ∈ set (tr A D)" "⟦M; A'⟧⇩d ℐ" by (metis ConsNegChecks.IH)
have 4: "∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ set X = {}"
using ConsNegChecks.prems(2) unfolding bvars⇩s⇩s⇩t_def by auto
have "⟦M; ?ineqs⟧⇩d ℐ"
using 3 tr⇩p⇩a⇩i⇩r⇩s_sem_equiv[OF 4] tr_NegChecks_constr_iff
by metis
moreover have "ik⇩s⇩t ?ineqs = {}" by auto
moreover have "M ⋅⇩s⇩e⇩t ℐ = M" using 1(2) ℐ by (simp add: subst_all_ground_ident)
ultimately show ?case
using strand_sem_append(2)[of M ?ineqs ℐ A'] A'
by force
qed simp
thus "?P ⟹ ?Q" by metis
have "(∃A' ∈ set (tr A D). ⟦M; A'⟧⇩d ℐ) ⟹ ?P" using assms(1,2,3)
proof (induction A arbitrary: D rule: strand_sem_stateful_induct)
case (ConsRcv M D ts A)
have "∃A' ∈ set (tr A D). ⟦(set ts ⋅⇩s⇩e⇩t ℐ) ∪ M; A'⟧⇩d ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground ((set ts ⋅⇩s⇩e⇩t ℐ) ∪ M)"
using ℐ ConsRcv.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
hence "⟦(set ts ⋅⇩s⇩e⇩t ℐ) ∪ M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ" by (metis ConsRcv.IH)
thus ?case by auto
next
case (ConsSnd M D ts A)
have "∃A' ∈ set (tr A D). ⟦M; A'⟧⇩d ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
and *: "∀t ∈ set ts. M ⊢ t ⋅ ℐ"
using ℐ ConsSnd.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
hence "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ" by (metis ConsSnd.IH)
thus ?case using * by auto
next
case (ConsEq M D ac t t' A)
have "∃A' ∈ set (tr A D). ⟦M; A'⟧⇩d ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
and *: "t ⋅ ℐ = t' ⋅ ℐ"
using ℐ ConsEq.prems unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
hence "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ" by (metis ConsEq.IH)
thus ?case using * by auto
next
case (ConsIns M D t s A)
hence "∃A' ∈ set (tr A (List.insert (t,s) D)). ⟦M; A'⟧⇩d ℐ"
"∀(t,t') ∈ set (List.insert (t,s) D). (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by auto+
hence "⟦M; set (List.insert (t,s) D) ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ" by (metis ConsIns.IH)
thus ?case by auto
next
case (ConsDel M D t s A)
define constr where "constr ≡
λDi. map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di@
map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di]"
let ?flt = "λDi. filter (λd. d ∉ set Di) D"
have "∃Di ∈ set (subseqs D). ∃B' ∈ set (tr A (?flt Di)). B = constr Di@B'"
when "B ∈ set (tr (delete⟨t,s⟩#A) D)" for B
using that unfolding constr_def by auto
then obtain A' Di where A':
"constr Di@A' ∈ set (tr (Delete t s#A) D)"
"A' ∈ set (tr A (?flt Di))"
"Di ∈ set (subseqs D)"
"⟦M; constr Di@A'⟧⇩d ℐ"
using ConsDel.prems(1) by blast
have 1: "∀(t,t')∈set (?flt Di). (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}" using ConsDel.prems(2) by auto
have 2: "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" using ConsDel.prems(3) by force+
have "ik⇩s⇩t (constr Di) = {}" unfolding constr_def by auto
hence 3: "⟦M; A'⟧⇩d ℐ"
using subst_all_ground_ident[OF ConsDel.prems(4)] A'(4)
strand_sem_split(4)[of M "constr Di" A' ℐ]
by simp
have IH: "⟦M; set (?flt Di) ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
by (metis ConsDel.IH[OF _ 1 2 ConsDel.prems(4)] 3 A'(2))
have "⟦M; constr Di⟧⇩d ℐ"
using subst_all_ground_ident[OF ConsDel.prems(4)] strand_sem_split(3) A'(4)
by metis
hence *: "set Di ⋅⇩p⇩s⇩e⇩t ℐ ⊆ {(t,s) ⋅⇩p ℐ}" "(t,s) ⋅⇩p ℐ ∉ (set D - set Di) ⋅⇩p⇩s⇩e⇩t ℐ"
using tr_Delete_constr_iff[OF ConsDel.prems(4), of ℐ Di t s D] unfolding constr_def by auto
have 4: "set (?flt Di) ⋅⇩p⇩s⇩e⇩t ℐ = (set D ⋅⇩p⇩s⇩e⇩t ℐ) - {((t,s) ⋅⇩p ℐ)}"
proof
show "set (?flt Di) ⋅⇩p⇩s⇩e⇩t ℐ ⊆ (set D ⋅⇩p⇩s⇩e⇩t ℐ) - {((t,s) ⋅⇩p ℐ)}"
proof
fix u u' assume u: "(u,u') ∈ set (?flt Di) ⋅⇩p⇩s⇩e⇩t ℐ"
then obtain v v' where v: "(v,v') ∈ set D - set Di" "(v,v') ⋅⇩p ℐ = (u,u')" by auto
hence "(u,u') ≠ (t,s) ⋅⇩p ℐ" using * by force
thus "(u,u') ∈ (set D ⋅⇩p⇩s⇩e⇩t ℐ) - {((t,s) ⋅⇩p ℐ)}"
using u v * subseqs_set_subset[OF A'(3)] by auto
qed
show "(set D ⋅⇩p⇩s⇩e⇩t ℐ) - {((t,s) ⋅⇩p ℐ)} ⊆ set (?flt Di) ⋅⇩p⇩s⇩e⇩t ℐ"
using * subseqs_set_subset[OF A'(3)] by force
qed
show ?case using 4 IH by simp
next
case (ConsIn M D ac t s A)
have "∃A' ∈ set (tr A D). ⟦M; A'⟧⇩d ℐ"
"∀(t,t') ∈ set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}"
"fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" "ground M"
and *: "(t,s) ⋅⇩p ℐ ∈ set D ⋅⇩p⇩s⇩e⇩t ℐ"
using ConsIn.prems(1,2,3,4) apply (fastforce, fastforce, fastforce, fastforce)
using ConsIn.prems(1) tr.simps(7)[of ac t s A D] unfolding pair_def by fastforce
hence "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ" by (metis ConsIn.IH)
moreover obtain d where "d ∈ set D" "pair (t,s) ⋅ ℐ = pair d ⋅ ℐ"
using * unfolding pair_def by auto
ultimately show ?case using * by auto
next
case (ConsNegChecks M D X F F' A)
let ?ineqs = "(map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))"
obtain B where B:
"?ineqs@B ∈ set (tr (NegChecks X F F'#A) D)" "⟦M; ?ineqs@B⟧⇩d ℐ" "B ∈ set (tr A D)"
using ConsNegChecks.prems(1) by atomize_elim auto
moreover have "M ⋅⇩s⇩e⇩t ℐ = M"
using ConsNegChecks.prems(4) ℐ by (simp add: subst_all_ground_ident)
moreover have "ik⇩s⇩t ?ineqs = {}" by auto
ultimately have "⟦M; B⟧⇩d ℐ" using strand_sem_split(4)[of M ?ineqs B ℐ] by simp
moreover have "∀(t,t')∈set D. (fv t ∪ fv t') ∩ bvars⇩s⇩s⇩t A = {}" "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}"
using ConsNegChecks.prems(2,3) unfolding fv⇩s⇩s⇩t_def bvars⇩s⇩s⇩t_def by force+
ultimately have "⟦M; set D ⋅⇩p⇩s⇩e⇩t ℐ; A⟧⇩s ℐ"
by (metis ConsNegChecks.IH B(3) ConsNegChecks.prems(4))
moreover have "∀(t, t')∈set D. (fv t ∪ fv t') ∩ set X = {}"
using ConsNegChecks.prems(2) unfolding bvars⇩s⇩s⇩t_def by force
ultimately show ?case
using tr⇩p⇩a⇩i⇩r⇩s_sem_equiv tr_NegChecks_constr_iff
B(2) strand_sem_split(3)[of M ?ineqs B ℐ] ‹M ⋅⇩s⇩e⇩t ℐ = M›
by simp
qed simp
thus "?Q ⟹ ?P" by metis
qed
lemma tr_sem_equiv:
assumes "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" and "interpretation⇩s⇩u⇩b⇩s⇩t ℐ"
shows "ℐ ⊨⇩s A ⟷ (∃A' ∈ set (tr A []). (ℐ ⊨ ⟨A'⟩))"
using tr_sem_equiv'[OF _ assms(1) _ assms(2), of "[]" "{}"]
unfolding constr_sem_d_def
by auto
end
end
subsubsection ‹Typing Result Locale Definition›
locale stateful_typing_result =
stateful_typed_model arity public Ana Γ Pair
+ typing_result arity public Ana Γ
for arity::"'fun ⇒ nat"
and public::"'fun ⇒ bool"
and Ana::"('fun,'var) term ⇒ (('fun,'var) term list × ('fun,'var) term list)"
and Γ::"('fun,'var) term ⇒ ('fun,'atom::finite) term_type"
and Pair::"'fun"
subsubsection ‹Type-Flaw Resistance Preservation of the Constraint Reduction›
context stateful_typing_result
begin
context
begin
private lemma tr_tfr⇩s⇩s⇩t⇩p:
assumes "A' ∈ set (tr A D)" "list_all tfr⇩s⇩s⇩t⇩p A"
and "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}" (is "?P0 A D")
and "∀(t,s) ∈ set D. (fv t ∪ fv s) ∩ bvars⇩s⇩s⇩t A = {}" (is "?P1 A D")
and "∀t ∈ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D. ∀t' ∈ pair ` setops⇩s⇩s⇩t A ∪ pair ` set D.
(∃δ. Unifier δ t t') ⟶ Γ t = Γ t'" (is "?P3 A D")
shows "list_all tfr⇩s⇩t⇩p A'"
proof -
have sublmm: "list_all tfr⇩s⇩s⇩t⇩p A" "?P0 A D" "?P1 A D" "?P3 A D"
when p: "list_all tfr⇩s⇩s⇩t⇩p (a#A)" "?P0 (a#A) D" "?P1 (a#A) D" "?P3 (a#A) D"
for a A D
using p(1) apply (simp add: tfr⇩s⇩s⇩t_def)
using p(2) fv⇩s⇩s⇩t_cons_subset bvars⇩s⇩s⇩t_cons_subset apply fast
using p(3) bvars⇩s⇩s⇩t_cons_subset apply fast
using p(4) setops⇩s⇩s⇩t_cons_subset by fast
show ?thesis using assms
proof (induction A D arbitrary: A' rule: tr.induct)
case 1 thus ?case by simp
next
case (2 t A D)
note prems = "2.prems"
note IH = "2.IH"
from prems(1) obtain A'' where A'': "A' = send⟨t⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)"
by atomize_elim auto
have "list_all tfr⇩s⇩t⇩p A''" using IH[OF A''(2)] prems(5) sublmm[OF prems(2,3,4,5)] by meson
thus ?case using A''(1) by simp
next
case (3 t A D)
note prems = "3.prems"
note IH = "3.IH"
from prems(1) obtain A'' where A'': "A' = receive⟨t⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)"
by atomize_elim auto
have "list_all tfr⇩s⇩t⇩p A''" using IH[OF A''(2)] prems(5) sublmm[OF prems(2,3,4,5)] by meson
thus ?case using A''(1) by simp
next
case (4 ac t t' A D)
note prems = "4.prems"
note IH = "4.IH"
from prems(1) obtain A'' where A'':
"A' = ⟨ac: t ≐ t'⟩⇩s⇩t#A''" "A'' ∈ set (tr A D)"
by atomize_elim auto
have "list_all tfr⇩s⇩t⇩p A''" using IH[OF A''(2)] prems(5) sublmm[OF prems(2,3,4,5)] by meson
moreover have "(∃δ. Unifier δ t t') ⟹ Γ t = Γ t'" using prems(2) by (simp add: tfr⇩s⇩s⇩t_def)
ultimately show ?case using A''(1) by auto
next
case (5 t s A D)
note prems = "5.prems"
note IH = "5.IH"
from prems(1) have A': "A' ∈ set (tr A (List.insert (t,s) D))" by simp
have 1: "list_all tfr⇩s⇩s⇩t⇩p A" using sublmm[OF prems(2,3,4,5)] by simp
have "pair ` setops⇩s⇩s⇩t (Insert t s#A) ∪ pair`set D =
pair ` setops⇩s⇩s⇩t A ∪ pair`set (List.insert (t,s) D)"
by (simp add: setops⇩s⇩s⇩t_def)
hence 3: "?P3 A (List.insert (t,s) D)" using prems(5) by metis
moreover have "?P1 A (List.insert (t, s) D)" using prems(3,4) bvars⇩s⇩s⇩t_cons_subset[of A] by auto
ultimately have "list_all tfr⇩s⇩t⇩p A'" using IH[OF A' sublmm(1,2)[OF prems(2,3,4,5)] _ 3] by metis
thus ?case using A'(1) by auto
next
case (6 t s A D)
note prems = "6.prems"
note IH = "6.IH"
define constr where constr:
"constr ≡ (λDi. (map (λd. ⟨check: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t) Di)@
(map (λd. ∀[]⟨∨≠: [(pair (t,s), pair d)]⟩⇩s⇩t) [d←D. d ∉ set Di]))"
from prems(1) obtain Di A'' where A'':
"A' = constr Di@A''" "A'' ∈ set (tr A [d←D. d ∉ set Di])"
"Di ∈ set (subseqs D)"
unfolding constr by auto
define Q1 where "Q1 ≡ (λ(F::(('fun,'var) term × ('fun,'var) term) list) X.
∀x ∈ (fv⇩p⇩a⇩i⇩r⇩s F) - set X. ∃a. Γ (Var x) = TAtom a)"
define Q2 where "Q2 ≡ (λ(F::(('fun,'var) term × ('fun,'var) term) list) X.
∀f T. Fun f T ∈ subterms⇩s⇩e⇩t (trms⇩p⇩a⇩i⇩r⇩s F) ⟶ T = [] ∨ (∃s ∈ set T. s ∉ Var ` set X))"
have "set [d←D. d ∉ set Di] ⊆ set D"
"pair ` setops⇩s⇩s⇩t A ∪ pair ` set [d←D. d ∉ set Di]
⊆ pair ` setops⇩s⇩s⇩t (Delete t s#A) ∪ pair ` set D"
by (auto simp add: setops⇩s⇩s⇩t_def)
hence *: "?P3 A [d←D. d ∉ set Di]" using prems(5) by blast
have **: "?P1 A [d←D. d ∉ set Di]" using prems(4,5) by auto
have 1: "list_all tfr⇩s⇩t⇩p A''"
using IH[OF A''(3,2) sublmm(1,2)[OF prems(2,3,4,5)] ** *]
by metis
have 2: "⟨ac: u ≐ u'⟩⇩s⇩t ∈ set A'' ∨
(∃d ∈ set Di. u = pair (t,s) ∧ u' = pair d)"
when "⟨ac: u ≐ u'⟩⇩s⇩t ∈ set A'" for ac u u'
using that A''(1) unfolding constr by force
have 3: "Inequality X U ∈ set A' ⟹ Inequality X U ∈ set A'' ∨
(∃d ∈ set [d←D. d ∉ set Di].
U = [(pair (t,s), pair d)] ∧ Q2 [(pair (t,s), pair d)] X)"
for X U
using A''(1) unfolding Q2_def constr by force
have 4:
"∀d∈set D. (∃δ. Unifier δ (pair (t,s)) (pair d)) ⟶ Γ (pair (t,s)) = Γ (pair d)"
using prems(5) by (simp add: setops⇩s⇩s⇩t_def)
{ fix ac u u'
assume a: "⟨ac: u ≐ u'⟩⇩s⇩t ∈ set A'" "∃δ. Unifier δ u u'"
hence "⟨ac: u ≐ u'⟩⇩s⇩t ∈ set A'' ∨ (∃d ∈ set Di. u = pair (t,s) ∧ u' = pair d)"
using 2 by metis
hence "Γ u = Γ u'"
using 1(1) 4 subseqs_set_subset[OF A''(3)] a(2) tfr⇩s⇩t⇩p_list_all_alt_def[of A'']
by blast
} moreover {
fix u U
assume "∀U⟨∨≠: u⟩⇩s⇩t ∈ set A'"
hence "∀U⟨∨≠: u⟩⇩s⇩t ∈ set A'' ∨
(∃d ∈ set [d←D. d ∉ set Di]. u = [(pair (t,s), pair d)] ∧ Q2 u U)"
using 3 by metis
hence "Q1 u U ∨ Q2 u U"
using 1 4 subseqs_set_subset[OF A''(3)] tfr⇩s⇩t⇩p_list_all_alt_def[of A'']
unfolding Q1_def Q2_def
by blast
} ultimately show ?case using tfr⇩s⇩t⇩p_list_all_alt_def[of A'] unfolding Q1_def Q2_def by blast
next
case (7 ac t s A D)
note prems = "7.prems"
note IH = "7.IH"
from prems(1) obtain d A'' where A'':
"A' = ⟨ac: (pair (t,s)) ≐ (pair d)⟩⇩s⇩t#A''"
"A'' ∈ set (tr A D)" "d ∈ set D"
by atomize_elim auto
have "list_all tfr⇩s⇩t⇩p A''"
using IH[OF A''(2) sublmm(1,2,3)[OF prems(2,3,4,5)] sublmm(4)[OF prems(2,3,4,5)]]
by metis
moreover have "(∃δ. Unifier δ (pair (t,s)) (pair d)) ⟹ Γ (pair (t,s)) = Γ (pair d)"
using prems(2,5) A''(3) unfolding tfr⇩s⇩s⇩t_def by (simp add: setops⇩s⇩s⇩t_def)
ultimately show ?case using A''(1) by fastforce
next
case (8 X F F' A D)
note prems = "8.prems"
note IH = "8.IH"
define constr where "constr = (map (λG. ∀X⟨∨≠: (F@G)⟩⇩s⇩t) (tr⇩p⇩a⇩i⇩r⇩s F' D))"
define Q1 where "Q1 ≡ (λ(F::(('fun,'var) term × ('fun,'var) term) list) X.
∀x ∈ (fv⇩p⇩a⇩i⇩r⇩s F) - set X. ∃a. Γ (Var x) = TAtom a)"
define Q2 where "Q2 ≡ (λ(M::('fun,'var) terms) X.
∀f T. Fun f T ∈ subterms⇩s⇩e⇩t M ⟶ T = [] ∨ (∃s ∈ set T. s ∉ Var ` set X))"
have Q2_subset: "Q2 M' X" when "M' ⊆ M" "Q2 M X" for X M M'
using that unfolding Q2_def by auto
have Q2_supset: "Q2 (M ∪ M') X" when "Q2 M X" "Q2 M' X" for X M M'
using that unfolding Q2_def by auto
from prems(1) obtain A'' where A'': "A' = constr@A''" "A'' ∈ set (tr A D)"
using constr_def by atomize_elim auto
have 0: "F' = [] ⟹ constr = [∀X⟨∨≠: F⟩⇩s⇩t]" unfolding constr_def by simp
have 1: "list_all tfr⇩s⇩t⇩p A''"
using IH[OF A''(2) sublmm(1,2,3)[OF prems(2,3,4,5)] sublmm(4)[OF prems(2,3,4,5)]]
by metis
have 2: "(F' = [] ∧ Q1 F X) ∨ Q2 (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F') X"
using prems(2) unfolding Q1_def Q2_def by simp
have 3: "list_all tfr⇩s⇩t⇩p constr" when "F' = []" "Q1 F X"
using that 0 2 tfr⇩s⇩t⇩p_list_all_alt_def[of constr] unfolding Q1_def by auto
{ fix c assume "c ∈ set constr"
hence "∃G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D). c = ∀X⟨∨≠: (F@G)⟩⇩s⇩t" unfolding constr_def by force
} moreover {
fix G
assume G: "G ∈ set (tr⇩p⇩a⇩i⇩r⇩s F' D)"
and c: "∀X⟨∨≠: (F@G)⟩⇩s⇩t ∈ set constr"
and e: "Q2 (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F') X"
have d_Q2: "Q2 (pair ` set D) X" unfolding Q2_def
proof (intro allI impI)
fix f T assume "Fun f T ∈ subterms⇩s⇩e⇩t (pair ` set D)"
then obtain d where d: "d ∈ set D" "Fun f T ∈ subterms (pair d)" by auto
hence "fv (pair d) ∩ set X = {}" using prems(4) unfolding pair_def by force
thus "T = [] ∨ (∃s ∈ set T. s ∉ Var ` set X)"
by (metis fv_disj_Fun_subterm_param_cases d(2))
qed
have "trms⇩p⇩a⇩i⇩r⇩s (F@G) ⊆ trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F' ∪ pair ` set D"
using tr⇩p⇩a⇩i⇩r⇩s_trms_subset[OF G] by auto
hence "Q2 (trms⇩p⇩a⇩i⇩r⇩s (F@G)) X" using Q2_subset[OF _ Q2_supset[OF e d_Q2]] by metis
hence "tfr⇩s⇩t⇩p (∀X⟨∨≠: (F@G)⟩⇩s⇩t)" by (metis Q2_def tfr⇩s⇩t⇩p.simps(2))
} ultimately have 4: "list_all tfr⇩s⇩t⇩p constr" when "Q2 (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F') X"
using that Ball_set by blast
have 5: "list_all tfr⇩s⇩t⇩p constr" using 2 3 4 by metis
show ?case using 1 5 A''(1) by simp
qed
qed
lemma tr_tfr:
assumes "A' ∈ set (tr A [])" and "tfr⇩s⇩s⇩t A" and "fv⇩s⇩s⇩t A ∩ bvars⇩s⇩s⇩t A = {}"
shows "tfr⇩s⇩t A'"
proof -
have *: "trms⇩s⇩t A' ⊆ trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A" using tr_trms_subset[OF assms(1)] by simp
hence "SMP (trms⇩s⇩t A') ⊆ SMP (trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A)" using SMP_mono by simp
moreover have "tfr⇩s⇩e⇩t (trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A)" using assms(2) unfolding tfr⇩s⇩s⇩t_def by fast
ultimately have 1: "tfr⇩s⇩e⇩t (trms⇩s⇩t A')" by (metis tfr_subset(2)[OF _ *])
have **: "list_all tfr⇩s⇩s⇩t⇩p A" using assms(2) unfolding tfr⇩s⇩s⇩t_def by fast
have "pair ` setops⇩s⇩s⇩t A ⊆ SMP (trms⇩s⇩s⇩t A ∪ pair ` setops⇩s⇩s⇩t A) - Var`𝒱"
using setops⇩s⇩s⇩t_are_pairs unfolding pair_def by auto
hence ***: "∀t ∈ pair`setops⇩s⇩s⇩t A. ∀t' ∈ pair`setops⇩s⇩s⇩t A. (∃δ. Unifier δ t t') ⟶ Γ t = Γ t'"
using assms(2) unfolding tfr⇩s⇩s⇩t_def tfr⇩s⇩e⇩t_def by blast
have 2: "list_all tfr⇩s⇩t⇩p A'"
using tr_tfr⇩s⇩s⇩t⇩p[OF assms(1) ** assms(3)] *** unfolding pair_def by fastforce
show ?thesis by (metis 1 2 tfr⇩s⇩t_def)
qed
end
end
subsubsection ‹Theorem: The Stateful Typing Result›
context stateful_typing_result
begin
theorem stateful_typing_result:
assumes "wf⇩s⇩s⇩t 𝒜"
and "tfr⇩s⇩s⇩t 𝒜"
and "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t 𝒜)"
and "interpretation⇩s⇩u⇩b⇩s⇩t ℐ"
and "ℐ ⊨⇩s 𝒜"
obtains ℐ⇩τ
where "interpretation⇩s⇩u⇩b⇩s⇩t ℐ⇩τ"
and "ℐ⇩τ ⊨⇩s 𝒜"
and "wt⇩s⇩u⇩b⇩s⇩t ℐ⇩τ"
and "wf⇩t⇩r⇩m⇩s (subst_range ℐ⇩τ)"
proof -
obtain 𝒜' where 𝒜':
"𝒜' ∈ set (tr 𝒜 [])" "ℐ ⊨ ⟨𝒜'⟩"
using tr_sem_equiv[of 𝒜] assms(1,4,5)
by auto
have *: "wf⇩s⇩t {} 𝒜'"
"fv⇩s⇩t 𝒜' ∩ bvars⇩s⇩t 𝒜' = {}"
"tfr⇩s⇩t 𝒜'" "wf⇩t⇩r⇩m⇩s (trms⇩s⇩t 𝒜')"
using tr_wf[OF 𝒜'(1) assms(1,3)]
tr_tfr[OF 𝒜'(1) assms(2)] assms(1)
by metis+
obtain ℐ⇩τ where ℐ⇩τ:
"interpretation⇩s⇩u⇩b⇩s⇩t ℐ⇩τ" "⟦{}; 𝒜'⟧⇩d ℐ⇩τ"
"wt⇩s⇩u⇩b⇩s⇩t ℐ⇩τ" "wf⇩t⇩r⇩m⇩s (subst_range ℐ⇩τ)"
using wt_attack_if_tfr_attack_d
* Ana_invar_subst' assms(4)
𝒜'(2)
unfolding constr_sem_d_def
by atomize_elim auto
thus ?thesis
using that tr_sem_equiv[of 𝒜] assms(1,3) 𝒜'(1)
unfolding constr_sem_d_def
by auto
qed
end
subsection ‹Proving Type-Flaw Resistance Automatically›
definition pair' where
"pair' pair_fun d ≡ case d of (t,t') ⇒ Fun pair_fun [t,t']"
fun comp_tfr⇩s⇩s⇩t⇩p where
"comp_tfr⇩s⇩s⇩t⇩p Γ pair_fun (⟨_: t ≐ t'⟩) = (mgu t t' ≠ None ⟶ Γ t = Γ t')"
| "comp_tfr⇩s⇩s⇩t⇩p Γ pair_fun (∀X⟨∨≠: F ∨∉: F'⟩) = (
(F' = [] ∧ (∀x ∈ fv⇩p⇩a⇩i⇩r⇩s F - set X. is_Var (Γ (Var x)))) ∨
(∀u ∈ subterms⇩s⇩e⇩t (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair' pair_fun ` set F').
is_Fun u ⟶ (args u = [] ∨ (∃s ∈ set (args u). s ∉ Var ` set X))))"
| "comp_tfr⇩s⇩s⇩t⇩p _ _ _ = True"
definition comp_tfr⇩s⇩s⇩t where
"comp_tfr⇩s⇩s⇩t arity Ana Γ pair_fun M S ≡
list_all (comp_tfr⇩s⇩s⇩t⇩p Γ pair_fun) S ∧
list_all (wf⇩t⇩r⇩m' arity) (trms_list⇩s⇩s⇩t S) ∧
has_all_wt_instances_of Γ (trms⇩s⇩s⇩t S ∪ pair' pair_fun ` setops⇩s⇩s⇩t S) M ∧
comp_tfr⇩s⇩e⇩t arity Ana Γ M"
locale stateful_typed_model' = stateful_typed_model arity public Ana Γ Pair
for arity::"'fun ⇒ nat"
and public::"'fun ⇒ bool"
and Ana::"('fun,(('fun,'atom::finite) term_type × nat)) term
⇒ (('fun,(('fun,'atom) term_type × nat)) term list
× ('fun,(('fun,'atom) term_type × nat)) term list)"
and Γ::"('fun,(('fun,'atom) term_type × nat)) term ⇒ ('fun,'atom) term_type"
and Pair::"'fun"
+
assumes Γ_Var_fst': "⋀τ n m. Γ (Var (τ,n)) = Γ (Var (τ,m))"
and Ana_const': "⋀c T. arity c = 0 ⟹ Ana (Fun c T) = ([], [])"
begin
sublocale typed_model'
by (unfold_locales, rule Γ_Var_fst', metis Ana_const', metis Ana_subst')
lemma pair_code:
"pair d = pair' Pair d"
by (simp add: pair_def pair'_def)
end
locale stateful_typing_result' =
stateful_typed_model' arity public Ana Γ Pair + stateful_typing_result arity public Ana Γ Pair
for arity::"'fun ⇒ nat"
and public::"'fun ⇒ bool"
and Ana::"('fun,(('fun,'atom::finite) term_type × nat)) term
⇒ (('fun,(('fun,'atom) term_type × nat)) term list
× ('fun,(('fun,'atom) term_type × nat)) term list)"
and Γ::"('fun,(('fun,'atom) term_type × nat)) term ⇒ ('fun,'atom) term_type"
and Pair::"'fun"
begin
lemma tfr⇩s⇩s⇩t⇩p_is_comp_tfr⇩s⇩s⇩t⇩p: "tfr⇩s⇩s⇩t⇩p a = comp_tfr⇩s⇩s⇩t⇩p Γ Pair a"
proof (cases a)
case (Equality ac t t')
thus ?thesis
using mgu_always_unifies[of t _ t'] mgu_gives_MGU[of t t']
by auto
next
case (NegChecks X F F')
thus ?thesis
using tfr⇩s⇩s⇩t⇩p.simps(2)[of X F F']
comp_tfr⇩s⇩s⇩t⇩p.simps(2)[of Γ Pair X F F']
Fun_range_case(2)[of "subterms⇩s⇩e⇩t (trms⇩p⇩a⇩i⇩r⇩s F ∪ pair ` set F')"]
unfolding is_Var_def pair_code[symmetric]
by auto
qed auto
lemma tfr⇩s⇩s⇩t_if_comp_tfr⇩s⇩s⇩t:
assumes "comp_tfr⇩s⇩s⇩t arity Ana Γ Pair M S"
shows "tfr⇩s⇩s⇩t S"
unfolding tfr⇩s⇩s⇩t_def
proof
have comp_tfr⇩s⇩e⇩t_M: "comp_tfr⇩s⇩e⇩t arity Ana Γ M"
using assms unfolding comp_tfr⇩s⇩s⇩t_def by blast
have SMP_repr_M: "finite_SMP_representation arity Ana Γ M"
using comp_tfr⇩s⇩e⇩t_M unfolding comp_tfr⇩s⇩e⇩t_def by blast
have wf⇩t⇩r⇩m⇩s_M: "wf⇩t⇩r⇩m⇩s M"
and wf⇩t⇩r⇩m⇩s_S: "wf⇩t⇩r⇩m⇩s (trms⇩s⇩s⇩t S ∪ pair ` setops⇩s⇩s⇩t S)"
and S_trms_instance_M: "has_all_wt_instances_of Γ (trms⇩s⇩s⇩t S ∪ pair ` setops⇩s⇩s⇩t S) M"
using assms setops⇩s⇩s⇩t_wf⇩t⇩r⇩m⇩s(2)[of S] trms_list⇩s⇩s⇩t_is_trms⇩s⇩s⇩t[of S]
finite_SMP_representationD[OF SMP_repr_M]
unfolding comp_tfr⇩s⇩s⇩t_def comp_tfr⇩s⇩e⇩t_def list_all_iff pair_code[symmetric] wf⇩t⇩r⇩m_code[symmetric]
finite_SMP_representation_def
by (meson, argo, argo)
show "tfr⇩s⇩e⇩t (trms⇩s⇩s⇩t S ∪ pair ` setops⇩s⇩s⇩t S)"
using tfr_subset(3)[OF tfr⇩s⇩e⇩t_if_comp_tfr⇩s⇩e⇩t[OF comp_tfr⇩s⇩e⇩t_M] SMP_SMP_subset]
SMP_I'[OF wf⇩t⇩r⇩m⇩s_S wf⇩t⇩r⇩m⇩s_M S_trms_instance_M]
by blast
have "list_all (comp_tfr⇩s⇩s⇩t⇩p Γ Pair) S" by (metis assms comp_tfr⇩s⇩s⇩t_def)
thus "list_all tfr⇩s⇩s⇩t⇩p S" by (induct S) (simp_all add: tfr⇩s⇩s⇩t⇩p_is_comp_tfr⇩s⇩s⇩t⇩p)
qed
lemma tfr⇩s⇩s⇩t_if_comp_tfr⇩s⇩s⇩t':
fixes S
defines "M ≡ SMP0 Ana Γ (trms_list⇩s⇩s⇩t S@map pair (setops_list⇩s⇩s⇩t S))"
assumes comp_tfr: "comp_tfr⇩s⇩s⇩t arity Ana Γ Pair (set M) S"
shows "tfr⇩s⇩s⇩t S"
by (rule tfr⇩s⇩s⇩t_if_comp_tfr⇩s⇩s⇩t[OF comp_tfr[unfolded M_def]])
end
end