Theory Labeled_Stateful_Strands
section ‹Labeled Stateful Strands›
theory Labeled_Stateful_Strands
imports Stateful_Strands Labeled_Strands
begin
subsection ‹Definitions›
text‹Syntax for stateful strand labels›
abbreviation Star_step (‹⟨⋆, _⟩›) where
"⟨⋆, (s::('a,'b) stateful_strand_step)⟩ ≡ (⋆, s)"
abbreviation LabelN_step (‹⟨_, _⟩›) where
"⟨(l::'a), (s::('b,'c) stateful_strand_step)⟩ ≡ (ln l, s)"
text‹Database projection›
definition dbproj where "dbproj l D ≡ filter (λd. fst d = l) D"
text‹The type of labeled stateful strands›
type_synonym ('a,'b,'c) labeled_stateful_strand_step = "'c strand_label × ('a,'b) stateful_strand_step"
type_synonym ('a,'b,'c) labeled_stateful_strand = "('a,'b,'c) labeled_stateful_strand_step list"
text‹Dual strands›
fun dual⇩l⇩s⇩s⇩t⇩p::"('a,'b,'c) labeled_stateful_strand_step ⇒ ('a,'b,'c) labeled_stateful_strand_step"
where
"dual⇩l⇩s⇩s⇩t⇩p (l,send⟨t⟩) = (l,receive⟨t⟩)"
| "dual⇩l⇩s⇩s⇩t⇩p (l,receive⟨t⟩) = (l,send⟨t⟩)"
| "dual⇩l⇩s⇩s⇩t⇩p x = x"
definition dual⇩l⇩s⇩s⇩t::"('a,'b,'c) labeled_stateful_strand ⇒ ('a,'b,'c) labeled_stateful_strand"
where
"dual⇩l⇩s⇩s⇩t ≡ map dual⇩l⇩s⇩s⇩t⇩p"
text‹Substitution application›
fun subst_apply_labeled_stateful_strand_step::
"('a,'b,'c) labeled_stateful_strand_step ⇒ ('a,'b) subst ⇒
('a,'b,'c) labeled_stateful_strand_step"
(infix ‹⋅⇩l⇩s⇩s⇩t⇩p› 51) where
"(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ = (l,s ⋅⇩s⇩s⇩t⇩p θ)"
definition subst_apply_labeled_stateful_strand::
"('a,'b,'c) labeled_stateful_strand ⇒ ('a,'b) subst ⇒ ('a,'b,'c) labeled_stateful_strand"
(infix ‹⋅⇩l⇩s⇩s⇩t› 51) where
"S ⋅⇩l⇩s⇩s⇩t θ ≡ map (λx. x ⋅⇩l⇩s⇩s⇩t⇩p θ) S"
text‹Definitions lifted from stateful strands›
abbreviation wfrestrictedvars⇩l⇩s⇩s⇩t where "wfrestrictedvars⇩l⇩s⇩s⇩t S ≡ wfrestrictedvars⇩s⇩s⇩t (unlabel S)"
abbreviation ik⇩l⇩s⇩s⇩t where "ik⇩l⇩s⇩s⇩t S ≡ ik⇩s⇩s⇩t (unlabel S)"
abbreviation db⇩l⇩s⇩s⇩t where "db⇩l⇩s⇩s⇩t S ≡ db⇩s⇩s⇩t (unlabel S)"
abbreviation db'⇩l⇩s⇩s⇩t where "db'⇩l⇩s⇩s⇩t S ≡ db'⇩s⇩s⇩t (unlabel S)"
abbreviation trms⇩l⇩s⇩s⇩t where "trms⇩l⇩s⇩s⇩t S ≡ trms⇩s⇩s⇩t (unlabel S)"
abbreviation trms_proj⇩l⇩s⇩s⇩t where "trms_proj⇩l⇩s⇩s⇩t n S ≡ trms⇩s⇩s⇩t (proj_unl n S)"
abbreviation vars⇩l⇩s⇩s⇩t where "vars⇩l⇩s⇩s⇩t S ≡ vars⇩s⇩s⇩t (unlabel S)"
abbreviation vars_proj⇩l⇩s⇩s⇩t where "vars_proj⇩l⇩s⇩s⇩t n S ≡ vars⇩s⇩s⇩t (proj_unl n S)"
abbreviation bvars⇩l⇩s⇩s⇩t where "bvars⇩l⇩s⇩s⇩t S ≡ bvars⇩s⇩s⇩t (unlabel S)"
abbreviation fv⇩l⇩s⇩s⇩t where "fv⇩l⇩s⇩s⇩t S ≡ fv⇩s⇩s⇩t (unlabel S)"
text‹Labeled set-operations›
fun setops⇩l⇩s⇩s⇩t⇩p where
"setops⇩l⇩s⇩s⇩t⇩p (i,insert⟨t,s⟩) = {(i,t,s)}"
| "setops⇩l⇩s⇩s⇩t⇩p (i,delete⟨t,s⟩) = {(i,t,s)}"
| "setops⇩l⇩s⇩s⇩t⇩p (i,⟨_: t ∈ s⟩) = {(i,t,s)}"
| "setops⇩l⇩s⇩s⇩t⇩p (i,∀_⟨∨≠: _ ∨∉: F'⟩) = ((λ(t,s). (i,t,s)) ` set F')"
| "setops⇩l⇩s⇩s⇩t⇩p _ = {}"
definition setops⇩l⇩s⇩s⇩t where
"setops⇩l⇩s⇩s⇩t S ≡ ⋃(setops⇩l⇩s⇩s⇩t⇩p ` set S)"
subsection ‹Minor Lemmata›
lemma in_ik⇩l⇩s⇩s⇩t_iff: "t ∈ ik⇩l⇩s⇩s⇩t A ⟷ (∃l ts. (l,receive⟨ts⟩) ∈ set A ∧ t ∈ set ts)"
unfolding unlabel_def ik⇩s⇩s⇩t_def by force
lemma ik⇩l⇩s⇩s⇩t_concat: "ik⇩l⇩s⇩s⇩t (concat xs) = ⋃(ik⇩l⇩s⇩s⇩t ` set xs)"
by (induct xs) auto
lemma ik⇩l⇩s⇩s⇩t_Cons[simp]:
"ik⇩l⇩s⇩s⇩t ((l,send⟨ts⟩)#A) = ik⇩l⇩s⇩s⇩t A" (is ?A)
"ik⇩l⇩s⇩s⇩t ((l,receive⟨ts⟩)#A) = set ts ∪ ik⇩l⇩s⇩s⇩t A" (is ?B)
"ik⇩l⇩s⇩s⇩t ((l,⟨ac: t ≐ s⟩)#A) = ik⇩l⇩s⇩s⇩t A" (is ?C)
"ik⇩l⇩s⇩s⇩t ((l,insert⟨t,s⟩)#A) = ik⇩l⇩s⇩s⇩t A" (is ?D)
"ik⇩l⇩s⇩s⇩t ((l,delete⟨t,s⟩)#A) = ik⇩l⇩s⇩s⇩t A" (is ?E)
"ik⇩l⇩s⇩s⇩t ((l,⟨ac: t ∈ s⟩)#A) = ik⇩l⇩s⇩s⇩t A" (is ?F)
"ik⇩l⇩s⇩s⇩t ((l,∀X⟨∨≠: F ∨∉: G⟩)#A) = ik⇩l⇩s⇩s⇩t A" (is ?G)
proof -
note 0 = ik⇩s⇩s⇩t_append[of _ "unlabel A"]
note 1 = in_ik⇩s⇩s⇩t_iff
show ?A using 0[of "[send⟨ts⟩]"] 1[of _ "[send⟨ts⟩]"] by auto
show ?B using 0[of "[receive⟨ts⟩]"] 1[of _ "[receive⟨ts⟩]"] by auto
show ?C using 0[of "[⟨ac: t ≐ s⟩]"] 1[of _ "[⟨ac: t ≐ s⟩]"] by auto
show ?D using 0[of "[insert⟨t,s⟩]"] 1[of _ "[insert⟨t,s⟩]"] by auto
show ?E using 0[of "[delete⟨t,s⟩]"] 1[of _ "[delete⟨t,s⟩]"] by auto
show ?F using 0[of "[⟨ac: t ∈ s⟩]"] 1[of _ "[⟨ac: t ∈ s⟩]"] by auto
show ?G using 0[of "[∀X⟨∨≠: F ∨∉: G⟩]"] 1[of _ "[∀X⟨∨≠: F ∨∉: G⟩]"] by auto
qed
lemma subst_lsstp_fst_eq:
"fst (a ⋅⇩l⇩s⇩s⇩t⇩p δ) = fst a"
by (cases a) auto
lemma subst_lsst_map_fst_eq:
"map fst (S ⋅⇩l⇩s⇩s⇩t δ) = map fst S"
using subst_lsstp_fst_eq unfolding subst_apply_labeled_stateful_strand_def by auto
lemma subst_lsst_nil[simp]: "[] ⋅⇩l⇩s⇩s⇩t δ = []"
by (simp add: subst_apply_labeled_stateful_strand_def)
lemma subst_lsst_cons: "a#A ⋅⇩l⇩s⇩s⇩t δ = (a ⋅⇩l⇩s⇩s⇩t⇩p δ)#(A ⋅⇩l⇩s⇩s⇩t δ)"
by (simp add: subst_apply_labeled_stateful_strand_def)
lemma subst_lsstp_id_subst: "a ⋅⇩l⇩s⇩s⇩t⇩p Var = a"
proof -
obtain l b where a: "a = (l,b)" by (metis surj_pair)
show ?thesis unfolding a by (cases b) auto
qed
lemma subst_lsst_id_subst: "A ⋅⇩l⇩s⇩s⇩t Var = A"
by (induct A) (simp, metis subst_lsstp_id_subst subst_lsst_cons)
lemma subst_lsst_singleton: "[(l,s)] ⋅⇩l⇩s⇩s⇩t δ = [(l,s ⋅⇩s⇩s⇩t⇩p δ)]"
by (simp add: subst_apply_labeled_stateful_strand_def)
lemma subst_lsst_append: "A@B ⋅⇩l⇩s⇩s⇩t δ = (A ⋅⇩l⇩s⇩s⇩t δ)@(B ⋅⇩l⇩s⇩s⇩t δ)"
by (simp add: subst_apply_labeled_stateful_strand_def)
lemma subst_lsst_append_inv:
assumes "A ⋅⇩l⇩s⇩s⇩t δ = B1@B2"
shows "∃A1 A2. A = A1@A2 ∧ A1 ⋅⇩l⇩s⇩s⇩t δ = B1 ∧ A2 ⋅⇩l⇩s⇩s⇩t δ = B2"
using assms
proof (induction A arbitrary: B1 B2)
case (Cons a A)
note prems = Cons.prems
note IH = Cons.IH
show ?case
proof (cases B1)
case Nil
then obtain b B3 where "B2 = b#B3" "a ⋅⇩l⇩s⇩s⇩t⇩p δ = b" "A ⋅⇩l⇩s⇩s⇩t δ = B3"
using prems subst_lsst_cons by fastforce
thus ?thesis by (simp add: Nil subst_apply_labeled_stateful_strand_def)
next
case (Cons b B3)
hence "a ⋅⇩l⇩s⇩s⇩t⇩p δ = b" "A ⋅⇩l⇩s⇩s⇩t δ = B3@B2"
using prems by (simp_all add: subst_lsst_cons)
thus ?thesis by (metis Cons_eq_appendI Cons IH subst_lsst_cons)
qed
qed (metis append_is_Nil_conv subst_lsst_nil)
lemma subst_lsst_memI[intro]: "x ∈ set A ⟹ x ⋅⇩l⇩s⇩s⇩t⇩p δ ∈ set (A ⋅⇩l⇩s⇩s⇩t δ)"
by (metis image_eqI set_map subst_apply_labeled_stateful_strand_def)
lemma subst_lsstpD:
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,send⟨ts⟩) ⟹ ∃ts'. ts = ts' ⋅⇩l⇩i⇩s⇩t σ ∧ a = (n,send⟨ts'⟩)"
(is "?A ⟹ ?A'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,receive⟨ts⟩) ⟹ ∃ts'. ts = ts' ⋅⇩l⇩i⇩s⇩t σ ∧ a = (n,receive⟨ts'⟩)"
(is "?B ⟹ ?B'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,⟨c: t ≐ s⟩) ⟹ ∃t' s'. t = t' ⋅ σ ∧ s = s' ⋅ σ ∧ a = (n,⟨c: t' ≐ s'⟩)"
(is "?C ⟹ ?C'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,insert⟨t,s⟩) ⟹ ∃t' s'. t = t' ⋅ σ ∧ s = s' ⋅ σ ∧ a = (n,insert⟨t',s'⟩)"
(is "?D ⟹ ?D'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,delete⟨t,s⟩) ⟹ ∃t' s'. t = t' ⋅ σ ∧ s = s' ⋅ σ ∧ a = (n,delete⟨t',s'⟩)"
(is "?E ⟹ ?E'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,⟨c: t ∈ s⟩) ⟹ ∃t' s'. t = t' ⋅ σ ∧ s = s' ⋅ σ ∧ a = (n,⟨c: t' ∈ s'⟩)"
(is "?F ⟹ ?F'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,∀X⟨∨≠: F ∨∉: G⟩) ⟹
∃F' G'. F = F' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) σ ∧ G = G' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) σ ∧
a = (n,∀X⟨∨≠: F' ∨∉: G'⟩)"
(is "?G ⟹ ?G'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,⟨t != s⟩) ⟹ ∃t' s'. t = t' ⋅ σ ∧ s = s' ⋅ σ ∧ a = (n,⟨t' != s'⟩)"
(is "?H ⟹ ?H'")
"a ⋅⇩l⇩s⇩s⇩t⇩p σ = (n,⟨t not in s⟩) ⟹ ∃t' s'. t = t' ⋅ σ ∧ s = s' ⋅ σ ∧ a = (n,⟨t' not in s'⟩)"
(is "?I ⟹ ?I'")
proof -
obtain m b where a: "a = (m,b)" by (metis surj_pair)
show "?A ⟹ ?A'" "?B ⟹ ?B'" "?C ⟹ ?C'" "?D ⟹ ?D'" "?E ⟹ ?E'" "?F ⟹ ?F'" "?G ⟹ ?G'"
"?H ⟹ ?H'" "?I ⟹ ?I'"
by (cases b; auto simp add: a subst_apply_pairs_def; fail)+
qed
lemma subst_lsst_memD:
"(n,receive⟨ts⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃us. (n,receive⟨us⟩) ∈ set S ∧ ts = us ⋅⇩l⇩i⇩s⇩t σ"
"(n,send⟨ts⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃us. (n,send⟨us⟩) ∈ set S ∧ ts = us ⋅⇩l⇩i⇩s⇩t σ"
"(n,⟨ac: t ≐ s⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃u v. (n,⟨ac: u ≐ v⟩) ∈ set S ∧ t = u ⋅ σ ∧ s = v ⋅ σ"
"(n,insert⟨t, s⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃u v. (n,insert⟨u, v⟩) ∈ set S ∧ t = u ⋅ σ ∧ s = v ⋅ σ"
"(n,delete⟨t, s⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃u v. (n,delete⟨u, v⟩) ∈ set S ∧ t = u ⋅ σ ∧ s = v ⋅ σ"
"(n,⟨ac: t ∈ s⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃u v. (n,⟨ac: u ∈ v⟩) ∈ set S ∧ t = u ⋅ σ ∧ s = v ⋅ σ"
"(n,∀X⟨∨≠: F ∨∉: G⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃F' G'. (n,∀X⟨∨≠: F' ∨∉: G'⟩) ∈ set S ∧
F = F' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) σ ∧
G = G' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) σ"
"(n,⟨t != s⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃u v. (n,⟨u != v⟩) ∈ set S ∧ t = u ⋅ σ ∧ s = v ⋅ σ"
"(n,⟨t not in s⟩) ∈ set (S ⋅⇩l⇩s⇩s⇩t σ) ⟹
∃u v. (n,⟨u not in v⟩) ∈ set S ∧ t = u ⋅ σ ∧ s = v ⋅ σ"
proof (induction S)
case (Cons b S)
obtain m a where a: "b = (m,a)" by (metis surj_pair)
have *: "x ∈ set (S ⋅⇩l⇩s⇩s⇩t σ)"
when "x ∈ set (b#S ⋅⇩l⇩s⇩s⇩t σ)" "x ≠ b ⋅⇩l⇩s⇩s⇩t⇩p σ" for x
using that by (simp add: subst_apply_labeled_stateful_strand_def)
{ case 1 thus ?case using Cons.IH(1)[OF *] a by (cases a) auto }
{ case 2 thus ?case using Cons.IH(2)[OF *] a by (cases a) auto }
{ case 3 thus ?case using Cons.IH(3)[OF *] a by (cases a) auto }
{ case 4 thus ?case using Cons.IH(4)[OF *] a by (cases a) auto }
{ case 5 thus ?case using Cons.IH(5)[OF *] a by (cases a) auto }
{ case 6 thus ?case using Cons.IH(6)[OF *] a by (cases a) auto }
{ case 7 thus ?case using Cons.IH(7)[OF *] a by (cases a) auto }
{ case 8 show ?case
proof (cases a)
case (NegChecks Y F' G') thus ?thesis
proof (cases "(n,⟨t != s⟩) = b ⋅⇩l⇩s⇩s⇩t⇩p σ")
case True thus ?thesis using subst_lsstpD(8)[of b σ n t s] by auto
qed (use 8 Cons.IH(8)[OF *] a in auto)
qed (use 8 Cons.IH(8)[OF *] a in simp_all)
}
{ case 9 show ?case
proof (cases a)
case (NegChecks Y F' G') thus ?thesis
proof (cases "(n,⟨t not in s⟩) = b ⋅⇩l⇩s⇩s⇩t⇩p σ")
case True thus ?thesis using subst_lsstpD(9)[of b σ n t s] by auto
qed (use 9 Cons.IH(9)[OF *] a in auto)
qed (use 9 Cons.IH(9)[OF *] a in simp_all)
}
qed simp_all
lemma subst_lsst_unlabel_cons: "unlabel ((l,b)#A ⋅⇩l⇩s⇩s⇩t θ) = (b ⋅⇩s⇩s⇩t⇩p θ)#(unlabel (A ⋅⇩l⇩s⇩s⇩t θ))"
by (simp add: subst_apply_labeled_stateful_strand_def)
lemma subst_lsst_unlabel: "unlabel (A ⋅⇩l⇩s⇩s⇩t δ) = unlabel A ⋅⇩s⇩s⇩t δ"
proof (induction A)
case (Cons a A)
then obtain l b where "a = (l,b)" by (metis surj_pair)
thus ?case
using Cons
by (simp add: subst_apply_labeled_stateful_strand_def subst_apply_stateful_strand_def)
qed simp
lemma subst_lsst_unlabel_member[intro]:
assumes "x ∈ set (unlabel A)"
shows "x ⋅⇩s⇩s⇩t⇩p δ ∈ set (unlabel (A ⋅⇩l⇩s⇩s⇩t δ))"
proof -
obtain l where x: "(l,x) ∈ set A" using assms unfolding unlabel_def by atomize_elim auto
thus ?thesis
using subst_lsst_memI
by (metis unlabel_def in_set_zipE subst_apply_labeled_stateful_strand_step.simps zip_map_fst_snd)
qed
lemma subst_lsst_prefix:
assumes "prefix B (A ⋅⇩l⇩s⇩s⇩t θ)"
shows "∃C. C ⋅⇩l⇩s⇩s⇩t θ = B ∧ prefix C A"
using assms
proof (induction A rule: List.rev_induct)
case (snoc a A) thus ?case
proof (cases "B = A@[a] ⋅⇩l⇩s⇩s⇩t θ")
case False thus ?thesis
using snoc by (auto simp add: subst_lsst_append[of A] subst_lsst_cons)
qed auto
qed simp
lemma subst_lsst_tl:
"tl (S ⋅⇩l⇩s⇩s⇩t δ) = tl S ⋅⇩l⇩s⇩s⇩t δ"
by (metis map_tl subst_apply_labeled_stateful_strand_def)
lemma dual⇩l⇩s⇩s⇩t_tl:
"tl (dual⇩l⇩s⇩s⇩t S) = dual⇩l⇩s⇩s⇩t (tl S)"
by (metis map_tl dual⇩l⇩s⇩s⇩t_def)
lemma dual⇩l⇩s⇩s⇩t⇩p_fst_eq:
"fst (dual⇩l⇩s⇩s⇩t⇩p a) = fst a"
proof -
obtain l b where "a = (l,b)" by (metis surj_pair)
thus ?thesis by (cases b) auto
qed
lemma dual⇩l⇩s⇩s⇩t_map_fst_eq:
"map fst (dual⇩l⇩s⇩s⇩t S) = map fst S"
using dual⇩l⇩s⇩s⇩t⇩p_fst_eq unfolding dual⇩l⇩s⇩s⇩t_def by auto
lemma dual⇩l⇩s⇩s⇩t_nil[simp]: "dual⇩l⇩s⇩s⇩t [] = []"
by (simp add: dual⇩l⇩s⇩s⇩t_def)
lemma dual⇩l⇩s⇩s⇩t_Cons[simp]:
"dual⇩l⇩s⇩s⇩t ((l,send⟨ts⟩)#A) = (l,receive⟨ts⟩)#(dual⇩l⇩s⇩s⇩t A)"
"dual⇩l⇩s⇩s⇩t ((l,receive⟨ts⟩)#A) = (l,send⟨ts⟩)#(dual⇩l⇩s⇩s⇩t A)"
"dual⇩l⇩s⇩s⇩t ((l,⟨a: t ≐ s⟩)#A) = (l,⟨a: t ≐ s⟩)#(dual⇩l⇩s⇩s⇩t A)"
"dual⇩l⇩s⇩s⇩t ((l,insert⟨t,s⟩)#A) = (l,insert⟨t,s⟩)#(dual⇩l⇩s⇩s⇩t A)"
"dual⇩l⇩s⇩s⇩t ((l,delete⟨t,s⟩)#A) = (l,delete⟨t,s⟩)#(dual⇩l⇩s⇩s⇩t A)"
"dual⇩l⇩s⇩s⇩t ((l,⟨a: t ∈ s⟩)#A) = (l,⟨a: t ∈ s⟩)#(dual⇩l⇩s⇩s⇩t A)"
"dual⇩l⇩s⇩s⇩t ((l,∀X⟨∨≠: F ∨∉: G⟩)#A) = (l,∀X⟨∨≠: F ∨∉: G⟩)#(dual⇩l⇩s⇩s⇩t A)"
by (simp_all add: dual⇩l⇩s⇩s⇩t_def)
lemma dual⇩l⇩s⇩s⇩t_append[simp]: "dual⇩l⇩s⇩s⇩t (A@B) = dual⇩l⇩s⇩s⇩t A@dual⇩l⇩s⇩s⇩t B"
by (simp add: dual⇩l⇩s⇩s⇩t_def)
lemma dual⇩l⇩s⇩s⇩t⇩p_subst: "dual⇩l⇩s⇩s⇩t⇩p (s ⋅⇩l⇩s⇩s⇩t⇩p δ) = (dual⇩l⇩s⇩s⇩t⇩p s) ⋅⇩l⇩s⇩s⇩t⇩p δ"
proof -
obtain l x where s: "s = (l,x)" by atomize_elim auto
thus ?thesis by (cases x) (auto simp add: subst_apply_labeled_stateful_strand_def)
qed
lemma dual⇩l⇩s⇩s⇩t_subst: "dual⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ) = (dual⇩l⇩s⇩s⇩t S) ⋅⇩l⇩s⇩s⇩t δ"
proof (induction S)
case (Cons s S) thus ?case
using Cons dual⇩l⇩s⇩s⇩t⇩p_subst[of s δ]
by (simp add: dual⇩l⇩s⇩s⇩t_def subst_apply_labeled_stateful_strand_def)
qed (simp add: dual⇩l⇩s⇩s⇩t_def subst_apply_labeled_stateful_strand_def)
lemma dual⇩l⇩s⇩s⇩t_subst_unlabel: "unlabel (dual⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ)) = unlabel (dual⇩l⇩s⇩s⇩t S) ⋅⇩s⇩s⇩t δ"
by (metis dual⇩l⇩s⇩s⇩t_subst subst_lsst_unlabel)
lemma dual⇩l⇩s⇩s⇩t_subst_cons: "dual⇩l⇩s⇩s⇩t (a#A ⋅⇩l⇩s⇩s⇩t σ) = (dual⇩l⇩s⇩s⇩t⇩p a ⋅⇩l⇩s⇩s⇩t⇩p σ)#(dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t σ))"
by (metis dual⇩l⇩s⇩s⇩t_subst list.simps(9) dual⇩l⇩s⇩s⇩t_def subst_apply_labeled_stateful_strand_def)
lemma dual⇩l⇩s⇩s⇩t_subst_append: "dual⇩l⇩s⇩s⇩t (A@B ⋅⇩l⇩s⇩s⇩t σ) = (dual⇩l⇩s⇩s⇩t A@dual⇩l⇩s⇩s⇩t B) ⋅⇩l⇩s⇩s⇩t σ"
by (metis (no_types) dual⇩l⇩s⇩s⇩t_subst dual⇩l⇩s⇩s⇩t_append)
lemma dual⇩l⇩s⇩s⇩t_subst_snoc: "dual⇩l⇩s⇩s⇩t (A@[a] ⋅⇩l⇩s⇩s⇩t σ) = (dual⇩l⇩s⇩s⇩t A ⋅⇩l⇩s⇩s⇩t σ)@[dual⇩l⇩s⇩s⇩t⇩p a ⋅⇩l⇩s⇩s⇩t⇩p σ]"
by (metis dual⇩l⇩s⇩s⇩t_def dual⇩l⇩s⇩s⇩t_subst dual⇩l⇩s⇩s⇩t_subst_cons list.map(1) map_append
subst_apply_labeled_stateful_strand_def)
lemma dual⇩l⇩s⇩s⇩t_memberD:
assumes "(l,a) ∈ set (dual⇩l⇩s⇩s⇩t A)"
shows "∃b. (l,b) ∈ set A ∧ dual⇩l⇩s⇩s⇩t⇩p (l,b) = (l,a)"
using assms
proof (induction A)
case (Cons c A)
hence "(l,a) ∈ set (dual⇩l⇩s⇩s⇩t A) ∨ dual⇩l⇩s⇩s⇩t⇩p c = (l,a)" unfolding dual⇩l⇩s⇩s⇩t_def by force
thus ?case
proof
assume "(l,a) ∈ set (dual⇩l⇩s⇩s⇩t A)" thus ?case using Cons.IH by auto
next
assume a: "dual⇩l⇩s⇩s⇩t⇩p c = (l,a)"
obtain i b where b: "c = (i,b)" by (metis surj_pair)
thus ?case using a by (cases b) auto
qed
qed simp
lemma dual⇩l⇩s⇩s⇩t_memberD':
assumes a: "a ∈ set (dual⇩l⇩s⇩s⇩t A ⋅⇩l⇩s⇩s⇩t δ)"
obtains b where "b ∈ set A" "a = dual⇩l⇩s⇩s⇩t⇩p b ⋅⇩l⇩s⇩s⇩t⇩p δ" "fst a = fst b"
proof -
obtain l a' where a': "a = (l,a')" by (metis surj_pair)
then obtain b' where b': "(l,b') ∈ set A" "(l,a') = dual⇩l⇩s⇩s⇩t⇩p ((l,b') ⋅⇩l⇩s⇩s⇩t⇩p δ)"
using a dual⇩l⇩s⇩s⇩t_subst[of A δ] dual⇩l⇩s⇩s⇩t_memberD[of l a' "A ⋅⇩l⇩s⇩s⇩t δ"]
unfolding subst_apply_labeled_stateful_strand_def by auto
show thesis
using that[OF b'(1) b'(2)[unfolded dual⇩l⇩s⇩s⇩t⇩p_subst[of "(l,b')" δ] a'[symmetric]], unfolded a']
by auto
qed
lemma dual⇩l⇩s⇩s⇩t⇩p_inv:
assumes "dual⇩l⇩s⇩s⇩t⇩p (l, a) = (k, b)"
shows "l = k"
and "a = receive⟨t⟩ ⟹ b = send⟨t⟩"
and "a = send⟨t⟩ ⟹ b = receive⟨t⟩"
and "(∄t. a = receive⟨t⟩ ∨ a = send⟨t⟩) ⟹ b = a"
proof -
show "l = k" using assms by (cases a) auto
show "a = receive⟨t⟩ ⟹ b = send⟨t⟩" using assms by (cases a) auto
show "a = send⟨t⟩ ⟹ b = receive⟨t⟩" using assms by (cases a) auto
show "(∄t. a = receive⟨t⟩ ∨ a = send⟨t⟩) ⟹ b = a" using assms by (cases a) auto
qed
lemma dual⇩l⇩s⇩s⇩t_self_inverse: "dual⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = A"
proof (induction A)
case (Cons a A)
obtain l b where "a = (l,b)" by (metis surj_pair)
thus ?case using Cons by (cases b) auto
qed simp
lemma dual⇩l⇩s⇩s⇩t_unlabel_cong:
assumes "unlabel S = unlabel S'"
shows "unlabel (dual⇩l⇩s⇩s⇩t S) = unlabel (dual⇩l⇩s⇩s⇩t S')"
using assms
proof (induction S arbitrary: S')
case (Cons x S S')
obtain y S'' where y: "S' = y#S''" using Cons.prems unfolding unlabel_def by force
hence IH: "unlabel (dual⇩l⇩s⇩s⇩t S) = unlabel (dual⇩l⇩s⇩s⇩t S'')" using Cons by (simp add: unlabel_def)
have "snd x = snd y" using Cons y by simp
then obtain lx ly a where a: "x = (lx,a)" "y = (ly,a)" by (metis prod.exhaust_sel)
have "snd (dual⇩l⇩s⇩s⇩t⇩p x) = snd (dual⇩l⇩s⇩s⇩t⇩p y)" unfolding a by (cases a) simp_all
thus ?case using IH unfolding unlabel_def dual⇩l⇩s⇩s⇩t_def y by force
qed (simp add: unlabel_def dual⇩l⇩s⇩s⇩t_def)
lemma vars⇩s⇩s⇩t_unlabel_dual⇩l⇩s⇩s⇩t_eq: "vars⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = vars⇩l⇩s⇩s⇩t A"
proof (induction A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
thus ?case using Cons.IH by (cases b) auto
qed simp
lemma fv⇩s⇩s⇩t_unlabel_dual⇩l⇩s⇩s⇩t_eq: "fv⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = fv⇩l⇩s⇩s⇩t A"
proof (induction A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
thus ?case using Cons.IH by (cases b) auto
qed simp
lemma bvars⇩s⇩s⇩t_unlabel_dual⇩l⇩s⇩s⇩t_eq: "bvars⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = bvars⇩l⇩s⇩s⇩t A"
proof (induction A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
thus ?case using Cons.IH by (cases b) simp+
qed simp
lemma vars⇩s⇩s⇩t_unlabel_Cons: "vars⇩l⇩s⇩s⇩t ((l,b)#A) = vars⇩s⇩s⇩t⇩p b ∪ vars⇩l⇩s⇩s⇩t A"
by (metis unlabel_Cons(1) vars⇩s⇩s⇩t_Cons)
lemma fv⇩s⇩s⇩t_unlabel_Cons: "fv⇩l⇩s⇩s⇩t ((l,b)#A) = fv⇩s⇩s⇩t⇩p b ∪ fv⇩l⇩s⇩s⇩t A"
by (metis unlabel_Cons(1) fv⇩s⇩s⇩t_Cons)
lemma bvars⇩s⇩s⇩t_unlabel_Cons: "bvars⇩l⇩s⇩s⇩t ((l,b)#A) = set (bvars⇩s⇩s⇩t⇩p b) ∪ bvars⇩l⇩s⇩s⇩t A"
by (metis unlabel_Cons(1) bvars⇩s⇩s⇩t_Cons)
lemma bvars⇩l⇩s⇩s⇩t_subst: "bvars⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t δ) = bvars⇩l⇩s⇩s⇩t A"
by (metis subst_lsst_unlabel bvars⇩s⇩s⇩t_subst)
lemma dual⇩l⇩s⇩s⇩t_member:
assumes "(l,x) ∈ set A"
and "¬is_Receive x" "¬is_Send x"
shows "(l,x) ∈ set (dual⇩l⇩s⇩s⇩t A)"
using assms
proof (induction A)
case (Cons a A) thus ?case using assms(2,3) by (cases x) (auto simp add: dual⇩l⇩s⇩s⇩t_def)
qed simp
lemma dual⇩l⇩s⇩s⇩t_unlabel_member:
assumes "x ∈ set (unlabel A)"
and "¬is_Receive x" "¬is_Send x"
shows "x ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
using assms dual⇩l⇩s⇩s⇩t_member[of _ _ A]
by (meson unlabel_in unlabel_mem_has_label)
lemma dual⇩l⇩s⇩s⇩t_steps_iff:
"(l,send⟨ts⟩) ∈ set A ⟷ (l,receive⟨ts⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
"(l,receive⟨ts⟩) ∈ set A ⟷ (l,send⟨ts⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
"(l,⟨c: t ≐ s⟩) ∈ set A ⟷ (l,⟨c: t ≐ s⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
"(l,insert⟨t,s⟩) ∈ set A ⟷ (l,insert⟨t,s⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
"(l,delete⟨t,s⟩) ∈ set A ⟷ (l,delete⟨t,s⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
"(l,⟨c: t ∈ s⟩) ∈ set A ⟷ (l,⟨c: t ∈ s⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
"(l,∀X⟨∨≠: F ∨∉: G⟩) ∈ set A ⟷ (l,∀X⟨∨≠: F ∨∉: G⟩) ∈ set (dual⇩l⇩s⇩s⇩t A)"
proof (induction A)
case (Cons a A)
obtain j b where a: "a = (j,b)" by (metis surj_pair)
{ case 1 thus ?case by (cases b) (simp_all add: Cons.IH(1) a dual⇩l⇩s⇩s⇩t_def) }
{ case 2 thus ?case by (cases b) (simp_all add: Cons.IH(2) a dual⇩l⇩s⇩s⇩t_def) }
{ case 3 thus ?case by (cases b) (simp_all add: Cons.IH(3) a dual⇩l⇩s⇩s⇩t_def) }
{ case 4 thus ?case by (cases b) (simp_all add: Cons.IH(4) a dual⇩l⇩s⇩s⇩t_def) }
{ case 5 thus ?case by (cases b) (simp_all add: Cons.IH(5) a dual⇩l⇩s⇩s⇩t_def) }
{ case 6 thus ?case by (cases b) (simp_all add: Cons.IH(6) a dual⇩l⇩s⇩s⇩t_def) }
{ case 7 thus ?case by (cases b) (simp_all add: Cons.IH(7) a dual⇩l⇩s⇩s⇩t_def) }
qed (simp_all add: dual⇩l⇩s⇩s⇩t_def)
lemma dual⇩l⇩s⇩s⇩t_unlabel_steps_iff:
"send⟨ts⟩ ∈ set (unlabel A) ⟷ receive⟨ts⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
"receive⟨ts⟩ ∈ set (unlabel A) ⟷ send⟨ts⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
"⟨c: t ≐ s⟩ ∈ set (unlabel A) ⟷ ⟨c: t ≐ s⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
"insert⟨t,s⟩ ∈ set (unlabel A) ⟷ insert⟨t,s⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
"delete⟨t,s⟩ ∈ set (unlabel A) ⟷ delete⟨t,s⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
"⟨c: t ∈ s⟩ ∈ set (unlabel A) ⟷ ⟨c: t ∈ s⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
"∀X⟨∨≠: F ∨∉: G⟩ ∈ set (unlabel A) ⟷ ∀X⟨∨≠: F ∨∉: G⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
using dual⇩l⇩s⇩s⇩t_steps_iff(1,2)[of _ ts A]
dual⇩l⇩s⇩s⇩t_steps_iff(3,6)[of _ c t s A]
dual⇩l⇩s⇩s⇩t_steps_iff(4,5)[of _ t s A]
dual⇩l⇩s⇩s⇩t_steps_iff(7)[of _ X F G A]
by (meson unlabel_in unlabel_mem_has_label)+
lemma dual⇩l⇩s⇩s⇩t_list_all:
"list_all is_Receive (unlabel A) ⟷ list_all is_Send (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Send (unlabel A) ⟷ list_all is_Receive (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Equality (unlabel A) ⟷ list_all is_Equality (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Insert (unlabel A) ⟷ list_all is_Insert (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Delete (unlabel A) ⟷ list_all is_Delete (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_InSet (unlabel A) ⟷ list_all is_InSet (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_NegChecks (unlabel A) ⟷ list_all is_NegChecks (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Assignment (unlabel A) ⟷ list_all is_Assignment (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Check (unlabel A) ⟷ list_all is_Check (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Update (unlabel A) ⟷ list_all is_Update (unlabel (dual⇩l⇩s⇩s⇩t A))"
"list_all is_Check_or_Assignment (unlabel A) ⟷
list_all is_Check_or_Assignment (unlabel (dual⇩l⇩s⇩s⇩t A))"
proof (induct A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
{ case 1 thus ?case using Cons.hyps(1) a by (cases b) auto }
{ case 2 thus ?case using Cons.hyps(2) a by (cases b) auto }
{ case 3 thus ?case using Cons.hyps(3) a by (cases b) auto }
{ case 4 thus ?case using Cons.hyps(4) a by (cases b) auto }
{ case 5 thus ?case using Cons.hyps(5) a by (cases b) auto }
{ case 6 thus ?case using Cons.hyps(6) a by (cases b) auto }
{ case 7 thus ?case using Cons.hyps(7) a by (cases b) auto }
{ case 8 thus ?case using Cons.hyps(8) a by (cases b) auto }
{ case 9 thus ?case using Cons.hyps(9) a by (cases b) auto }
{ case 10 thus ?case using Cons.hyps(10) a by (cases b) auto }
{ case 11 thus ?case using Cons.hyps(11) a by (cases b) auto }
qed simp_all
lemma dual⇩l⇩s⇩s⇩t_list_all_same:
"list_all is_Equality (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_Insert (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_Delete (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_InSet (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_NegChecks (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_Assignment (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_Check (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_Update (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
"list_all is_Check_or_Assignment (unlabel A) ⟹ dual⇩l⇩s⇩s⇩t A = A"
proof (induct A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
{ case 1 thus ?case using Cons.hyps(1) a by (cases b) auto }
{ case 2 thus ?case using Cons.hyps(2) a by (cases b) auto }
{ case 3 thus ?case using Cons.hyps(3) a by (cases b) auto }
{ case 4 thus ?case using Cons.hyps(4) a by (cases b) auto }
{ case 5 thus ?case using Cons.hyps(5) a by (cases b) auto }
{ case 6 thus ?case using Cons.hyps(6) a by (cases b) auto }
{ case 7 thus ?case using Cons.hyps(7) a by (cases b) auto }
{ case 8 thus ?case using Cons.hyps(8) a by (cases b) auto }
{ case 9 thus ?case using Cons.hyps(9) a by (cases b) auto }
qed simp_all
lemma dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain:
assumes "s ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))"
shows "∃l B s'. (l,s) = dual⇩l⇩s⇩s⇩t⇩p (l,s') ∧ prefix (B@[(l,s')]) A"
using assms
proof (induction A rule: List.rev_induct)
case (snoc a A)
obtain i b where a: "a = (i,b)" by (metis surj_pair)
show ?case using snoc
proof (cases "s ∈ set (unlabel (dual⇩l⇩s⇩s⇩t A))")
case False thus ?thesis
using a snoc.prems unlabel_append[of "dual⇩l⇩s⇩s⇩t A" "dual⇩l⇩s⇩s⇩t [a]"] dual⇩l⇩s⇩s⇩t_append[of A "[a]"]
by (cases b) (force simp add: unlabel_def dual⇩l⇩s⇩s⇩t_def)+
qed auto
qed simp
lemma dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain_subst:
assumes "s ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t θ)))"
shows "∃l B s'. (l,s) = dual⇩l⇩s⇩s⇩t⇩p ((l,s') ⋅⇩l⇩s⇩s⇩t⇩p θ) ∧ prefix ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s') ⋅⇩l⇩s⇩s⇩t⇩p θ]) (A ⋅⇩l⇩s⇩s⇩t θ)"
proof -
obtain B l s' where B: "(l,s) = dual⇩l⇩s⇩s⇩t⇩p (l,s')" "prefix (B@[(l,s')]) (A ⋅⇩l⇩s⇩s⇩t θ)"
using dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain[OF assms] by atomize_elim auto
obtain C where C: "C ⋅⇩l⇩s⇩s⇩t θ = B@[(l,s')]"
using subst_lsst_prefix[OF B(2)] by atomize_elim auto
obtain D u where D: "C = D@[(l,u)]" "D ⋅⇩l⇩s⇩s⇩t θ = B" "[(l,u)] ⋅⇩l⇩s⇩s⇩t θ = [(l, s')]"
using subst_lsst_prefix[OF B(2)] subst_lsst_append_inv[OF C(1)]
by (auto simp add: subst_apply_labeled_stateful_strand_def)
show ?thesis
using B D subst_lsst_cons subst_lsst_singleton
by (metis (no_types, lifting) nth_append_length)
qed
lemma trms⇩s⇩s⇩t_unlabel_dual⇩l⇩s⇩s⇩t_eq: "trms⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = trms⇩l⇩s⇩s⇩t A"
proof (induction A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
thus ?case using Cons.IH by (cases b) auto
qed simp
lemma trms⇩s⇩s⇩t_unlabel_subst_cons:
"trms⇩l⇩s⇩s⇩t ((l,b)#A ⋅⇩l⇩s⇩s⇩t δ) = trms⇩s⇩s⇩t⇩p (b ⋅⇩s⇩s⇩t⇩p δ) ∪ trms⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t δ)"
by (metis subst_lsst_unlabel trms⇩s⇩s⇩t_subst_cons unlabel_Cons(1))
lemma trms⇩s⇩s⇩t_unlabel_subst:
assumes "bvars⇩l⇩s⇩s⇩t S ∩ subst_domain θ = {}"
shows "trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t θ) = trms⇩l⇩s⇩s⇩t S ⋅⇩s⇩e⇩t θ"
by (metis trms⇩s⇩s⇩t_subst[OF assms] subst_lsst_unlabel)
lemma trms⇩s⇩s⇩t_unlabel_subst':
fixes t::"('a,'b) term" and δ::"('a,'b) subst"
assumes "t ∈ trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ)"
shows "∃s ∈ trms⇩l⇩s⇩s⇩t S. ∃X. set X ⊆ bvars⇩l⇩s⇩s⇩t S ∧ t = s ⋅ rm_vars (set X) δ"
using assms
proof (induction S)
case (Cons a S)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
hence "t ∈ trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ) ∨ t ∈ trms⇩s⇩s⇩t⇩p (b ⋅⇩s⇩s⇩t⇩p δ)"
using Cons.prems trms⇩s⇩s⇩t_unlabel_subst_cons by fast
thus ?case
proof
assume *: "t ∈ trms⇩s⇩s⇩t⇩p (b ⋅⇩s⇩s⇩t⇩p δ)"
show ?thesis using trms⇩s⇩s⇩t⇩p_subst''[OF *] a by auto
next
assume *: "t ∈ trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ)"
show ?thesis using Cons.IH[OF *] a by auto
qed
qed simp
lemma trms⇩s⇩s⇩t_unlabel_subst'':
fixes t::"('a,'b) term" and δ θ::"('a,'b) subst"
assumes "t ∈ trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ) ⋅⇩s⇩e⇩t θ"
shows "∃s ∈ trms⇩l⇩s⇩s⇩t S. ∃X. set X ⊆ bvars⇩l⇩s⇩s⇩t S ∧ t = s ⋅ rm_vars (set X) δ ∘⇩s θ"
proof -
obtain s where s: "s ∈ trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ)" "t = s ⋅ θ" using assms by atomize_elim auto
show ?thesis using trms⇩s⇩s⇩t_unlabel_subst'[OF s(1)] s(2) by auto
qed
lemma trms⇩s⇩s⇩t_unlabel_dual_subst_cons:
"trms⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t (a#A ⋅⇩l⇩s⇩s⇩t σ)) = (trms⇩s⇩s⇩t⇩p (snd a ⋅⇩s⇩s⇩t⇩p σ)) ∪ (trms⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t σ)))"
proof -
obtain l b where a: "a = (l,b)" by (metis surj_pair)
thus ?thesis using a dual⇩l⇩s⇩s⇩t_subst_cons[of a A σ] by (cases b) auto
qed
lemma dual⇩l⇩s⇩s⇩t_funs_term:
"⋃(funs_term ` (trms⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t S)))) = ⋃(funs_term ` (trms⇩s⇩s⇩t (unlabel S)))"
using trms⇩s⇩s⇩t_unlabel_dual⇩l⇩s⇩s⇩t_eq by fast
lemma dual⇩l⇩s⇩s⇩t_db⇩l⇩s⇩s⇩t:
"db'⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = db'⇩l⇩s⇩s⇩t A"
proof (induction A)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
thus ?case using Cons by (cases b) auto
qed simp
lemma db⇩s⇩s⇩t_unlabel_append:
"db'⇩l⇩s⇩s⇩t (A@B) I D = db'⇩l⇩s⇩s⇩t B I (db'⇩l⇩s⇩s⇩t A I D)"
by (metis db⇩s⇩s⇩t_append unlabel_append)
lemma db⇩s⇩s⇩t_dual⇩l⇩s⇩s⇩t:
"db'⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (T ⋅⇩l⇩s⇩s⇩t δ))) ℐ D = db'⇩s⇩s⇩t (unlabel (T ⋅⇩l⇩s⇩s⇩t δ)) ℐ D"
proof (induction T arbitrary: D)
case (Cons x T)
obtain l s where "x = (l,s)" by atomize_elim auto
thus ?case
using Cons
by (cases s) (simp_all add: unlabel_def dual⇩l⇩s⇩s⇩t_def subst_apply_labeled_stateful_strand_def)
qed (simp add: unlabel_def dual⇩l⇩s⇩s⇩t_def subst_apply_labeled_stateful_strand_def)
lemma labeled_list_insert_eq_cases:
"d ∉ set (unlabel D) ⟹ List.insert d (unlabel D) = unlabel (List.insert (i,d) D)"
"(i,d) ∈ set D ⟹ List.insert d (unlabel D) = unlabel (List.insert (i,d) D)"
unfolding unlabel_def
by (metis (no_types, opaque_lifting) List.insert_def image_eqI list.simps(9) set_map snd_conv,
metis in_set_insert set_zip_rightD zip_map_fst_snd)
lemma labeled_list_insert_eq_ex_cases:
"List.insert d (unlabel D) = unlabel (List.insert (i,d) D) ∨
(∃j. (j,d) ∈ set D ∧ List.insert d (unlabel D) = unlabel (List.insert (j,d) D))"
using labeled_list_insert_eq_cases unfolding unlabel_def
by (metis in_set_impl_in_set_zip2 length_map zip_map_fst_snd)
lemma in_proj_set:
assumes "⟨l,r⟩ ∈ set A"
shows "⟨l,r⟩ ∈ set (proj l A)"
using assms unfolding proj_def by force
lemma proj_subst: "proj l (A ⋅⇩l⇩s⇩s⇩t δ) = proj l A ⋅⇩l⇩s⇩s⇩t δ"
proof (induction A)
case (Cons a A)
obtain l b where "a = (l,b)" by (metis surj_pair)
thus ?case using Cons unfolding proj_def subst_apply_labeled_stateful_strand_def by force
qed simp
lemma proj_set_subset[simp]:
"set (proj n A) ⊆ set A"
unfolding proj_def by auto
lemma proj_proj_set_subset[simp]:
"set (proj n (proj m A)) ⊆ set (proj n A)"
"set (proj n (proj m A)) ⊆ set (proj m A)"
"set (proj_unl n (proj m A)) ⊆ set (proj_unl n A)"
"set (proj_unl n (proj m A)) ⊆ set (proj_unl m A)"
unfolding unlabel_def proj_def by auto
lemma proj_mem_iff:
"(ln i, d) ∈ set D ⟷ (ln i, d) ∈ set (proj i D)"
"(⋆, d) ∈ set D ⟷ (⋆, d) ∈ set (proj i D)"
unfolding proj_def by auto
lemma proj_list_insert:
"proj i (List.insert (ln i,d) D) = List.insert (ln i,d) (proj i D)"
"proj i (List.insert (⋆,d) D) = List.insert (⋆,d) (proj i D)"
"i ≠ j ⟹ proj i (List.insert (ln j,d) D) = proj i D"
unfolding List.insert_def proj_def by auto
lemma proj_filter: "proj i [d←D. d ∉ set Di] = [d←proj i D. d ∉ set Di]"
by (simp_all add: proj_def conj_commute)
lemma proj_list_Cons:
"proj i ((ln i,d)#D) = (ln i,d)#proj i D"
"proj i ((⋆,d)#D) = (⋆,d)#proj i D"
"i ≠ j ⟹ proj i ((ln j,d)#D) = proj i D"
unfolding List.insert_def proj_def by auto
lemma proj_dual⇩l⇩s⇩s⇩t:
"proj l (dual⇩l⇩s⇩s⇩t A) = dual⇩l⇩s⇩s⇩t (proj l A)"
proof (induction A)
case (Cons a A)
obtain k b where "a = (k,b)" by (metis surj_pair)
thus ?case using Cons unfolding dual⇩l⇩s⇩s⇩t_def proj_def by (cases b) auto
qed simp
lemma proj_instance_ex:
assumes B: "∀b ∈ set B. ∃a ∈ set A. ∃δ. b = a ⋅⇩l⇩s⇩s⇩t⇩p δ ∧ P δ"
and b: "b ∈ set (proj l B)"
shows "∃a ∈ set (proj l A). ∃δ. b = a ⋅⇩l⇩s⇩s⇩t⇩p δ ∧ P δ"
proof -
obtain a δ where a: "a ∈ set A" "b = a ⋅⇩l⇩s⇩s⇩t⇩p δ" "P δ" using B b proj_set_subset by fast
obtain k b' where b': "b = (k, b')" "k = (ln l) ∨ k = ⋆" using b proj_in_setD by metis
obtain a' where a': "a = (k, a')" using b'(1) a(2) by (cases a) simp_all
show ?thesis using a a' b'(2) unfolding proj_def by auto
qed
lemma proj_dbproj:
"dbproj (ln i) (proj i D) = dbproj (ln i) D"
"dbproj ⋆ (proj i D) = dbproj ⋆ D"
"i ≠ j ⟹ dbproj (ln j) (proj i D) = []"
unfolding proj_def dbproj_def by (induct D) auto
lemma dbproj_Cons:
"dbproj i ((i,d)#D) = (i,d)#dbproj i D"
"i ≠ j ⟹ dbproj j ((i,d)#D) = dbproj j D"
unfolding dbproj_def by auto
lemma dbproj_subset[simp]:
"set (unlabel (dbproj i D)) ⊆ set (unlabel D)"
unfolding unlabel_def dbproj_def by auto
lemma dbproj_subseq:
assumes "Di ∈ set (subseqs (dbproj k D))"
shows "dbproj k Di = Di" (is ?A)
and "i ≠ k ⟹ dbproj i Di = []" (is "i ≠ k ⟹ ?B")
proof -
have *: "set Di ⊆ set (dbproj k D)" using subseqs_powset[of "dbproj k D"] assms by auto
thus ?A by (metis dbproj_def filter_True filter_set member_filter subsetCE)
have "⋀j d. (j,d) ∈ set Di ⟹ j = k" using * unfolding dbproj_def by auto
moreover have "⋀j d. (j,d) ∈ set (dbproj i Di) ⟹ j = i" unfolding dbproj_def by auto
moreover have "⋀j d. (j,d) ∈ set (dbproj i Di) ⟹ (j,d) ∈ set Di" unfolding dbproj_def by auto
ultimately show "i ≠ k ⟹ ?B" by (metis set_empty subrelI subset_empty)
qed
lemma dbproj_subseq_subset:
assumes "Di ∈ set (subseqs (dbproj i D))"
shows "set Di ⊆ set D"
using assms unfolding dbproj_def
by (metis Pow_iff filter_set image_eqI member_filter subseqs_powset subsetCE subsetI)
lemma dbproj_subseq_in_subseqs:
assumes "Di ∈ set (subseqs (dbproj i D))"
shows "Di ∈ set (subseqs D)"
using assms in_set_subseqs subseq_filter_left subseq_order.dual_order.trans
unfolding dbproj_def by blast
lemma proj_subseq:
assumes "Di ∈ set (subseqs (dbproj (ln j) D))" "j ≠ i"
shows "[d←proj i D. d ∉ set Di] = proj i D"
proof -
have "set Di ⊆ set (dbproj (ln j) D)" using subseqs_powset[of "dbproj (ln j) D"] assms by auto
hence "⋀k d. (k,d) ∈ set Di ⟹ k = ln j" unfolding dbproj_def by auto
moreover have "⋀k d. (k,d) ∈ set (proj i D) ⟹ k ≠ ln j"
using assms(2) unfolding proj_def by auto
ultimately have "⋀d. d ∈ set (proj i D) ⟹ d ∉ set Di" by auto
thus ?thesis by simp
qed
lemma unlabel_subseqsD:
assumes "A ∈ set (subseqs (unlabel B))"
shows "∃C ∈ set (subseqs B). unlabel C = A"
using assms map_subseqs unfolding unlabel_def by (metis imageE set_map)
lemma unlabel_filter_eq:
assumes "∀(j, p) ∈ set A ∪ B. ∀(k, q) ∈ set A ∪ B. p = q ⟶ j = k" (is "?P (set A)")
shows "[d←unlabel A. d ∉ snd ` B] = unlabel [d←A. d ∉ B]"
using assms unfolding unlabel_def
proof (induction A)
case (Cons a A)
have "set A ⊆ set (a#A)" "{a} ⊆ set (a#A)" by auto
hence *: "?P (set A)" "?P {a}" using Cons.prems by fast+
hence IH: "[d←map snd A . d ∉ snd ` B] = map snd [d←A . d ∉ B]" using Cons.IH by auto
{ assume "snd a ∈ snd ` B"
then obtain b where b: "b ∈ B" "snd a = snd b" by atomize_elim auto
hence "fst a = fst b" using *(2) by auto
hence "a ∈ B" using b by (metis surjective_pairing)
} hence **: "a ∉ B ⟹ snd a ∉ snd ` B" by metis
show ?case by (cases "a ∈ B") (simp add: ** IH)+
qed simp
lemma subseqs_mem_dbproj:
assumes "Di ∈ set (subseqs D)" "list_all (λd. fst d = i) Di"
shows "Di ∈ set (subseqs (dbproj i D))"
using assms
proof (induction D arbitrary: Di)
case (Cons di D)
obtain d j where di: "di = (j,d)" by (metis surj_pair)
show ?case
proof (cases "Di ∈ set (subseqs D)")
case True
hence "Di ∈ set (subseqs (dbproj i D))" using Cons.IH Cons.prems by auto
thus ?thesis using subseqs_Cons unfolding dbproj_def by auto
next
case False
then obtain Di' where Di': "Di = di#Di'" using Cons.prems(1)
by (metis (mono_tags, lifting) Un_iff imageE set_append set_map subseqs.simps(2))
hence "Di' ∈ set (subseqs D)" using Cons.prems(1) False
by (metis (no_types, lifting) UnE imageE list.inject set_append set_map subseqs.simps(2))
hence "Di' ∈ set (subseqs (dbproj i D))" using Cons.IH Cons.prems Di' by auto
moreover have "i = j" using Di' di Cons.prems(2) by auto
hence "dbproj i (di#D) = di#dbproj i D" unfolding dbproj_def by (simp add: di)
ultimately show ?thesis using Di'
by (metis (no_types, lifting) UnCI image_eqI set_append set_map subseqs.simps(2))
qed
qed simp
lemma unlabel_subst: "unlabel S ⋅⇩s⇩s⇩t δ = unlabel (S ⋅⇩l⇩s⇩s⇩t δ)"
unfolding unlabel_def subst_apply_stateful_strand_def subst_apply_labeled_stateful_strand_def
by auto
lemma subterms_subst_lsst:
assumes "∀x ∈ fv⇩s⇩e⇩t (trms⇩l⇩s⇩s⇩t S). (∃f. σ x = Fun f []) ∨ (∃y. σ x = Var y)"
and "bvars⇩l⇩s⇩s⇩t S ∩ subst_domain σ = {}"
shows "subterms⇩s⇩e⇩t (trms⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t σ)) = subterms⇩s⇩e⇩t (trms⇩l⇩s⇩s⇩t S) ⋅⇩s⇩e⇩t σ"
using subterms_subst''[OF assms(1)] trms⇩s⇩s⇩t_subst[OF assms(2)] unlabel_subst[of S σ]
by simp
lemma subterms_subst_lsst_ik:
assumes "∀x ∈ fv⇩s⇩e⇩t (ik⇩l⇩s⇩s⇩t S). (∃f. σ x = Fun f []) ∨ (∃y. σ x = Var y)"
shows "subterms⇩s⇩e⇩t (ik⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t σ)) = subterms⇩s⇩e⇩t (ik⇩l⇩s⇩s⇩t S) ⋅⇩s⇩e⇩t σ"
using subterms_subst''[OF assms(1)] ik⇩s⇩s⇩t_subst[of "unlabel S" σ] unlabel_subst[of S σ]
by simp
lemma labeled_stateful_strand_subst_comp:
assumes "range_vars δ ∩ bvars⇩l⇩s⇩s⇩t S = {}"
shows "S ⋅⇩l⇩s⇩s⇩t δ ∘⇩s θ = (S ⋅⇩l⇩s⇩s⇩t δ) ⋅⇩l⇩s⇩s⇩t θ"
using assms
proof (induction S)
case (Cons s S)
obtain l x where s: "s = (l,x)" by (metis surj_pair)
hence IH: "S ⋅⇩l⇩s⇩s⇩t δ ∘⇩s θ = (S ⋅⇩l⇩s⇩s⇩t δ) ⋅⇩l⇩s⇩s⇩t θ" using Cons by auto
have "x ⋅⇩s⇩s⇩t⇩p δ ∘⇩s θ = (x ⋅⇩s⇩s⇩t⇩p δ) ⋅⇩s⇩s⇩t⇩p θ"
using s Cons.prems stateful_strand_step_subst_comp[of δ x θ] by auto
thus ?case using s IH by (simp add: subst_apply_labeled_stateful_strand_def)
qed simp
lemma sst_vars_proj_subset[simp]:
"fv⇩s⇩s⇩t (proj_unl n A) ⊆ fv⇩s⇩s⇩t (unlabel A)"
"bvars⇩s⇩s⇩t (proj_unl n A) ⊆ bvars⇩s⇩s⇩t (unlabel A)"
"vars⇩s⇩s⇩t (proj_unl n A) ⊆ vars⇩s⇩s⇩t (unlabel A)"
using vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t[of "unlabel A"]
vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t[of "proj_unl n A"]
unfolding unlabel_def proj_def by auto
lemma trms⇩s⇩s⇩t_proj_subset[simp]:
"trms⇩s⇩s⇩t (proj_unl n A) ⊆ trms⇩s⇩s⇩t (unlabel A)" (is ?A)
"trms⇩s⇩s⇩t (proj_unl m (proj n A)) ⊆ trms⇩s⇩s⇩t (proj_unl n A)" (is ?B)
"trms⇩s⇩s⇩t (proj_unl m (proj n A)) ⊆ trms⇩s⇩s⇩t (proj_unl m A)" (is ?C)
proof -
show ?A unfolding unlabel_def proj_def by auto
show ?B using trms⇩s⇩s⇩t_mono[OF proj_proj_set_subset(4)] by metis
show ?C using trms⇩s⇩s⇩t_mono[OF proj_proj_set_subset(3)] by metis
qed
lemma trms⇩s⇩s⇩t_unlabel_prefix_subset:
"trms⇩s⇩s⇩t (unlabel A) ⊆ trms⇩s⇩s⇩t (unlabel (A@B))" (is ?A)
"trms⇩s⇩s⇩t (proj_unl n A) ⊆ trms⇩s⇩s⇩t (proj_unl n (A@B))" (is ?B)
using trms⇩s⇩s⇩t_mono[of "proj_unl n A" "proj_unl n (A@B)"]
unfolding unlabel_def proj_def by auto
lemma trms⇩s⇩s⇩t_unlabel_suffix_subset:
"trms⇩s⇩s⇩t (unlabel B) ⊆ trms⇩s⇩s⇩t (unlabel (A@B))"
"trms⇩s⇩s⇩t (proj_unl n B) ⊆ trms⇩s⇩s⇩t (proj_unl n (A@B))"
using trms⇩s⇩s⇩t_mono[of "proj_unl n B" "proj_unl n (A@B)"]
unfolding unlabel_def proj_def by auto
lemma setops⇩l⇩s⇩s⇩t⇩pD:
assumes p: "p ∈ setops⇩l⇩s⇩s⇩t⇩p a"
shows "fst p = fst a" (is ?P)
and "is_Update (snd a) ∨ is_InSet (snd a) ∨ is_NegChecks (snd a)" (is ?Q)
proof -
obtain l k p' a' where a: "p = (l,p')" "a = (k,a')" by (metis surj_pair)
show ?P using p a by (cases a') auto
show ?Q using p a by (cases a') auto
qed
lemma setops⇩l⇩s⇩s⇩t_nil[simp]:
"setops⇩l⇩s⇩s⇩t [] = {}"
by (simp add: setops⇩l⇩s⇩s⇩t_def)
lemma setops⇩l⇩s⇩s⇩t_cons[simp]:
"setops⇩l⇩s⇩s⇩t (x#S) = setops⇩l⇩s⇩s⇩t⇩p x ∪ setops⇩l⇩s⇩s⇩t S"
by (simp add: setops⇩l⇩s⇩s⇩t_def)
lemma setops⇩s⇩s⇩t_proj_subset:
"setops⇩s⇩s⇩t (proj_unl n A) ⊆ setops⇩s⇩s⇩t (unlabel A)"
"setops⇩s⇩s⇩t (proj_unl m (proj n A)) ⊆ setops⇩s⇩s⇩t (proj_unl n A)"
"setops⇩s⇩s⇩t (proj_unl m (proj n A)) ⊆ setops⇩s⇩s⇩t (proj_unl m A)"
unfolding unlabel_def proj_def
proof (induction A)
case (Cons a A)
obtain l b where lb: "a = (l,b)" by atomize_elim auto
{ case 1 thus ?case using Cons.IH(1) unfolding lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
{ case 2 thus ?case using Cons.IH(2) unfolding lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
{ case 3 thus ?case using Cons.IH(3) unfolding lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
qed simp_all
lemma setops⇩s⇩s⇩t_unlabel_prefix_subset:
"setops⇩s⇩s⇩t (unlabel A) ⊆ setops⇩s⇩s⇩t (unlabel (A@B))"
"setops⇩s⇩s⇩t (proj_unl n A) ⊆ setops⇩s⇩s⇩t (proj_unl n (A@B))"
unfolding unlabel_def proj_def
proof (induction A)
case (Cons a A)
obtain l b where lb: "a = (l,b)" by atomize_elim auto
{ case 1 thus ?case using Cons.IH lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
{ case 2 thus ?case using Cons.IH lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
qed (simp_all add: setops⇩s⇩s⇩t_def)
lemma setops⇩s⇩s⇩t_unlabel_suffix_subset:
"setops⇩s⇩s⇩t (unlabel B) ⊆ setops⇩s⇩s⇩t (unlabel (A@B))"
"setops⇩s⇩s⇩t (proj_unl n B) ⊆ setops⇩s⇩s⇩t (proj_unl n (A@B))"
unfolding unlabel_def proj_def
proof (induction A)
case (Cons a A)
obtain l b where lb: "a = (l,b)" by atomize_elim auto
{ case 1 thus ?case using Cons.IH lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
{ case 2 thus ?case using Cons.IH lb by (cases b) (auto simp add: setops⇩s⇩s⇩t_def) }
qed simp_all
lemma setops⇩l⇩s⇩s⇩t_proj_subset:
"setops⇩l⇩s⇩s⇩t (proj n A) ⊆ setops⇩l⇩s⇩s⇩t A"
"setops⇩l⇩s⇩s⇩t (proj m (proj n A)) ⊆ setops⇩l⇩s⇩s⇩t (proj n A)"
unfolding proj_def setops⇩l⇩s⇩s⇩t_def by auto
lemma setops⇩l⇩s⇩s⇩t_prefix_subset:
"setops⇩l⇩s⇩s⇩t A ⊆ setops⇩l⇩s⇩s⇩t (A@B)"
"setops⇩l⇩s⇩s⇩t (proj n A) ⊆ setops⇩l⇩s⇩s⇩t (proj n (A@B))"
unfolding proj_def setops⇩l⇩s⇩s⇩t_def by auto
lemma setops⇩l⇩s⇩s⇩t_suffix_subset:
"setops⇩l⇩s⇩s⇩t B ⊆ setops⇩l⇩s⇩s⇩t (A@B)"
"setops⇩l⇩s⇩s⇩t (proj n B) ⊆ setops⇩l⇩s⇩s⇩t (proj n (A@B))"
unfolding proj_def setops⇩l⇩s⇩s⇩t_def by auto
lemma setops⇩l⇩s⇩s⇩t_mono:
"set M ⊆ set N ⟹ setops⇩l⇩s⇩s⇩t M ⊆ setops⇩l⇩s⇩s⇩t N"
by (auto simp add: setops⇩l⇩s⇩s⇩t_def)
lemma trms⇩s⇩s⇩t_unlabel_subset_if_no_label:
"¬list_ex (has_LabelN l) A ⟹ trms⇩l⇩s⇩s⇩t (proj l A) ⊆ trms⇩l⇩s⇩s⇩t (proj l' A)"
by (rule trms⇩s⇩s⇩t_mono[OF proj_subset_if_no_label(2)[of l A l']])
lemma setops⇩s⇩s⇩t_unlabel_subset_if_no_label:
"¬list_ex (has_LabelN l) A ⟹ setops⇩s⇩s⇩t (proj_unl l A) ⊆ setops⇩s⇩s⇩t (proj_unl l' A)"
by (rule setops⇩s⇩s⇩t_mono[OF proj_subset_if_no_label(2)[of l A l']])
lemma setops⇩l⇩s⇩s⇩t_proj_subset_if_no_label:
"¬list_ex (has_LabelN l) A ⟹ setops⇩l⇩s⇩s⇩t (proj l A) ⊆ setops⇩l⇩s⇩s⇩t (proj l' A)"
by (rule setops⇩l⇩s⇩s⇩t_mono[OF proj_subset_if_no_label(1)[of l A l']])
lemma setops⇩l⇩s⇩s⇩t⇩p_subst_cases[simp]:
"setops⇩l⇩s⇩s⇩t⇩p ((l,send⟨ts⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) = {}"
"setops⇩l⇩s⇩s⇩t⇩p ((l,receive⟨ts⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) = {}"
"setops⇩l⇩s⇩s⇩t⇩p ((l,⟨ac: s ≐ t⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) = {}"
"setops⇩l⇩s⇩s⇩t⇩p ((l,insert⟨t,s⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) = {(l,t ⋅ δ,s ⋅ δ)}"
"setops⇩l⇩s⇩s⇩t⇩p ((l,delete⟨t,s⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) = {(l,t ⋅ δ,s ⋅ δ)}"
"setops⇩l⇩s⇩s⇩t⇩p ((l,⟨ac: t ∈ s⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) = {(l,t ⋅ δ,s ⋅ δ)}"
"setops⇩l⇩s⇩s⇩t⇩p ((l,∀X⟨∨≠: F ∨∉: F'⟩) ⋅⇩l⇩s⇩s⇩t⇩p δ) =
((λ(t,s). (l,t ⋅ rm_vars (set X) δ,s ⋅ rm_vars (set X) δ)) ` set F')" (is "?A = ?B")
proof -
have "?A = (λ(t,s). (l,t,s)) ` set (F' ⋅⇩p⇩a⇩i⇩r⇩s rm_vars (set X) δ)" by auto
thus "?A = ?B" unfolding subst_apply_pairs_def by auto
qed simp_all
lemma setops⇩l⇩s⇩s⇩t⇩p_subst:
assumes "set (bvars⇩s⇩s⇩t⇩p (snd a)) ∩ subst_domain θ = {}"
shows "setops⇩l⇩s⇩s⇩t⇩p (a ⋅⇩l⇩s⇩s⇩t⇩p θ) = (λp. (fst a,snd p ⋅⇩p θ)) ` setops⇩l⇩s⇩s⇩t⇩p a"
proof -
obtain l a' where a: "a = (l,a')" by (metis surj_pair)
show ?thesis
proof (cases a')
case (NegChecks X F G)
hence *: "rm_vars (set X) θ = θ" using a assms rm_vars_apply'[of θ "set X"] by auto
have "setops⇩l⇩s⇩s⇩t⇩p (a ⋅⇩l⇩s⇩s⇩t⇩p θ) = (λp. (fst a, p)) ` set (G ⋅⇩p⇩a⇩i⇩r⇩s θ)"
using * NegChecks a by auto
moreover have "setops⇩l⇩s⇩s⇩t⇩p a = (λp. (fst a, p)) ` set G" using NegChecks a by simp
hence "(λp. (fst a,snd p ⋅⇩p θ)) ` setops⇩l⇩s⇩s⇩t⇩p a = (λp. (fst a, p ⋅⇩p θ)) ` set G"
by (metis (mono_tags, lifting) image_cong image_image snd_conv)
hence "(λp. (fst a,snd p ⋅⇩p θ)) ` setops⇩l⇩s⇩s⇩t⇩p a = (λp. (fst a, p)) ` (set G ⋅⇩p⇩s⇩e⇩t θ)"
unfolding case_prod_unfold by auto
ultimately show ?thesis by (simp add: subst_apply_pairs_def)
qed (use a in simp_all)
qed
lemma setops⇩l⇩s⇩s⇩t⇩p_subst':
assumes "set (bvars⇩s⇩s⇩t⇩p (snd a)) ∩ subst_domain θ = {}"
shows "setops⇩l⇩s⇩s⇩t⇩p (a ⋅⇩l⇩s⇩s⇩t⇩p θ) = (λ(i,p). (i,p ⋅⇩p θ)) ` setops⇩l⇩s⇩s⇩t⇩p a"
using setops⇩l⇩s⇩s⇩t⇩p_subst[OF assms] setops⇩l⇩s⇩s⇩t⇩pD(1) unfolding case_prod_unfold
by (metis (mono_tags, lifting) image_cong)
lemma setops⇩l⇩s⇩s⇩t_subst:
assumes "bvars⇩l⇩s⇩s⇩t S ∩ subst_domain θ = {}"
shows "setops⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t θ) = (λp. (fst p,snd p ⋅⇩p θ)) ` setops⇩l⇩s⇩s⇩t S"
using assms
proof (induction S)
case (Cons a S)
have "bvars⇩l⇩s⇩s⇩t S ∩ subst_domain θ = {}" and *: "set (bvars⇩s⇩s⇩t⇩p (snd a)) ∩ subst_domain θ = {}"
using Cons.prems by auto
hence IH: "setops⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t θ) = (λp. (fst p,snd p ⋅⇩p θ)) ` setops⇩l⇩s⇩s⇩t S"
using Cons.IH by auto
show ?case
using setops⇩l⇩s⇩s⇩t⇩p_subst'[OF *] IH
unfolding setops⇩l⇩s⇩s⇩t_def case_prod_unfold subst_lsst_cons
by auto
qed (simp add: setops⇩s⇩s⇩t_def)
lemma setops⇩l⇩s⇩s⇩t⇩p_in_subst:
assumes p: "p ∈ setops⇩l⇩s⇩s⇩t⇩p (a ⋅⇩l⇩s⇩s⇩t⇩p δ)"
shows "∃q ∈ setops⇩l⇩s⇩s⇩t⇩p a. fst p = fst q ∧ snd p = snd q ⋅⇩p rm_vars (set (bvars⇩s⇩s⇩t⇩p (snd a))) δ"
(is "∃q ∈ setops⇩l⇩s⇩s⇩t⇩p a. ?P q")
proof -
obtain l b where a: "a = (l,b)" by (metis surj_pair)
show ?thesis
proof (cases b)
case (NegChecks X F F')
hence "p ∈ (λ(t, s). (l, t ⋅ rm_vars (set X) δ, s ⋅ rm_vars (set X) δ)) ` set F'"
using p a setops⇩l⇩s⇩s⇩t⇩p_subst_cases(7)[of l X F F' δ] by blast
then obtain s t where st:
"(t,s) ∈ set F'" "p = (l, t ⋅ rm_vars (set X) δ, s ⋅ rm_vars (set X) δ)"
by auto
hence "(l,t,s) ∈ setops⇩l⇩s⇩s⇩t⇩p a" "fst p = fst (l,t,s)"
"snd p = snd (l,t,s) ⋅⇩p rm_vars (set X) δ"
using a NegChecks by fastforce+
moreover have "bvars⇩s⇩s⇩t⇩p (snd a) = X" using NegChecks a by auto
ultimately show ?thesis by blast
qed (use p a in auto)
qed
lemma setops⇩l⇩s⇩s⇩t_in_subst:
assumes "p ∈ setops⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t δ)"
shows "∃q ∈ setops⇩l⇩s⇩s⇩t A. fst p = fst q ∧ (∃X ⊆ bvars⇩l⇩s⇩s⇩t A. snd p = snd q ⋅⇩p rm_vars X δ)"
(is "∃q ∈ setops⇩l⇩s⇩s⇩t A. ?P A q")
using assms
proof (induction A)
case (Cons a A)
note 0 = unlabel_Cons(2)[of a A] bvars⇩s⇩s⇩t_Cons[of "snd a" "unlabel A"]
show ?case
proof (cases "p ∈ setops⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t δ)")
case False
hence "p ∈ setops⇩l⇩s⇩s⇩t⇩p (a ⋅⇩l⇩s⇩s⇩t⇩p δ)"
using Cons.prems setops⇩l⇩s⇩s⇩t_cons[of "a ⋅⇩l⇩s⇩s⇩t⇩p δ" "A ⋅⇩l⇩s⇩s⇩t δ"] subst_lsst_cons[of a A δ] by auto
moreover have "(set (bvars⇩s⇩s⇩t⇩p (snd a))) ⊆ bvars⇩l⇩s⇩s⇩t (a#A)" using 0 by simp
ultimately have "∃q ∈ setops⇩l⇩s⇩s⇩t⇩p a. ?P (a#A) q" using setops⇩l⇩s⇩s⇩t⇩p_in_subst[of p a δ] by blast
thus ?thesis by auto
qed (use Cons.IH 0 in auto)
qed simp
lemma setops⇩l⇩s⇩s⇩t_dual⇩l⇩s⇩s⇩t_eq:
"setops⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A) = setops⇩l⇩s⇩s⇩t A"
proof (induction A)
case (Cons a A)
obtain l b where "a = (l,b)" by (metis surj_pair)
thus ?case using Cons unfolding setops⇩l⇩s⇩s⇩t_def dual⇩l⇩s⇩s⇩t_def by (cases b) auto
qed simp
end