Automated_Stateful_Protocol.../Automated_Stateful_Protocol.../Stateful_Protocol_Model.thy

4411 lines
257 KiB
Plaintext

(*
(C) Copyright Andreas Viktor Hess, DTU, 2020
(C) Copyright Sebastian A. Mödersheim, DTU, 2020
(C) Copyright Achim D. Brucker, University of Exeter, 2020
(C) Copyright Anders Schlichtkrull, DTU, 2020
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
(* Title: Stateful_Protocol_Model.thy
Author: Andreas Viktor Hess, DTU
Author: Sebastian A. Mödersheim, DTU
Author: Achim D. Brucker, University of Exeter
Author: Anders Schlichtkrull, DTU
*)
section\<open>Stateful Protocol Model\<close>
theory Stateful_Protocol_Model
imports Stateful_Protocol_Composition_and_Typing.Stateful_Compositionality
Transactions Term_Abstraction
begin
subsection \<open>Locale Setup\<close>
locale stateful_protocol_model =
fixes arity\<^sub>f::"'fun \<Rightarrow> nat"
and arity\<^sub>s::"'sets \<Rightarrow> nat"
and public\<^sub>f::"'fun \<Rightarrow> bool"
and Ana\<^sub>f::"'fun \<Rightarrow> ((('fun,'atom::finite,'sets) prot_fun, nat) term list \<times> nat list)"
and \<Gamma>\<^sub>f::"'fun \<Rightarrow> 'atom option"
and label_witness1::"'lbl"
and label_witness2::"'lbl"
assumes Ana\<^sub>f_assm1: "\<forall>f. let (K, M) = Ana\<^sub>f f in (\<forall>k \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K).
is_Fun k \<longrightarrow> (is_Fu (the_Fun k)) \<and> length (args k) = arity\<^sub>f (the_Fu (the_Fun k)))"
and Ana\<^sub>f_assm2: "\<forall>f. let (K, M) = Ana\<^sub>f f in \<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K) \<union> set M. i < arity\<^sub>f f"
and public\<^sub>f_assm: "\<forall>f. arity\<^sub>f f > (0::nat) \<longrightarrow> public\<^sub>f f"
and \<Gamma>\<^sub>f_assm: "\<forall>f. arity\<^sub>f f = (0::nat) \<longrightarrow> \<Gamma>\<^sub>f f \<noteq> None"
and label_witness_assm: "label_witness1 \<noteq> label_witness2"
begin
lemma Ana\<^sub>f_assm1_alt:
assumes "Ana\<^sub>f f = (K,M)" "k \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K)"
shows "(\<exists>x. k = Var x) \<or> (\<exists>h T. k = Fun (Fu h) T \<and> length T = arity\<^sub>f h)"
proof (cases k)
case (Fun g T)
let ?P = "\<lambda>k. is_Fun k \<longrightarrow> is_Fu (the_Fun k) \<and> length (args k) = arity\<^sub>f (the_Fu (the_Fun k))"
let ?Q = "\<lambda>K M. \<forall>k \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K). ?P k"
have "?Q (fst (Ana\<^sub>f f)) (snd (Ana\<^sub>f f))" using Ana\<^sub>f_assm1 split_beta[of ?Q "Ana\<^sub>f f"] by meson
hence "?Q K M" using assms(1) by simp
hence "?P k" using assms(2) by blast
thus ?thesis using Fun by (cases g) auto
qed simp
lemma Ana\<^sub>f_assm2_alt:
assumes "Ana\<^sub>f f = (K,M)" "i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K) \<union> set M"
shows "i < arity\<^sub>f f"
using Ana\<^sub>f_assm2 assms by fastforce
subsection \<open>Definitions\<close>
fun arity where
"arity (Fu f) = arity\<^sub>f f"
| "arity (Set s) = arity\<^sub>s s"
| "arity (Val _) = 0"
| "arity (Abs _) = 0"
| "arity Pair = 2"
| "arity (Attack _) = 0"
| "arity OccursFact = 2"
| "arity OccursSec = 0"
| "arity (PubConstAtom _ _) = 0"
| "arity (PubConstSetType _) = 0"
| "arity (PubConstAttackType _) = 0"
| "arity (PubConstBottom _) = 0"
| "arity (PubConstOccursSecType _) = 0"
fun public where
"public (Fu f) = public\<^sub>f f"
| "public (Set s) = (arity\<^sub>s s > 0)"
| "public (Val n) = snd n"
| "public (Abs _) = False"
| "public Pair = True"
| "public (Attack _) = False"
| "public OccursFact = True"
| "public OccursSec = False"
| "public (PubConstAtom _ _) = True"
| "public (PubConstSetType _) = True"
| "public (PubConstAttackType _) = True"
| "public (PubConstBottom _) = True"
| "public (PubConstOccursSecType _) = True"
fun Ana where
"Ana (Fun (Fu f) T) = (
if arity\<^sub>f f = length T \<and> arity\<^sub>f f > 0
then let (K,M) = Ana\<^sub>f f in (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M)
else ([], []))"
| "Ana _ = ([], [])"
definition \<Gamma>\<^sub>v where
"\<Gamma>\<^sub>v v \<equiv> (
if (\<forall>t \<in> subterms (fst v).
case t of (TComp f T) \<Rightarrow> arity f > 0 \<and> arity f = length T | _ \<Rightarrow> True)
then fst v
else TAtom Bottom)"
fun \<Gamma> where
"\<Gamma> (Var v) = \<Gamma>\<^sub>v v"
| "\<Gamma> (Fun f T) = (
if arity f = 0
then case f of
(Fu g) \<Rightarrow> TAtom (case \<Gamma>\<^sub>f g of Some a \<Rightarrow> Atom a | None \<Rightarrow> Bottom)
| (Val _) \<Rightarrow> TAtom Value
| (Abs _) \<Rightarrow> TAtom Value
| (Set _) \<Rightarrow> TAtom SetType
| (Attack _) \<Rightarrow> TAtom AttackType
| OccursSec \<Rightarrow> TAtom OccursSecType
| (PubConstAtom a _) \<Rightarrow> TAtom (Atom a)
| (PubConstSetType _) \<Rightarrow> TAtom SetType
| (PubConstAttackType _) \<Rightarrow> TAtom AttackType
| (PubConstBottom _) \<Rightarrow> TAtom Bottom
| (PubConstOccursSecType _) \<Rightarrow> TAtom OccursSecType
| _ \<Rightarrow> TAtom Bottom
else TComp f (map \<Gamma> T))"
lemma \<Gamma>_consts_simps[simp]:
"arity\<^sub>f g = 0 \<Longrightarrow> \<Gamma> (Fun (Fu g) []) = TAtom (case \<Gamma>\<^sub>f g of Some a \<Rightarrow> Atom a | None \<Rightarrow> Bottom)"
"\<Gamma> (Fun (Val n) []) = TAtom Value"
"\<Gamma> (Fun (Abs b) []) = TAtom Value"
"arity\<^sub>s s = 0 \<Longrightarrow> \<Gamma> (Fun (Set s) []) = TAtom SetType"
"\<Gamma> (Fun (Attack x) []) = TAtom AttackType"
"\<Gamma> (Fun OccursSec []) = TAtom OccursSecType"
"\<Gamma> (Fun (PubConstAtom a t) []) = TAtom (Atom a)"
"\<Gamma> (Fun (PubConstSetType t) []) = TAtom SetType"
"\<Gamma> (Fun (PubConstAttackType t) []) = TAtom AttackType"
"\<Gamma> (Fun (PubConstBottom t) []) = TAtom Bottom"
"\<Gamma> (Fun (PubConstOccursSecType t) []) = TAtom OccursSecType"
by simp+
lemma \<Gamma>_Set_simps[simp]:
"arity\<^sub>s s \<noteq> 0 \<Longrightarrow> \<Gamma> (Fun (Set s) T) = TComp (Set s) (map \<Gamma> T)"
"\<Gamma> (Fun (Set s) T) = TAtom SetType \<or> \<Gamma> (Fun (Set s) T) = TComp (Set s) (map \<Gamma> T)"
"\<Gamma> (Fun (Set s) T) \<noteq> TAtom Value"
"\<Gamma> (Fun (Set s) T) \<noteq> TAtom (Atom a)"
"\<Gamma> (Fun (Set s) T) \<noteq> TAtom AttackType"
"\<Gamma> (Fun (Set s) T) \<noteq> TAtom OccursSecType"
"\<Gamma> (Fun (Set s) T) \<noteq> TAtom Bottom"
by auto
subsection \<open>Locale Interpretations\<close>
lemma Ana_Fu_cases:
assumes "Ana (Fun f T) = (K,M)"
and "f = Fu g"
and "Ana\<^sub>f g = (K',M')"
shows "(K,M) = (if arity\<^sub>f g = length T \<and> arity\<^sub>f g > 0
then (K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M')
else ([],[]))" (is ?A)
and "(K,M) = (K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M') \<or> (K,M) = ([],[])" (is ?B)
proof -
show ?A using assms by (cases "arity\<^sub>f g = length T \<and> arity\<^sub>f g > 0") auto
thus ?B by metis
qed
lemma Ana_Fu_intro:
assumes "arity\<^sub>f f = length T" "arity\<^sub>f f > 0"
and "Ana\<^sub>f f = (K',M')"
shows "Ana (Fun (Fu f) T) = (K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M')"
using assms by simp
lemma Ana_Fu_elim:
assumes "Ana (Fun f T) = (K,M)"
and "f = Fu g"
and "Ana\<^sub>f g = (K',M')"
and "(K,M) \<noteq> ([],[])"
shows "arity\<^sub>f g = length T" (is ?A)
and "(K,M) = (K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M')" (is ?B)
proof -
show ?A using assms by force
moreover have "arity\<^sub>f g > 0" using assms by force
ultimately show ?B using assms by auto
qed
lemma Ana_nonempty_inv:
assumes "Ana t \<noteq> ([],[])"
shows "\<exists>f T. t = Fun (Fu f) T \<and> arity\<^sub>f f = length T \<and> arity\<^sub>f f > 0 \<and>
(\<exists>K M. Ana\<^sub>f f = (K, M) \<and> Ana t = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M))"
using assms
proof (induction t rule: Ana.induct)
case (1 f T)
hence *: "arity\<^sub>f f = length T" "0 < arity\<^sub>f f"
"Ana (Fun (Fu f) T) = (case Ana\<^sub>f f of (K, M) \<Rightarrow> (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M))"
using Ana.simps(1)[of f T] unfolding Let_def by metis+
obtain K M where **: "Ana\<^sub>f f = (K, M)" by (metis surj_pair)
hence "Ana (Fun (Fu f) T) = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M)" using *(3) by simp
thus ?case using ** *(1,2) by blast
qed simp_all
lemma assm1:
assumes "Ana t = (K,M)"
shows "fv\<^sub>s\<^sub>e\<^sub>t (set K) \<subseteq> fv t"
using assms
proof (induction t rule: term.induct)
case (Fun f T)
have aux: "fv\<^sub>s\<^sub>e\<^sub>t (set K \<cdot>\<^sub>s\<^sub>e\<^sub>t (!) T) \<subseteq> fv\<^sub>s\<^sub>e\<^sub>t (set T)"
when K: "\<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K). i < length T"
for K::"(('fun,'atom,'sets) prot_fun, nat) term list"
proof
fix x assume "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K \<cdot>\<^sub>s\<^sub>e\<^sub>t (!) T)"
then obtain k where k: "k \<in> set K" "x \<in> fv (k \<cdot> (!) T)" by moura
have "\<forall>i \<in> fv k. i < length T" using K k(1) by simp
thus "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set T)"
by (metis (no_types, lifting) k(2) contra_subsetD fv_set_mono image_subsetI nth_mem
subst_apply_fv_unfold)
qed
{ fix g assume f: "f = Fu g" and K: "K \<noteq> []"
obtain K' M' where *: "Ana\<^sub>f g = (K',M')" by moura
have "(K, M) \<noteq> ([], [])" using K by simp
hence "(K, M) = (K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M')" "arity\<^sub>f g = length T"
using Ana_Fu_cases(1)[OF Fun.prems f *]
by presburger+
hence ?case using aux[of K'] Ana\<^sub>f_assm2_alt[OF *] by auto
} thus ?case using Fun by (cases f) fastforce+
qed simp
lemma assm2:
assumes "Ana t = (K,M)"
and "\<And>g S'. Fun g S' \<sqsubseteq> t \<Longrightarrow> length S' = arity g"
and "k \<in> set K"
and "Fun f T' \<sqsubseteq> k"
shows "length T' = arity f"
using assms
proof (induction t rule: term.induct)
case (Fun g T)
obtain h where 2: "g = Fu h"
using Fun.prems(1,3) by (cases g) auto
obtain K' M' where 1: "Ana\<^sub>f h = (K',M')" by moura
have "(K,M) \<noteq> ([],[])" using Fun.prems(3) by auto
hence "(K,M) = (K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T, map ((!) T) M')"
"\<And>i. i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K') \<union> set M' \<Longrightarrow> i < length T"
using Ana_Fu_cases(1)[OF Fun.prems(1) 2 1] Ana\<^sub>f_assm2_alt[OF 1]
by presburger+
hence "K = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T" and 3: "\<forall>i\<in>fv\<^sub>s\<^sub>e\<^sub>t (set K'). i < length T" by simp_all
then obtain k' where k': "k' \<in> set K'" "k = k' \<cdot> (!) T" using Fun.prems(3) by moura
hence 4: "Fun f T' \<in> subterms (k' \<cdot> (!) T)" "fv k' \<subseteq> fv\<^sub>s\<^sub>e\<^sub>t (set K')"
using Fun.prems(4) by auto
show ?case
proof (cases "\<exists>i \<in> fv k'. Fun f T' \<in> subterms (T ! i)")
case True
hence "Fun f T' \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set T)" using k' Fun.prems(4) 3 by auto
thus ?thesis using Fun.prems(2) by auto
next
case False
then obtain S where "Fun f S \<in> subterms k'" "Fun f T' = Fun f S \<cdot> (!) T"
using k'(2) Fun.prems(4) subterm_subst_not_img_subterm by force
thus ?thesis using Ana\<^sub>f_assm1_alt[OF 1, of "Fun f S"] k'(1) by (cases f) auto
qed
qed simp
lemma assm4:
assumes "Ana (Fun f T) = (K, M)"
shows "set M \<subseteq> set T"
using assms
proof (cases f)
case (Fu g)
obtain K' M' where *: "Ana\<^sub>f g = (K',M')" by moura
have "M = [] \<or> (arity\<^sub>f g = length T \<and> M = map ((!) T) M')"
using Ana_Fu_cases(1)[OF assms Fu *]
by (meson prod.inject)
thus ?thesis using Ana\<^sub>f_assm2_alt[OF *] by auto
qed auto
lemma assm5: "Ana t = (K,M) \<Longrightarrow> K \<noteq> [] \<or> M \<noteq> [] \<Longrightarrow> Ana (t \<cdot> \<delta>) = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>, M \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>)"
proof (induction t rule: term.induct)
case (Fun f T) thus ?case
proof (cases f)
case (Fu g)
obtain K' M' where *: "Ana\<^sub>f g = (K',M')" by moura
have **: "K = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T" "M = map ((!) T) M'"
"arity\<^sub>f g = length T" "\<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K') \<union> set M'. i < arity\<^sub>f g" "0 < arity\<^sub>f g"
using Fun.prems(2) Ana_Fu_cases(1)[OF Fun.prems(1) Fu *] Ana\<^sub>f_assm2_alt[OF *]
by (meson prod.inject)+
have ***: "\<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K'). i < length T" "\<forall>i \<in> set M'. i < length T" using **(3,4) by auto
have "K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta> = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) (map (\<lambda>t. t \<cdot> \<delta>) T)"
"M \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta> = map ((!) (map (\<lambda>t. t \<cdot> \<delta>) T)) M'"
using subst_idx_map[OF ***(2), of \<delta>]
subst_idx_map'[OF ***(1), of \<delta>]
**(1,2)
by fast+
thus ?thesis using Fu * **(3,5) by auto
qed auto
qed simp
sublocale intruder_model arity public Ana
apply unfold_locales
by (metis assm1, metis assm2, rule Ana.simps, metis assm4, metis assm5)
adhoc_overloading INTRUDER_SYNTH intruder_synth
adhoc_overloading INTRUDER_DEDUCT intruder_deduct
lemma assm6: "arity c = 0 \<Longrightarrow> \<exists>a. \<forall>X. \<Gamma> (Fun c X) = TAtom a" by (cases c) auto
lemma assm7: "0 < arity f \<Longrightarrow> \<Gamma> (Fun f T) = TComp f (map \<Gamma> T)" by auto
lemma assm8: "infinite {c. \<Gamma> (Fun c []::('fun,'atom,'sets) prot_term) = TAtom a \<and> public c}"
(is "?P a")
proof -
let ?T = "\<lambda>f. (range f)::('fun,'atom,'sets) prot_fun set"
let ?A = "\<lambda>f. \<forall>x::nat \<in> UNIV. \<forall>y::nat \<in> UNIV. (f x = f y) = (x = y)"
let ?B = "\<lambda>f. \<forall>x::nat \<in> UNIV. f x \<in> ?T f"
let ?C = "\<lambda>f. \<forall>y::('fun,'atom,'sets) prot_fun \<in> ?T f. \<exists>x \<in> UNIV. y = f x"
let ?D = "\<lambda>f b. ?T f \<subseteq> {c. \<Gamma> (Fun c []::('fun,'atom,'sets) prot_term) = TAtom b \<and> public c}"
have sub_lmm: "?P b" when "?A f" "?C f" "?C f" "?D f b" for b f
proof -
have "\<exists>g::nat \<Rightarrow> ('fun,'atom,'sets) prot_fun. bij_betw g UNIV (?T f)"
using bij_betwI'[of UNIV f "?T f"] that(1,2,3) by blast
hence "infinite (?T f)" by (metis nat_not_finite bij_betw_finite)
thus ?thesis using infinite_super[OF that(4)] by blast
qed
show ?thesis
proof (cases a)
case (Atom b) thus ?thesis using sub_lmm[of "PubConstAtom b" a] by force
next
case Value thus ?thesis using sub_lmm[of "\<lambda>n. Val (n,True)" a] by force
next
case SetType thus ?thesis using sub_lmm[of PubConstSetType a] by fastforce
next
case AttackType thus ?thesis using sub_lmm[of PubConstAttackType a] by fastforce
next
case Bottom thus ?thesis using sub_lmm[of PubConstBottom a] by fastforce
next
case OccursSecType thus ?thesis using sub_lmm[of PubConstOccursSecType a] by fastforce
qed
qed
lemma assm9: "TComp f T \<sqsubseteq> \<Gamma> t \<Longrightarrow> arity f > 0"
proof (induction t rule: term.induct)
case (Var x)
hence "\<Gamma> (Var x) \<noteq> TAtom Bottom" by force
hence "\<forall>t \<in> subterms (fst x). case t of
TComp f T \<Rightarrow> arity f > 0 \<and> arity f = length T
| _ \<Rightarrow> True"
using Var \<Gamma>.simps(1)[of x] unfolding \<Gamma>\<^sub>v_def by meson
thus ?case using Var by (fastforce simp add: \<Gamma>\<^sub>v_def)
next
case (Fun g S)
have "arity g \<noteq> 0" using Fun.prems Var_subtermeq assm6 by force
thus ?case using Fun by (cases "TComp f T = TComp g (map \<Gamma> S)") auto
qed
lemma assm10: "wf\<^sub>t\<^sub>r\<^sub>m (\<Gamma> (Var x))"
unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by (auto simp add: \<Gamma>\<^sub>v_def)
lemma assm11: "arity f > 0 \<Longrightarrow> public f" using public\<^sub>f_assm by (cases f) auto
lemma assm12: "\<Gamma> (Var (\<tau>, n)) = \<Gamma> (Var (\<tau>, m))" by (simp add: \<Gamma>\<^sub>v_def)
lemma assm13: "arity c = 0 \<Longrightarrow> Ana (Fun c T) = ([],[])" by (cases c) simp_all
lemma assm14:
assumes "Ana (Fun f T) = (K,M)"
shows "Ana (Fun f T \<cdot> \<delta>) = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>, M \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>)"
proof -
show ?thesis
proof (cases "(K, M) = ([],[])")
case True
{ fix g assume f: "f = Fu g"
obtain K' M' where "Ana\<^sub>f g = (K',M')" by moura
hence ?thesis using assms f True by auto
} thus ?thesis using True assms by (cases f) auto
next
case False
then obtain g where **: "f = Fu g" using assms by (cases f) auto
obtain K' M' where *: "Ana\<^sub>f g = (K',M')" by moura
have ***: "K = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T" "M = map ((!) T) M'" "arity\<^sub>f g = length T"
"\<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K') \<union> set M'. i < arity\<^sub>f g"
using Ana_Fu_cases(1)[OF assms ** *] False Ana\<^sub>f_assm2_alt[OF *]
by (meson prod.inject)+
have ****: "\<forall>i\<in>fv\<^sub>s\<^sub>e\<^sub>t (set K'). i < length T" "\<forall>i\<in>set M'. i < length T" using ***(3,4) by auto
have "K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta> = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) (map (\<lambda>t. t \<cdot> \<delta>) T)"
"M \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta> = map ((!) (map (\<lambda>t. t \<cdot> \<delta>) T)) M'"
using subst_idx_map[OF ****(2), of \<delta>]
subst_idx_map'[OF ****(1), of \<delta>]
***(1,2)
by auto
thus ?thesis using assms * ** ***(3) by auto
qed
qed
sublocale labeled_stateful_typed_model' arity public Ana \<Gamma> Pair label_witness1 label_witness2
by unfold_locales
(metis assm6, metis assm7, metis assm8, metis assm9,
rule assm10, metis assm11, rule arity.simps(5), metis assm14,
metis assm12, metis assm13, metis assm14, rule label_witness_assm)
subsection \<open>Minor Lemmata\<close>
lemma \<Gamma>\<^sub>v_TAtom[simp]: "\<Gamma>\<^sub>v (TAtom a, n) = TAtom a"
unfolding \<Gamma>\<^sub>v_def by simp
lemma \<Gamma>\<^sub>v_TAtom':
assumes "a \<noteq> Bottom"
shows "\<Gamma>\<^sub>v (\<tau>, n) = TAtom a \<longleftrightarrow> \<tau> = TAtom a"
proof
assume "\<Gamma>\<^sub>v (\<tau>, n) = TAtom a"
thus "\<tau> = TAtom a" by (metis (no_types, lifting) assms \<Gamma>\<^sub>v_def fst_conv term.inject(1))
qed simp
lemma \<Gamma>\<^sub>v_TAtom_inv:
"\<Gamma>\<^sub>v x = TAtom (Atom a) \<Longrightarrow> \<exists>m. x = (TAtom (Atom a), m)"
"\<Gamma>\<^sub>v x = TAtom Value \<Longrightarrow> \<exists>m. x = (TAtom Value, m)"
"\<Gamma>\<^sub>v x = TAtom SetType \<Longrightarrow> \<exists>m. x = (TAtom SetType, m)"
"\<Gamma>\<^sub>v x = TAtom AttackType \<Longrightarrow> \<exists>m. x = (TAtom AttackType, m)"
"\<Gamma>\<^sub>v x = TAtom OccursSecType \<Longrightarrow> \<exists>m. x = (TAtom OccursSecType, m)"
by (metis \<Gamma>\<^sub>v_TAtom' surj_pair prot_atom.distinct(7),
metis \<Gamma>\<^sub>v_TAtom' surj_pair prot_atom.distinct(15),
metis \<Gamma>\<^sub>v_TAtom' surj_pair prot_atom.distinct(21),
metis \<Gamma>\<^sub>v_TAtom' surj_pair prot_atom.distinct(25),
metis \<Gamma>\<^sub>v_TAtom' surj_pair prot_atom.distinct(30))
lemma \<Gamma>\<^sub>v_TAtom'':
"(fst x = TAtom (Atom a)) = (\<Gamma>\<^sub>v x = TAtom (Atom a))" (is "?A = ?A'")
"(fst x = TAtom Value) = (\<Gamma>\<^sub>v x = TAtom Value)" (is "?B = ?B'")
"(fst x = TAtom SetType) = (\<Gamma>\<^sub>v x = TAtom SetType)" (is "?C = ?C'")
"(fst x = TAtom AttackType) = (\<Gamma>\<^sub>v x = TAtom AttackType)" (is "?D = ?D'")
"(fst x = TAtom OccursSecType) = (\<Gamma>\<^sub>v x = TAtom OccursSecType)" (is "?E = ?E'")
proof -
have 1: "?A \<Longrightarrow> ?A'" "?B \<Longrightarrow> ?B'" "?C \<Longrightarrow> ?C'" "?D \<Longrightarrow> ?D'" "?E \<Longrightarrow> ?E'"
by (metis \<Gamma>\<^sub>v_TAtom prod.collapse)+
have 2: "?A' \<Longrightarrow> ?A" "?B' \<Longrightarrow> ?B" "?C' \<Longrightarrow> ?C" "?D' \<Longrightarrow> ?D" "?E' \<Longrightarrow> ?E"
using \<Gamma>\<^sub>v_TAtom \<Gamma>\<^sub>v_TAtom_inv(1) apply fastforce
using \<Gamma>\<^sub>v_TAtom \<Gamma>\<^sub>v_TAtom_inv(2) apply fastforce
using \<Gamma>\<^sub>v_TAtom \<Gamma>\<^sub>v_TAtom_inv(3) apply fastforce
using \<Gamma>\<^sub>v_TAtom \<Gamma>\<^sub>v_TAtom_inv(4) apply fastforce
using \<Gamma>\<^sub>v_TAtom \<Gamma>\<^sub>v_TAtom_inv(5) by fastforce
show "?A = ?A'" "?B = ?B'" "?C = ?C'" "?D = ?D'" "?E = ?E'"
using 1 2 by metis+
qed
lemma \<Gamma>\<^sub>v_Var_image:
"\<Gamma>\<^sub>v ` X = \<Gamma> ` Var ` X"
by force
lemma \<Gamma>_Fu_const:
assumes "arity\<^sub>f g = 0"
shows "\<exists>a. \<Gamma> (Fun (Fu g) T) = TAtom (Atom a)"
proof -
have "\<Gamma>\<^sub>f g \<noteq> None" using assms \<Gamma>\<^sub>f_assm by blast
thus ?thesis using assms by force
qed
lemma Fun_Value_type_inv:
fixes T::"('fun,'atom,'sets) prot_term list"
assumes "\<Gamma> (Fun f T) = TAtom Value"
shows "(\<exists>n. f = Val n) \<or> (\<exists>bs. f = Abs bs)"
proof -
have *: "arity f = 0" by (metis const_type_inv assms)
show ?thesis using assms
proof (cases f)
case (Fu g)
hence "arity\<^sub>f g = 0" using * by simp
hence False using Fu \<Gamma>_Fu_const[of g T] assms by auto
thus ?thesis by metis
next
case (Set s)
hence "arity\<^sub>s s = 0" using * by simp
hence False using Set assms by auto
thus ?thesis by metis
qed simp_all
qed
lemma abs_\<Gamma>: "\<Gamma> t = \<Gamma> (t \<cdot>\<^sub>\<alpha> \<alpha>)"
by (induct t \<alpha> rule: abs_apply_term.induct) auto
lemma Ana\<^sub>f_keys_not_pubval_terms:
assumes "Ana\<^sub>f f = (K, T)"
and "k \<in> set K"
and "g \<in> funs_term k"
shows "\<not>is_Val g"
proof
assume "is_Val g"
then obtain n S where *: "Fun (Val n) S \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K)"
using assms(2) funs_term_Fun_subterm[OF assms(3)]
by (cases g) auto
show False using Ana\<^sub>f_assm1_alt[OF assms(1) *] by simp
qed
lemma Ana\<^sub>f_keys_not_abs_terms:
assumes "Ana\<^sub>f f = (K, T)"
and "k \<in> set K"
and "g \<in> funs_term k"
shows "\<not>is_Abs g"
proof
assume "is_Abs g"
then obtain a S where *: "Fun (Abs a) S \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K)"
using assms(2) funs_term_Fun_subterm[OF assms(3)]
by (cases g) auto
show False using Ana\<^sub>f_assm1_alt[OF assms(1) *] by simp
qed
lemma Ana\<^sub>f_keys_not_pairs:
assumes "Ana\<^sub>f f = (K, T)"
and "k \<in> set K"
and "g \<in> funs_term k"
shows "g \<noteq> Pair"
proof
assume "g = Pair"
then obtain S where *: "Fun Pair S \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K)"
using assms(2) funs_term_Fun_subterm[OF assms(3)]
by (cases g) auto
show False using Ana\<^sub>f_assm1_alt[OF assms(1) *] by simp
qed
lemma Ana_Fu_keys_funs_term_subset:
fixes K::"('fun,'atom,'sets) prot_term list"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana\<^sub>f f = (K', T')"
shows "\<Union>(funs_term ` set K) \<subseteq> \<Union>(funs_term ` set K') \<union> funs_term (Fun (Fu f) S)"
proof -
{ fix k assume k: "k \<in> set K"
then obtain k' where k':
"k' \<in> set K'" "k = k' \<cdot> (!) S" "arity\<^sub>f f = length S"
"subterms k' \<subseteq> subterms\<^sub>s\<^sub>e\<^sub>t (set K')"
using assms Ana_Fu_elim[OF assms(1) _ assms(2)] by fastforce
have 1: "funs_term k' \<subseteq> \<Union>(funs_term ` set K')" using k'(1) by auto
have "i < length S" when "i \<in> fv k'" for i
using that Ana\<^sub>f_assm2_alt[OF assms(2), of i] k'(1,3)
by auto
hence 2: "funs_term (S ! i) \<subseteq> funs_term (Fun (Fu f) S)" when "i \<in> fv k'" for i
using that by force
have "funs_term k \<subseteq> \<Union>(funs_term ` set K') \<union> funs_term (Fun (Fu f) S)"
using funs_term_subst[of k' "(!) S"] k'(2) 1 2 by fast
} thus ?thesis by blast
qed
lemma Ana_Fu_keys_not_pubval_terms:
fixes k::"('fun,'atom,'sets) prot_term"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana\<^sub>f f = (K', T')"
and "k \<in> set K"
and "\<forall>g \<in> funs_term (Fun (Fu f) S). is_Val g \<longrightarrow> \<not>public g"
shows "\<forall>g \<in> funs_term k. is_Val g \<longrightarrow> \<not>public g"
using assms(3,4) Ana\<^sub>f_keys_not_pubval_terms[OF assms(2)]
Ana_Fu_keys_funs_term_subset[OF assms(1,2)]
by blast
lemma Ana_Fu_keys_not_abs_terms:
fixes k::"('fun,'atom,'sets) prot_term"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana\<^sub>f f = (K', T')"
and "k \<in> set K"
and "\<forall>g \<in> funs_term (Fun (Fu f) S). \<not>is_Abs g"
shows "\<forall>g \<in> funs_term k. \<not>is_Abs g"
using assms(3,4) Ana\<^sub>f_keys_not_abs_terms[OF assms(2)]
Ana_Fu_keys_funs_term_subset[OF assms(1,2)]
by blast
lemma Ana_Fu_keys_not_pairs:
fixes k::"('fun,'atom,'sets) prot_term"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana\<^sub>f f = (K', T')"
and "k \<in> set K"
and "\<forall>g \<in> funs_term (Fun (Fu f) S). g \<noteq> Pair"
shows "\<forall>g \<in> funs_term k. g \<noteq> Pair"
using assms(3,4) Ana\<^sub>f_keys_not_pairs[OF assms(2)]
Ana_Fu_keys_funs_term_subset[OF assms(1,2)]
by blast
lemma deduct_occurs_in_ik:
fixes t::"('fun,'atom,'sets) prot_term"
assumes t: "M \<turnstile> occurs t"
and M: "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t M. OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
"\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t M. OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
"Fun OccursSec [] \<notin> M"
shows "occurs t \<in> M"
using private_fun_deduct_in_ik''[of M OccursFact "[Fun OccursSec [], t]" OccursSec] t M
by fastforce
lemma wellformed_transaction_sem_receives:
fixes T::"('fun,'atom,'sets,'lbl) prot_transaction"
assumes T_valid: "wellformed_transaction T"
and \<I>: "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I>"
and s: "receive\<langle>t\<rangle> \<in> set (unlabel (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
shows "IK \<turnstile> t \<cdot> \<I>"
proof -
let ?R = "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S = "\<lambda>A. unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S' = "?S (transaction_receive T)"
obtain l B s where B:
"(l,send\<langle>t\<rangle>) = dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p ((l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>)"
"prefix ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>]) (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)"
using s dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(2)[of t "transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>"]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_in_set_prefix_obtain_subst[of "send\<langle>t\<rangle>" "transaction_receive T" \<theta>]
by blast
have 1: "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>])) = unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[send\<langle>t\<rangle>]"
using B(1) unlabel_append dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_subst dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst singleton_lst_proj(4)
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps )
have "strand_sem_stateful IK DB ?S' \<I>"
using \<I> strand_sem_append_stateful[of IK DB _ _ \<I>] transaction_dual_subst_unfold[of T \<theta>]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[send\<langle>t\<rangle>]) \<I>"
using B 1 unfolding prefix_def unlabel_def
by (metis dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def map_append strand_sem_append_stateful)
hence t_deduct: "IK \<union> (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<turnstile> t \<cdot> \<I>"
using strand_sem_append_stateful[of IK DB "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" "[send\<langle>t\<rangle>]" \<I>]
by simp
have "\<forall>s \<in> set (unlabel (transaction_receive T)). \<exists>t. s = receive\<langle>t\<rangle>"
using T_valid wellformed_transaction_unlabel_cases(1)[OF T_valid] by auto
moreover { fix A::"('fun,'atom,'sets,'lbl) prot_strand" and \<theta>
assume "\<forall>s \<in> set (unlabel A). \<exists>t. s = receive\<langle>t\<rangle>"
hence "\<forall>s \<in> set (unlabel (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). \<exists>t. s = receive\<langle>t\<rangle>"
proof (induction A)
case (Cons a A) thus ?case using subst_lsst_cons[of a A \<theta>] by (cases a) auto
qed simp
hence "\<forall>s \<in> set (unlabel (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). \<exists>t. s = receive\<langle>t\<rangle>"
by (simp add: list.pred_set is_Receive_def)
hence "\<forall>s \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). \<exists>t. s = send\<langle>t\<rangle>"
by (metis dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_memberD dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_inv(2) unlabel_in unlabel_mem_has_label)
}
ultimately have "\<forall>s \<in> set ?R. \<exists>t. s = send\<langle>t\<rangle>" by simp
hence "ik\<^sub>s\<^sub>s\<^sub>t ?R = {}" unfolding unlabel_def ik\<^sub>s\<^sub>s\<^sub>t_def by fast
hence "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) = {}"
using B(2) 1 ik\<^sub>s\<^sub>s\<^sub>t_append dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_append
by (metis (no_types, lifting) Un_empty map_append prefix_def unlabel_def)
thus ?thesis using t_deduct by simp
qed
lemma wellformed_transaction_sem_selects:
assumes T_valid: "wellformed_transaction T"
and \<I>: "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I>"
and "select\<langle>t,u\<rangle> \<in> set (unlabel (transaction_selects T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
shows "(t \<cdot> \<I>, u \<cdot> \<I>) \<in> DB"
proof -
let ?s = "select\<langle>t,u\<rangle>"
let ?R = "transaction_receive T@transaction_selects T"
let ?R' = "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S = "\<lambda>A. unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S' = "?S (transaction_receive T)@?S (transaction_selects T)"
let ?P = "\<lambda>a. is_Receive a \<or> is_Assignment a"
let ?Q = "\<lambda>a. is_Send a \<or> is_Assignment a"
have s: "?s \<in> set (unlabel (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using assms(3) subst_lsst_append[of "transaction_receive T"]
unlabel_append[of "transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>"]
by auto
obtain l B s where B:
"(l,?s) = dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p ((l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>)"
"prefix ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>]) (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)"
using s dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(6)[of assign t u]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_in_set_prefix_obtain_subst[of ?s ?R \<theta>]
by blast
have 1: "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>])) = unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[?s]"
using B(1) unlabel_append dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_subst dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst singleton_lst_proj(4)
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps)
have "strand_sem_stateful IK DB ?S' \<I>"
using \<I> strand_sem_append_stateful[of IK DB _ _ \<I>] transaction_dual_subst_unfold[of T \<theta>]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[?s]) \<I>"
using B 1 strand_sem_append_stateful subst_lsst_append
unfolding prefix_def unlabel_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def
by (metis (no_types) map_append)
hence in_db: "(t \<cdot> \<I>, u \<cdot> \<I>) \<in> dbupd\<^sub>s\<^sub>s\<^sub>t (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I> DB"
using strand_sem_append_stateful[of IK DB "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" "[?s]" \<I>]
by simp
have "\<forall>a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). ?Q a"
proof
fix a assume a: "a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
have "\<forall>a \<in> set (unlabel ?R). ?P a"
using wellformed_transaction_unlabel_cases(1)[OF T_valid]
wellformed_transaction_unlabel_cases(2)[OF T_valid]
unfolding unlabel_def
by fastforce
hence "\<forall>a \<in> set (unlabel (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). ?P a"
using stateful_strand_step_cases_subst(2,8)[of _ \<theta>] subst_lsst_unlabel[of ?R \<theta>]
by (simp add: subst_apply_stateful_strand_def del: unlabel_append)
hence B_P: "\<forall>a \<in> set (unlabel (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). ?P a"
using unlabel_mono[OF set_mono_prefix[OF append_prefixD[OF B(2)]]]
by blast
obtain l where "(l,a) \<in> set (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using a by (meson unlabel_mem_has_label)
then obtain b where b: "(l,b) \<in> set (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)" "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (l,b) = (l,a)"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_memberD by blast
hence "?P b" using B_P unfolding unlabel_def by fastforce
thus "?Q a" using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_inv[OF b(2)] by (cases b) auto
qed
hence "\<forall>a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). \<not>is_Insert a \<and> \<not>is_Delete a" by fastforce
thus ?thesis using dbupd\<^sub>s\<^sub>s\<^sub>t_no_upd[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" \<I> DB] in_db by simp
qed
lemma wellformed_transaction_sem_pos_checks:
assumes T_valid: "wellformed_transaction T"
and \<I>: "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I>"
and "\<langle>t in u\<rangle> \<in> set (unlabel (transaction_checks T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
shows "(t \<cdot> \<I>, u \<cdot> \<I>) \<in> DB"
proof -
let ?s = "\<langle>t in u\<rangle>"
let ?R = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?R' = "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S = "\<lambda>A. unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S' = "?S (transaction_receive T)@?S (transaction_selects T)@?S (transaction_checks T)"
let ?P = "\<lambda>a. is_Receive a \<or> is_Assignment a \<or> is_Check a"
let ?Q = "\<lambda>a. is_Send a \<or> is_Assignment a \<or> is_Check a"
have s: "?s \<in> set (unlabel (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using assms(3) subst_lsst_append[of "transaction_receive T@transaction_selects T"]
unlabel_append[of "transaction_receive T@transaction_selects T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>"]
by auto
obtain l B s where B:
"(l,?s) = dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p ((l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>)"
"prefix ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>]) (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)"
using s dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(6)[of check t u]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_in_set_prefix_obtain_subst[of ?s ?R \<theta>]
by blast
have 1: "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>])) = unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[?s]"
using B(1) unlabel_append dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_subst dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst singleton_lst_proj(4)
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps )
have "strand_sem_stateful IK DB ?S' \<I>"
using \<I> strand_sem_append_stateful[of IK DB _ _ \<I>] transaction_dual_subst_unfold[of T \<theta>]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[?s]) \<I>"
using B 1 strand_sem_append_stateful subst_lsst_append
unfolding prefix_def unlabel_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def
by (metis (no_types) map_append)
hence in_db: "(t \<cdot> \<I>, u \<cdot> \<I>) \<in> dbupd\<^sub>s\<^sub>s\<^sub>t (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I> DB"
using strand_sem_append_stateful[of IK DB "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" "[?s]" \<I>]
by simp
have "\<forall>a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). ?Q a"
proof
fix a assume a: "a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
have "\<forall>a \<in> set (unlabel ?R). ?P a"
using wellformed_transaction_unlabel_cases(1,2,3)[OF T_valid]
unfolding unlabel_def
by fastforce
hence "\<forall>a \<in> set (unlabel (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). ?P a"
using stateful_strand_step_cases_subst(2,8,9)[of _ \<theta>] subst_lsst_unlabel[of ?R \<theta>]
by (simp add: subst_apply_stateful_strand_def del: unlabel_append)
hence B_P: "\<forall>a \<in> set (unlabel (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). ?P a"
using unlabel_mono[OF set_mono_prefix[OF append_prefixD[OF B(2)]]]
by blast
obtain l where "(l,a) \<in> set (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using a by (meson unlabel_mem_has_label)
then obtain b where b: "(l,b) \<in> set (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)" "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (l,b) = (l,a)"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_memberD by blast
hence "?P b" using B_P unfolding unlabel_def by fastforce
thus "?Q a" using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_inv[OF b(2)] by (cases b) auto
qed
hence "\<forall>a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). \<not>is_Insert a \<and> \<not>is_Delete a" by fastforce
thus ?thesis using dbupd\<^sub>s\<^sub>s\<^sub>t_no_upd[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" \<I> DB] in_db by simp
qed
lemma wellformed_transaction_sem_neg_checks:
assumes T_valid: "wellformed_transaction T"
and \<I>: "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I>"
and "NegChecks X [] [(t,u)] \<in> set (unlabel (transaction_checks T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
shows "\<forall>\<delta>. subst_domain \<delta> = set X \<and> ground (subst_range \<delta>) \<longrightarrow> (t \<cdot> \<delta> \<cdot> \<I>, u \<cdot> \<delta> \<cdot> \<I>) \<notin> DB" (is ?A)
and "X = [] \<Longrightarrow> (t \<cdot> \<I>, u \<cdot> \<I>) \<notin> DB" (is "?B \<Longrightarrow> ?B'")
proof -
let ?s = "NegChecks X [] [(t,u)]"
let ?R = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?R' = "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S = "\<lambda>A. unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
let ?S' = "?S (transaction_receive T)@?S (transaction_selects T)@?S (transaction_checks T)"
let ?P = "\<lambda>a. is_Receive a \<or> is_Assignment a \<or> is_Check a"
let ?Q = "\<lambda>a. is_Send a \<or> is_Assignment a \<or> is_Check a"
let ?U = "\<lambda>\<delta>. subst_domain \<delta> = set X \<and> ground (subst_range \<delta>)"
have s: "?s \<in> set (unlabel (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using assms(3) subst_lsst_append[of "transaction_receive T@transaction_selects T"]
unlabel_append[of "transaction_receive T@transaction_selects T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>"]
by auto
obtain l B s where B:
"(l,?s) = dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p ((l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>)"
"prefix ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>]) (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)"
using s dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(7)[of X "[]" "[(t,u)]"]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_in_set_prefix_obtain_subst[of ?s ?R \<theta>]
by blast
have 1: "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)@[(l,s) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>])) = unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[?s]"
using B(1) unlabel_append dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_subst dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst singleton_lst_proj(4)
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps)
have "strand_sem_stateful IK DB ?S' \<I>"
using \<I> strand_sem_append_stateful[of IK DB _ _ \<I>] transaction_dual_subst_unfold[of T \<theta>]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))@[?s]) \<I>"
using B 1 strand_sem_append_stateful subst_lsst_append
unfolding prefix_def unlabel_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def
by (metis (no_types) map_append)
hence "negchecks_model \<I> (dbupd\<^sub>s\<^sub>s\<^sub>t (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I> DB) X [] [(t,u)]"
using strand_sem_append_stateful[of IK DB "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" "[?s]" \<I>]
by fastforce
hence in_db: "\<forall>\<delta>. ?U \<delta> \<longrightarrow> (t \<cdot> \<delta> \<cdot> \<I>, u \<cdot> \<delta> \<cdot> \<I>) \<notin> dbupd\<^sub>s\<^sub>s\<^sub>t (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I> DB"
unfolding negchecks_model_def
by simp
have "\<forall>a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). ?Q a"
proof
fix a assume a: "a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
have "\<forall>a \<in> set (unlabel ?R). ?P a"
using wellformed_transaction_unlabel_cases(1,2,3)[OF T_valid]
unfolding unlabel_def
by fastforce
hence "\<forall>a \<in> set (unlabel (?R \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). ?P a"
using stateful_strand_step_cases_subst(2,8,9)[of _ \<theta>] subst_lsst_unlabel[of ?R \<theta>]
by (simp add: subst_apply_stateful_strand_def del: unlabel_append)
hence B_P: "\<forall>a \<in> set (unlabel (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)). ?P a"
using unlabel_mono[OF set_mono_prefix[OF append_prefixD[OF B(2)]]]
by blast
obtain l where "(l,a) \<in> set (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using a by (meson unlabel_mem_has_label)
then obtain b where b: "(l,b) \<in> set (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)" "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (l,b) = (l,a)"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_memberD by blast
hence "?P b" using B_P unfolding unlabel_def by fastforce
thus "?Q a" using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_inv[OF b(2)] by (cases b) auto
qed
hence "\<forall>a \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))). \<not>is_Insert a \<and> \<not>is_Delete a" by fastforce
thus ?A using dbupd\<^sub>s\<^sub>s\<^sub>t_no_upd[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (B \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" \<I> DB] in_db by simp
moreover have "\<delta> = Var" "t \<cdot> \<delta> = t"
when "subst_domain \<delta> = set []" for t and \<delta>::"('fun, 'atom, 'sets) prot_subst"
using that by auto
moreover have "subst_domain Var = set []" "range_vars Var = {}"
by simp_all
ultimately show "?B \<Longrightarrow> ?B'" unfolding range_vars_alt_def by metis
qed
lemma wellformed_transaction_fv_in_receives_or_selects:
assumes T: "wellformed_transaction T"
and x: "x \<in> fv_transaction T" "x \<notin> set (transaction_fresh T)"
shows "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T) \<union> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
proof -
have "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T) \<union> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T) \<union>
fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T) \<union> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_updates T) \<union>
fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)"
using x(1) fv\<^sub>s\<^sub>s\<^sub>t_append unlabel_append
by (metis transaction_strand_def append_assoc)
thus ?thesis using T x(2) unfolding wellformed_transaction_def by blast
qed
lemma dual_transaction_ik_is_transaction_send'':
fixes \<delta> \<I>::"('a,'b,'c) prot_subst"
assumes "wellformed_transaction T"
shows "(ik\<^sub>s\<^sub>s\<^sub>t (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>))) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a =
(trms\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<delta> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a" (is "?A = ?B")
using dual_transaction_ik_is_transaction_send[OF assms]
subst_lsst_unlabel[of "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)" \<delta>]
ik\<^sub>s\<^sub>s\<^sub>t_subst[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T))" \<delta>]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst[of "transaction_strand T" \<delta>]
by (auto simp add: abs_apply_terms_def)
lemma while_prot_terms_fun_mono:
"mono (\<lambda>M'. M \<union> \<Union>(subterms ` M') \<union> \<Union>((set \<circ> fst \<circ> Ana) ` M'))"
unfolding mono_def by fast
lemma while_prot_terms_SMP_overapprox:
fixes M::"('fun,'atom,'sets) prot_terms"
assumes N_supset: "M \<union> \<Union>(subterms ` N) \<union> \<Union>((set \<circ> fst \<circ> Ana) ` N) \<subseteq> N"
and Value_vars_only: "\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t N. \<Gamma>\<^sub>v x = TAtom Value"
shows "SMP M \<subseteq> {a \<cdot> \<delta> | a \<delta>. a \<in> N \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)}"
proof -
define f where "f \<equiv> \<lambda>M'. M \<union> \<Union>(subterms ` M') \<union> \<Union>((set \<circ> fst \<circ> Ana) ` M')"
define S where "S \<equiv> {a \<cdot> \<delta> | a \<delta>. a \<in> N \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)}"
note 0 = Value_vars_only
have "t \<in> S" when "t \<in> SMP M" for t
using that
proof (induction t rule: SMP.induct)
case (MP t)
hence "t \<in> N" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t Var" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range Var)" using N_supset by auto
hence "t \<cdot> Var \<in> S" unfolding S_def by blast
thus ?case by simp
next
case (Subterm t t')
then obtain \<delta> a where a: "a \<cdot> \<delta> = t" "a \<in> N" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
by (auto simp add: S_def)
hence "\<forall>x \<in> fv a. \<exists>\<tau>. \<Gamma> (Var x) = TAtom \<tau>" using 0 by auto
hence *: "\<forall>x \<in> fv a. (\<exists>f. \<delta> x = Fun f []) \<or> (\<exists>y. \<delta> x = Var y)"
using a(3) TAtom_term_cases[OF wf_trm_subst_rangeD[OF a(4)]]
by (metis wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def)
obtain b where b: "b \<cdot> \<delta> = t'" "b \<in> subterms a"
using subterms_subst_subterm[OF *, of t'] Subterm.hyps(2) a(1)
by fast
hence "b \<in> N" using N_supset a(2) by blast
thus ?case using a b(1) unfolding S_def by blast
next
case (Substitution t \<theta>)
then obtain \<delta> a where a: "a \<cdot> \<delta> = t" "a \<in> N" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
by (auto simp add: S_def)
have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<delta> \<circ>\<^sub>s \<theta>)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<delta> \<circ>\<^sub>s \<theta>))"
by (fact wt_subst_compose[OF a(3) Substitution.hyps(2)],
fact wf_trms_subst_compose[OF a(4) Substitution.hyps(3)])
moreover have "t \<cdot> \<theta> = a \<cdot> \<delta> \<circ>\<^sub>s \<theta>" using a(1) subst_subst_compose[of a \<delta> \<theta>] by simp
ultimately show ?case using a(2) unfolding S_def by blast
next
case (Ana t K T k)
then obtain \<delta> a where a: "a \<cdot> \<delta> = t" "a \<in> N" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
by (auto simp add: S_def)
obtain Ka Ta where a': "Ana a = (Ka,Ta)" by moura
have *: "K = Ka \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>"
proof (cases a)
case (Var x)
then obtain g U where gU: "t = Fun g U"
using a(1) Ana.hyps(2,3) Ana_var
by (cases t) simp_all
have "\<Gamma> (Var x) = TAtom Value" using Var a(2) 0 by auto
hence "\<Gamma> (Fun g U) = TAtom Value"
using a(1,3) Var gU wt_subst_trm''[OF a(3), of a]
by argo
thus ?thesis using gU Fun_Value_type_inv Ana.hyps(2,3) by fastforce
next
case (Fun g U) thus ?thesis using a(1) a' Ana.hyps(2) Ana_subst'[of g U] by simp
qed
then obtain ka where ka: "k = ka \<cdot> \<delta>" "ka \<in> set Ka" using Ana.hyps(3) by auto
have "ka \<in> set ((fst \<circ> Ana) a)" using ka(2) a' by simp
hence "ka \<in> N" using a(2) N_supset by auto
thus ?case using ka a(3,4) unfolding S_def by blast
qed
thus ?thesis unfolding S_def by blast
qed
subsection \<open>The Protocol Transition System, Defined in Terms of the Reachable Constraints\<close>
definition transaction_fresh_subst where
"transaction_fresh_subst \<sigma> T \<A> \<equiv>
subst_domain \<sigma> = set (transaction_fresh T) \<and>
(\<forall>t \<in> subst_range \<sigma>. \<exists>n. t = Fun (Val (n,False)) []) \<and>
(\<forall>t \<in> subst_range \<sigma>. t \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)) \<and>
(\<forall>t \<in> subst_range \<sigma>. t \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms_transaction T)) \<and>
inj_on \<sigma> (subst_domain \<sigma>)"
(* NB: We need the protocol P as a parameter for this definition---even though we will only apply \<alpha>
to a single transaction T of P---because we have to ensure that \<alpha>(fv(T)) is disjoint from
the bound variables of P and \<A>. *)
definition transaction_renaming_subst where
"transaction_renaming_subst \<alpha> P \<A> \<equiv>
\<exists>n \<ge> max_var_set (\<Union>(vars_transaction ` set P) \<union> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). \<alpha> = var_rename n"
definition constraint_model where
"constraint_model \<I> \<A> \<equiv>
constr_sem_stateful \<I> (unlabel \<A>) \<and>
interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I> \<and>
wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)"
definition welltyped_constraint_model where
"welltyped_constraint_model \<I> \<A> \<equiv> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I> \<and> constraint_model \<I> \<A>"
lemma constraint_model_prefix:
assumes "constraint_model I (A@B)"
shows "constraint_model I A"
by (metis assms strand_sem_append_stateful unlabel_append constraint_model_def)
lemma welltyped_constraint_model_prefix:
assumes "welltyped_constraint_model I (A@B)"
shows "welltyped_constraint_model I A"
by (metis assms constraint_model_prefix welltyped_constraint_model_def)
lemma constraint_model_Val_is_Value_term:
assumes "welltyped_constraint_model I A"
and "t \<cdot> I = Fun (Val n) []"
shows "t = Fun (Val n) [] \<or> (\<exists>m. t = Var (TAtom Value, m))"
proof -
have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t I" using assms(1) unfolding welltyped_constraint_model_def by simp
moreover have "\<Gamma> (Fun (Val n) []) = TAtom Value" by auto
ultimately have *: "\<Gamma> t = TAtom Value" by (metis (no_types) assms(2) wt_subst_trm'')
show ?thesis
proof (cases t)
case (Var x)
obtain \<tau> m where x: "x = (\<tau>, m)" by (metis surj_pair)
have "\<Gamma>\<^sub>v x = TAtom Value" using * Var by auto
hence "\<tau> = TAtom Value" using x \<Gamma>\<^sub>v_TAtom'[of Value \<tau> m] by simp
thus ?thesis using x Var by metis
next
case (Fun f T) thus ?thesis using assms(2) by auto
qed
qed
text \<open>
The set of symbolic constraints reachable in any symbolic run of the protocol \<open>P\<close>.
\<open>\<sigma>\<close> instantiates the fresh variables of transaction \<open>T\<close> with fresh terms.
\<open>\<alpha>\<close> is a variable-renaming whose range consists of fresh variables.
\<close>
inductive_set reachable_constraints::
"('fun,'atom,'sets,'lbl) prot \<Rightarrow> ('fun,'atom,'sets,'lbl) prot_constr set"
for P::"('fun,'atom,'sets,'lbl) prot"
where
init:
"[] \<in> reachable_constraints P"
| step:
"\<lbrakk>\<A> \<in> reachable_constraints P;
T \<in> set P;
transaction_fresh_subst \<sigma> T \<A>;
transaction_renaming_subst \<alpha> P \<A>
\<rbrakk> \<Longrightarrow> \<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>) \<in> reachable_constraints P"
subsection \<open>Admissible Transactions\<close>
definition admissible_transaction_checks where
"admissible_transaction_checks T \<equiv>
\<forall>x \<in> set (unlabel (transaction_checks T)).
is_Check x \<and>
(is_InSet x \<longrightarrow>
is_Var (the_elem_term x) \<and> is_Fun_Set (the_set_term x) \<and>
fst (the_Var (the_elem_term x)) = TAtom Value) \<and>
(is_NegChecks x \<longrightarrow>
bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p x = [] \<and>
((the_eqs x = [] \<and> length (the_ins x) = 1) \<or>
(the_ins x = [] \<and> length (the_eqs x) = 1))) \<and>
(is_NegChecks x \<and> the_eqs x = [] \<longrightarrow> (let h = hd (the_ins x) in
is_Var (fst h) \<and> is_Fun_Set (snd h) \<and>
fst (the_Var (fst h)) = TAtom Value))"
definition admissible_transaction_selects where
"admissible_transaction_selects T \<equiv>
\<forall>x \<in> set (unlabel (transaction_selects T)).
is_InSet x \<and> the_check x = Assign \<and> is_Var (the_elem_term x) \<and> is_Fun_Set (the_set_term x) \<and>
fst (the_Var (the_elem_term x)) = TAtom Value"
definition admissible_transaction_updates where
"admissible_transaction_updates T \<equiv>
\<forall>x \<in> set (unlabel (transaction_updates T)).
is_Update x \<and> is_Var (the_elem_term x) \<and> is_Fun_Set (the_set_term x) \<and>
fst (the_Var (the_elem_term x)) = TAtom Value"
definition admissible_transaction_terms where
"admissible_transaction_terms T \<equiv>
wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)) \<and>
(\<forall>f \<in> \<Union>(funs_term ` trms_transaction T).
\<not>is_Val f \<and> \<not>is_Abs f \<and> \<not>is_PubConstSetType f \<and> f \<noteq> Pair \<and>
\<not>is_PubConstAttackType f \<and> \<not>is_PubConstBottom f \<and> \<not>is_PubConstOccursSecType f) \<and>
(\<forall>r \<in> set (unlabel (transaction_strand T)).
(\<exists>f \<in> \<Union>(funs_term ` (trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p r)). is_Attack f) \<longrightarrow>
(let t = the_msg r in is_Send r \<and> is_Fun t \<and> is_Attack (the_Fun t) \<and> args t = []))"
definition admissible_transaction_occurs_checks where
"admissible_transaction_occurs_checks T \<equiv> (
(\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow>
receive\<langle>occurs (Var x)\<rangle> \<in> set (unlabel (transaction_receive T))) \<and>
(\<forall>x \<in> set (transaction_fresh T). fst x = TAtom Value \<longrightarrow>
send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel (transaction_send T))) \<and>
(\<forall>r \<in> set (unlabel (transaction_receive T)). is_Receive r \<longrightarrow>
(OccursFact \<in> funs_term (the_msg r) \<or> OccursSec \<in> funs_term (the_msg r)) \<longrightarrow>
(\<exists>x \<in> fv_transaction T - set (transaction_fresh T).
fst x = TAtom Value \<and> the_msg r = occurs (Var x))) \<and>
(\<forall>r \<in> set (unlabel (transaction_send T)). is_Send r \<longrightarrow>
(OccursFact \<in> funs_term (the_msg r) \<or> OccursSec \<in> funs_term (the_msg r)) \<longrightarrow>
(\<exists>x \<in> set (transaction_fresh T).
fst x = TAtom Value \<and> the_msg r = occurs (Var x)))
)"
definition admissible_transaction where
"admissible_transaction T \<equiv> (
wellformed_transaction T \<and>
distinct (transaction_fresh T) \<and>
list_all (\<lambda>x. fst x = TAtom Value) (transaction_fresh T) \<and>
(\<forall>x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T). is_Var (fst x) \<and> (the_Var (fst x) = Value)) \<and>
bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) = {} \<and>
(\<forall>x \<in> fv_transaction T - set (transaction_fresh T).
\<forall>y \<in> fv_transaction T - set (transaction_fresh T).
x \<noteq> y \<longrightarrow> \<langle>Var x != Var y\<rangle> \<in> set (unlabel (transaction_checks T)) \<or>
\<langle>Var y != Var x\<rangle> \<in> set (unlabel (transaction_checks T))) \<and>
admissible_transaction_selects T \<and>
admissible_transaction_checks T \<and>
admissible_transaction_updates T \<and>
admissible_transaction_terms T \<and>
admissible_transaction_occurs_checks T
)"
lemma transaction_no_bvars:
assumes "admissible_transaction T"
shows "fv_transaction T = vars_transaction T"
and "bvars_transaction T = {}"
proof -
have "wellformed_transaction T" "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) = {}"
using assms unfolding admissible_transaction_def
by blast+
thus "bvars_transaction T = {}" "fv_transaction T = vars_transaction T"
using bvars_wellformed_transaction_unfold vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t
by fast+
qed
lemma transactions_fv_bvars_disj:
assumes "\<forall>T \<in> set P. admissible_transaction T"
shows "(\<Union>T \<in> set P. fv_transaction T) \<inter> (\<Union>T \<in> set P. bvars_transaction T) = {}"
using assms transaction_no_bvars(2) by fast
lemma transaction_bvars_no_Value_type:
assumes "admissible_transaction T"
and "x \<in> bvars_transaction T"
shows "\<not>TAtom Value \<sqsubseteq> \<Gamma>\<^sub>v x"
using assms transaction_no_bvars(2) by blast
lemma transaction_receive_deduct:
assumes T_adm: "admissible_transaction T"
and \<I>: "constraint_model \<I> (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
and \<sigma>: "transaction_fresh_subst \<sigma> T A"
and \<alpha>: "transaction_renaming_subst \<alpha> P A"
and t: "receive\<langle>t\<rangle> \<in> set (unlabel (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
shows "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<turnstile> t \<cdot> \<I>"
proof -
define \<theta> where "\<theta> \<equiv> \<sigma> \<circ>\<^sub>s \<alpha>"
have t': "send\<langle>t\<rangle> \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
using t dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(2) unfolding \<theta>_def by blast
then obtain T1 T2 where T: "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) = T1@send\<langle>t\<rangle>#T2"
using t' by (meson split_list)
have "constr_sem_stateful \<I> (unlabel A@unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
using \<I> unlabel_append[of A] unfolding constraint_model_def \<theta>_def by simp
hence "constr_sem_stateful \<I> (unlabel A@T1@[send\<langle>t\<rangle>])"
using strand_sem_append_stateful[of "{}" "{}" "unlabel A@T1@[send\<langle>t\<rangle>]" _ \<I>]
transaction_dual_subst_unfold[of T \<theta>] T
by (metis append.assoc append_Cons append_Nil)
hence "ik\<^sub>s\<^sub>s\<^sub>t (unlabel A@T1) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<turnstile> t \<cdot> \<I>"
using strand_sem_append_stateful[of "{}" "{}" "unlabel A@T1" "[send\<langle>t\<rangle>]" \<I>] T
by force
moreover have "\<not>is_Receive x"
when x: "x \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))" for x
proof -
have *: "is_Receive a" when "a \<in> set (unlabel (transaction_receive T))" for a
using T_adm Ball_set[of "unlabel (transaction_receive T)" is_Receive] that
unfolding admissible_transaction_def wellformed_transaction_def
by blast
obtain l where l: "(l,x) \<in> set (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using x unfolding unlabel_def by fastforce
then obtain ly where ly: "ly \<in> set (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)" "(l,x) = dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p ly"
unfolding dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by auto
obtain j y where j: "ly = (j,y)" by (metis surj_pair)
hence "j = l" using ly(2) by (cases y) auto
hence y: "(l,y) \<in> set (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)" "(l,x) = dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (l,y)"
by (metis j ly(1), metis j ly(2))
obtain z where z:
"z \<in> set (unlabel (transaction_receive T))"
"(l,z) \<in> set (transaction_receive T)"
"(l,y) = (l,z) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>"
using y(1) unfolding subst_apply_labeled_stateful_strand_def unlabel_def by force
have "is_Receive y" using *[OF z(1)] z(3) by (cases z) auto
thus "\<not>is_Receive x" using l y by (cases y) auto
qed
hence "\<not>is_Receive x" when "x \<in> set T1" for x using T that by simp
hence "ik\<^sub>s\<^sub>s\<^sub>t T1 = {}" unfolding ik\<^sub>s\<^sub>s\<^sub>t_def is_Receive_def by fast
hence "ik\<^sub>s\<^sub>s\<^sub>t (unlabel A@T1) = ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" using ik\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A" T1] by simp
ultimately show ?thesis by (simp add: \<theta>_def)
qed
lemma transaction_checks_db:
assumes T: "admissible_transaction T"
and \<I>: "constraint_model \<I> (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
and \<sigma>: "transaction_fresh_subst \<sigma> T A"
and \<alpha>: "transaction_renaming_subst \<alpha> P A"
shows "\<langle>Var (TAtom Value, n) in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T))
\<Longrightarrow> (\<alpha> (TAtom Value, n) \<cdot> \<I>, Fun (Set s) []) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<I>)"
(is "?A \<Longrightarrow> ?B")
and "\<langle>Var (TAtom Value, n) not in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T))
\<Longrightarrow> (\<alpha> (TAtom Value, n) \<cdot> \<I>, Fun (Set s) []) \<notin> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<I>)"
(is "?C \<Longrightarrow> ?D")
proof -
let ?x = "\<lambda>n. (TAtom Value, n)"
let ?s = "Fun (Set s) []"
let ?T = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?T' = "?T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
let ?S = "\<lambda>S. transaction_receive T@transaction_selects T@S"
let ?S' = "\<lambda>S. ?S S \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
have T_valid: "wellformed_transaction T" using T by (simp add: admissible_transaction_def)
have "constr_sem_stateful \<I> (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)))"
using \<I> unfolding constraint_model_def by simp
moreover have
"dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>) =
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S (T1@[c]) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>)@
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (T2@transaction_updates T@transaction_send T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>)"
when "transaction_checks T = T1@c#T2" for T1 T2 c \<delta>
using that dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_append subst_lsst_append
unfolding transaction_strand_def
by (metis append.assoc append_Cons append_Nil)
ultimately have T'_model: "constr_sem_stateful \<I> (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' (T1@[(l,c)]))))"
when "transaction_checks T = T1@(l,c)#T2" for T1 T2 l c
using strand_sem_append_stateful[of _ _ _ _ \<I>]
by (simp add: that transaction_strand_def)
show "?A \<Longrightarrow> ?B"
proof -
assume a: ?A
hence *: "\<langle>Var (?x n) in ?s\<rangle> \<in> set (unlabel ?T)"
unfolding transaction_strand_def unlabel_def by simp
then obtain l T1 T2 where T1: "transaction_checks T = T1@(l,\<langle>Var (?x n) in ?s\<rangle>)#T2"
by (metis a split_list unlabel_mem_has_label)
have "?x n \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T)"
using a by force
hence "?x n \<notin> set (transaction_fresh T)"
using a transaction_fresh_vars_notin[OF T_valid] by fast
hence "unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' (T1@[(l,\<langle>Var (?x n) in ?s\<rangle>)]))) =
unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' T1))@[\<langle>\<alpha> (?x n) in ?s\<rangle>]"
using T a \<sigma> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_append subst_lsst_append unlabel_append
by (fastforce simp add: transaction_fresh_subst_def unlabel_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def
subst_apply_labeled_stateful_strand_def)
moreover have "db\<^sub>s\<^sub>s\<^sub>t (unlabel A) = db\<^sub>s\<^sub>s\<^sub>t (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' T1)))"
by (simp add: T1 db\<^sub>s\<^sub>s\<^sub>t_transaction_prefix_eq[OF T_valid] del: unlabel_append)
ultimately have "\<exists>M. strand_sem_stateful M (set (db\<^sub>s\<^sub>s\<^sub>t (unlabel A) \<I>)) [\<langle>\<alpha> (?x n) in ?s\<rangle>] \<I>"
using T'_model[OF T1] db\<^sub>s\<^sub>s\<^sub>t_set_is_dbupd\<^sub>s\<^sub>s\<^sub>t[of _ \<I>] strand_sem_append_stateful[of _ _ _ _ \<I>]
by (simp add: db\<^sub>s\<^sub>s\<^sub>t_def del: unlabel_append)
thus ?B by simp
qed
show "?C \<Longrightarrow> ?D"
proof -
assume a: ?C
hence *: "\<langle>Var (?x n) not in ?s\<rangle> \<in> set (unlabel ?T)"
unfolding transaction_strand_def unlabel_def by simp
then obtain l T1 T2 where T1: "transaction_checks T = T1@(l,\<langle>Var (?x n) not in ?s\<rangle>)#T2"
by (metis a split_list unlabel_mem_has_label)
have "?x n \<in> vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<langle>Var (?x n) not in ?s\<rangle>"
using vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p_cases(9)[of "[]" "Var (?x n)" ?s] by auto
hence "?x n \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T)"
using a unfolding vars\<^sub>s\<^sub>s\<^sub>t_def by force
hence "?x n \<notin> set (transaction_fresh T)"
using a transaction_fresh_vars_notin[OF T_valid] by fast
hence "unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' (T1@[(l,\<langle>Var (?x n) not in ?s\<rangle>)]))) =
unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' T1))@[\<langle>\<alpha> (?x n) not in ?s\<rangle>]"
using T a \<sigma> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_append subst_lsst_append unlabel_append
by (fastforce simp add: transaction_fresh_subst_def unlabel_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def
subst_apply_labeled_stateful_strand_def)
moreover have "db\<^sub>s\<^sub>s\<^sub>t (unlabel A) = db\<^sub>s\<^sub>s\<^sub>t (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' T1)))"
by (simp add: T1 db\<^sub>s\<^sub>s\<^sub>t_transaction_prefix_eq[OF T_valid] del: unlabel_append)
ultimately have "\<exists>M. strand_sem_stateful M (set (db\<^sub>s\<^sub>s\<^sub>t (unlabel A) \<I>)) [\<langle>\<alpha> (?x n) not in ?s\<rangle>] \<I>"
using T'_model[OF T1] db\<^sub>s\<^sub>s\<^sub>t_set_is_dbupd\<^sub>s\<^sub>s\<^sub>t[of _ \<I>] strand_sem_append_stateful[of _ _ _ _ \<I>]
by (simp add: db\<^sub>s\<^sub>s\<^sub>t_def del: unlabel_append)
thus ?D using stateful_strand_sem_NegChecks_no_bvars(1)[of _ _ _ ?s \<I>] by simp
qed
qed
lemma transaction_selects_db:
assumes T: "admissible_transaction T"
and \<I>: "constraint_model \<I> (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
and \<sigma>: "transaction_fresh_subst \<sigma> T A"
and \<alpha>: "transaction_renaming_subst \<alpha> P A"
shows "select\<langle>Var (TAtom Value, n), Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_selects T))
\<Longrightarrow> (\<alpha> (TAtom Value, n) \<cdot> \<I>, Fun (Set s) []) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<I>)"
(is "?A \<Longrightarrow> ?B")
proof -
let ?x = "\<lambda>n. (TAtom Value, n)"
let ?s = "Fun (Set s) []"
let ?T = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?T' = "?T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
let ?S = "\<lambda>S. transaction_receive T@S"
let ?S' = "\<lambda>S. ?S S \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
have T_valid: "wellformed_transaction T" using T by (simp add: admissible_transaction_def)
have "constr_sem_stateful \<I> (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)))"
using \<I> unfolding constraint_model_def by simp
moreover have
"dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>) =
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S (T1@[c]) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>)@
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (T2@transaction_checks T @ transaction_updates T@transaction_send T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<delta>)"
when "transaction_selects T = T1@c#T2" for T1 T2 c \<delta>
using that dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_append subst_lsst_append
unfolding transaction_strand_def by (metis append.assoc append_Cons append_Nil)
ultimately have T'_model: "constr_sem_stateful \<I> (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' (T1@[(l,c)]))))"
when "transaction_selects T = T1@(l,c)#T2" for T1 T2 l c
using strand_sem_append_stateful[of _ _ _ _ \<I>]
by (simp add: that transaction_strand_def)
show "?A \<Longrightarrow> ?B"
proof -
assume a: ?A
hence *: "select\<langle>Var (?x n), ?s\<rangle> \<in> set (unlabel ?T)"
unfolding transaction_strand_def unlabel_def by simp
then obtain l T1 T2 where T1: "transaction_selects T = T1@(l,select\<langle>Var (?x n), ?s\<rangle>)#T2"
by (metis a split_list unlabel_mem_has_label)
have "?x n \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
using a by force
hence "?x n \<notin> set (transaction_fresh T)"
using a transaction_fresh_vars_notin[OF T_valid] by fast
hence "unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' (T1@[(l,select\<langle>Var (?x n), ?s\<rangle>)]))) =
unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' T1))@[select\<langle>\<alpha> (?x n), ?s\<rangle>]"
using T a \<sigma> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_append subst_lsst_append unlabel_append
by (fastforce simp add: transaction_fresh_subst_def unlabel_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def
subst_apply_labeled_stateful_strand_def)
moreover have "db\<^sub>s\<^sub>s\<^sub>t (unlabel A) = db\<^sub>s\<^sub>s\<^sub>t (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (?S' T1)))"
by (simp add: T1 db\<^sub>s\<^sub>s\<^sub>t_transaction_prefix_eq[OF T_valid] del: unlabel_append)
ultimately have "\<exists>M. strand_sem_stateful M (set (db\<^sub>s\<^sub>s\<^sub>t (unlabel A) \<I>)) [\<langle>\<alpha> (?x n) in ?s\<rangle>] \<I>"
using T'_model[OF T1] db\<^sub>s\<^sub>s\<^sub>t_set_is_dbupd\<^sub>s\<^sub>s\<^sub>t[of _ \<I>] strand_sem_append_stateful[of _ _ _ _ \<I>]
by (simp add: db\<^sub>s\<^sub>s\<^sub>t_def del: unlabel_append)
thus ?B by simp
qed
qed
lemma transactions_have_no_Value_consts:
assumes "admissible_transaction T"
and "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T))"
shows "\<nexists>a T. t = Fun (Val a) T" (is ?A)
and "\<nexists>a T. t = Fun (Abs a) T" (is ?B)
proof -
have "admissible_transaction_terms T" using assms(1) unfolding admissible_transaction_def by blast
hence "\<not>is_Val f" "\<not>is_Abs f"
when "f \<in> \<Union>(funs_term ` (trms_transaction T))" for f
using that unfolding admissible_transaction_terms_def by blast+
moreover have "f \<in> \<Union>(funs_term ` (trms_transaction T))"
when "f \<in> funs_term t" for f
using that assms(2) funs_term_subterms_eq(2)[of "trms_transaction T"] by blast+
ultimately have *: "\<not>is_Val f" "\<not>is_Abs f"
when "f \<in> funs_term t" for f
using that by presburger+
show ?A using *(1) by force
show ?B using *(2) by force
qed
lemma transactions_have_no_Value_consts':
assumes "admissible_transaction T"
and "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)"
shows "\<nexists>a T. Fun (Val a) T \<in> subterms t"
and "\<nexists>a T. Fun (Abs a) T \<in> subterms t"
using transactions_have_no_Value_consts[OF assms(1)] assms(2) by fast+
lemma transactions_have_no_PubConsts:
assumes "admissible_transaction T"
and "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T))"
shows "\<nexists>a T. t = Fun (PubConstSetType a) T" (is ?A)
and "\<nexists>a T. t = Fun (PubConstAttackType a) T" (is ?B)
and "\<nexists>a T. t = Fun (PubConstBottom a) T" (is ?C)
and "\<nexists>a T. t = Fun (PubConstOccursSecType a) T" (is ?D)
proof -
have "admissible_transaction_terms T" using assms(1) unfolding admissible_transaction_def by blast
hence "\<not>is_PubConstSetType f" "\<not>is_PubConstAttackType f"
"\<not>is_PubConstBottom f" "\<not>is_PubConstOccursSecType f"
when "f \<in> \<Union>(funs_term ` (trms_transaction T))" for f
using that unfolding admissible_transaction_terms_def by blast+
moreover have "f \<in> \<Union>(funs_term ` (trms_transaction T))"
when "f \<in> funs_term t" for f
using that assms(2) funs_term_subterms_eq(2)[of "trms_transaction T"] by blast+
ultimately have *:
"\<not>is_PubConstSetType f" "\<not>is_PubConstAttackType f"
"\<not>is_PubConstBottom f" "\<not>is_PubConstOccursSecType f"
when "f \<in> funs_term t" for f
using that by presburger+
show ?A using *(1) by force
show ?B using *(2) by force
show ?C using *(3) by force
show ?D using *(4) by force
qed
lemma transactions_have_no_PubConsts':
assumes "admissible_transaction T"
and "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)"
shows "\<nexists>a T. Fun (PubConstSetType a) T \<in> subterms t"
and "\<nexists>a T. Fun (PubConstAttackType a) T \<in> subterms t"
and "\<nexists>a T. Fun (PubConstBottom a) T \<in> subterms t"
and "\<nexists>a T. Fun (PubConstOccursSecType a) T \<in> subterms t"
using transactions_have_no_PubConsts[OF assms(1)] assms(2) by fast+
lemma transaction_inserts_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_updates T"
and "insert\<langle>t,s\<rangle> \<in> set (unlabel (transaction_strand T))"
shows "\<exists>n. t = Var (TAtom Value, n)"
and "\<exists>u. s = Fun (Set u) []"
proof -
let ?x = "insert\<langle>t,s\<rangle>"
have "?x \<in> set (unlabel (transaction_updates T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
hence *: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using assms(2) unfolding admissible_transaction_updates_def is_Fun_Set_def by fastforce+
show "\<exists>n. t = Var (TAtom Value, n)" using *(1,2) by (cases t) auto
show "\<exists>u. s = Fun (Set u) []" using *(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_deletes_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_updates T"
and "delete\<langle>t,s\<rangle> \<in> set (unlabel (transaction_strand T))"
shows "\<exists>n. t = Var (TAtom Value, n)"
and "\<exists>u. s = Fun (Set u) []"
proof -
let ?x = "delete\<langle>t,s\<rangle>"
have "?x \<in> set (unlabel (transaction_updates T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
hence *: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using assms(2) unfolding admissible_transaction_updates_def is_Fun_Set_def by fastforce+
show "\<exists>n. t = Var (TAtom Value, n)" using *(1,2) by (cases t) auto
show "\<exists>u. s = Fun (Set u) []" using *(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_selects_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_selects T"
and "select\<langle>t,s\<rangle> \<in> set (unlabel (transaction_strand T))"
shows "\<exists>n. t = Var (TAtom Value, n) \<and> (TAtom Value, n) \<notin> set (transaction_fresh T)" (is ?A)
and "\<exists>u. s = Fun (Set u) []" (is ?B)
proof -
let ?x = "select\<langle>t,s\<rangle>"
have *: "?x \<in> set (unlabel (transaction_selects T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
have **: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using * assms(2) unfolding admissible_transaction_selects_def is_Fun_Set_def by fastforce+
have "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
using * by force
hence ***: "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x \<inter> set (transaction_fresh T) = {}"
using T_valid unfolding wellformed_transaction_def by fast
show ?A using **(1,2) *** by (cases t) auto
show ?B using **(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_inset_checks_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_checks T"
and "\<langle>t in s\<rangle> \<in> set (unlabel (transaction_strand T))"
shows "\<exists>n. t = Var (TAtom Value, n) \<and> (TAtom Value, n) \<notin> set (transaction_fresh T)" (is ?A)
and "\<exists>u. s = Fun (Set u) []" (is ?B)
proof -
let ?x = "\<langle>t in s\<rangle>"
have *: "?x \<in> set (unlabel (transaction_checks T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
have **: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using * assms(2) unfolding admissible_transaction_checks_def is_Fun_Set_def by fastforce+
have "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T)"
using * by force
hence ***: "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x \<inter> set (transaction_fresh T) = {}"
using T_valid unfolding wellformed_transaction_def by fast
show ?A using **(1,2) *** by (cases t) auto
show ?B using **(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_notinset_checks_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_checks T"
and "\<forall>X\<langle>\<or>\<noteq>: F \<or>\<notin>: G\<rangle> \<in> set (unlabel (transaction_strand T))"
and "(t,s) \<in> set G"
shows "\<exists>n. t = Var (TAtom Value, n) \<and> (TAtom Value, n) \<notin> set (transaction_fresh T)" (is ?A)
and "\<exists>u. s = Fun (Set u) []" (is ?B)
proof -
let ?x = "\<forall>X\<langle>\<or>\<noteq>: F \<or>\<notin>: G\<rangle>"
have 0: "?x \<in> set (unlabel (transaction_checks T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
hence 1: "F = [] \<and> length G = 1"
using assms(2,4) unfolding admissible_transaction_checks_def by fastforce
hence "hd G = (t,s)" using assms(4) by (cases "the_ins ?x") auto
hence **: "is_Var t" "fst (the_Var t) = TAtom Value" "is_Fun s" "args s = []" "is_Set (the_Fun s)"
using 0 1 assms(2) unfolding admissible_transaction_checks_def Let_def is_Fun_Set_def
by fastforce+
have "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T)"
"set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x) \<subseteq> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T)"
using 0 by force+
moreover have
"fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_checks T) \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T) \<union> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
"set (transaction_fresh T) \<inter> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T) = {}"
"set (transaction_fresh T) \<inter> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T) = {}"
using T_valid unfolding wellformed_transaction_def by fast+
ultimately have
"fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x \<inter> set (transaction_fresh T) = {}"
"set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p ?x) \<inter> set (transaction_fresh T) = {}"
using wellformed_transaction_wf\<^sub>s\<^sub>s\<^sub>t(2,3)[OF T_valid]
fv_transaction_unfold[of T] bvars_transaction_unfold[of T]
by blast+
hence ***: "fv t \<inter> set (transaction_fresh T) = {}"
using assms(4) by auto
show ?A using **(1,2) *** by (cases t) auto
show ?B using **(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma admissible_transaction_strand_step_cases:
assumes T_adm: "admissible_transaction T"
shows "r \<in> set (unlabel (transaction_receive T)) \<Longrightarrow> \<exists>t. r = receive\<langle>t\<rangle>"
(is "?A \<Longrightarrow> ?A'")
and "r \<in> set (unlabel (transaction_selects T)) \<Longrightarrow>
\<exists>x s. r = select\<langle>Var x, Fun (Set s) []\<rangle> \<and>
fst x = TAtom Value \<and> x \<in> fv_transaction T - set (transaction_fresh T)"
(is "?B \<Longrightarrow> ?B'")
and "r \<in> set (unlabel (transaction_checks T)) \<Longrightarrow>
(\<exists>x s. (r = \<langle>Var x in Fun (Set s) []\<rangle> \<or> r = \<langle>Var x not in Fun (Set s) []\<rangle>) \<and>
fst x = TAtom Value \<and> x \<in> fv_transaction T - set (transaction_fresh T)) \<or>
(\<exists>s t. r = \<langle>s == t\<rangle> \<or> r = \<langle>s != t\<rangle>)"
(is "?C \<Longrightarrow> ?C'")
and "r \<in> set (unlabel (transaction_updates T)) \<Longrightarrow>
\<exists>x s. (r = insert\<langle>Var x, Fun (Set s) []\<rangle> \<or> r = delete\<langle>Var x, Fun (Set s) []\<rangle>) \<and>
fst x = TAtom Value"
(is "?D \<Longrightarrow> ?D'")
and "r \<in> set (unlabel (transaction_send T)) \<Longrightarrow> \<exists>t. r = send\<langle>t\<rangle>"
(is "?E \<Longrightarrow> ?E'")
proof -
have T_valid: "wellformed_transaction T"
using T_adm unfolding admissible_transaction_def by metis
show "?A \<Longrightarrow> ?A'"
using T_valid Ball_set[of "unlabel (transaction_receive T)" is_Receive]
unfolding wellformed_transaction_def is_Receive_def
by blast
show "?E \<Longrightarrow> ?E'"
using T_valid Ball_set[of "unlabel (transaction_send T)" is_Send]
unfolding wellformed_transaction_def is_Send_def
by blast
show "?B \<Longrightarrow> ?B'"
proof -
assume r: ?B
have "admissible_transaction_selects T"
using T_adm unfolding admissible_transaction_def by simp
hence *: "is_InSet r" "the_check r = Assign" "is_Var (the_elem_term r)"
"is_Fun (the_set_term r)" "is_Set (the_Fun (the_set_term r))"
"args (the_set_term r) = []" "fst (the_Var (the_elem_term r)) = TAtom Value"
using r unfolding admissible_transaction_selects_def is_Fun_Set_def
by fast+
obtain rt rs where r': "r = select\<langle>rt,rs\<rangle>" using *(1,2) by (cases r) auto
obtain x where x: "rt = Var x" "fst x = TAtom Value" using *(3,7) r' by auto
obtain f S where fS: "rs = Fun f S" using *(4) r' by auto
obtain s where s: "f = Set s" using *(5) fS r' by (cases f) auto
hence S: "S = []" using *(6) fS r' by (cases S) auto
have fv_r1: "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p r \<subseteq> fv_transaction T"
using r fv_transaction_unfold[of T] by auto
have fv_r2: "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p r \<inter> set (transaction_fresh T) = {}"
using r T_valid unfolding wellformed_transaction_def by fastforce
show ?B' using r' x fS s S fv_r1 fv_r2 by simp
qed
show "?C \<Longrightarrow> ?C'"
proof -
assume r: ?C
have adm_checks: "admissible_transaction_checks T"
using assms unfolding admissible_transaction_def by simp
have fv_r1: "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p r \<subseteq> fv_transaction T"
using r fv_transaction_unfold[of T] by auto
have fv_r2: "fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p r \<inter> set (transaction_fresh T) = {}"
using r T_valid unfolding wellformed_transaction_def by fastforce
have "(is_InSet r \<and> the_check r = Check) \<or>
(is_Equality r \<and> the_check r = Check) \<or>
is_NegChecks r"
using r adm_checks unfolding admissible_transaction_checks_def by fast
thus ?C'
proof (elim disjE conjE)
assume *: "is_InSet r" "the_check r = Check"
hence **: "is_Var (the_elem_term r)" "is_Fun (the_set_term r)"
"is_Set (the_Fun (the_set_term r))" "args (the_set_term r) = []"
"fst (the_Var (the_elem_term r)) = TAtom Value"
using r adm_checks unfolding admissible_transaction_checks_def is_Fun_Set_def
by fast+
obtain rt rs where r': "r = \<langle>rt in rs\<rangle>" using * by (cases r) auto
obtain x where x: "rt = Var x" "fst x = TAtom Value" using **(1,5) r' by auto
obtain f S where fS: "rs = Fun f S" using **(2) r' by auto
obtain s where s: "f = Set s" using **(3) fS r' by (cases f) auto
hence S: "S = []" using **(4) fS r' by auto
show ?C' using r' x fS s S fv_r1 fv_r2 by simp
next
assume *: "is_NegChecks r"
hence **: "bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p r = []"
"(the_eqs r = [] \<and> length (the_ins r) = 1) \<or>
(the_ins r = [] \<and> length (the_eqs r) = 1)"
using r adm_checks unfolding admissible_transaction_checks_def by fast+
show ?C' using **(2)
proof (elim disjE conjE)
assume ***: "the_eqs r = []" "length (the_ins r) = 1"
then obtain t s where ts: "the_ins r = [(t,s)]" by (cases "the_ins r") auto
hence "hd (the_ins r) = (t,s)" by simp
hence ****: "is_Var (fst (t,s))" "is_Fun (snd (t,s))"
"is_Set (the_Fun (snd (t,s)))" "args (snd (t,s)) = []"
"fst (the_Var (fst (t,s))) = TAtom Value"
using r adm_checks * ***(1) unfolding admissible_transaction_checks_def is_Fun_Set_def
by metis+
obtain x where x: "t = Var x" "fst x = TAtom Value" using ts ****(1,5) by (cases t) simp_all
obtain f S where fS: "s = Fun f S" using ts ****(2) by (cases s) simp_all
obtain ss where ss: "f = Set ss" using fS ****(3) by (cases f) simp_all
have S: "S = []" using ts fS ss ****(4) by simp
show ?C' using ts x fS ss S *** **(1) * fv_r1 fv_r2 by (cases r) auto
next
assume ***: "the_ins r = []" "length (the_eqs r) = 1"
then obtain t s where "the_eqs r = [(t,s)]" by (cases "the_eqs r") auto
thus ?C' using *** **(1) * by (cases r) auto
qed
qed (auto simp add: is_Equality_def the_check_def)
qed
show "?D \<Longrightarrow> ?D'"
proof -
assume r: ?D
have adm_upds: "admissible_transaction_updates T"
using assms unfolding admissible_transaction_def by simp
have *: "is_Update r" "is_Var (the_elem_term r)" "is_Fun (the_set_term r)"
"is_Set (the_Fun (the_set_term r))" "args (the_set_term r) = []"
"fst (the_Var (the_elem_term r)) = TAtom Value"
using r adm_upds unfolding admissible_transaction_updates_def is_Fun_Set_def by fast+
obtain t s where ts: "r = insert\<langle>t,s\<rangle> \<or> r = delete\<langle>t,s\<rangle>" using *(1) by (cases r) auto
obtain x where x: "t = Var x" "fst x = TAtom Value" using ts *(2,6) by (cases t) auto
obtain f T where fT: "s = Fun f T" using ts *(3) by (cases s) auto
obtain ss where ss: "f = Set ss" using ts fT *(4) by (cases f) fastforce+
have T: "T = []" using ts fT *(5) ss by (cases T) auto
show ?D'
using ts x fT ss T by blast
qed
qed
lemma transaction_Value_vars_are_fv:
assumes "admissible_transaction T"
and "x \<in> vars_transaction T"
and "\<Gamma>\<^sub>v x = TAtom Value"
shows "x \<in> fv_transaction T"
using assms \<Gamma>\<^sub>v_TAtom''(2)[of x] vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel (transaction_strand T)"]
unfolding admissible_transaction_def by fast
lemma protocol_transaction_vars_TAtom_typed:
assumes P: "admissible_transaction T"
shows "\<forall>x \<in> vars_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
and "\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
and "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
proof -
have P': "wellformed_transaction T"
using P unfolding admissible_transaction_def by fast
show "\<forall>x \<in> vars_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
using P \<Gamma>\<^sub>v_TAtom''
unfolding admissible_transaction_def is_Var_def prot_atom.is_Atom_def the_Var_def
by fastforce
thus "\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
using vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t by fast
have "list_all (\<lambda>x. fst x = Var Value) (transaction_fresh T)"
using P \<Gamma>\<^sub>v_TAtom'' unfolding admissible_transaction_def by fast
thus "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
using \<Gamma>\<^sub>v_TAtom''(2) unfolding list_all_iff by fast
qed
lemma protocol_transactions_no_pubconsts:
assumes "admissible_transaction T"
shows "Fun (Val (n,True)) S \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms_transaction T)"
using assms transactions_have_no_Value_consts(1)
by fast
lemma protocol_transactions_no_abss:
assumes "admissible_transaction T"
shows "Fun (Abs n) S \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms_transaction T)"
using assms transactions_have_no_Value_consts(2)
by fast
lemma admissible_transaction_strand_sem_fv_ineq:
assumes T_adm: "admissible_transaction T"
and \<I>: "strand_sem_stateful IK DB (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<I>"
and x: "x \<in> fv_transaction T - set (transaction_fresh T)"
and y: "y \<in> fv_transaction T - set (transaction_fresh T)"
and x_not_y: "x \<noteq> y"
shows "\<theta> x \<cdot> \<I> \<noteq> \<theta> y \<cdot> \<I>"
proof -
have "\<langle>Var x != Var y\<rangle> \<in> set (unlabel (transaction_checks T)) \<or>
\<langle>Var y != Var x\<rangle> \<in> set (unlabel (transaction_checks T))"
using x y x_not_y T_adm unfolding admissible_transaction_def by auto
hence "\<langle>Var x != Var y\<rangle> \<in> set (unlabel (transaction_strand T)) \<or>
\<langle>Var y != Var x\<rangle> \<in> set (unlabel (transaction_strand T))"
unfolding transaction_strand_def unlabel_def by auto
hence "\<langle>\<theta> x != \<theta> y\<rangle> \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<or>
\<langle>\<theta> y != \<theta> x\<rangle> \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
using stateful_strand_step_subst_inI(8)[of _ _ "unlabel (transaction_strand T)" \<theta>]
subst_lsst_unlabel[of "transaction_strand T" \<theta>]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(7)[of "[]" _ "[]"]
by force
then obtain B where B:
"prefix (B@[\<langle>\<theta> x != \<theta> y\<rangle>]) (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) \<or>
prefix (B@[\<langle>\<theta> y != \<theta> x\<rangle>]) (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
unfolding prefix_def
by (metis (no_types, hide_lams) append.assoc append_Cons append_Nil split_list)
thus ?thesis
using \<I> strand_sem_append_stateful[of IK DB _ _ \<I>]
stateful_strand_sem_NegChecks_no_bvars(2)
unfolding prefix_def
by metis
qed
lemma admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s:
assumes "admissible_transaction T"
shows "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms_transaction T)"
by (metis wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_code assms admissible_transaction_def admissible_transaction_terms_def)
lemma admissible_transaction_no_Ana_Attack:
assumes "admissible_transaction_terms T"
and "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms_transaction T)"
shows "attack\<langle>n\<rangle> \<notin> set (snd (Ana t))"
proof -
obtain r where r: "r \<in> set (unlabel (transaction_strand T))" "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p r)"
using assms(2) by force
obtain K M where t: "Ana t = (K, M)"
by (metis surj_pair)
show ?thesis
proof
assume n: "attack\<langle>n\<rangle> \<in> set (snd (Ana t))"
hence "attack\<langle>n\<rangle> \<in> set M" using t by simp
hence n': "attack\<langle>n\<rangle> \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p r)"
using Ana_subterm[OF t] r(2) subterms_subset by fast
hence "\<exists>f \<in> \<Union>(funs_term ` trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p r). is_Attack f"
using funs_term_Fun_subterm' unfolding is_Attack_def by fast
hence "is_Send r" "is_Fun (the_msg r)" "is_Attack (the_Fun (the_msg r))" "args (the_msg r) = []"
using assms(1) r(1) unfolding admissible_transaction_terms_def by metis+
hence "t = attack\<langle>n\<rangle>"
using n' r(2) unfolding is_Send_def is_Attack_def by auto
thus False using n by fastforce
qed
qed
lemma admissible_transaction_occurs_fv_types:
assumes "admissible_transaction T"
and "x \<in> vars_transaction T"
shows "\<exists>a. \<Gamma> (Var x) = TAtom a \<and> \<Gamma> (Var x) \<noteq> TAtom OccursSecType"
proof -
have "is_Var (fst x)" "the_Var (fst x) = Value"
using assms unfolding admissible_transaction_def by blast+
thus ?thesis using \<Gamma>\<^sub>v_TAtom''(2)[of x] by force
qed
lemma admissible_transaction_Value_vars:
assumes T: "admissible_transaction T"
and x: "x \<in> fv_transaction T"
shows "\<Gamma>\<^sub>v x = TAtom Value"
proof -
have "x \<in> vars_transaction T"
using x vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel (transaction_strand T)"]
by blast
hence "is_Var (fst x)" "the_Var (fst x) = Value"
using T assms unfolding admissible_transaction_def list_all_iff by fast+
thus "\<Gamma>\<^sub>v x = TAtom Value" using \<Gamma>\<^sub>v_TAtom''(2)[of x] by force
qed
subsection \<open>Lemmata: Renaming and Fresh Substitutions\<close>
lemma transaction_renaming_subst_is_renaming:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "\<exists>m. \<alpha> (\<tau>,n) = Var (\<tau>,n+Suc m)"
using assms by (auto simp add: transaction_renaming_subst_def var_rename_def)
lemma transaction_renaming_subst_is_renaming':
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "\<exists>y. \<alpha> x = Var y"
using assms by (auto simp add: transaction_renaming_subst_def var_rename_def)
lemma transaction_renaming_subst_vars_disj:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "fv\<^sub>s\<^sub>e\<^sub>t (\<alpha> ` (\<Union>(vars_transaction ` set P))) \<inter> (\<Union>(vars_transaction ` set P)) = {}" (is ?A)
and "fv\<^sub>s\<^sub>e\<^sub>t (\<alpha> ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A) \<inter> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A = {}" (is ?B)
and "T \<in> set P \<Longrightarrow> vars_transaction T \<inter> range_vars \<alpha> = {}" (is "T \<in> set P \<Longrightarrow> ?C1")
and "T \<in> set P \<Longrightarrow> bvars_transaction T \<inter> range_vars \<alpha> = {}" (is "T \<in> set P \<Longrightarrow> ?C2")
and "T \<in> set P \<Longrightarrow> fv_transaction T \<inter> range_vars \<alpha> = {}" (is "T \<in> set P \<Longrightarrow> ?C3")
and "vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<inter> range_vars \<alpha> = {}" (is ?D1)
and "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<inter> range_vars \<alpha> = {}" (is ?D2)
and "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<inter> range_vars \<alpha> = {}" (is ?D3)
proof -
define X where "X \<equiv> \<Union>(vars_transaction ` set P) \<union> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
have 1: "finite X" by (simp add: X_def)
obtain n where n: "n \<ge> max_var_set X" "\<alpha> = var_rename n"
using assms unfolding transaction_renaming_subst_def X_def by moura
hence 2: "\<forall>x \<in> X. snd x < Suc n"
using less_Suc_max_var_set[OF _ 1] unfolding var_rename_def by fastforce
have 3: "x \<notin> fv\<^sub>s\<^sub>e\<^sub>t (\<alpha> ` X)" "fv (\<alpha> x) \<inter> X = {}" "x \<notin> range_vars \<alpha>" when x: "x \<in> X" for x
using 2 x n unfolding var_rename_def by force+
show ?A ?B using 3(1,2) unfolding X_def by auto
show ?C1 when T: "T \<in> set P" using T 3(3) unfolding X_def by blast
thus ?C2 ?C3 when T: "T \<in> set P"
using T by (simp_all add: disjoint_iff_not_equal vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t)
show ?D1 using 3(3) unfolding X_def by auto
thus ?D2 ?D3 by (simp_all add: disjoint_iff_not_equal vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t)
qed
lemma transaction_renaming_subst_wt:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<alpha>"
proof -
{ fix x::"('fun,'atom,'sets) prot_var"
obtain \<tau> n where x: "x = (\<tau>,n)" by moura
then obtain m where m: "\<alpha> x = Var (\<tau>,m)"
using assms transaction_renaming_subst_is_renaming by moura
hence "\<Gamma> (\<alpha> x) = \<Gamma>\<^sub>v x" using x by (simp add: \<Gamma>\<^sub>v_def)
} thus ?thesis by (simp add: wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def)
qed
lemma transaction_renaming_subst_is_wf_trm:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "wf\<^sub>t\<^sub>r\<^sub>m (\<alpha> v)"
proof -
obtain \<tau> n where "v = (\<tau>, n)" by moura
then obtain m where "\<alpha> v = Var (\<tau>, n + Suc m)"
using transaction_renaming_subst_is_renaming[OF assms]
by moura
thus ?thesis by (metis wf_trm_Var)
qed
lemma transaction_renaming_subst_range_wf_trms:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<alpha>)"
by (metis transaction_renaming_subst_is_wf_trm[OF assms] wf_trm_subst_range_iff)
lemma transaction_renaming_subst_range_notin_vars:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P \<A>"
shows "\<exists>y. \<alpha> x = Var y \<and> y \<notin> \<Union>(vars_transaction ` set P) \<union> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
proof -
obtain \<tau> n where x: "x = (\<tau>,n)" by (metis surj_pair)
define y where "y \<equiv> \<lambda>m. (\<tau>,n+Suc m)"
have "\<exists>m \<ge> max_var_set (\<Union>(vars_transaction ` set P) \<union> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). \<alpha> x = Var (y m)"
using assms x by (auto simp add: y_def transaction_renaming_subst_def var_rename_def)
moreover have "finite (\<Union>(vars_transaction ` set P) \<union> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" by auto
ultimately show ?thesis using x unfolding y_def by force
qed
lemma transaction_renaming_subst_var_obtain:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes x: "x \<in> fv\<^sub>s\<^sub>s\<^sub>t (S \<cdot>\<^sub>s\<^sub>s\<^sub>t \<alpha>)"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
shows "\<exists>y. \<alpha> y = Var x"
proof -
obtain y where y: "y \<in> fv\<^sub>s\<^sub>s\<^sub>t S" "x \<in> fv (\<alpha> y)" using fv\<^sub>s\<^sub>s\<^sub>t_subst_obtain_var[OF x] by moura
thus ?thesis using transaction_renaming_subst_is_renaming'[OF \<alpha>, of y] by fastforce
qed
lemma transaction_fresh_subst_is_wf_trm:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T A"
shows "wf\<^sub>t\<^sub>r\<^sub>m (\<sigma> v)"
proof (cases "v \<in> subst_domain \<sigma>")
case True
then obtain n where "\<sigma> v = Fun (Val n) []"
using assms unfolding transaction_fresh_subst_def
by moura
thus ?thesis by auto
qed auto
lemma transaction_fresh_subst_wt:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T A"
and "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<sigma>"
proof -
have 1: "subst_domain \<sigma> = set (transaction_fresh T)"
and 2: "\<forall>t \<in> subst_range \<sigma>. \<exists>n. t = Fun (Val n) []"
using assms(1) unfolding transaction_fresh_subst_def by metis+
{ fix x::"('fun,'atom,'sets) prot_var"
have "\<Gamma> (Var x) = \<Gamma> (\<sigma> x)" using assms(2) 1 2 by (cases "x \<in> subst_domain \<sigma>") force+
} thus ?thesis by (simp add: wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def)
qed
lemma transaction_fresh_subst_domain:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
shows "subst_domain \<sigma> = set (transaction_fresh T)"
using assms unfolding transaction_fresh_subst_def by fast
lemma transaction_fresh_subst_range_wf_trms:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
shows "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<sigma>)"
by (metis transaction_fresh_subst_is_wf_trm[OF assms] wf_trm_subst_range_iff)
lemma transaction_fresh_subst_range_fresh:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
shows "\<forall>t \<in> subst_range \<sigma>. t \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
and "\<forall>t \<in> subst_range \<sigma>. t \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T))"
using assms unfolding transaction_fresh_subst_def by meson+
lemma transaction_fresh_subst_sends_to_val:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
and "y \<in> set (transaction_fresh T)"
obtains n where "\<sigma> y = Fun (Val n) []" "Fun (Val n) [] \<in> subst_range \<sigma>"
proof -
have "\<sigma> y \<in> subst_range \<sigma>" using assms unfolding transaction_fresh_subst_def by simp
thus ?thesis
using assms that unfolding transaction_fresh_subst_def
by fastforce
qed
lemma transaction_fresh_subst_sends_to_val':
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
and "y \<in> set (transaction_fresh T)"
obtains n where "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val n) []" "Fun (Val n) [] \<in> subst_range \<sigma>"
proof -
obtain n where "\<sigma> y = Fun (Val n) []" "Fun (Val n) [] \<in> subst_range \<sigma>"
using transaction_fresh_subst_sends_to_val[OF assms] by moura
thus ?thesis using that by (fastforce simp add: subst_compose_def)
qed
lemma transaction_fresh_subst_grounds_domain:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
and "y \<in> set (transaction_fresh T)"
shows "fv (\<sigma> y) = {}"
proof -
obtain n where "\<sigma> y = Fun (Val n) []"
using transaction_fresh_subst_sends_to_val[OF assms]
by moura
thus ?thesis by simp
qed
lemma transaction_fresh_subst_transaction_renaming_subst_range:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>" "transaction_renaming_subst \<alpha> P \<A>"
shows "x \<in> set (transaction_fresh T) \<Longrightarrow> \<exists>n. (\<sigma> \<circ>\<^sub>s \<alpha>) x = Fun (Val (n,False)) []"
and "x \<notin> set (transaction_fresh T) \<Longrightarrow> \<exists>y. (\<sigma> \<circ>\<^sub>s \<alpha>) x = Var y"
proof -
assume "x \<in> set (transaction_fresh T)"
then obtain n where "\<sigma> x = Fun (Val (n,False)) []"
using assms(1) unfolding transaction_fresh_subst_def by fastforce
thus "\<exists>n. (\<sigma> \<circ>\<^sub>s \<alpha>) x = Fun (Val (n,False)) []" using subst_compose[of \<sigma> \<alpha> x] by simp
next
assume "x \<notin> set (transaction_fresh T)"
hence "\<sigma> x = Var x"
using assms(1) unfolding transaction_fresh_subst_def by fastforce
thus "\<exists>y. (\<sigma> \<circ>\<^sub>s \<alpha>) x = Var y"
using transaction_renaming_subst_is_renaming[OF assms(2)] subst_compose[of \<sigma> \<alpha> x]
by (cases x) force
qed
lemma transaction_fresh_subst_transaction_renaming_subst_range':
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>" "transaction_renaming_subst \<alpha> P \<A>"
and "t \<in> subst_range (\<sigma> \<circ>\<^sub>s \<alpha>)"
shows "(\<exists>n. t = Fun (Val (n,False)) []) \<or> (\<exists>x. t = Var x)"
proof -
obtain x where "x \<in> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>)" "(\<sigma> \<circ>\<^sub>s \<alpha>) x = t"
using assms(3) by auto
thus ?thesis
using transaction_fresh_subst_transaction_renaming_subst_range[OF assms(1,2), of x]
by auto
qed
lemma transaction_fresh_subst_transaction_renaming_subst_range'':
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes s: "transaction_fresh_subst \<sigma> T \<A>" "transaction_renaming_subst \<alpha> P \<A>"
and y: "y \<in> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) x)"
shows "\<sigma> x = Var x"
and "\<alpha> x = Var y"
and "(\<sigma> \<circ>\<^sub>s \<alpha>) x = Var y"
proof -
have "\<exists>z. z \<in> fv (\<sigma> x)"
using y subst_compose_fv'
by fast
hence x: "x \<notin> subst_domain \<sigma>"
using y transaction_fresh_subst_domain[OF s(1)]
transaction_fresh_subst_grounds_domain[OF s(1), of x]
by blast
thus "\<sigma> x = Var x" by blast
thus "\<alpha> x = Var y" "(\<sigma> \<circ>\<^sub>s \<alpha>) x = Var y"
using y transaction_renaming_subst_is_renaming'[OF s(2), of x]
unfolding subst_compose_def by fastforce+
qed
lemma transaction_fresh_subst_transaction_renaming_subst_vars_subset:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
shows "\<Union>(fv_transaction ` set P) \<subseteq> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>)" (is ?A)
and "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>)" (is ?B)
and "T' \<in> set P \<Longrightarrow> fv_transaction T' \<subseteq> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>)" (is "T' \<in> set P \<Longrightarrow> ?C")
and "T' \<in> set P \<Longrightarrow> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T' \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)) \<subseteq> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>)"
(is "T' \<in> set P \<Longrightarrow> ?D")
proof -
have *: "x \<in> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>)" for x
proof (cases "x \<in> subst_domain \<sigma>")
case True
hence "x \<notin> {x. \<exists>y. \<sigma> x = Var y \<and> \<alpha> y = Var x}"
using transaction_fresh_subst_domain[OF \<sigma>]
transaction_fresh_subst_grounds_domain[OF \<sigma>, of x]
by auto
thus ?thesis using subst_domain_subst_compose[of \<sigma> \<alpha>] by blast
next
case False
hence "(\<sigma> \<circ>\<^sub>s \<alpha>) x = \<alpha> x" unfolding subst_compose_def by fastforce
moreover have "\<alpha> x \<noteq> Var x"
using transaction_renaming_subst_is_renaming[OF \<alpha>, of "fst x" "snd x"] by (cases x) auto
ultimately show ?thesis by fastforce
qed
show ?A ?B using * by blast+
show ?C when T: "T' \<in> set P" using T * by blast
hence "fv\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T') \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>) \<subseteq> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>)"
when T: "T' \<in> set P"
using T fv\<^sub>s\<^sub>s\<^sub>t_subst_subset_range_vars_if_subset_domain by blast
thus ?D when T: "T' \<in> set P" by (metis T unlabel_subst)
qed
lemma transaction_fresh_subst_transaction_renaming_subst_vars_disj:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
shows "fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` (\<Union>(vars_transaction ` set P))) \<inter> (\<Union>(vars_transaction ` set P)) = {}"
(is ?A)
and "x \<in> \<Union>(vars_transaction ` set P) \<Longrightarrow> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) x) \<inter> (\<Union>(vars_transaction ` set P)) = {}"
(is "?B' \<Longrightarrow> ?B")
and "T' \<in> set P \<Longrightarrow> vars_transaction T' \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}" (is "T' \<in> set P \<Longrightarrow> ?C1")
and "T' \<in> set P \<Longrightarrow> bvars_transaction T' \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}" (is "T' \<in> set P \<Longrightarrow> ?C2")
and "T' \<in> set P \<Longrightarrow> fv_transaction T' \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}" (is "T' \<in> set P \<Longrightarrow> ?C3")
and "vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}" (is ?D1)
and "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}" (is ?D2)
and "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}" (is ?D3)
proof -
note 0 = transaction_renaming_subst_vars_disj[OF \<alpha>]
show ?A
proof (cases "fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` (\<Union>(vars_transaction ` set P))) = {}")
case False
hence "\<forall>x \<in> (\<Union>(vars_transaction ` set P)). (\<sigma> \<circ>\<^sub>s \<alpha>) x = \<alpha> x \<or> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) x) = {}"
using transaction_fresh_subst_transaction_renaming_subst_range''[OF \<sigma> \<alpha>] by auto
thus ?thesis using 0(1) by force
qed blast
thus "?B' \<Longrightarrow> ?B" by auto
have 1: "range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) \<subseteq> range_vars \<alpha>"
using range_vars_subst_compose_subset[of \<sigma> \<alpha>]
transaction_fresh_subst_domain[OF \<sigma>]
transaction_fresh_subst_grounds_domain[OF \<sigma>]
by force
show ?C1 ?C2 ?C3 when T: "T' \<in> set P" using T 1 0(3,4,5)[of T'] by blast+
show ?D1 ?D2 ?D3 using 1 0(6,7,8) by blast+
qed
lemma transaction_fresh_subst_transaction_renaming_subst_trms:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>" "transaction_renaming_subst \<alpha> P \<A>"
and "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \<inter> subst_domain \<sigma> = {}"
and "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \<inter> subst_domain \<alpha> = {}"
shows "subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (S \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>))) = subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t S) \<cdot>\<^sub>s\<^sub>e\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
proof -
have 1: "\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t S). (\<exists>f. (\<sigma> \<circ>\<^sub>s \<alpha>) x = Fun f []) \<or> (\<exists>y. (\<sigma> \<circ>\<^sub>s \<alpha>) x = Var y)"
using transaction_fresh_subst_transaction_renaming_subst_range[OF assms(1,2)] by blast
have 2: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \<inter> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>) = {}"
using assms(3,4) subst_domain_compose[of \<sigma> \<alpha>] by blast
show ?thesis using subterms_subst_lsst[OF 1 2] by simp
qed
lemma transaction_fresh_subst_transaction_renaming_wt:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>" "transaction_renaming_subst \<alpha> P \<A>"
and "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using transaction_renaming_subst_wt[OF assms(2)]
transaction_fresh_subst_wt[OF assms(1,3)]
by (metis wt_subst_compose)
lemma transaction_fresh_subst_transaction_renaming_fv:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes \<sigma>: "transaction_fresh_subst \<sigma> T A"
and \<alpha>: "transaction_renaming_subst \<alpha> P A"
and x: "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
shows "\<exists>y \<in> fv_transaction T - set (transaction_fresh T). (\<sigma> \<circ>\<^sub>s \<alpha>) y = Var x"
proof -
have "x \<in> fv\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using x fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by argo
then obtain y where "y \<in> fv_transaction T" "x \<in> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) y)"
by (metis fv\<^sub>s\<^sub>s\<^sub>t_subst_obtain_var)
thus ?thesis
using transaction_fresh_subst_transaction_renaming_subst_range[OF \<sigma> \<alpha>, of y]
by (cases "y \<in> set (transaction_fresh T)") force+
qed
lemma transaction_fresh_subst_transaction_renaming_subst_occurs_fact_send_receive:
fixes t::"('fun,'atom,'sets) prot_term"
assumes \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
and T: "wellformed_transaction T"
shows "send\<langle>occurs t\<rangle> \<in> set (unlabel (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))
\<Longrightarrow> \<exists>s. send\<langle>occurs s\<rangle> \<in> set (unlabel (transaction_send T)) \<and> t = s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
(is "?A \<Longrightarrow> ?A'")
and "receive\<langle>occurs t\<rangle> \<in> set (unlabel (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))
\<Longrightarrow> \<exists>s. receive\<langle>occurs s\<rangle> \<in> set (unlabel (transaction_receive T)) \<and> t = s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
(is "?B \<Longrightarrow> ?B'")
proof -
assume ?A
then obtain s where s: "send\<langle>s\<rangle> \<in> set (unlabel (transaction_strand T))" "occurs t = s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
using stateful_strand_step_subst_inv_cases(1)[
of "occurs t" "unlabel (transaction_strand T)" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by auto
note 0 = s(2) transaction_fresh_subst_transaction_renaming_subst_range[OF \<sigma> \<alpha>]
have "\<exists>u. s = occurs u"
proof (cases s)
case (Var x)
hence "(\<exists>n. s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Fun (Val (n, False)) []) \<or> (\<exists>y. s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Var y)"
using 0(2,3)[of x] by (auto simp del: subst_subst_compose)
thus ?thesis
using 0(1) by simp
next
case (Fun f T)
hence 1: "f = OccursFact" "length T = 2" "T ! 0 \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Fun OccursSec []" "T ! 1 \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = t"
using 0(1) by auto
have "T ! 0 = Fun OccursSec []"
proof (cases "T ! 0")
case (Var x) thus ?thesis using 0(2,3)[of x] 1(3) by (auto simp del: subst_subst_compose)
qed (use 1(3) in simp)
thus ?thesis using Fun 1 0(1) by (auto simp del: subst_subst_compose)
qed
then obtain u where u: "s = occurs u" by moura
hence "t = u \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>" using s(2) by fastforce
thus ?A' using s u wellformed_transaction_strand_unlabel_memberD(8)[OF T] by metis
next
assume ?B
then obtain s where s: "receive\<langle>s\<rangle> \<in> set (unlabel (transaction_strand T))" "occurs t = s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
using stateful_strand_step_subst_inv_cases(2)[
of "occurs t" "unlabel (transaction_strand T)" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by auto
note 0 = s(2) transaction_fresh_subst_transaction_renaming_subst_range[OF \<sigma> \<alpha>]
have "\<exists>u. s = occurs u"
proof (cases s)
case (Var x)
hence "(\<exists>n. s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Fun (Val (n, False)) []) \<or> (\<exists>y. s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Var y)"
using 0(2,3)[of x] by (auto simp del: subst_subst_compose)
thus ?thesis
using 0(1) by simp
next
case (Fun f T)
hence 1: "f = OccursFact" "length T = 2" "T ! 0 \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Fun OccursSec []" "T ! 1 \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = t"
using 0(1) by auto
have "T ! 0 = Fun OccursSec []"
proof (cases "T ! 0")
case (Var x) thus ?thesis using 0(2,3)[of x] 1(3) by (auto simp del: subst_subst_compose)
qed (use 1(3) in simp)
thus ?thesis using Fun 1 0(1) by (auto simp del: subst_subst_compose)
qed
then obtain u where u: "s = occurs u" by moura
hence "t = u \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>" using s(2) by fastforce
thus ?B' using s u wellformed_transaction_strand_unlabel_memberD(1)[OF T] by metis
qed
lemma transaction_fresh_subst_proj:
assumes "transaction_fresh_subst \<sigma> T A"
shows "transaction_fresh_subst \<sigma> (transaction_proj n T) (proj n A)"
using assms transaction_proj_fresh_eq[of n T]
contra_subsetD[OF subterms\<^sub>s\<^sub>e\<^sub>t_mono[OF transaction_proj_trms_subset[of n T]]]
contra_subsetD[OF subterms\<^sub>s\<^sub>e\<^sub>t_mono[OF trms\<^sub>s\<^sub>s\<^sub>t_proj_subset(1)[of n A]]]
unfolding transaction_fresh_subst_def by metis
lemma transaction_renaming_subst_proj:
assumes "transaction_renaming_subst \<alpha> P A"
shows "transaction_renaming_subst \<alpha> (map (transaction_proj n) P) (proj n A)"
proof -
let ?X = "\<lambda>P A. \<Union>(vars_transaction ` set P) \<union> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
define Y where "Y \<equiv> ?X (map (transaction_proj n) P) (proj n A)"
define Z where "Z \<equiv> ?X P A"
have "Y \<subseteq> Z"
using sst_vars_proj_subset(3)[of n A] transaction_proj_vars_subset[of n]
unfolding Y_def Z_def by fastforce
hence "insert 0 (snd ` Y) \<subseteq> insert 0 (snd ` Z)" by blast
moreover have "finite (insert 0 (snd ` Z))" "finite (insert 0 (snd ` Y))"
unfolding Y_def Z_def by auto
ultimately have 0: "max_var_set Y \<le> max_var_set Z" using Max_mono by blast
have "\<exists>n\<ge>max_var_set Z. \<alpha> = var_rename n"
using assms unfolding transaction_renaming_subst_def Z_def by blast
hence "\<exists>n\<ge>max_var_set Y. \<alpha> = var_rename n" using 0 le_trans by fast
thus ?thesis unfolding transaction_renaming_subst_def Y_def by blast
qed
lemma protocol_transaction_wf_subst:
fixes \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes T: "wf'\<^sub>s\<^sub>s\<^sub>t (set (transaction_fresh T)) (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)))"
and \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
shows "wf'\<^sub>s\<^sub>s\<^sub>t {} (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)))"
proof -
have 0: "range_vars \<sigma> \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)) = {}"
"ground (\<sigma> ` set (transaction_fresh T))" "ground (\<alpha> ` {})"
using transaction_fresh_subst_domain[OF \<sigma>] transaction_fresh_subst_grounds_domain[OF \<sigma>]
by fastforce+
have "wf'\<^sub>s\<^sub>s\<^sub>t {} ((unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma>) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<alpha>)"
by (metis wf\<^sub>s\<^sub>s\<^sub>t_subst_apply[OF wf\<^sub>s\<^sub>s\<^sub>t_subst_apply[OF T]] 0(2,3))
thus ?thesis
by (metis dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst unlabel_subst labeled_stateful_strand_subst_comp[OF 0(1)])
qed
subsection \<open>Lemmata: Reachable Constraints\<close>
lemma reachable_constraints_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s:
assumes "\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms_transaction T)"
and "\<A> \<in> reachable_constraints P"
shows "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
using assms(2)
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
have "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms_transaction T)"
using assms(1) step.hyps(2) by blast
moreover have "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using wf_trms_subst_compose[of \<sigma> \<alpha>]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]
transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
by fastforce
ultimately have "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms_transaction T \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)" by (metis wf_trms_subst)
hence "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
using wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_trms\<^sub>s\<^sub>s\<^sub>t_subst unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"] by metis
hence "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)))"
using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq by blast
thus ?case using step.IH unlabel_append[of \<A>] trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] by auto
qed simp
lemma reachable_constraints_TAtom_types:
assumes "\<A> \<in> reachable_constraints P"
and "\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
shows "\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` fv_transaction T)" (is "?A \<A>")
and "\<Gamma>\<^sub>v ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` bvars_transaction T)" (is "?B \<A>")
and "\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` vars_transaction T)" (is "?C \<A>")
using assms(1)
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
have 2: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using transaction_renaming_subst_wt[OF step.hyps(4)]
transaction_fresh_subst_wt[OF step.hyps(3)]
by (metis step.hyps(2) assms(2) wt_subst_compose)
have 3: "\<forall>t \<in> subst_range (\<sigma> \<circ>\<^sub>s \<alpha>). fv t = {} \<or> (\<exists>x. t = Var x)"
using transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)]
by fastforce
have "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
"bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
"vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
unfolding T'_def
by (metis fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq,
metis bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq,
metis vars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq)
hence "\<Gamma> ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> \<Gamma> ` Var ` fv_transaction T"
"\<Gamma> ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = \<Gamma> ` Var ` bvars_transaction T"
"\<Gamma> ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> \<Gamma> ` Var ` vars_transaction T"
using wt_subst_lsst_vars_type_subset[OF 2 3, of "transaction_strand T"]
by argo+
hence "\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> \<Gamma>\<^sub>v ` fv_transaction T"
"\<Gamma>\<^sub>v ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = \<Gamma>\<^sub>v ` bvars_transaction T"
"\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> \<Gamma>\<^sub>v ` vars_transaction T"
by (metis \<Gamma>\<^sub>v_Var_image)+
hence 4: "\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` fv_transaction T)"
"\<Gamma>\<^sub>v ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` bvars_transaction T)"
"\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` vars_transaction T)"
using step.hyps(2) by fast+
have 5: "\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A> @ T') = (\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<union> (\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
"\<Gamma>\<^sub>v ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A> @ T') = (\<Gamma>\<^sub>v ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<union> (\<Gamma>\<^sub>v ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
"\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A> @ T') = (\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<union> (\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
using unlabel_append[of \<A> T']
fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel T'"]
bvars\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel T'"]
vars\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel T'"]
by auto
{ case 1 thus ?case
using step.IH(1) 4(1) 5(1)
unfolding T'_def by (simp del: subst_subst_compose fv\<^sub>s\<^sub>s\<^sub>t_def)
}
{ case 2 thus ?case
using step.IH(2) 4(2) 5(2)
unfolding T'_def by (simp del: subst_subst_compose bvars\<^sub>s\<^sub>s\<^sub>t_def)
}
{ case 3 thus ?case
using step.IH(3) 4(3) 5(3)
unfolding T'_def by (simp del: subst_subst_compose)
}
qed simp_all
lemma reachable_constraints_no_bvars:
assumes \<A>: "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) = {}"
shows "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> = {}"
using assms proof (induction)
case init
then show ?case
unfolding unlabel_def by auto
next
case (step \<A> T \<sigma> \<alpha>)
then have "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> = {}"
by metis
moreover
have "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)) = {}"
using step by (metis bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq)
ultimately
show ?case
using bvars\<^sub>s\<^sub>s\<^sub>t_append unlabel_append by (metis sup_bot.left_neutral)
qed
lemma reachable_constraints_fv_bvars_disj:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and P: "\<forall>S \<in> set P. admissible_transaction S"
shows "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> = {}"
proof -
let ?X = "\<Union>T \<in> set P. bvars_transaction T"
note 0 = transactions_fv_bvars_disj[OF P]
have 1: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> ?X" using \<A>_reach
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
have "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)) = bvars_transaction T"
using bvars\<^sub>s\<^sub>s\<^sub>t_subst[of "unlabel (transaction_strand T)" "\<sigma> \<circ>\<^sub>s \<alpha>"]
bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by argo
hence "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)) \<subseteq> ?X"
using step.hyps(2)
by blast
thus ?case
using step.IH bvars\<^sub>s\<^sub>s\<^sub>t_append
by auto
qed (simp add: unlabel_def bvars\<^sub>s\<^sub>s\<^sub>t_def)
have 2: "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> ?X = {}" using \<A>_reach
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
have "x \<noteq> y" when x: "x \<in> ?X" and y: "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)" for x y
proof -
obtain y' where y': "y' \<in> fv_transaction T" "y \<in> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) y')"
using y unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by (metis fv\<^sub>s\<^sub>s\<^sub>t_subst_obtain_var)
have "y \<notin> \<Union>(vars_transaction ` set P)"
using transaction_fresh_subst_transaction_renaming_subst_range''[OF step.hyps(3,4) y'(2)]
transaction_renaming_subst_range_notin_vars[OF step.hyps(4), of y']
by auto
thus ?thesis using x vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t by fast
qed
hence "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>) \<inter> ?X = {}"
by blast
thus ?case
using step.IH
fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"]
unlabel_append[of \<A> "transaction_strand T"]
by force
qed (simp add: unlabel_def fv\<^sub>s\<^sub>s\<^sub>t_def)
show ?thesis using 0 1 2 by blast
qed
lemma reachable_constraints_vars_TAtom_typed:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and x: "x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
shows "\<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
proof -
have \<A>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
by (metis reachable_constraints_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s P \<A>_reach)
have T_adm: "admissible_transaction T" when "T \<in> set P" for T
by (meson that Ball_set P)
have "\<forall>T\<in>set P. \<forall>x\<in>set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
using protocol_transaction_vars_TAtom_typed(3) P by blast
hence *: "\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> (\<Union>T\<in>set P. \<Gamma>\<^sub>v ` vars_transaction T)"
using reachable_constraints_TAtom_types[of \<A> P, OF \<A>_reach] by auto
have "\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> TAtom ` insert Value (range Atom)"
proof -
have "\<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
when "T \<in> set P" "x \<in> vars_transaction T" for T x
using that protocol_transaction_vars_TAtom_typed(1)[of T] P
unfolding admissible_transaction_def
by blast
hence "(\<Union>T\<in>set P. \<Gamma>\<^sub>v ` vars_transaction T) \<subseteq> TAtom ` insert Value (range Atom)"
using P by blast
thus "\<Gamma>\<^sub>v ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<subseteq> TAtom ` insert Value (range Atom)"
using * by auto
qed
thus ?thesis using x by auto
qed
lemma reachable_constraints_Value_vars_are_fv:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and x: "x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
and "\<Gamma>\<^sub>v x = TAtom Value"
shows "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
proof -
have "\<forall>T\<in>set P. bvars_transaction T = {}"
using P unfolding list_all_iff admissible_transaction_def by metis
hence \<A>_no_bvars: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> = {}"
using reachable_constraints_no_bvars[OF \<A>_reach] by metis
thus ?thesis using x vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel \<A>"] by blast
qed
lemma reachable_constraints_subterms_subst:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model \<I> \<A>"
and P: "\<forall>T \<in> set P. admissible_transaction T"
shows "subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A> \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<I>)) = (subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
proof -
have \<A>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
by (metis reachable_constraints_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s P \<A>_reach)
from \<I> have \<I>': "welltyped_constraint_model \<I> \<A>"
using welltyped_constraint_model_prefix by auto
have 1: "\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). (\<exists>f. \<I> x = Fun f []) \<or> (\<exists>y. \<I> x = Var y)"
proof
fix x
assume xa: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
have "\<exists>f T. \<I> x = Fun f T"
using \<I> interpretation_grounds[of \<I> "Var x"]
unfolding welltyped_constraint_model_def constraint_model_def
by (cases "\<I> x") auto
then obtain f T where fT_p: "\<I> x = Fun f T"
by auto
hence "wf\<^sub>t\<^sub>r\<^sub>m (Fun f T)"
using \<I>
unfolding welltyped_constraint_model_def constraint_model_def
using wf_trm_subst_rangeD
by metis
moreover
have "x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
using xa var_subterm_trms\<^sub>s\<^sub>s\<^sub>t_is_vars\<^sub>s\<^sub>s\<^sub>t[of x "unlabel \<A>"] vars_iff_subtermeq[of x]
by auto
hence "\<exists>a. \<Gamma>\<^sub>v x = TAtom a"
using reachable_constraints_vars_TAtom_typed[OF \<A>_reach P] by blast
hence "\<exists>a. \<Gamma> (Var x) = TAtom a"
by simp
hence "\<exists>a. \<Gamma> (Fun f T) = TAtom a"
by (metis (no_types, hide_lams) \<I>' welltyped_constraint_model_def fT_p wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def)
ultimately show "(\<exists>f. \<I> x = Fun f []) \<or> (\<exists>y. \<I> x = Var y)"
using TAtom_term_cases fT_p by metis
qed
have "\<forall>T\<in>set P. bvars_transaction T = {}"
using assms unfolding list_all_iff admissible_transaction_def by metis
then have "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> = {}"
using reachable_constraints_no_bvars assms by metis
then have 2: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> subst_domain \<I> = {}"
by auto
show ?thesis
using subterms_subst_lsst[OF _ 2] 1
by simp
qed
lemma reachable_constraints_val_funs_private:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and f: "f \<in> \<Union>(funs_term ` trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
shows "is_Val f \<Longrightarrow> \<not>public f"
and "\<not>is_Abs f"
proof -
have "(is_Val f \<longrightarrow> \<not>public f) \<and> \<not>is_Abs f" using \<A>_reach f
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
let ?T' = "unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
let ?T'' = "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
have T: "admissible_transaction_terms T"
using P step.hyps(2) unfolding admissible_transaction_def by metis
show ?thesis using step
proof (cases "f \<in> \<Union>(funs_term ` trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)")
case False
then obtain t where t: "t \<in> trms\<^sub>s\<^sub>s\<^sub>t ?T'" "f \<in> funs_term t"
using step.prems trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of ?T'']
trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?T'')"]
unlabel_append[of \<A> "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?T''"] unlabel_subst[of "transaction_strand T"]
by fastforce
show ?thesis using trms\<^sub>s\<^sub>s\<^sub>t_funs_term_cases[OF t]
proof
assume "\<exists>u \<in> trms_transaction T. f \<in> funs_term u"
thus ?thesis using T unfolding admissible_transaction_terms_def by blast
next
assume "\<exists>x \<in> fv_transaction T. f \<in> funs_term ((\<sigma> \<circ>\<^sub>s \<alpha>) x)"
then obtain x where "x \<in> fv_transaction T" "f \<in> funs_term ((\<sigma> \<circ>\<^sub>s \<alpha>) x)" by moura
thus ?thesis
using transaction_fresh_subst_transaction_renaming_subst_range[OF step.hyps(3,4), of x]
by (force simp del: subst_subst_compose)
qed
qed simp
qed simp
thus "is_Val f \<Longrightarrow> \<not>public f" "\<not>is_Abs f" by simp_all
qed
lemma reachable_constraints_occurs_fact_ik_case:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and occ: "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
shows "\<exists>n. t = Fun (Val (n,False)) []"
using \<A>_reach occ
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
define \<theta> where "\<theta> \<equiv> \<sigma> \<circ>\<^sub>s \<alpha>"
have T: "wellformed_transaction T" "admissible_transaction_occurs_checks T"
using P step.hyps(2) unfolding list_all_iff admissible_transaction_def by blast+
show ?case
proof (cases "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A")
case False
hence "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using step.prems unfolding \<theta>_def by simp
hence "receive\<langle>occurs t\<rangle> \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
unfolding ik\<^sub>s\<^sub>s\<^sub>t_def by force
hence "send\<langle>occurs t\<rangle> \<in> set (unlabel (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(1) by blast
then obtain s where s:
"send\<langle>s\<rangle> \<in> set (unlabel (transaction_strand T))" "s \<cdot> \<theta> = occurs t"
by (metis (no_types) stateful_strand_step_subst_inv_cases(1) unlabel_subst)
note 0 = transaction_fresh_subst_transaction_renaming_subst_range[OF step.hyps(3,4)]
have 1: "send\<langle>s\<rangle> \<in> set (unlabel (transaction_send T))"
using s(1) wellformed_transaction_strand_unlabel_memberD(8)[OF T(1)] by blast
have 2: "is_Send (send\<langle>s\<rangle>)"
unfolding is_Send_def by simp
have 3: "\<exists>u. s = occurs u"
proof -
{ fix z
have "(\<exists>n. \<theta> z = Fun (Val (n, False)) []) \<or> (\<exists>y. \<theta> z = Var y)"
using 0
unfolding \<theta>_def
by blast
hence "\<nexists>u. \<theta> z = occurs u" "\<theta> z \<noteq> Fun OccursSec []" by auto
} note * = this
obtain u u' where T: "s = Fun OccursFact [u,u']"
using *(1) s(2) by (cases s) auto
thus ?thesis using *(2) s(2) by (cases u) auto
qed
obtain x where x: "x \<in> set (transaction_fresh T)" "s = occurs (Var x)"
using T(2) 1 2 3
unfolding admissible_transaction_occurs_checks_def
by fastforce
have "t = \<theta> x"
using s(2) x(2) by auto
thus ?thesis
using 0(1)[OF x(1)] unfolding \<theta>_def by fast
qed (simp add: step.IH)
qed simp
lemma reachable_constraints_occurs_fact_send_ex:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and x: "\<Gamma>\<^sub>v x = TAtom Value" "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
(* shows "\<exists>B. prefix B A \<and> x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<and> send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel A)" *)
shows "send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel A)"
using \<A>_reach x(2)
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
have T: "admissible_transaction_occurs_checks T"
using P step.hyps(2) unfolding list_all_iff admissible_transaction_def by blast
show ?case
proof (cases "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A")
case True
show ?thesis
using step.IH[OF True] unlabel_append[of A]
by auto
next
case False
then obtain y where y: "y \<in> fv_transaction T - set (transaction_fresh T)" "(\<sigma> \<circ>\<^sub>s \<alpha>) y = Var x"
using transaction_fresh_subst_transaction_renaming_fv[OF step.hyps(3,4), of x]
step.prems(1) fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A"] unlabel_append[of A]
by auto
have "\<sigma> y = Var y" using y(1) step.hyps(3) unfolding transaction_fresh_subst_def by auto
hence "\<alpha> y = Var x" using y(2) unfolding subst_compose_def by simp
hence y_val: "fst y = TAtom Value"
using x(1) \<Gamma>\<^sub>v_TAtom''[of x] \<Gamma>\<^sub>v_TAtom''[of y]
wt_subst_trm''[OF transaction_renaming_subst_wt[OF step.hyps(4)], of "Var y"]
by force
hence "receive\<langle>occurs (Var y)\<rangle> \<in> set (unlabel (transaction_receive T))"
using y(1) T unfolding admissible_transaction_occurs_checks_def by fast
hence *: "receive\<langle>occurs (Var y)\<rangle> \<in> set (unlabel (transaction_strand T))"
using transaction_strand_subsets(6) by blast
have "receive\<langle>occurs (Var x)\<rangle> \<in> set (unlabel (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
using y(2) unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
stateful_strand_step_subst_inI(2)[OF *, of "\<sigma> \<circ>\<^sub>s \<alpha>"]
by (auto simp del: subst_subst_compose)
hence "send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)))"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(2) by blast
thus ?thesis using unlabel_append[of A] by fastforce
qed
qed simp
lemma reachable_constraints_db\<^sub>l\<^sub>s\<^sub>s\<^sub>t_set_args_empty:
assumes \<A>: "\<A> \<in> reachable_constraints P"
and PP: "list_all wellformed_transaction P"
and admissible_transaction_updates:
"let f = (\<lambda>T. \<forall>x \<in> set (unlabel (transaction_updates T)).
is_Update x \<and> is_Var (the_elem_term x) \<and> is_Fun_Set (the_set_term x) \<and>
fst (the_Var (the_elem_term x)) = TAtom Value)
in list_all f P"
and d: "(t, s) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
shows "\<exists>ss. s = Fun (Set ss) []"
using \<A> d
proof (induction)
case (step \<A> TT \<sigma> \<alpha>)
let ?TT = "transaction_strand TT \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
let ?TTu = "unlabel ?TT"
let ?TTd = "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?TT"
let ?TTdu = "unlabel ?TTd"
from step(6) have "(t, s) \<in> set (db'\<^sub>s\<^sub>s\<^sub>t ?TTdu \<I> (db'\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>) \<I> []))"
unfolding db\<^sub>s\<^sub>s\<^sub>t_def by (simp add: db\<^sub>s\<^sub>s\<^sub>t_append)
hence "(t, s) \<in> set (db'\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>) \<I> []) \<or>
(\<exists>t' s'. insert\<langle>t',s'\<rangle> \<in> set ?TTdu \<and> t = t' \<cdot> \<I> \<and> s = s' \<cdot> \<I>)"
using db\<^sub>s\<^sub>s\<^sub>t_in_cases[of t "s" ?TTdu \<I>] by metis
thus ?case
proof
assume "\<exists>t' s'. insert\<langle>t',s'\<rangle> \<in> set ?TTdu \<and> t = t' \<cdot> \<I> \<and> s = s' \<cdot> \<I>"
then obtain t' s' where t's'_p: "insert\<langle>t',s'\<rangle> \<in> set ?TTdu" "t = t' \<cdot> \<I>" "s = s' \<cdot> \<I>" by metis
then obtain lll where "(lll, insert\<langle>t',s'\<rangle>) \<in> set ?TTd" by (meson unlabel_mem_has_label)
hence "(lll, insert\<langle>t',s'\<rangle>) \<in> set (transaction_strand TT \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_steps_iff(4) by blast
hence "insert\<langle>t',s'\<rangle> \<in> set ?TTu" by (meson unlabel_in)
hence "insert\<langle>t',s'\<rangle> \<in> set ((unlabel (transaction_strand TT)) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
by (simp add: subst_lsst_unlabel)
hence "insert\<langle>t',s'\<rangle> \<in> (\<lambda>x. x \<cdot>\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<sigma> \<circ>\<^sub>s \<alpha>) ` set (unlabel (transaction_strand TT))"
unfolding subst_apply_stateful_strand_def by auto
then obtain u where "u \<in> set (unlabel (transaction_strand TT)) \<and> u \<cdot>\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<sigma> \<circ>\<^sub>s \<alpha> = insert\<langle>t',s'\<rangle>"
by auto
hence "\<exists>t'' s''. insert\<langle>t'',s''\<rangle> \<in> set (unlabel (transaction_strand TT)) \<and>
t' = t'' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<and> s' = s'' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
by (cases u) auto
then obtain t'' s'' where t''s''_p:
"insert\<langle>t'',s''\<rangle> \<in> set (unlabel (transaction_strand TT)) \<and>
t' = t'' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<and> s' = s'' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
by auto
hence "insert\<langle>t'',s''\<rangle> \<in> set (unlabel (transaction_updates TT))"
using is_Update_in_transaction_updates[of "insert\<langle>t'',s''\<rangle>" TT]
using PP step(2) unfolding list_all_iff by auto
moreover have "\<forall>x\<in>set (unlabel (transaction_updates TT)). is_Fun_Set (the_set_term x)"
using step(2) admissible_transaction_updates unfolding is_Fun_Set_def list_all_iff by auto
ultimately have "is_Fun_Set (the_set_term (insert\<langle>t'',s''\<rangle>))" by auto
moreover have "s' = s'' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>" using t''s''_p by blast
ultimately have "is_Fun_Set (the_set_term (insert\<langle>t',s'\<rangle>))" by (auto simp add: is_Fun_Set_subst)
hence "is_Fun_Set s" by (simp add: t's'_p(3) is_Fun_Set_subst)
thus ?case using is_Fun_Set_exi by auto
qed (auto simp add: step db\<^sub>s\<^sub>s\<^sub>t_def)
qed auto
lemma reachable_constraints_occurs_fact_ik_ground:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and t: "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
shows "fv (occurs t) = {}"
proof -
have 0: "admissible_transaction T"
when "T \<in> set P" for T
using P that unfolding list_all_iff by simp
have 1: "wellformed_transaction T"
when "T \<in> set P" for T
using 0[OF that] unfolding admissible_transaction_def by simp
have 2: "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) =
(ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A) \<union> (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>)"
when "T \<in> set P" for T \<theta> and A::"('fun,'atom,'sets,'lbl) prot_constr"
using dual_transaction_ik_is_transaction_send'[OF 1[OF that]] by fastforce
have 3: "admissible_transaction_occurs_checks T"
when "T \<in> set P" for T
using 0[OF that] unfolding admissible_transaction_def by simp
show ?thesis using \<A>_reach t
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>) thus ?case
proof (cases "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A")
case False
hence "occurs t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
using 2[OF step.hyps(2)] step.prems by blast
hence "send\<langle>occurs t\<rangle> \<in> set (unlabel (transaction_send T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
using wellformed_transaction_send_receive_subst_trm_cases(2)[OF 1[OF step.hyps(2)]]
by blast
then obtain s where s:
"send\<langle>occurs s\<rangle> \<in> set (unlabel (transaction_send T))" "t = s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
using transaction_fresh_subst_transaction_renaming_subst_occurs_fact_send_receive(1)[
OF step.hyps(3,4) 1[OF step.hyps(2)]]
transaction_strand_subst_subsets(10)
by blast
obtain x where x: "x \<in> set (transaction_fresh T)" "s = Var x"
using s(1) 3[OF step.hyps(2)]
unfolding admissible_transaction_occurs_checks_def
by fastforce
have "fv t = {}"
using transaction_fresh_subst_transaction_renaming_subst_range(1)[OF step.hyps(3,4) x(1)]
s(2) x(2)
by (auto simp del: subst_subst_compose)
thus ?thesis by simp
qed simp
qed simp
qed
lemma reachable_constraints_occurs_fact_ik_funs_terms:
fixes A::"('fun,'atom,'sets,'lbl) prot_constr"
assumes \<A>_reach: "A \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model I A"
and P: "\<forall>T \<in> set P. admissible_transaction T"
shows "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I). OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana s)))" (is "?A A")
and "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I). OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana s)))" (is "?B A")
and "Fun OccursSec [] \<notin> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I" (is "?C A")
and "\<forall>x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. I x \<noteq> Fun OccursSec []" (is "?D A")
proof -
have T_adm: "admissible_transaction T" when "T \<in> set P" for T
using P that unfolding list_all_iff by simp
have T_valid: "wellformed_transaction T" when "T \<in> set P" for T
using T_adm[OF that] unfolding admissible_transaction_def by blast
have T_occ: "admissible_transaction_occurs_checks T" when "T \<in> set P" for T
using T_adm[OF that] unfolding admissible_transaction_def by blast
have \<I>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t I" by (metis \<I> welltyped_constraint_model_def)
have \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range I)"
by (metis \<I> welltyped_constraint_model_def constraint_model_def)
have \<I>_grounds: "fv (I x) = {}" "\<exists>f T. I x = Fun f T" for x
using \<I> interpretation_grounds[of I, of "Var x"] empty_fv_exists_fun[of "I x"]
unfolding welltyped_constraint_model_def constraint_model_def by auto
have 00: "fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<subseteq> vars_transaction T"
"fv\<^sub>s\<^sub>e\<^sub>t (subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))) = fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))"
for T::"('fun,'atom,'sets,'lbl) prot_transaction"
using fv_trms\<^sub>s\<^sub>s\<^sub>t_subset(1)[of "unlabel (transaction_send T)"] vars_transaction_unfold
fv_subterms_set[of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)"]
by blast+
have 0: "\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)). \<exists>a. \<Gamma> (Var x) = TAtom a"
"\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)). \<Gamma> (Var x) \<noteq> TAtom OccursSecType"
"\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))). \<exists>a. \<Gamma> (Var x) = TAtom a"
"\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))). \<Gamma> (Var x) \<noteq> TAtom OccursSecType"
"\<forall>x \<in> vars_transaction T. \<exists>a. \<Gamma> (Var x) = TAtom a"
"\<forall>x \<in> vars_transaction T. \<Gamma> (Var x) \<noteq> TAtom OccursSecType"
when "T \<in> set P" for T
using admissible_transaction_occurs_fv_types[OF T_adm[OF that]] 00
by blast+
have 1: "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<cdot>\<^sub>s\<^sub>e\<^sub>t I =
(ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I) \<union> (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta> \<cdot>\<^sub>s\<^sub>e\<^sub>t I)"
when "T \<in> set P" for T \<theta> and A::"('fun,'atom,'sets,'lbl) prot_constr"
using dual_transaction_ik_is_transaction_send'[OF T_valid[OF that]]
by fastforce
have 2: "subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta> \<cdot>\<^sub>s\<^sub>e\<^sub>t I) =
subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta> \<cdot>\<^sub>s\<^sub>e\<^sub>t I"
when "T \<in> set P" and \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)" for T \<theta>
using wt_subst_TAtom_subterms_set_subst[OF wt_subst_compose[OF \<theta>(1) \<I>_wt] 0(1)[OF that(1)]]
wf_trm_subst_rangeD[OF wf_trms_subst_compose[OF \<theta>(2) \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s]]
by auto
have 3: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
when "T \<in> set P" "transaction_fresh_subst \<sigma> T A" "transaction_renaming_subst \<alpha> P A"
for \<sigma> \<alpha> and T::"('fun,'atom,'sets,'lbl) prot_transaction"
and A::"('fun,'atom,'sets,'lbl) prot_constr"
using protocol_transaction_vars_TAtom_typed(3)[of T] P that(1)
transaction_fresh_subst_transaction_renaming_wt[OF that(2,3)]
transaction_fresh_subst_range_wf_trms[OF that(2)]
transaction_renaming_subst_range_wf_trms[OF that(3)]
wf_trms_subst_compose
by simp_all
have 4: "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)).
OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana s))) \<and>
OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
when T: "T \<in> set P" for T
proof
fix t assume t: "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))"
then obtain s where s: "send\<langle>s\<rangle> \<in> set (unlabel (transaction_send T))" "t \<in> subterms s"
using wellformed_transaction_unlabel_cases(5)[OF T_valid[OF T]]
by fastforce
have s_occ: "\<exists>x. s = occurs (Var x)" when "OccursFact \<in> funs_term t \<or> OccursSec \<in> funs_term t"
proof -
have "OccursFact \<in> funs_term s \<or> OccursSec \<in> funs_term s"
using that subtermeq_imp_funs_term_subset[OF s(2)]
by blast
thus ?thesis
using s T_occ[OF T]
unfolding admissible_transaction_occurs_checks_def
by fastforce
qed
obtain K T' where K: "Ana t = (K,T')" by moura
show "OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana t))) \<and>
OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana t)))"
proof (rule ccontr)
assume "\<not>(OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana t))) \<and>
OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana t))))"
hence a: "OccursFact \<in> \<Union>(funs_term ` set (snd (Ana t))) \<or>
OccursSec \<in> \<Union>(funs_term ` set (snd (Ana t)))"
by simp
hence "OccursFact \<in> \<Union>(funs_term ` set T') \<or> OccursSec \<in> \<Union>(funs_term ` set T')"
using K by simp
hence "OccursFact \<in> funs_term t \<or> OccursSec \<in> funs_term t"
using Ana_subterm[OF K] funs_term_subterms_eq(1)[of t] by blast
then obtain x where x: "t \<in> subterms (occurs (Var x))"
using s(2) s_occ by blast
thus False using a by fastforce
qed
qed
have 5: "OccursFact \<notin> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
"OccursSec \<notin> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
when \<sigma>\<alpha>: "transaction_fresh_subst \<sigma> T A" "transaction_renaming_subst \<alpha> P A"
for \<sigma> \<alpha> and T::"('fun,'atom,'sets,'lbl) prot_transaction"
and A::"('fun,'atom,'sets,'lbl) prot_constr"
proof -
have "OccursFact \<notin> funs_term t" "OccursSec \<notin> funs_term t"
when "t \<in> subst_range (\<sigma> \<circ>\<^sub>s \<alpha>)" for t
using transaction_fresh_subst_transaction_renaming_subst_range'[OF \<sigma>\<alpha> that]
by auto
thus "OccursFact \<notin> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
"OccursSec \<notin> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
by blast+
qed
have 6: "I x \<noteq> Fun OccursSec []" "\<nexists>t. I x = occurs t" "\<exists>a. \<Gamma> (I x) = TAtom a \<and> a \<noteq> OccursSecType"
when T: "T \<in> set P"
and \<sigma>\<alpha>: "transaction_fresh_subst \<sigma> T A" "transaction_renaming_subst \<alpha> P A"
and x: "Var x \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
for x \<sigma> \<alpha> and T::"('fun,'atom,'sets,'lbl) prot_transaction"
and A::"('fun,'atom,'sets,'lbl) prot_constr"
proof -
obtain t where t: "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)" "t \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>) = Var x"
using x by moura
then obtain y where y: "t = Var y" by (cases t) auto
have "\<exists>a. \<Gamma> t = TAtom a \<and> a \<noteq> OccursSecType"
using 0(1,2)[OF T] t(1) y
by force
thus "\<exists>a. \<Gamma> (I x) = TAtom a \<and> a \<noteq> OccursSecType"
using wt_subst_trm''[OF 3(1)[OF T \<sigma>\<alpha>]] wt_subst_trm''[OF \<I>_wt] t(2)
by (metis subst_apply_term.simps(1))
thus "I x \<noteq> Fun OccursSec []" "\<nexists>t. I x = occurs t"
by auto
qed
have 7: "I x \<noteq> Fun OccursSec []" "\<nexists>t. I x = occurs t" "\<exists>a. \<Gamma> (I x) = TAtom a \<and> a \<noteq> OccursSecType"
when T: "T \<in> set P"
and \<sigma>\<alpha>: "transaction_fresh_subst \<sigma> T A" "transaction_renaming_subst \<alpha> P A"
and x: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars_transaction T)"
for x \<sigma> \<alpha> and T::"('fun,'atom,'sets,'lbl) prot_transaction"
and A::"('fun,'atom,'sets,'lbl) prot_constr"
proof -
obtain y where y: "y \<in> vars_transaction T" "x \<in> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) y)"
using x by auto
hence y': "(\<sigma> \<circ>\<^sub>s \<alpha>) y = Var x"
using transaction_fresh_subst_transaction_renaming_subst_range'[OF \<sigma>\<alpha>]
by (cases "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<in> subst_range (\<sigma> \<circ>\<^sub>s \<alpha>)") force+
have "\<exists>a. \<Gamma> (Var y) = TAtom a \<and> a \<noteq> OccursSecType"
using 0(5,6)[OF T] y
by force
thus "\<exists>a. \<Gamma> (I x) = TAtom a \<and> a \<noteq> OccursSecType"
using wt_subst_trm''[OF 3(1)[OF T \<sigma>\<alpha>]] wt_subst_trm''[OF \<I>_wt] y'
by (metis subst_apply_term.simps(1))
thus "I x \<noteq> Fun OccursSec []" "\<nexists>t. I x = occurs t"
by auto
qed
have 8: "I x \<noteq> Fun OccursSec []" "\<nexists>t. I x = occurs t" "\<exists>a. \<Gamma> (I x) = TAtom a \<and> a \<noteq> OccursSecType"
when T: "T \<in> set P"
and \<sigma>\<alpha>: "transaction_fresh_subst \<sigma> T A" "transaction_renaming_subst \<alpha> P A"
and x: "Var x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
for x \<sigma> \<alpha> and T::"('fun,'atom,'sets,'lbl) prot_transaction"
and A::"('fun,'atom,'sets,'lbl) prot_constr"
proof -
obtain t where t: "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))" "t \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>) = Var x"
using x by moura
then obtain y where y: "t = Var y" by (cases t) auto
have "\<exists>a. \<Gamma> t = TAtom a \<and> a \<noteq> OccursSecType"
using 0(3,4)[OF T] t(1) y
by force
thus "\<exists>a. \<Gamma> (I x) = TAtom a \<and> a \<noteq> OccursSecType"
using wt_subst_trm''[OF 3(1)[OF T \<sigma>\<alpha>]] wt_subst_trm''[OF \<I>_wt] t(2)
by (metis subst_apply_term.simps(1))
thus "I x \<noteq> Fun OccursSec []" "\<nexists>t. I x = occurs t"
by auto
qed
have s_fv: "fv s \<subseteq> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars_transaction T)"
when s: "s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
and T: "T \<in> set P"
for s and \<sigma> \<alpha>::"('fun,'atom,'sets) prot_subst" and T::"('fun,'atom,'sets,'lbl) prot_transaction"
proof
fix x assume "x \<in> fv s"
hence "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using s by auto
hence *: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using fv_subterms_set_subst' by fast
have **: "list_all is_Send (unlabel (transaction_send T))"
using T_valid[OF T] unfolding wellformed_transaction_def by blast
have "x \<in> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))"
proof -
obtain t where t: "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)" "x \<in> fv (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>)"
using * by fastforce
hence "fv t \<subseteq> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)"
using fv_trms\<^sub>s\<^sub>s\<^sub>t_subset(1)[of "unlabel (transaction_send T)"]
by auto
thus ?thesis using t(2) subst_apply_fv_subset by fast
qed
thus "x \<in> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars_transaction T)"
using vars_transaction_unfold[of T] by fastforce
qed
show "?A A" using \<A>_reach
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
have *: "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)).
OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
using 4[OF step.hyps(2)] by blast
have "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha> \<cdot>\<^sub>s\<^sub>e\<^sub>t I.
OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
proof
fix t assume t: "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha> \<cdot>\<^sub>s\<^sub>e\<^sub>t I"
then obtain s u where su:
"s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>" "s \<cdot> I = t"
"u \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))" "u \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = s"
by force
obtain Ku Tu where KTu: "Ana u = (Ku,Tu)" by moura
have *: "OccursFact \<notin> \<Union>(funs_term ` set Tu)"
"OccursFact \<notin> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
"OccursFact \<notin> \<Union>(funs_term ` \<Union>(((set \<circ> snd \<circ> Ana) ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))))"
using transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)]
4[OF step.hyps(2)] su(3) KTu
by fastforce+
have "OccursFact \<notin> \<Union>(funs_term ` set (Tu \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
proof -
{ fix f assume f: "f \<in> \<Union>(funs_term ` set (Tu \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
then obtain tf where tf: "tf \<in> set Tu" "f \<in> funs_term (tf \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>)" by moura
hence "f \<in> funs_term tf \<or> f \<in> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using funs_term_subst[of tf "\<sigma> \<circ>\<^sub>s \<alpha>"] by force
hence "f \<noteq> OccursFact" using *(1,2) tf(1) by blast
} thus ?thesis by metis
qed
hence **: "OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
proof (cases u)
case (Var xu)
hence "s = (\<sigma> \<circ>\<^sub>s \<alpha>) xu" using su(4) by (metis subst_apply_term.simps(1))
thus ?thesis using *(3) by fastforce
qed (use su(4) KTu Ana_subst'[of _ _ Ku Tu "\<sigma> \<circ>\<^sub>s \<alpha>"] in simp)
show "OccursFact \<notin> \<Union>(funs_term ` set (snd (Ana t)))"
proof (cases s)
case (Var sx)
then obtain a where a: "\<Gamma> (I sx) = Var a"
using su(1) 8(3)[OF step.hyps(2,3,4), of sx] by fast
hence "Ana (I sx) = ([],[])" by (metis \<I>_grounds(2) const_type_inv[THEN Ana_const])
thus ?thesis using Var su(2) by simp
next
case (Fun f S)
hence snd_Ana_t: "snd (Ana t) = snd (Ana s) \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t I"
using su(2) Ana_subst'[of f S _ "snd (Ana s)" I] by (cases "Ana s") simp_all
{ fix g assume "g \<in> \<Union>(funs_term ` set (snd (Ana t)))"
hence "g \<in> \<Union>(funs_term ` set (snd (Ana s))) \<or>
(\<exists>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set (snd (Ana s))). g \<in> funs_term (I x))"
using snd_Ana_t funs_term_subst[of _ I] by auto
hence "g \<noteq> OccursFact"
proof
assume "\<exists>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set (snd (Ana s))). g \<in> funs_term (I x)"
then obtain x where x: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set (snd (Ana s)))" "g \<in> funs_term (I x)" by moura
have "x \<in> fv s" using x(1) Ana_vars(2)[of s] by (cases "Ana s") auto
hence "x \<in> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars_transaction T)"
using s_fv[OF su(1) step.hyps(2)] by blast
then obtain a h U where h:
"I x = Fun h U" "\<Gamma> (I x) = Var a" "a \<noteq> OccursSecType" "arity h = 0"
using \<I>_grounds(2) 7(3)[OF step.hyps(2,3,4)] const_type_inv
by metis
hence "h \<noteq> OccursFact" by auto
moreover have "U = []" using h(1,2,4) const_type_inv_wf[of h U a] \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s by fastforce
ultimately show ?thesis using h(1) x(2) by auto
qed (use ** in blast)
} thus ?thesis by blast
qed
qed
thus ?case
using step.IH step.prems 1[OF step.hyps(2), of A "\<sigma> \<circ>\<^sub>s \<alpha>"]
2[OF step.hyps(2) 3[OF step.hyps(2,3,4)]]
by auto
qed simp
show "?B A" using \<A>_reach
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
have "\<forall>s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha> \<cdot>\<^sub>s\<^sub>e\<^sub>t I.
OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
proof
fix t assume t: "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha> \<cdot>\<^sub>s\<^sub>e\<^sub>t I"
then obtain s u where su:
"s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>" "s \<cdot> I = t"
"u \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))" "u \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = s"
by force
obtain Ku Tu where KTu: "Ana u = (Ku,Tu)" by moura
have *: "OccursSec \<notin> \<Union>(funs_term ` set Tu)"
"OccursSec \<notin> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
"OccursSec \<notin> \<Union>(funs_term ` \<Union>(((set \<circ> snd \<circ> Ana) ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))))"
using transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)]
4[OF step.hyps(2)] su(3) KTu
by fastforce+
have "OccursSec \<notin> \<Union>(funs_term ` set (Tu \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
proof -
{ fix f assume f: "f \<in> \<Union>(funs_term ` set (Tu \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
then obtain tf where tf: "tf \<in> set Tu" "f \<in> funs_term (tf \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>)" by moura
hence "f \<in> funs_term tf \<or> f \<in> \<Union>(funs_term ` subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using funs_term_subst[of tf "\<sigma> \<circ>\<^sub>s \<alpha>"] by force
hence "f \<noteq> OccursSec" using *(1,2) tf(1) by blast
} thus ?thesis by metis
qed
hence **: "OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana s)))"
proof (cases u)
case (Var xu)
hence "s = (\<sigma> \<circ>\<^sub>s \<alpha>) xu" using su(4) by (metis subst_apply_term.simps(1))
thus ?thesis using *(3) by fastforce
qed (use su(4) KTu Ana_subst'[of _ _ Ku Tu "\<sigma> \<circ>\<^sub>s \<alpha>"] in simp)
show "OccursSec \<notin> \<Union>(funs_term ` set (snd (Ana t)))"
proof (cases s)
case (Var sx)
then obtain a where a: "\<Gamma> (I sx) = Var a"
using su(1) 8(3)[OF step.hyps(2,3,4), of sx] by fast
hence "Ana (I sx) = ([],[])" by (metis \<I>_grounds(2) const_type_inv[THEN Ana_const])
thus ?thesis using Var su(2) by simp
next
case (Fun f S)
hence snd_Ana_t: "snd (Ana t) = snd (Ana s) \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t I"
using su(2) Ana_subst'[of f S _ "snd (Ana s)" I] by (cases "Ana s") simp_all
{ fix g assume "g \<in> \<Union>(funs_term ` set (snd (Ana t)))"
hence "g \<in> \<Union>(funs_term ` set (snd (Ana s))) \<or>
(\<exists>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set (snd (Ana s))). g \<in> funs_term (I x))"
using snd_Ana_t funs_term_subst[of _ I] by auto
hence "g \<noteq> OccursSec"
proof
assume "\<exists>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set (snd (Ana s))). g \<in> funs_term (I x)"
then obtain x where x: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set (snd (Ana s)))" "g \<in> funs_term (I x)" by moura
have "x \<in> fv s" using x(1) Ana_vars(2)[of s] by (cases "Ana s") auto
hence "x \<in> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars_transaction T)"
using s_fv[OF su(1) step.hyps(2)] by blast
then obtain a h U where h:
"I x = Fun h U" "\<Gamma> (I x) = Var a" "a \<noteq> OccursSecType" "arity h = 0"
using \<I>_grounds(2) 7(3)[OF step.hyps(2,3,4)] const_type_inv
by metis
hence "h \<noteq> OccursSec" by auto
moreover have "U = []" using h(1,2,4) const_type_inv_wf[of h U a] \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s by fastforce
ultimately show ?thesis using h(1) x(2) by auto
qed (use ** in blast)
} thus ?thesis by blast
qed
qed
thus ?case
using step.IH step.prems 1[OF step.hyps(2), of A "\<sigma> \<circ>\<^sub>s \<alpha>"]
2[OF step.hyps(2) 3[OF step.hyps(2,3,4)]]
by auto
qed simp
show "?C A" using \<A>_reach
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
have *: "Fun OccursSec [] \<notin> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)"
using wellformed_transaction_unlabel_cases(5)[OF T_valid[OF step.hyps(2)]]
T_occ[OF step.hyps(2)]
unfolding admissible_transaction_occurs_checks_def
by fastforce
have **: "Fun OccursSec [] \<notin> subst_range (\<sigma> \<circ>\<^sub>s \<alpha>)"
using transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)]
by auto
have "Fun OccursSec [] \<notin> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha> \<cdot>\<^sub>s\<^sub>e\<^sub>t I"
proof
assume "Fun OccursSec [] \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha> \<cdot>\<^sub>s\<^sub>e\<^sub>t I"
then obtain s where "s \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>" "s \<cdot> I = Fun OccursSec []"
by moura
moreover have "Fun OccursSec [] \<notin> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
proof
assume "Fun OccursSec [] \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
then obtain u where "u \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)" "u \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> = Fun OccursSec []"
by moura
thus False using * ** by (cases u) (force simp del: subst_subst_compose)+
qed
ultimately show False using 6[OF step.hyps(2,3,4)] by (cases s) auto
qed
thus ?case using step.IH step.prems 1[OF step.hyps(2), of A "\<sigma> \<circ>\<^sub>s \<alpha>"] by fast
qed simp
show "?D A" using \<A>_reach
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
{ fix x assume x: "x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
hence x': "x \<in> vars\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
by (metis vars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq unlabel_subst)
hence "x \<in> vars_transaction T \<or> x \<in> fv\<^sub>s\<^sub>e\<^sub>t ((\<sigma> \<circ>\<^sub>s \<alpha>) ` vars_transaction T)"
using vars\<^sub>s\<^sub>s\<^sub>t_subst_cases[OF x'] by metis
moreover have "I x \<noteq> Fun OccursSec []" when "x \<in> vars_transaction T"
using that 0(5,6)[OF step.hyps(2)] wt_subst_trm''[OF \<I>_wt, of "Var x"]
by fastforce
ultimately have "I x \<noteq> Fun OccursSec []"
using 7(1)[OF step.hyps(2,3,4), of x]
by blast
} thus ?case using step.IH by auto
qed simp
qed
lemma reachable_constraints_occurs_fact_ik_subst_aux:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model I A"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and t: "t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "t \<cdot> I = occurs s"
shows "\<exists>u. t = occurs u"
proof -
have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t I"
using \<I> unfolding welltyped_constraint_model_def constraint_model_def by metis
hence 0: "\<Gamma> t = \<Gamma> (occurs s)"
using t(2) wt_subst_trm'' by metis
have 1: "\<Gamma>\<^sub>v ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<subseteq> (\<Union>T \<in> set P. \<Gamma>\<^sub>v ` fv_transaction T)"
"\<forall>T \<in> set P. \<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
using reachable_constraints_TAtom_types(1)[OF \<A>_reach]
protocol_transaction_vars_TAtom_typed(2,3) P
by fast+
show ?thesis
proof (cases t)
case (Var x)
thus ?thesis
using 0 1 t(1) var_subterm_ik\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t[of x "unlabel A"]
by fastforce
next
case (Fun f T)
hence 2: "f = OccursFact" "length T = Suc (Suc 0)" "T ! 0 \<cdot> I = Fun OccursSec []"
using t(2) by auto
have "T ! 0 = Fun OccursSec []"
proof (cases "T ! 0")
case (Var y)
hence "I y = Fun OccursSec []" using Fun 2(3) by simp
moreover have "Var y \<in> set T" using Var 2(2) length_Suc_conv[of T 1] by auto
hence "y \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" using Fun t(1) by force
hence "y \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
using fv_ik_subset_fv_sst'[of "unlabel A"] vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel A"]
by blast
ultimately have False
using reachable_constraints_occurs_fact_ik_funs_terms(4)[OF \<A>_reach \<I> P]
by blast
thus ?thesis by simp
qed (use 2(3) in simp)
moreover have "\<exists>u u'. T = [u,u']"
using 2(2) by (metis (no_types, lifting) Suc_length_conv length_0_conv)
ultimately show ?thesis using Fun 2(1,2) by force
qed
qed
lemma reachable_constraints_occurs_fact_ik_subst:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model I A"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and t: "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I"
shows "occurs t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
proof -
have \<I>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t I"
using \<I> unfolding welltyped_constraint_model_def constraint_model_def by metis
obtain s where s: "s \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "s \<cdot> I = occurs t"
using t by auto
hence u: "\<exists>u. s = occurs u"
using \<I>_wt reachable_constraints_occurs_fact_ik_subst_aux[OF \<A>_reach \<I> P]
by blast
hence "fv s = {}"
using reachable_constraints_occurs_fact_ik_ground[OF \<A>_reach P] s
by fast
thus ?thesis
using s u subst_ground_ident[of s I]
by argo
qed
lemma reachable_constraints_occurs_fact_send_in_ik:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model I A"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and x: "send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel A)"
shows "occurs (I x) \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
using \<A>_reach \<I> x
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
define \<theta> where "\<theta> \<equiv> \<sigma> \<circ>\<^sub>s \<alpha>"
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)"
have T_adm: "admissible_transaction T"
using P step.hyps(2) unfolding list_all_iff by blast
have T_valid: "wellformed_transaction T"
using T_adm unfolding admissible_transaction_def by blast
have T_adm_occ: "admissible_transaction_occurs_checks T"
using T_adm unfolding admissible_transaction_def by blast
have \<I>_is_T_model: "strand_sem_stateful (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I) (set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t A I)) (unlabel T') I"
using step.prems unlabel_append[of A T'] db\<^sub>s\<^sub>s\<^sub>t_set_is_dbupd\<^sub>s\<^sub>s\<^sub>t[of "unlabel A" I "[]"]
strand_sem_append_stateful[of "{}" "{}" "unlabel A" "unlabel T'" I]
by (simp add: T'_def \<theta>_def welltyped_constraint_model_def constraint_model_def db\<^sub>s\<^sub>s\<^sub>t_def)
show ?case
proof (cases "send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel A)")
case False
hence "send\<langle>occurs (Var x)\<rangle> \<in> set (unlabel T')"
using step.prems(2) unfolding T'_def \<theta>_def by simp
hence "receive\<langle>occurs (Var x)\<rangle> \<in> set (unlabel (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(2) unfolding T'_def by blast
then obtain y where y:
"receive\<langle>occurs (Var y)\<rangle> \<in> set (unlabel (transaction_receive T))"
"\<theta> y = Var x"
using transaction_fresh_subst_transaction_renaming_subst_occurs_fact_send_receive(2)[
OF step.hyps(3,4) T_valid]
subst_to_var_is_var[of _ \<theta> x]
unfolding \<theta>_def by (force simp del: subst_subst_compose)
hence "receive\<langle>occurs (Var y) \<cdot> \<theta>\<rangle> \<in> set (unlabel (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"
using subst_lsst_unlabel_member[of "receive\<langle>occurs (Var y)\<rangle>" "transaction_receive T" \<theta>]
by fastforce
hence "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I \<turnstile> occurs (Var y) \<cdot> \<theta> \<cdot> I"
using wellformed_transaction_sem_receives[
OF T_valid, of "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I" "set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t A I)" \<theta> I "occurs (Var y) \<cdot> \<theta>"]
\<I>_is_T_model
by (metis T'_def)
hence *: "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t I \<turnstile> occurs (\<theta> y \<cdot> I)"
by auto
have "occurs (\<theta> y \<cdot> I) \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
using deduct_occurs_in_ik[OF *]
reachable_constraints_occurs_fact_ik_subst[
OF step.hyps(1) welltyped_constraint_model_prefix[OF step.prems(1)] P, of "\<theta> y \<cdot> I"]
reachable_constraints_occurs_fact_ik_funs_terms[
OF step.hyps(1) welltyped_constraint_model_prefix[OF step.prems(1)] P]
by blast
thus ?thesis using y(2) by simp
qed (simp add: step.IH[OF welltyped_constraint_model_prefix[OF step.prems(1)]])
qed simp
lemma reachable_contraints_fv_bvars_subset:
assumes A: "A \<in> reachable_constraints P"
shows "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<subseteq> (\<Union>T \<in> set P. bvars_transaction T)"
using assms
proof (induction A rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
let ?T' = "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
show ?case
using step.IH step.hyps(2)
bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of ?T']
bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
bvars\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?T')"]
unlabel_append[of \<A> "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?T'"]
by (metis (no_types, lifting) SUP_upper Un_subset_iff)
qed simp
lemma reachable_contraints_fv_disj:
assumes A: "A \<in> reachable_constraints P"
shows "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<inter> (\<Union>T \<in> set P. bvars_transaction T) = {}"
using A
proof (induction A rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
define T' where "T' \<equiv> transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
define X where "X \<equiv> \<Union>T \<in> set P. bvars_transaction T"
have "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<inter> X = {}"
using transaction_fresh_subst_transaction_renaming_subst_vars_disj(4)[OF step.hyps(3,4)]
transaction_fresh_subst_transaction_renaming_subst_vars_subset(4)[OF step.hyps(3,4,2)]
unfolding T'_def X_def by blast
hence "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T') \<inter> X = {}"
using step.IH[unfolded X_def[symmetric]] fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of T'] by auto
thus ?case unfolding T'_def X_def by blast
qed simp
lemma reachable_contraints_fv_bvars_disj:
assumes P: "\<forall>T \<in> set P. wellformed_transaction T"
and A: "A \<in> reachable_constraints P"
shows "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A = {}"
using A
proof (induction A rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
note 0 = transaction_fresh_subst_transaction_renaming_subst_vars_disj[OF step.hyps(3,4)]
note 1 = transaction_fresh_subst_transaction_renaming_subst_vars_subset[OF step.hyps(3,4)]
have 2: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = {}"
using 0(7) 1(4)[OF step.hyps(2)] fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq
unfolding T'_def by (metis (no_types) disjoint_iff_not_equal subset_iff)
have "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> \<Union>(bvars_transaction ` set P)"
"fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> \<Union>(bvars_transaction ` set P) = {}"
using reachable_contraints_fv_bvars_subset[OF reachable_constraints.step[OF step.hyps]]
reachable_contraints_fv_disj[OF reachable_constraints.step[OF step.hyps]]
unfolding T'_def by auto
hence 3: "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = {}" by blast
have "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>) \<inter> bvars_transaction T = {}"
using 0(4)[OF step.hyps(2)] 1(4)[OF step.hyps(2)] by blast
hence 4: "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = {}"
by (metis (no_types) T'_def fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq
unlabel_subst bvars\<^sub>s\<^sub>s\<^sub>t_subst)
have "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T') \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T') = {}"
using 2 3 4 step.IH
unfolding unlabel_append[of \<A> T']
fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel T'"]
bvars\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel T'"]
by fast
thus ?case unfolding T'_def by blast
qed simp
lemma reachable_constraints_wf:
assumes P:
"\<forall>T \<in> set P. wellformed_transaction T"
"\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
and A: "A \<in> reachable_constraints P"
shows "wf\<^sub>s\<^sub>s\<^sub>t (unlabel A)"
and "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)"
proof -
have "wellformed_transaction T"
when "T \<in> set P" for T
using P(1) that by fast+
hence 0: "wf'\<^sub>s\<^sub>s\<^sub>t (set (transaction_fresh T)) (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)))"
"fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)) \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)) = {}"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms_transaction T)"
when T: "T \<in> set P" for T
unfolding admissible_transaction_terms_def
by (metis T wellformed_transaction_wf\<^sub>s\<^sub>s\<^sub>t(1),
metis T wellformed_transaction_wf\<^sub>s\<^sub>s\<^sub>t(2) fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq,
metis T wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_code P(2))
from A have "wf\<^sub>s\<^sub>s\<^sub>t (unlabel A) \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)"
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
let ?T' = "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
have IH: "wf'\<^sub>s\<^sub>s\<^sub>t {} (unlabel A)" "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A = {}" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)"
using step.IH by metis+
have 1: "wf'\<^sub>s\<^sub>s\<^sub>t {} (unlabel (A@?T'))"
using protocol_transaction_wf_subst[OF 0(1)[OF step.hyps(2)] step.hyps(3,4)]
wf\<^sub>s\<^sub>s\<^sub>t_vars_mono[of "{}"] wf\<^sub>s\<^sub>s\<^sub>t_append[OF IH(1)]
by simp
have 2: "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@?T') \<inter> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@?T') = {}"
using reachable_contraints_fv_bvars_disj[OF P(1)]
reachable_constraints.step[OF step.hyps]
by blast
have "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?T')"
using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq unlabel_subst
wf_trms_subst[
OF wf_trms_subst_compose[
OF transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]],
THEN wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_trms\<^sub>s\<^sub>s\<^sub>t_subst,
OF 0(3)[OF step.hyps(2)]]
by metis
hence 3: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@?T'))"
using IH(3) by auto
show ?case using 1 2 3 by force
qed simp
thus "wf\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" by metis+
qed
lemma reachable_constraints_no_Ana_Attack:
assumes \<A>: "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and t: "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
shows "attack\<langle>n\<rangle> \<notin> set (snd (Ana t))"
proof -
have T_adm: "admissible_transaction T" when "T \<in> set P" for T
using P that by blast
have T_adm_term: "admissible_transaction_terms T" when "T \<in> set P" for T
using T_adm[OF that] unfolding admissible_transaction_def by blast
have T_valid: "wellformed_transaction T" when "T \<in> set P" for T
using T_adm[OF that] unfolding admissible_transaction_def by blast
show ?thesis
using \<A> t
proof (induction \<A> rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>) thus ?case
proof (cases "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)")
case False
hence "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)))"
using step.prems by simp
hence "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using dual_transaction_ik_is_transaction_send'[OF T_valid[OF step.hyps(2)]]
by metis
hence "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
using transaction_fresh_subst_transaction_renaming_subst_trms[
OF step.hyps(3,4), of "transaction_send T"]
wellformed_transaction_unlabel_cases(5)[OF T_valid[OF step.hyps(2)]]
by fastforce
then obtain s where s: "s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T))" "t = s \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
by moura
hence s': "attack\<langle>n\<rangle> \<notin> set (snd (Ana s))"
using admissible_transaction_no_Ana_Attack[OF T_adm_term[OF step.hyps(2)]]
trms_transaction_unfold[of T]
by blast
note * = transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)]
show ?thesis
proof
assume n: "attack\<langle>n\<rangle> \<in> set (snd (Ana t))"
thus False
proof (cases s)
case (Var x) thus ?thesis using Var * n s(2) by (force simp del: subst_subst_compose)
next
case (Fun f T)
hence "attack\<langle>n\<rangle> \<in> set (snd (Ana s)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
using Ana_subst'[of f T _ "snd (Ana s)" "\<sigma> \<circ>\<^sub>s \<alpha>"] s(2) s' n
by (cases "Ana s") auto
hence "attack\<langle>n\<rangle> \<in> set (snd (Ana s)) \<or> attack\<langle>n\<rangle> \<in> subst_range (\<sigma> \<circ>\<^sub>s \<alpha>)"
using const_mem_subst_cases' by fast
thus ?thesis using * s' by blast
qed
qed
qed simp
qed simp
qed
lemma constraint_model_Value_term_is_Val:
assumes \<A>_reach: "A \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model I A"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and x: "\<Gamma>\<^sub>v x = TAtom Value" "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
shows "\<exists>n. I x = Fun (Val (n,False)) []"
using reachable_constraints_occurs_fact_send_ex[OF \<A>_reach P x]
reachable_constraints_occurs_fact_send_in_ik[OF \<A>_reach \<I> P]
reachable_constraints_occurs_fact_ik_case[OF \<A>_reach P]
by fast
lemma constraint_model_Value_term_is_Val':
assumes \<A>_reach: "A \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model I A"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and x: "(TAtom Value, m) \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
shows "\<exists>n. I (TAtom Value, m) = Fun (Val (n,False)) []"
using constraint_model_Value_term_is_Val[OF \<A>_reach \<I> P _ x] by simp
(* We use this lemma to show that fresh constants first occur in \<I>(\<A>) at the point where they were generated *)
lemma constraint_model_Value_var_in_constr_prefix:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model \<I> \<A>"
and P: "\<forall>T \<in> set P. admissible_transaction T"
shows "\<forall>x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>. \<Gamma>\<^sub>v x = TAtom Value
\<longrightarrow> (\<exists>B. prefix B \<A> \<and> x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<and> \<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B))" (is "?P \<A>")
using \<A>_reach \<I>
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
have IH: "?P \<A>" using step welltyped_constraint_model_prefix by fast
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
have T_adm: "admissible_transaction T"
by (metis P step.hyps(2))
have T_valid: "wellformed_transaction T"
by (metis T_adm admissible_transaction_def)
have \<I>_is_T_model: "strand_sem_stateful (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) (set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)) (unlabel T') \<I>"
using step.prems unlabel_append[of \<A> T'] db\<^sub>s\<^sub>s\<^sub>t_set_is_dbupd\<^sub>s\<^sub>s\<^sub>t[of "unlabel \<A>" \<I> "[]"]
strand_sem_append_stateful[of "{}" "{}" "unlabel \<A>" "unlabel T'" \<I>]
by (simp add: T'_def welltyped_constraint_model_def constraint_model_def db\<^sub>s\<^sub>s\<^sub>t_def)
have \<I>_interp: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>"
and \<I>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>"
and \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)"
by (metis \<I> welltyped_constraint_model_def constraint_model_def,
metis \<I> welltyped_constraint_model_def,
metis \<I> welltyped_constraint_model_def constraint_model_def)
have 1: "\<exists>B. prefix B \<A> \<and> x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<and> \<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
when x: "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'" "\<Gamma>\<^sub>v x = TAtom Value" for x
proof -
obtain n where n: "\<I> x = Fun n []" "is_Val n \<or> is_Abs n" "\<not>public n"
using constraint_model_Value_term_is_Val[
OF reachable_constraints.step[OF step.hyps] step.prems P x(2)]
x(1) fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel T'"] unlabel_append[of \<A> T']
unfolding T'_def by moura
have "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using x(1) fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq unfolding T'_def by fastforce
then obtain y where y: "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)" "x \<in> fv ((\<sigma> \<circ>\<^sub>s \<alpha>) y)"
using fv\<^sub>s\<^sub>s\<^sub>t_subst_obtain_var[of x "unlabel (transaction_strand T)" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by auto
have y_x: "(\<sigma> \<circ>\<^sub>s \<alpha>) y = Var x"
using y(2) transaction_fresh_subst_transaction_renaming_subst_range[OF step.hyps(3,4), of y]
by force
have "\<Gamma> ((\<sigma> \<circ>\<^sub>s \<alpha>) y) = TAtom Value" using x(2) y_x by simp
moreover have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using protocol_transaction_vars_TAtom_typed(3) P(1) step.hyps(2)
transaction_fresh_subst_transaction_renaming_wt[OF step.hyps(3,4)]
by fast
ultimately have y_val: "\<Gamma>\<^sub>v y = TAtom Value"
by (metis wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def \<Gamma>.simps(1))
have y_not_fresh: "y \<notin> set (transaction_fresh T)"
using y(2) transaction_fresh_subst_transaction_renaming_subst_range(1)[OF step.hyps(3,4)]
by fastforce
have y_n: "Fun n [] = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>" using n y_x by simp
hence y_n': "Fun n [] = (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>) y"
by (metis subst_subst_compose[of "Var y" "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>] subst_apply_term.simps(1))
have "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T) \<or> y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
using wellformed_transaction_fv_in_receives_or_selects[OF T_valid] y(1) y_not_fresh by blast
hence n_cases:
"Fun n [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<or>
(\<exists>z \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>. \<Gamma>\<^sub>v z = TAtom Value \<and> \<I> z = Fun n [])"
proof
assume y_in: "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T)"
then obtain t where t: "receive\<langle>t\<rangle> \<in> set (unlabel (transaction_receive T))" "y \<in> fv t"
using admissible_transaction_strand_step_cases(1)[OF T_adm]
by force
hence "receive\<langle>t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>\<rangle> \<in> set (unlabel (transaction_receive T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
using subst_lsst_unlabel_member[of "receive\<langle>t\<rangle>" "transaction_receive T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by fastforce
hence *: "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<turnstile> t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I>"
using wellformed_transaction_sem_receives[
OF T_valid, of "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>" "set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)" "\<sigma> \<circ>\<^sub>s \<alpha>" \<I> "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"]
\<I>_is_T_model
by (metis T'_def)
have "\<exists>a. \<Gamma> (\<I> x) = Var a" when "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" for x
using that reachable_constraints_vars_TAtom_typed[OF step.hyps(1) P, of x]
vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel \<A>"] wt_subst_trm''[OF \<I>_wt, of "Var x"]
by force
hence "\<exists>f. \<I> x = Fun f []" when "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" for x
using that wf_trm_subst[OF \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s, of "Var x"] wf_trm_Var[of x] const_type_inv_wf
empty_fv_exists_fun[OF interpretation_grounds[OF \<I>_interp], of "Var x"]
by (metis subst_apply_term.simps(1)[of x \<I>])
hence \<A>_ik_\<I>_vals: "\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). \<exists>f. \<I> x = Fun f []"
using fv_ik_subset_fv_sst'[of "unlabel \<A>"] vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel \<A>"]
by blast
hence "subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) = subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
using ik\<^sub>s\<^sub>s\<^sub>t_subst[of "unlabel \<A>" \<I>] unlabel_subst[of \<A> \<I>]
subterms_subst_lsst_ik[of \<A> \<I>]
by metis
moreover have "v \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" when "v \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" for v
by (meson contra_subsetD fv_ik_subset_fv_sst' that)
moreover have "Fun n [] \<in> subterms (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I>)"
using imageI[of "Var y" "subterms t" "\<lambda>x. x \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>"]
var_is_subterm[OF t(2)] subterms_subst_subset[of "\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>" t]
subst_subst_compose[of t "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>] y_n'
by (auto simp del: subst_subst_compose)
hence "Fun n [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>)"
using private_fun_deduct_in_ik[OF *, of n "[]"] n(2,3)
unfolding is_Val_def is_Abs_def
by auto
hence "Fun n [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<or>
(\<exists>z \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). Fun n [] \<in> subterms (\<I> z))"
using const_subterm_subst_cases[of n _ \<I>]
by auto
hence "Fun n [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<or> (\<exists>z \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). \<I> z = Fun n [])"
using \<A>_ik_\<I>_vals by fastforce
hence "Fun n [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<or>
(\<exists>z \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). \<Gamma>\<^sub>v z = TAtom Value \<and> \<I> z = Fun n [])"
using \<I>_wt n(2) unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def is_Val_def is_Abs_def by force
ultimately show ?thesis using ik\<^sub>s\<^sub>s\<^sub>t_trms\<^sub>s\<^sub>s\<^sub>t_subset[of "unlabel \<A>"] by fast
next
assume y_in: "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
then obtain s where s: "select\<langle>Var y,Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_selects T))"
using admissible_transaction_strand_step_cases(2)[OF T_adm]
by force
hence "select\<langle>(\<sigma> \<circ>\<^sub>s \<alpha>) y, Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_selects T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
using subst_lsst_unlabel_member
by fastforce
hence n_in_db: "(Fun n [], Fun (Set s) []) \<in> set (db'\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>) \<I> [])"
using wellformed_transaction_sem_selects[
OF T_valid, of "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>" "set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)" "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>
"(\<sigma> \<circ>\<^sub>s \<alpha>) y" "Fun (Set s) []"]
\<I>_is_T_model n y_x
unfolding T'_def db\<^sub>s\<^sub>s\<^sub>t_def
by fastforce
obtain tn sn where tsn: "insert\<langle>tn,sn\<rangle> \<in> set (unlabel \<A>)" "Fun n [] = tn \<cdot> \<I>"
using db\<^sub>s\<^sub>s\<^sub>t_in_cases[OF n_in_db] by force
have "Fun n [] = tn \<or> (\<exists>z. \<Gamma>\<^sub>v z = TAtom Value \<and> tn = Var z)"
using \<I>_wt tsn(2) n(2) unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def is_Val_def is_Abs_def by (cases tn) auto
moreover have "tn \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" "fv tn \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
using tsn(1) in_subterms_Union by force+
ultimately show ?thesis using tsn(2) by auto
qed
have x_nin_\<A>: "x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
proof -
have "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using x(1) fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq
unfolding T'_def
by fast
hence "x \<in> fv\<^sub>s\<^sub>s\<^sub>t ((unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma>) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<alpha>)"
using transaction_fresh_subst_grounds_domain[OF step.hyps(3)] step.hyps(3)
labeled_stateful_strand_subst_comp[of \<sigma> "transaction_strand T" \<alpha>]
unlabel_subst[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma>" \<alpha>]
unlabel_subst[of "transaction_strand T" \<sigma>]
by (simp add: transaction_fresh_subst_def range_vars_alt_def)
then obtain y where y: "\<alpha> y = Var x"
using transaction_renaming_subst_var_obtain[OF _ step.hyps(4)]
by blast
thus ?thesis
using transaction_renaming_subst_range_notin_vars[OF step.hyps(4), of y]
vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel \<A>"]
by auto
qed
from n_cases show ?thesis
proof
assume "\<exists>z \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>. \<Gamma>\<^sub>v z = TAtom Value \<and> \<I> z = Fun n []"
then obtain B where B: "prefix B \<A>" "Fun n [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
by (metis IH n(1))
thus ?thesis
using n x_nin_\<A> trms\<^sub>s\<^sub>s\<^sub>t_unlabel_prefix_subset(1)[of B]
by (metis (no_types, hide_lams) self_append_conv subset_iff subterms\<^sub>s\<^sub>e\<^sub>t_mono prefix_def)
qed (use n x_nin_\<A> in fastforce)
qed
have "?P (\<A>@T')"
proof (intro ballI impI)
fix x assume x: "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T')" "\<Gamma>\<^sub>v x = TAtom Value"
show "\<exists>B. prefix B (\<A>@T') \<and> x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<and> \<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
proof (cases "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>")
case False
hence x': "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'" using x(1) unlabel_append[of \<A>] fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] by simp
then obtain B where B: "prefix B \<A>" "x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B" "\<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
using x(2) 1 by moura
thus ?thesis using prefix_prefix by fast
qed (use x(2) IH prefix_prefix in fast)
qed
thus ?case unfolding T'_def by blast
qed simp
lemma admissible_transaction_occurs_checks_prop:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model \<I> \<A>"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and f: "f \<in> \<Union>(funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
shows "is_Val f \<Longrightarrow> \<not>public f"
and "\<not>is_Abs f"
proof -
obtain x where x: "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" "f \<in> funs_term (\<I> x)" using f by moura
obtain T where T: "Fun f T \<sqsubseteq> \<I> x" using funs_term_Fun_subterm[OF x(2)] by moura
have \<I>_interp: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>"
and \<I>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>"
and \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)"
by (metis \<I> welltyped_constraint_model_def constraint_model_def,
metis \<I> welltyped_constraint_model_def,
metis \<I> welltyped_constraint_model_def constraint_model_def)
have 1: "\<Gamma> (Var x) = \<Gamma> (\<I> x)" using wt_subst_trm''[OF \<I>_wt, of "Var x"] by simp
hence "\<exists>a. \<Gamma> (\<I> x) = Var a"
using x(1) reachable_constraints_vars_TAtom_typed[OF \<A>_reach P, of x]
vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel \<A>"]
by force
hence "\<exists>f. \<I> x = Fun f []"
using x(1) wf_trm_subst[OF \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s, of "Var x"] wf_trm_Var[of x] const_type_inv_wf
empty_fv_exists_fun[OF interpretation_grounds[OF \<I>_interp], of "Var x"]
by (metis subst_apply_term.simps(1)[of x \<I>])
hence 2: "\<I> x = Fun f []" using x(2) by force
have "(is_Val f \<longrightarrow> \<not>public f) \<and> \<not>is_Abs f"
proof (cases "\<Gamma>\<^sub>v x = TAtom Value")
case True
then obtain B where B: "prefix B \<A>" "x \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B" "\<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
using constraint_model_Value_var_in_constr_prefix[OF \<A>_reach \<I> P] x(1)
by fast
have "\<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
using B(1,3) trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel B"] unlabel_append[of B]
unfolding prefix_def by auto
hence "f \<in> \<Union>(funs_term ` trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
using x(2) funs_term_subterms_eq(2)[of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"] by blast
thus ?thesis
using reachable_constraints_val_funs_private[OF \<A>_reach P]
by blast+
next
case False thus ?thesis using x 1 2 by (cases f) auto
qed
thus "is_Val f \<Longrightarrow> \<not>public f" "\<not>is_Abs f" by metis+
qed
lemma admissible_transaction_occurs_checks_prop':
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model \<I> \<A>"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and f: "f \<in> \<Union>(funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
shows "\<nexists>n. f = Val (n,True)"
and "\<nexists>n. f = Abs n"
using admissible_transaction_occurs_checks_prop[OF \<A>_reach \<I> P f] by auto
lemma transaction_var_becomes_Val:
assumes \<A>_reach: "\<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>) \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model \<I> (\<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>))"
and \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and T: "T \<in> set P"
and x: "x \<in> fv_transaction T" "fst x = TAtom Value"
shows "\<exists>n. Fun (Val (n,False)) [] = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I>"
proof -
obtain m where m: "x = (TAtom Value, m)" by (metis x(2) eq_fst_iff)
have x_not_bvar: "x \<notin> bvars_transaction T" "fv ((\<sigma> \<circ>\<^sub>s \<alpha>) x) \<inter> bvars_transaction T = {}"
using x(1) transactions_fv_bvars_disj[OF P] T
transaction_fresh_subst_transaction_renaming_subst_vars_disj(2)[OF \<sigma> \<alpha>, of x]
vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel (transaction_strand T)"]
by blast+
show ?thesis
proof (cases "x \<in> subst_domain \<sigma>")
case True
then obtain n where "\<sigma> x = Fun (Val (n, False)) []"
using \<sigma> unfolding transaction_fresh_subst_def by fastforce
thus ?thesis using subst_compose[of \<sigma> \<alpha> x] by simp
next
case False
hence "\<sigma> x = Var x" by auto
then obtain n where n: "(\<sigma> \<circ>\<^sub>s \<alpha>) x = Var (TAtom Value, n)"
using m transaction_renaming_subst_is_renaming[OF \<alpha>] subst_compose[of \<sigma> \<alpha> x]
by force
hence "(TAtom Value, n) \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using x_not_bvar fv\<^sub>s\<^sub>s\<^sub>t_subst_fv_subset[OF x(1), of "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by force
hence "\<exists>n'. \<I> (TAtom Value, n) = Fun (Val (n',False)) []"
using constraint_model_Value_term_is_Val'[OF \<A>_reach \<I> P, of n] x
fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] unlabel_append[of \<A>]
by fastforce
thus ?thesis using n by simp
qed
qed
lemma reachable_constraints_SMP_subset:
assumes \<A>: "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
shows "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>) \<subseteq> SMP (\<Union>T \<in> set P. trms_transaction T)" (is "?A \<A>")
and "SMP (pair`setops\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>)) \<subseteq> SMP (\<Union>T\<in>set P. pair`setops_transaction T)" (is "?B \<A>")
proof -
have "?A \<A> \<and> ?B \<A>" using \<A>
proof (induction \<A> rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
define T' where "T' \<equiv> transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
define M where "M \<equiv> \<Union>T \<in> set P. trms_transaction T"
define N where "N \<equiv> \<Union>T \<in> set P. pair ` setops_transaction T"
let ?P = "\<lambda>t. \<exists>s \<delta>. s \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = s \<cdot> \<delta>"
let ?Q = "\<lambda>t. \<exists>s \<delta>. s \<in> N \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = s \<cdot> \<delta>"
have IH: "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A) \<subseteq> SMP M" "SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)) \<subseteq> SMP N"
using step.IH by (metis M_def, metis N_def)
have \<sigma>\<alpha>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using P(1) step.hyps(2)
transaction_fresh_subst_transaction_renaming_wt[OF step.hyps(3,4)]
by fast
have \<sigma>\<alpha>_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]
by (metis wf_trms_subst_compose)
have 0: "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')) = SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A) \<union> SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
"SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'))) =
SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)) \<union> SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel T'))"
using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of T']
setops\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of T']
trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A" "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"]
setops\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A" "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"]
unlabel_append[of A "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'"]
image_Un[of pair "setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "setops\<^sub>s\<^sub>s\<^sub>t (unlabel T')"]
SMP_union[of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'"]
SMP_union[of "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel T')"]
by argo+
have 1: "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T') \<subseteq> SMP M"
proof (intro SMP_subset_I ballI)
fix t show "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<Longrightarrow> ?P t"
using trms\<^sub>s\<^sub>s\<^sub>t_wt_subst_ex[OF \<sigma>\<alpha>_wt \<sigma>\<alpha>_wf, of t "unlabel (transaction_strand T)"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"] step.hyps(2)
unfolding T'_def M_def by auto
qed
have 2: "SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel T')) \<subseteq> SMP N"
proof (intro SMP_subset_I ballI)
fix t show "t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel T') \<Longrightarrow> ?Q t"
using setops\<^sub>s\<^sub>s\<^sub>t_wt_subst_ex[OF \<sigma>\<alpha>_wt \<sigma>\<alpha>_wf, of t "unlabel (transaction_strand T)"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"] step.hyps(2)
unfolding T'_def N_def by auto
qed
have "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')) \<subseteq> SMP M"
"SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'))) \<subseteq> SMP N"
using 0 1 2 IH by blast+
thus ?case unfolding T'_def M_def N_def by blast
qed (simp add: setops\<^sub>s\<^sub>s\<^sub>t_def)
thus "?A \<A>" "?B \<A>" by metis+
qed
lemma reachable_constraints_no_Pair_fun:
assumes A: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
shows "Pair \<notin> \<Union>(funs_term ` SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A))"
using A
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
have T_adm: "admissible_transaction T" using step.hyps(2) P unfolding list_all_iff by blast
have \<sigma>\<alpha>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using protocol_transaction_vars_TAtom_typed(3) P(1) step.hyps(2)
transaction_fresh_subst_transaction_renaming_wt[OF step.hyps(3,4)]
by fast
have \<sigma>\<alpha>_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]
by (metis wf_trms_subst_compose)
have 0: "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T')) = SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A) \<union> SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
using SMP_union[of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'"]
unlabel_append[of A T'] trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A" "unlabel T'"]
by simp
have 1: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
using reachable_constraints_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s[OF _ reachable_constraints.step[OF step.hyps]]
admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s P
trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A"] unlabel_append[of A]
unfolding T'_def by force
have 2: "Pair \<notin> \<Union>(funs_term ` (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>)))"
using transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)] by force
have "Pair \<notin> \<Union>(funs_term ` (trms_transaction T))"
using T_adm
unfolding admissible_transaction_def admissible_transaction_terms_def
by blast
hence "Pair \<notin> funs_term t"
when t: "t \<in> trms\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)" for t
using 2 trms\<^sub>s\<^sub>s\<^sub>t_funs_term_cases[OF t]
by force
hence 3: "Pair \<notin> funs_term t" when t: "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'" for t
using t unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
unfolding T'_def by metis
have "\<exists>a. \<Gamma>\<^sub>v x = TAtom a" when "x \<in> vars_transaction T" for x
using that protocol_transaction_vars_TAtom_typed(1) P step.hyps(2)
by fast
hence "\<exists>a. \<Gamma>\<^sub>v x = TAtom a" when "x \<in> vars\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)" for x
using wt_subst_fv\<^sub>s\<^sub>e\<^sub>t_termtype_subterm[OF _ \<sigma>\<alpha>_wt \<sigma>\<alpha>_wf, of x "vars_transaction T"]
vars\<^sub>s\<^sub>s\<^sub>t_subst_cases[OF that]
by fastforce
hence "\<exists>a. \<Gamma>\<^sub>v x = TAtom a" when "x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'" for x
using that unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
vars\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
unfolding T'_def
by simp
hence "\<exists>a. \<Gamma>\<^sub>v x = TAtom a" when "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')" for x
using that fv_trms\<^sub>s\<^sub>s\<^sub>t_subset(1) by fast
hence "Pair \<notin> funs_term (\<Gamma> (Var x))" when "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')" for x
using that by fastforce
moreover have "Pair \<in> funs_term s"
when s: "Ana s = (K, M)" "Pair \<in> \<Union>(funs_term ` set K)"
for s::"('fun,'atom,'sets) prot_term" and K M
proof (cases s)
case (Fun f S) thus ?thesis using s Ana_Fu_keys_not_pairs[of _ S K M] by (cases f) force+
qed (use s in simp)
ultimately have "Pair \<notin> funs_term t" when t: "t \<in> SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')" for t
using t 3 SMP_funs_term[OF t _ _ 1, of Pair] funs_term_type_iff by fastforce
thus ?case using 0 step.IH(1) unfolding T'_def by blast
qed simp
lemma reachable_constraints_setops_form:
assumes A: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and t: "t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)"
shows "\<exists>c s. t = pair (c, Fun (Set s) []) \<and> \<Gamma> c = TAtom Value"
using A t
proof (induction A rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
have T_adm: "admissible_transaction T" when "T \<in> set P" for T
using P that unfolding list_all_iff by simp
have T_adm':
"admissible_transaction_selects T"
"admissible_transaction_checks T"
"admissible_transaction_updates T"
when "T \<in> set P" for T
using T_adm[OF that] unfolding admissible_transaction_def by simp_all
have T_valid: "wellformed_transaction T" when "T \<in> set P" for T
using T_adm[OF that] unfolding admissible_transaction_def by blast
have \<sigma>\<alpha>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using protocol_transaction_vars_TAtom_typed(3) P(1) step.hyps(2)
transaction_fresh_subst_transaction_renaming_wt[OF step.hyps(3,4)]
by fast
have \<sigma>\<alpha>_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]
by (metis wf_trms_subst_compose)
show ?case using step.IH
proof (cases "t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)")
case False
hence "t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T) \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
using step.prems setops\<^sub>s\<^sub>s\<^sub>t_append unlabel_append
setops\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by fastforce
then obtain t' \<delta> where t':
"t' \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T))"
"wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)" "t = t' \<cdot> \<delta>"
using setops\<^sub>s\<^sub>s\<^sub>t_wt_subst_ex[OF \<sigma>\<alpha>_wt \<sigma>\<alpha>_wf] by blast
then obtain s s' where s: "t' = pair (s,s')"
using setops\<^sub>s\<^sub>s\<^sub>t_are_pairs by fastforce
moreover have "InSet ac s s' = InSet Assign s s' \<or> InSet ac s s' = InSet Check s s'" for ac
by (cases ac) simp_all
ultimately have "\<exists>n. s = Var (Var Value, n)" "\<exists>u. s' = Fun (Set u) []"
using t'(1) setops\<^sub>s\<^sub>s\<^sub>t_member_iff[of s s' "unlabel (transaction_strand T)"]
pair_in_pair_image_iff[of s s']
transaction_inserts_are_Value_vars[
OF T_valid[OF step.hyps(2)] T_adm'(3)[OF step.hyps(2)], of s s']
transaction_deletes_are_Value_vars[
OF T_valid[OF step.hyps(2)] T_adm'(3)[OF step.hyps(2)], of s s']
transaction_selects_are_Value_vars[
OF T_valid[OF step.hyps(2)] T_adm'(1)[OF step.hyps(2)], of s s']
transaction_inset_checks_are_Value_vars[
OF T_valid[OF step.hyps(2)] T_adm'(2)[OF step.hyps(2)], of s s']
transaction_notinset_checks_are_Value_vars[
OF T_valid[OF step.hyps(2)] T_adm'(2)[OF step.hyps(2)], of _ _ _ s s']
by metis+
then obtain ss n where ss: "t = pair (\<delta> (Var Value, n), Fun (Set ss) [])"
using t'(4) s unfolding pair_def by force
have "\<Gamma> (\<delta> (Var Value, n)) = TAtom Value" "wf\<^sub>t\<^sub>r\<^sub>m (\<delta> (Var Value, n))"
using t'(2) wt_subst_trm''[OF t'(2), of "Var (Var Value, n)"] apply simp
using t'(3) by (cases "(Var Value, n) \<in> subst_domain \<delta>") auto
thus ?thesis using ss by blast
qed simp
qed (simp add: setops\<^sub>s\<^sub>s\<^sub>t_def)
lemma reachable_constraints_setops_type:
fixes t::"('fun,'atom,'sets) prot_term"
assumes A: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
and t: "t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)"
shows "\<Gamma> t = TComp Pair [TAtom Value, TAtom SetType]"
proof -
obtain s c where s: "t = pair (c, Fun (Set s) [])" "\<Gamma> c = TAtom Value"
using reachable_constraints_setops_form[OF A P t] by moura
hence "(Fun (Set s) []::('fun,'atom,'sets) prot_term) \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A"
using t setops\<^sub>s\<^sub>s\<^sub>t_member_iff[of c "Fun (Set s) []" "unlabel A"]
by force
hence "wf\<^sub>t\<^sub>r\<^sub>m (Fun (Set s) []::('fun,'atom,'sets) prot_term)"
using reachable_constraints_wf(2) P A
unfolding admissible_transaction_def admissible_transaction_terms_def by blast
hence "arity (Set s) = 0" unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by simp
thus ?thesis using s unfolding pair_def by fastforce
qed
lemma reachable_constraints_setops_same_type_if_unifiable:
assumes A: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
shows "\<forall>s \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A). \<forall>t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A).
(\<exists>\<delta>. Unifier \<delta> s t) \<longrightarrow> \<Gamma> s = \<Gamma> t"
(is "?P A")
using reachable_constraints_setops_type[OF A P] by simp
lemma reachable_constraints_setops_unfiable_if_wt_instance_unifiable:
assumes A: "A \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. admissible_transaction T"
shows "\<forall>s \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A). \<forall>t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A).
(\<exists>\<sigma> \<theta> \<rho>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<sigma> \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<sigma>) \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>) \<and>
Unifier \<rho> (s \<cdot> \<sigma>) (t \<cdot> \<theta>))
\<longrightarrow> (\<exists>\<delta>. Unifier \<delta> s t)"
proof (intro ballI impI)
fix s t assume st: "s \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "t \<in> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" and
"\<exists>\<sigma> \<theta> \<rho>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<sigma> \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<sigma>) \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>) \<and>
Unifier \<rho> (s \<cdot> \<sigma>) (t \<cdot> \<theta>)"
then obtain \<sigma> \<theta> \<rho> where \<sigma>:
"wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<sigma>" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<sigma>)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)"
"Unifier \<rho> (s \<cdot> \<sigma>) (t \<cdot> \<theta>)"
by moura
obtain fs ft cs ct where c:
"s = pair (cs, Fun (Set fs) [])" "t = pair (ct, Fun (Set ft) [])"
"\<Gamma> cs = TAtom Value" "\<Gamma> ct = TAtom Value"
using reachable_constraints_setops_form[OF A P st(1)]
reachable_constraints_setops_form[OF A P st(2)]
by moura
have "cs \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" "ct \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)"
using c(1,2) setops_subterm_trms[OF st(1), of cs] setops_subterm_trms[OF st(2), of ct]
Fun_param_is_subterm[of cs "args s"] Fun_param_is_subterm[of ct "args t"]
unfolding pair_def by simp_all
moreover have
"\<forall>T \<in> set P. wellformed_transaction T"
"\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
using P unfolding admissible_transaction_def admissible_transaction_terms_def by fast+
ultimately have *: "wf\<^sub>t\<^sub>r\<^sub>m cs" "wf\<^sub>t\<^sub>r\<^sub>m ct"
using reachable_constraints_wf(2)[OF _ _ A] wf_trms_subterms by blast+
have "(\<exists>x. cs = Var x) \<or> (\<exists>c d. cs = Fun c [])"
using const_type_inv_wf c(3) *(1) by (cases cs) auto
moreover have "(\<exists>x. ct = Var x) \<or> (\<exists>c d. ct = Fun c [])"
using const_type_inv_wf c(4) *(2) by (cases ct) auto
ultimately show "\<exists>\<delta>. Unifier \<delta> s t"
using reachable_constraints_setops_form[OF A P] reachable_constraints_setops_type[OF A P] st \<sigma> c
unfolding pair_def by auto
qed
lemma reachable_constraints_tfr:
assumes M:
"M \<equiv> \<Union>T \<in> set P. trms_transaction T"
"has_all_wt_instances_of \<Gamma> M N"
"finite N"
"tfr\<^sub>s\<^sub>e\<^sub>t N"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
"\<forall>T \<in> set P. list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
and \<A>: "\<A> \<in> reachable_constraints P"
shows "tfr\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>)"
using \<A>
proof (induction \<A> rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
have P':
"\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
"\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms_transaction T)"
using P(1) protocol_transaction_vars_TAtom_typed(3) admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s
by blast+
have AT'_reach: "A@T' \<in> reachable_constraints P"
using reachable_constraints.step[OF step.hyps] unfolding T'_def by metis
have \<sigma>\<alpha>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using P'(1) step.hyps(2) transaction_fresh_subst_transaction_renaming_wt[OF step.hyps(3,4)]
by fast
have \<sigma>\<alpha>_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]
by (metis wf_trms_subst_compose)
have \<sigma>\<alpha>_bvars_disj: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}"
by (rule transaction_fresh_subst_transaction_renaming_subst_vars_disj(4)[OF step.hyps(3,4,2)])
have wf_trms_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M"
using admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s P(1)
unfolding M(1) by blast
have "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T'))"
using reachable_constraints_SMP_subset(1)[OF AT'_reach P'(1)]
tfr_subset(3)[OF M(4), of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T')"]
SMP_SMP_subset[of M N] SMP_I'[OF wf_trms_M M(5,2)]
unfolding M(1) by blast
moreover have "\<forall>p. Ana (pair p) = ([],[])" unfolding pair_def by auto
ultimately have 1: "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T') \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T')))"
using tfr_setops_if_tfr_trms[of "unlabel (A@T')"]
reachable_constraints_no_Pair_fun[OF AT'_reach P(1)]
reachable_constraints_setops_same_type_if_unifiable[OF AT'_reach P(1)]
reachable_constraints_setops_unfiable_if_wt_instance_unifiable[OF AT'_reach P(1)]
by blast
have "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
using step.hyps(2) P(2) tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p_is_comp_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p
unfolding comp_tfr\<^sub>s\<^sub>s\<^sub>t_def tfr\<^sub>s\<^sub>s\<^sub>t_def by fastforce
hence "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel T')"
using tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p_all_wt_subst_apply[OF _ \<sigma>\<alpha>_wt \<sigma>\<alpha>_wf \<sigma>\<alpha>_bvars_disj]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unfolding T'_def by argo
hence 2: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (A@T'))"
using step.IH unlabel_append
unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by auto
have "tfr\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T'))" using 1 2 by (metis tfr\<^sub>s\<^sub>s\<^sub>t_def)
thus ?case by (metis T'_def)
qed simp
lemma reachable_constraints_tfr':
assumes M:
"M \<equiv> \<Union>T \<in> set P. trms_transaction T \<union> pair' Pair ` setops_transaction T"
"has_all_wt_instances_of \<Gamma> M N"
"finite N"
"tfr\<^sub>s\<^sub>e\<^sub>t N"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N"
and P:
"\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
"\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
"\<forall>T \<in> set P. list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
and \<A>: "\<A> \<in> reachable_constraints P"
shows "tfr\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>)"
using \<A>
proof (induction \<A> rule: reachable_constraints.induct)
case (step A T \<sigma> \<alpha>)
define T' where "T' \<equiv> dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>)"
have AT'_reach: "A@T' \<in> reachable_constraints P"
using reachable_constraints.step[OF step.hyps] unfolding T'_def by metis
have \<sigma>\<alpha>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using P(1) step.hyps(2) transaction_fresh_subst_transaction_renaming_wt[OF step.hyps(3,4)]
by fast
have \<sigma>\<alpha>_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha>))"
using transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]
by (metis wf_trms_subst_compose)
have \<sigma>\<alpha>_bvars_disj: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) \<inter> range_vars (\<sigma> \<circ>\<^sub>s \<alpha>) = {}"
by (rule transaction_fresh_subst_transaction_renaming_subst_vars_disj(4)[OF step.hyps(3,4,2)])
have wf_trms_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M"
using P(2) setops\<^sub>s\<^sub>s\<^sub>t_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s(2) unfolding M(1) pair_code wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_code[symmetric] by fast
have "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T')) \<subseteq> SMP M" "SMP (pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T'))) \<subseteq> SMP M"
using reachable_constraints_SMP_subset[OF AT'_reach P(1)]
SMP_mono[of "\<Union>T \<in> set P. trms_transaction T" M]
SMP_mono[of "\<Union>T \<in> set P. pair ` setops_transaction T" M]
unfolding M(1) pair_code[symmetric] by blast+
hence 1: "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T') \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T')))"
using tfr_subset(3)[OF M(4), of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T') \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T'))"]
SMP_union[of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@T')" "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T'))"]
SMP_SMP_subset[of M N] SMP_I'[OF wf_trms_M M(5,2)]
by blast
have "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
using step.hyps(2) P(3) tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p_is_comp_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p
unfolding comp_tfr\<^sub>s\<^sub>s\<^sub>t_def tfr\<^sub>s\<^sub>s\<^sub>t_def by fastforce
hence "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel T')"
using tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p_all_wt_subst_apply[OF _ \<sigma>\<alpha>_wt \<sigma>\<alpha>_wf \<sigma>\<alpha>_bvars_disj]
dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p[of "transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unfolding T'_def by argo
hence 2: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (A@T'))"
using step.IH unlabel_append
unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by auto
have "tfr\<^sub>s\<^sub>s\<^sub>t (unlabel (A@T'))" using 1 2 by (metis tfr\<^sub>s\<^sub>s\<^sub>t_def)
thus ?case by (metis T'_def)
qed simp
lemma reachable_constraints_typing_cond\<^sub>s\<^sub>s\<^sub>t:
assumes M:
"M \<equiv> \<Union>T \<in> set P. trms_transaction T \<union> pair' Pair ` setops_transaction T"
"has_all_wt_instances_of \<Gamma> M N"
"finite N"
"tfr\<^sub>s\<^sub>e\<^sub>t N"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N"
and P:
"\<forall>T \<in> set P. wellformed_transaction T"
"\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
"\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
"\<forall>T \<in> set P. list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
and \<A>: "\<A> \<in> reachable_constraints P"
shows "typing_cond\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>)"
using reachable_constraints_wf[OF P(1,2) \<A>] reachable_constraints_tfr'[OF M P(3,2,4) \<A>]
unfolding typing_cond\<^sub>s\<^sub>s\<^sub>t_def by blast
context
begin
private lemma reachable_constraints_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_aux:
fixes P
defines "Ts \<equiv> concat (map transaction_strand P)"
assumes P_fresh_wf: "\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
(is "\<forall>T \<in> set P. ?fresh_wf T")
and A: "A \<in> reachable_constraints P"
shows "\<forall>b \<in> set (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A). \<exists>a \<in> set Ts. \<exists>\<delta>. b = a \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<delta> \<and>
wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and>
(\<forall>t \<in> subst_range \<delta>. (\<exists>x. t = Var x) \<or> (\<exists>c. t = Fun c []))"
(is "\<forall>b \<in> set (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A). \<exists>a \<in> set Ts. ?P b a")
using A
proof (induction A rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
define Q where "Q \<equiv> ?P"
define \<theta> where "\<theta> \<equiv> \<sigma> \<circ>\<^sub>s \<alpha>"
let ?R = "\<lambda>A Ts. \<forall>b \<in> set A. \<exists>a \<in> set Ts. Q b a"
have T_fresh_wf: "?fresh_wf T" using step.hyps(2) P_fresh_wf by blast
have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)"
"\<forall>t \<in> subst_range \<theta>. (\<exists>x. t = Var x) \<or> (\<exists>c. t = Fun c [])"
using wt_subst_compose[
OF transaction_fresh_subst_wt[OF step.hyps(3) T_fresh_wf]
transaction_renaming_subst_wt[OF step.hyps(4)]]
wf_trms_subst_compose[
OF transaction_fresh_subst_range_wf_trms[OF step.hyps(3)]
transaction_renaming_subst_range_wf_trms[OF step.hyps(4)]]
transaction_fresh_subst_transaction_renaming_subst_range'[OF step.hyps(3,4)]
unfolding \<theta>_def by metis+
hence "?R (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T)) \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>) (transaction_strand T)"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_self_inverse[of "transaction_strand T"]
by (auto simp add: Q_def subst_apply_labeled_stateful_strand_def)
hence "?R (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) (transaction_strand T)"
by (metis dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst)
hence "?R (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) Ts"
using step.hyps(2) unfolding Ts_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by fastforce
thus ?case using step.IH unfolding Q_def \<theta>_def by auto
qed simp
lemma reachable_constraints_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t:
fixes P
defines "f \<equiv> \<lambda>M. {t \<cdot> \<delta> | t \<delta>. t \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> fv (t \<cdot> \<delta>) = {}}"
and "Ts \<equiv> concat (map transaction_strand P)"
assumes P_pc: "comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t public arity Ana \<Gamma> Pair Ts M S"
and P_wf: "\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
and A: "A \<in> reachable_constraints P"
shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A ((f (set S)) - {m. intruder_synth {} m})"
using par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_if_comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t'[OF P_pc, of "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A", THEN par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t]
reachable_constraints_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_aux[OF P_wf A, unfolded Ts_def[symmetric]]
unfolding f_def dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_self_inverse by fast
end
lemma reachable_constraints_par_comp_constr:
fixes P f S
defines "f \<equiv> \<lambda>M. {t \<cdot> \<delta> | t \<delta>. t \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> fv (t \<cdot> \<delta>) = {}}"
and "Ts \<equiv> concat (map transaction_strand P)"
and "Sec \<equiv> (f (set S)) - {m. intruder_synth {} m}"
and "M \<equiv> \<Union>T \<in> set P. trms_transaction T \<union> pair' Pair ` setops_transaction T"
assumes M:
"has_all_wt_instances_of \<Gamma> M N"
"finite N"
"tfr\<^sub>s\<^sub>e\<^sub>t N"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N"
and P:
"\<forall>T \<in> set P. wellformed_transaction T"
"\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
"\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
"\<forall>T \<in> set P. list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
"comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t public arity Ana \<Gamma> Pair Ts M_fun S"
and \<A>: "\<A> \<in> reachable_constraints P"
and \<I>: "constraint_model \<I> \<A>"
shows "\<exists>\<I>\<^sub>\<tau>. welltyped_constraint_model \<I>\<^sub>\<tau> \<A> \<and>
((\<forall>n. welltyped_constraint_model \<I>\<^sub>\<tau> (proj n \<A>)) \<or>
(\<exists>\<A>'. prefix \<A>' \<A> \<and> strand_leaks\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>' Sec \<I>\<^sub>\<tau>))"
proof -
have \<I>': "constr_sem_stateful \<I> (unlabel \<A>)" "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>"
using \<I> unfolding constraint_model_def by blast+
show ?thesis
using reachable_constraints_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t[OF P(5,3)[unfolded Ts_def] \<A>]
reachable_constraints_typing_cond\<^sub>s\<^sub>s\<^sub>t[OF M_def M P(1,2,3,4) \<A>]
par_comp_constr_stateful[OF _ _ \<I>', of Sec]
unfolding f_def Sec_def welltyped_constraint_model_def constraint_model_def by blast
qed
end
end