Automated_Stateful_Protocol.../Automated_Stateful_Protocol.../Stateful_Protocol_Verificat...

3682 lines
216 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_Verification.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 Verification\<close>
theory Stateful_Protocol_Verification
imports Stateful_Protocol_Model Term_Implication
begin
subsection \<open>Fixed-Point Intruder Deduction Lemma\<close>
context stateful_protocol_model
begin
abbreviation pubval_terms::"('fun,'atom,'sets) prot_terms" where
"pubval_terms \<equiv> {t. \<exists>f \<in> funs_term t. is_Val f \<and> public f}"
abbreviation abs_terms::"('fun,'atom,'sets) prot_terms" where
"abs_terms \<equiv> {t. \<exists>f \<in> funs_term t. is_Abs f}"
definition intruder_deduct_GSMP::
"[('fun,'atom,'sets) prot_terms,
('fun,'atom,'sets) prot_terms,
('fun,'atom,'sets) prot_term]
\<Rightarrow> bool" ("\<langle>_;_\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P _" 50)
where
"\<langle>M; T\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P t \<equiv> intruder_deduct_restricted M (\<lambda>t. t \<in> GSMP T - (pubval_terms \<union> abs_terms)) t"
lemma intruder_deduct_GSMP_induct[consumes 1, case_names AxiomH ComposeH DecomposeH]:
assumes "\<langle>M; T\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P t" "\<And>t. t \<in> M \<Longrightarrow> P M t"
"\<And>S f. \<lbrakk>length S = arity f; public f;
\<And>s. s \<in> set S \<Longrightarrow> \<langle>M; T\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P s;
\<And>s. s \<in> set S \<Longrightarrow> P M s;
Fun f S \<in> GSMP T - (pubval_terms \<union> abs_terms)
\<rbrakk> \<Longrightarrow> P M (Fun f S)"
"\<And>t K T' t\<^sub>i. \<lbrakk>\<langle>M; T\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P t; P M t; Ana t = (K, T'); \<And>k. k \<in> set K \<Longrightarrow> \<langle>M; T\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P k;
\<And>k. k \<in> set K \<Longrightarrow> P M k; t\<^sub>i \<in> set T'\<rbrakk> \<Longrightarrow> P M t\<^sub>i"
shows "P M t"
proof -
let ?Q = "\<lambda>t. t \<in> GSMP T - (pubval_terms \<union> abs_terms)"
show ?thesis
using intruder_deduct_restricted_induct[of M ?Q t "\<lambda>M Q t. P M t"] assms
unfolding intruder_deduct_GSMP_def
by blast
qed
lemma pubval_terms_subst:
assumes "t \<cdot> \<theta> \<in> pubval_terms" "\<theta> ` fv t \<inter> pubval_terms = {}"
shows "t \<in> pubval_terms"
using assms(1,2)
proof (induction t)
case (Fun f T)
let ?P = "\<lambda>f. is_Val f \<and> public f"
from Fun show ?case
proof (cases "?P f")
case False
then obtain t where t: "t \<in> set T" "t \<cdot> \<theta> \<in> pubval_terms"
using Fun.prems by auto
hence "\<theta> ` fv t \<inter> pubval_terms = {}" using Fun.prems(2) by auto
thus ?thesis using Fun.IH[OF t] t(1) by auto
qed force
qed simp
lemma abs_terms_subst:
assumes "t \<cdot> \<theta> \<in> abs_terms" "\<theta> ` fv t \<inter> abs_terms = {}"
shows "t \<in> abs_terms"
using assms(1,2)
proof (induction t)
case (Fun f T)
let ?P = "\<lambda>f. is_Abs f"
from Fun show ?case
proof (cases "?P f")
case False
then obtain t where t: "t \<in> set T" "t \<cdot> \<theta> \<in> abs_terms"
using Fun.prems by auto
hence "\<theta> ` fv t \<inter> abs_terms = {}" using Fun.prems(2) by auto
thus ?thesis using Fun.IH[OF t] t(1) by auto
qed force
qed simp
lemma pubval_terms_subst':
assumes "t \<cdot> \<theta> \<in> pubval_terms" "\<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` (\<theta> ` fv t))"
shows "t \<in> pubval_terms"
proof -
have "\<not>public f"
when fs: "f \<in> funs_term s" "s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (\<theta> ` fv t)" "is_Val f"
for f s
proof -
obtain T where T: "Fun f T \<in> subterms s" using funs_term_Fun_subterm[OF fs(1)] by moura
hence "Fun f T \<in> subterms\<^sub>s\<^sub>e\<^sub>t (\<theta> ` fv t)" using fs(2) in_subterms_subset_Union by blast
thus ?thesis using assms(2) funs_term_Fun_subterm'[of f T] fs(3) by (cases f) force+
qed
thus ?thesis using pubval_terms_subst[OF assms(1)] by force
qed
lemma abs_terms_subst':
assumes "t \<cdot> \<theta> \<in> abs_terms" "\<forall>n. Abs n \<notin> \<Union>(funs_term ` (\<theta> ` fv t))"
shows "t \<in> abs_terms"
proof -
have "\<not>is_Abs f" when fs: "f \<in> funs_term s" "s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (\<theta> ` fv t)" for f s
proof -
obtain T where T: "Fun f T \<in> subterms s" using funs_term_Fun_subterm[OF fs(1)] by moura
hence "Fun f T \<in> subterms\<^sub>s\<^sub>e\<^sub>t (\<theta> ` fv t)" using fs(2) in_subterms_subset_Union by blast
thus ?thesis using assms(2) funs_term_Fun_subterm'[of f T] by (cases f) auto
qed
thus ?thesis using abs_terms_subst[OF assms(1)] by force
qed
lemma pubval_terms_subst_range_disj:
"subst_range \<theta> \<inter> pubval_terms = {} \<Longrightarrow> \<theta> ` fv t \<inter> pubval_terms = {}"
proof (induction t)
case (Var x) thus ?case by (cases "x \<in> subst_domain \<theta>") auto
qed auto
lemma abs_terms_subst_range_disj:
"subst_range \<theta> \<inter> abs_terms = {} \<Longrightarrow> \<theta> ` fv t \<inter> abs_terms = {}"
proof (induction t)
case (Var x) thus ?case by (cases "x \<in> subst_domain \<theta>") auto
qed auto
lemma pubval_terms_subst_range_comp:
assumes "subst_range \<theta> \<inter> pubval_terms = {}" "subst_range \<delta> \<inter> pubval_terms = {}"
shows "subst_range (\<theta> \<circ>\<^sub>s \<delta>) \<inter> pubval_terms = {}"
proof -
{ fix t f assume t:
"t \<in> subst_range (\<theta> \<circ>\<^sub>s \<delta>)" "f \<in> funs_term t" "is_Val f" "public f"
then obtain x where x: "(\<theta> \<circ>\<^sub>s \<delta>) x = t" by auto
have "\<theta> x \<notin> pubval_terms" using assms(1) by (cases "\<theta> x \<in> subst_range \<theta>") force+
hence "(\<theta> \<circ>\<^sub>s \<delta>) x \<notin> pubval_terms"
using assms(2) pubval_terms_subst[of "\<theta> x" \<delta>] pubval_terms_subst_range_disj
by (metis (mono_tags, lifting) subst_compose_def)
hence False using t(2,3,4) x by blast
} thus ?thesis by fast
qed
lemma pubval_terms_subst_range_comp':
assumes "(\<theta> ` X) \<inter> pubval_terms = {}" "(\<delta> ` fv\<^sub>s\<^sub>e\<^sub>t (\<theta> ` X)) \<inter> pubval_terms = {}"
shows "((\<theta> \<circ>\<^sub>s \<delta>) ` X) \<inter> pubval_terms = {}"
proof -
{ fix t f assume t:
"t \<in> (\<theta> \<circ>\<^sub>s \<delta>) ` X" "f \<in> funs_term t" "is_Val f" "public f"
then obtain x where x: "(\<theta> \<circ>\<^sub>s \<delta>) x = t" "x \<in> X" by auto
have "\<theta> x \<notin> pubval_terms" using assms(1) x(2) by force
moreover have "fv (\<theta> x) \<subseteq> fv\<^sub>s\<^sub>e\<^sub>t (\<theta> ` X)" using x(2) by (auto simp add: fv_subset)
hence "\<delta> ` fv (\<theta> x) \<inter> pubval_terms = {}" using assms(2) by auto
ultimately have "(\<theta> \<circ>\<^sub>s \<delta>) x \<notin> pubval_terms"
using pubval_terms_subst[of "\<theta> x" \<delta>]
by (metis (mono_tags, lifting) subst_compose_def)
hence False using t(2,3,4) x by blast
} thus ?thesis by fast
qed
lemma abs_terms_subst_range_comp:
assumes "subst_range \<theta> \<inter> abs_terms = {}" "subst_range \<delta> \<inter> abs_terms = {}"
shows "subst_range (\<theta> \<circ>\<^sub>s \<delta>) \<inter> abs_terms = {}"
proof -
{ fix t f assume t: "t \<in> subst_range (\<theta> \<circ>\<^sub>s \<delta>)" "f \<in> funs_term t" "is_Abs f"
then obtain x where x: "(\<theta> \<circ>\<^sub>s \<delta>) x = t" by auto
have "\<theta> x \<notin> abs_terms" using assms(1) by (cases "\<theta> x \<in> subst_range \<theta>") force+
hence "(\<theta> \<circ>\<^sub>s \<delta>) x \<notin> abs_terms"
using assms(2) abs_terms_subst[of "\<theta> x" \<delta>] abs_terms_subst_range_disj
by (metis (mono_tags, lifting) subst_compose_def)
hence False using t(2,3) x by blast
} thus ?thesis by fast
qed
lemma abs_terms_subst_range_comp':
assumes "(\<theta> ` X) \<inter> abs_terms = {}" "(\<delta> ` fv\<^sub>s\<^sub>e\<^sub>t (\<theta> ` X)) \<inter> abs_terms = {}"
shows "((\<theta> \<circ>\<^sub>s \<delta>) ` X) \<inter> abs_terms = {}"
proof -
{ fix t f assume t:
"t \<in> (\<theta> \<circ>\<^sub>s \<delta>) ` X" "f \<in> funs_term t" "is_Abs f"
then obtain x where x: "(\<theta> \<circ>\<^sub>s \<delta>) x = t" "x \<in> X" by auto
have "\<theta> x \<notin> abs_terms" using assms(1) x(2) by force
moreover have "fv (\<theta> x) \<subseteq> fv\<^sub>s\<^sub>e\<^sub>t (\<theta> ` X)" using x(2) by (auto simp add: fv_subset)
hence "\<delta> ` fv (\<theta> x) \<inter> abs_terms = {}" using assms(2) by auto
ultimately have "(\<theta> \<circ>\<^sub>s \<delta>) x \<notin> abs_terms"
using abs_terms_subst[of "\<theta> x" \<delta>]
by (metis (mono_tags, lifting) subst_compose_def)
hence False using t(2,3) x by blast
} thus ?thesis by fast
qed
context
begin
private lemma Ana_abs_aux1:
fixes \<delta>::"(('fun,'atom,'sets) prot_fun, nat, ('fun,'atom,'sets) prot_var) gsubst"
and \<alpha>::"nat \<times> bool \<Rightarrow> 'sets set"
assumes "Ana\<^sub>f f = (K,T)"
shows "(K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>) \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha> = K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (\<lambda>n. \<delta> n \<cdot>\<^sub>\<alpha> \<alpha>)"
proof -
{ fix k assume "k \<in> set K"
hence "k \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K)" by force
hence "k \<cdot> \<delta> \<cdot>\<^sub>\<alpha> \<alpha> = k \<cdot> (\<lambda>n. \<delta> n \<cdot>\<^sub>\<alpha> \<alpha>)"
proof (induction k)
case (Fun g S)
have "\<And>s. s \<in> set S \<Longrightarrow> s \<cdot> \<delta> \<cdot>\<^sub>\<alpha> \<alpha> = s \<cdot> (\<lambda>n. \<delta> n \<cdot>\<^sub>\<alpha> \<alpha>)"
using Fun.IH in_subterms_subset_Union[OF Fun.prems] Fun_param_in_subterms[of _ S g]
by (meson contra_subsetD)
thus ?case using Ana\<^sub>f_assm1_alt[OF assms Fun.prems] by (cases g) auto
qed simp
} thus ?thesis unfolding abs_apply_list_def by force
qed
private lemma Ana_abs_aux2:
fixes \<alpha>::"nat \<times> bool \<Rightarrow> 'sets set"
and K::"(('fun,'atom,'sets) prot_fun, nat) term list"
and M::"nat list"
and T::"('fun,'atom,'sets) prot_term list"
assumes "\<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K) \<union> set M. i < length T"
and "(K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T) \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha> = K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (\<lambda>n. T ! n \<cdot>\<^sub>\<alpha> \<alpha>)"
shows "(K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) T) \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha> = K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T)" (is "?A1 = ?A2")
and "(map ((!) T) M) \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha> = map ((!) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T)) M" (is "?B1 = ?B2")
proof -
have "T ! i \<cdot>\<^sub>\<alpha> \<alpha> = (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ! i" when "i \<in> fv\<^sub>s\<^sub>e\<^sub>t (set K)" for i
using that assms(1) by auto
hence "k \<cdot> (\<lambda>i. T ! i \<cdot>\<^sub>\<alpha> \<alpha>) = k \<cdot> (\<lambda>i. (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ! i)" when "k \<in> set K" for k
using that term_subst_eq_conv[of k "\<lambda>i. T ! i \<cdot>\<^sub>\<alpha> \<alpha>" "\<lambda>i. (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ! i"]
by auto
thus "?A1 = ?A2" using assms(2) by (force simp add: abs_apply_terms_def)
have "T ! i \<cdot>\<^sub>\<alpha> \<alpha> = map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T ! i" when "i \<in> set M" for i
using that assms(1) by auto
thus "?B1 = ?B2" by (force simp add: abs_apply_list_def)
qed
private lemma Ana_abs_aux1_set:
fixes \<delta>::"(('fun,'atom,'sets) prot_fun, nat, ('fun,'atom,'sets) prot_var) gsubst"
and \<alpha>::"nat \<times> bool \<Rightarrow> 'sets set"
assumes "Ana\<^sub>f f = (K,T)"
shows "(set K \<cdot>\<^sub>s\<^sub>e\<^sub>t \<delta>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha> = set K \<cdot>\<^sub>s\<^sub>e\<^sub>t (\<lambda>n. \<delta> n \<cdot>\<^sub>\<alpha> \<alpha>)"
proof -
{ fix k assume "k \<in> set K"
hence "k \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set K)" by force
hence "k \<cdot> \<delta> \<cdot>\<^sub>\<alpha> \<alpha> = k \<cdot> (\<lambda>n. \<delta> n \<cdot>\<^sub>\<alpha> \<alpha>)"
proof (induction k)
case (Fun g S)
have "\<And>s. s \<in> set S \<Longrightarrow> s \<cdot> \<delta> \<cdot>\<^sub>\<alpha> \<alpha> = s \<cdot> (\<lambda>n. \<delta> n \<cdot>\<^sub>\<alpha> \<alpha>)"
using Fun.IH in_subterms_subset_Union[OF Fun.prems] Fun_param_in_subterms[of _ S g]
by (meson contra_subsetD)
thus ?case using Ana\<^sub>f_assm1_alt[OF assms Fun.prems] by (cases g) auto
qed simp
} thus ?thesis unfolding abs_apply_terms_def by force
qed
private lemma Ana_abs_aux2_set:
fixes \<alpha>::"nat \<times> bool \<Rightarrow> 'sets set"
and K::"(('fun,'atom,'sets) prot_fun, nat) terms"
and M::"nat set"
and T::"('fun,'atom,'sets) prot_term list"
assumes "\<forall>i \<in> fv\<^sub>s\<^sub>e\<^sub>t K \<union> M. i < length T"
and "(K \<cdot>\<^sub>s\<^sub>e\<^sub>t (!) T) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha> = K \<cdot>\<^sub>s\<^sub>e\<^sub>t (\<lambda>n. T ! n \<cdot>\<^sub>\<alpha> \<alpha>)"
shows "(K \<cdot>\<^sub>s\<^sub>e\<^sub>t (!) T) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha> = K \<cdot>\<^sub>s\<^sub>e\<^sub>t (!) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T)" (is "?A1 = ?A2")
and "((!) T ` M) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha> = (!) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ` M" (is "?B1 = ?B2")
proof -
have "T ! i \<cdot>\<^sub>\<alpha> \<alpha> = (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ! i" when "i \<in> fv\<^sub>s\<^sub>e\<^sub>t K" for i
using that assms(1) by auto
hence "k \<cdot> (\<lambda>i. T ! i \<cdot>\<^sub>\<alpha> \<alpha>) = k \<cdot> (\<lambda>i. (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ! i)" when "k \<in> K" for k
using that term_subst_eq_conv[of k "\<lambda>i. T ! i \<cdot>\<^sub>\<alpha> \<alpha>" "\<lambda>i. (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T) ! i"]
by auto
thus "?A1 = ?A2" using assms(2) by (force simp add: abs_apply_terms_def)
have "T ! i \<cdot>\<^sub>\<alpha> \<alpha> = map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) T ! i" when "i \<in> M" for i
using that assms(1) by auto
thus "?B1 = ?B2" by (force simp add: abs_apply_terms_def)
qed
lemma Ana_abs:
fixes t::"('fun,'atom,'sets) prot_term"
assumes "Ana t = (K, T)"
shows "Ana (t \<cdot>\<^sub>\<alpha> \<alpha>) = (K \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha>, T \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha>)"
using assms
proof (induction t rule: Ana.induct)
case (1 f S)
obtain K' T' where *: "Ana\<^sub>f f = (K',T')" by moura
show ?case using 1
proof (cases "arity\<^sub>f f = length S \<and> arity\<^sub>f f > 0")
case True
hence "K = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) S" "T = map ((!) S) T'"
and **: "arity\<^sub>f f = length (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) S)" "arity\<^sub>f f > 0"
using 1 * by auto
hence "K \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha> = K' \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t (!) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) S)"
"T \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha> = map ((!) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) S)) T'"
using Ana\<^sub>f_assm2_alt[OF *] Ana_abs_aux2[OF _ Ana_abs_aux1[OF *], of T' S \<alpha>]
unfolding abs_apply_list_def
by auto
moreover have "Fun (Fu f) S \<cdot>\<^sub>\<alpha> \<alpha> = Fun (Fu f) (map (\<lambda>s. s \<cdot>\<^sub>\<alpha> \<alpha>) S)" by simp
ultimately show ?thesis using Ana_Fu_intro[OF ** *] by metis
qed (auto simp add: abs_apply_list_def)
qed (simp_all add: abs_apply_list_def)
end
lemma deduct_FP_if_deduct:
fixes M IK FP::"('fun,'atom,'sets) prot_terms"
assumes IK: "IK \<subseteq> GSMP M - (pubval_terms \<union> abs_terms)" "\<forall>t \<in> IK \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>. FP \<turnstile>\<^sub>c t"
and t: "IK \<turnstile> t" "t \<in> GSMP M - (pubval_terms \<union> abs_terms)"
shows "FP \<turnstile> t \<cdot>\<^sub>\<alpha> \<alpha>"
proof -
let ?P = "\<lambda>f. is_Val f \<longrightarrow> \<not>public f"
let ?GSMP = "GSMP M - (pubval_terms \<union> abs_terms)"
have 1: "\<forall>m \<in> IK. m \<in> ?GSMP"
using IK(1) by blast
have 2: "\<forall>t t'. t \<in> ?GSMP \<longrightarrow> t' \<sqsubseteq> t \<longrightarrow> t' \<in> ?GSMP"
proof (intro allI impI)
fix t t' assume t: "t \<in> ?GSMP" "t' \<sqsubseteq> t"
hence "t' \<in> GSMP M" using ground_subterm unfolding GSMP_def by auto
moreover have "\<not>public f"
when "f \<in> funs_term t" "is_Val f" for f
using t(1) that by auto
hence "\<not>public f"
when "f \<in> funs_term t'" "is_Val f" for f
using that subtermeq_imp_funs_term_subset[OF t(2)] by auto
moreover have "\<not>is_Abs f" when "f \<in> funs_term t" for f using t(1) that by auto
hence "\<not>is_Abs f" when "f \<in> funs_term t'" for f
using that subtermeq_imp_funs_term_subset[OF t(2)] by auto
ultimately show "t' \<in> ?GSMP" by simp
qed
have 3: "\<forall>t K T k. t \<in> ?GSMP \<longrightarrow> Ana t = (K, T) \<longrightarrow> k \<in> set K \<longrightarrow> k \<in> ?GSMP"
proof (intro allI impI)
fix t K T k assume t: "t \<in> ?GSMP" "Ana t = (K, T)" "k \<in> set K"
hence "k \<in> GSMP M" using GSMP_Ana_key by blast
moreover have "\<forall>f \<in> funs_term t. ?P f" using t(1) by auto
with t(2,3) have "\<forall>f \<in> funs_term k. ?P f"
proof (induction t arbitrary: k rule: Ana.induct)
case 1 thus ?case by (metis Ana_Fu_keys_not_pubval_terms surj_pair)
qed auto
moreover have "\<forall>f \<in> funs_term t. \<not>is_Abs f" using t(1) by auto
with t(2,3) have "\<forall>f \<in> funs_term k. \<not>is_Abs f"
proof (induction t arbitrary: k rule: Ana.induct)
case 1 thus ?case by (metis Ana_Fu_keys_not_abs_terms surj_pair)
qed auto
ultimately show "k \<in> ?GSMP" by simp
qed
have "\<langle>IK; M\<rangle> \<turnstile>\<^sub>G\<^sub>S\<^sub>M\<^sub>P t"
unfolding intruder_deduct_GSMP_def
by (rule restricted_deduct_if_deduct'[OF 1 2 3 t])
thus ?thesis
proof (induction t rule: intruder_deduct_GSMP_induct)
case (AxiomH t)
show ?case using IK(2) abs_in[OF AxiomH.hyps] by force
next
case (ComposeH T f)
have *: "Fun f T \<cdot>\<^sub>\<alpha> \<alpha> = Fun f (map (\<lambda>t. t \<cdot>\<^sub>\<alpha> \<alpha>) T)"
using ComposeH.hyps(2,4)
by (cases f) auto
have **: "length (map (\<lambda>t. t \<cdot>\<^sub>\<alpha> \<alpha>) T) = arity f"
using ComposeH.hyps(1)
by auto
show ?case
using intruder_deduct.Compose[OF ** ComposeH.hyps(2)] ComposeH.IH(1) *
by auto
next
case (DecomposeH t K T' t\<^sub>i)
have *: "Ana (t \<cdot>\<^sub>\<alpha> \<alpha>) = (K \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha>, T' \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha>)"
using Ana_abs[OF DecomposeH.hyps(2)]
by metis
have **: "t\<^sub>i \<cdot>\<^sub>\<alpha> \<alpha> \<in> set (T' \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha>)"
using DecomposeH.hyps(4) abs_in abs_list_set_is_set_abs_set[of T']
by auto
have ***: "FP \<turnstile> k"
when k: "k \<in> set (K \<cdot>\<^sub>\<alpha>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<alpha>)" for k
proof -
obtain k' where k': "k' \<in> set K" "k = k' \<cdot>\<^sub>\<alpha> \<alpha>"
by (metis (no_types) k abs_apply_terms_def imageE abs_list_set_is_set_abs_set)
show "FP \<turnstile> k"
using DecomposeH.IH k' by blast
qed
show ?case
using intruder_deduct.Decompose[OF _ * _ **]
DecomposeH.IH(1) ***(1)
by blast
qed
qed
end
subsection \<open>Computing and Checking Term Implications and Messages\<close>
context stateful_protocol_model
begin
abbreviation (input) "absc s \<equiv> (Fun (Abs s) []::('fun, 'atom, 'sets) prot_term)"
fun absdbupd where
"absdbupd [] _ a = a"
| "absdbupd (insert\<langle>Var y, Fun (Set s) T\<rangle>#D) x a = (
if x = y then absdbupd D x (insert s a) else absdbupd D x a)"
| "absdbupd (delete\<langle>Var y, Fun (Set s) T\<rangle>#D) x a = (
if x = y then absdbupd D x (a - {s}) else absdbupd D x a)"
| "absdbupd (_#D) x a = absdbupd D x a"
lemma absdbupd_cons_cases:
"absdbupd (insert\<langle>Var x, Fun (Set s) T\<rangle>#D) x d = absdbupd D x (insert s d)"
"absdbupd (delete\<langle>Var x, Fun (Set s) T\<rangle>#D) x d = absdbupd D x (d - {s})"
"t \<noteq> Var x \<or> (\<nexists>s T. u = Fun (Set s) T) \<Longrightarrow> absdbupd (insert\<langle>t,u\<rangle>#D) x d = absdbupd D x d"
"t \<noteq> Var x \<or> (\<nexists>s T. u = Fun (Set s) T) \<Longrightarrow> absdbupd (delete\<langle>t,u\<rangle>#D) x d = absdbupd D x d"
proof -
assume *: "t \<noteq> Var x \<or> (\<nexists>s T. u = Fun (Set s) T)"
let ?P = "absdbupd (insert\<langle>t,u\<rangle>#D) x d = absdbupd D x d"
let ?Q = "absdbupd (delete\<langle>t,u\<rangle>#D) x d = absdbupd D x d"
{ fix y f T assume "t = Fun f T \<or> u = Var y" hence ?P ?Q by auto
} moreover {
fix y f T assume "t = Var y" "u = Fun f T" hence ?P using * by (cases f) auto
} moreover {
fix y f T assume "t = Var y" "u = Fun f T" hence ?Q using * by (cases f) auto
} ultimately show ?P ?Q by (metis term.exhaust)+
qed simp_all
lemma absdbupd_filter: "absdbupd S x d = absdbupd (filter is_Update S) x d"
by (induction S x d rule: absdbupd.induct) simp_all
lemma absdbupd_append:
"absdbupd (A@B) x d = absdbupd B x (absdbupd A x d)"
proof (induction A arbitrary: d)
case (Cons a A) thus ?case
proof (cases a)
case (Insert t u) thus ?thesis
proof (cases "t \<noteq> Var x \<or> (\<nexists>s T. u = Fun (Set s) T)")
case False
then obtain s T where "t = Var x" "u = Fun (Set s) T" by moura
thus ?thesis by (simp add: Insert Cons.IH absdbupd_cons_cases(1))
qed (simp_all add: Cons.IH absdbupd_cons_cases(3))
next
case (Delete t u) thus ?thesis
proof (cases "t \<noteq> Var x \<or> (\<nexists>s T. u = Fun (Set s) T)")
case False
then obtain s T where "t = Var x" "u = Fun (Set s) T" by moura
thus ?thesis by (simp add: Delete Cons.IH absdbupd_cons_cases(2))
qed (simp_all add: Cons.IH absdbupd_cons_cases(4))
qed simp_all
qed simp
lemma absdbupd_wellformed_transaction:
assumes T: "wellformed_transaction T"
shows "absdbupd (unlabel (transaction_strand T)) = absdbupd (unlabel (transaction_updates T))"
proof -
define S0 where "S0 \<equiv> unlabel (transaction_strand T)"
define S1 where "S1 \<equiv> unlabel (transaction_receive T)"
define S2 where "S2 \<equiv> unlabel (transaction_selects T)"
define S3 where "S3 \<equiv> unlabel (transaction_checks T)"
define S4 where "S4 \<equiv> unlabel (transaction_updates T)"
define S5 where "S5 \<equiv> unlabel (transaction_send T)"
note S_defs = S0_def S1_def S2_def S3_def S4_def S5_def
have 0: "list_all is_Receive S1"
"list_all is_Assignment S2"
"list_all is_Check S3"
"list_all is_Update S4"
"list_all is_Send S5"
using T unfolding wellformed_transaction_def S_defs by metis+
have "filter is_Update S1 = []"
"filter is_Update S2 = []"
"filter is_Update S3 = []"
"filter is_Update S4 = S4"
"filter is_Update S5 = []"
using list_all_filter_nil[OF 0(1), of is_Update]
list_all_filter_nil[OF 0(2), of is_Update]
list_all_filter_nil[OF 0(3), of is_Update]
list_all_filter_eq[OF 0(4)]
list_all_filter_nil[OF 0(5), of is_Update]
by blast+
moreover have "S0 = S1@S2@S3@S4@S5"
unfolding S_defs transaction_strand_def unlabel_def by auto
ultimately have "filter is_Update S0 = S4"
using filter_append[of is_Update] list_all_append[of is_Update]
by simp
thus ?thesis
using absdbupd_filter[of S0]
unfolding S_defs by presburger
qed
fun abs_substs_set::
"[('fun,'atom,'sets) prot_var list,
'sets set list,
('fun,'atom,'sets) prot_var \<Rightarrow> 'sets set,
('fun,'atom,'sets) prot_var \<Rightarrow> 'sets set]
\<Rightarrow> ((('fun,'atom,'sets) prot_var \<times> 'sets set) list) list"
where
"abs_substs_set [] _ _ _ = [[]]"
| "abs_substs_set (x#xs) as posconstrs negconstrs = (
let bs = filter (\<lambda>a. posconstrs x \<subseteq> a \<and> a \<inter> negconstrs x = {}) as
in concat (map (\<lambda>b. map (\<lambda>\<delta>. (x, b)#\<delta>) (abs_substs_set xs as posconstrs negconstrs)) bs))"
definition abs_substs_fun::
"[(('fun,'atom,'sets) prot_var \<times> 'sets set) list,
('fun,'atom,'sets) prot_var]
\<Rightarrow> 'sets set"
where
"abs_substs_fun \<delta> x = (case find (\<lambda>b. fst b = x) \<delta> of Some (_,a) \<Rightarrow> a | None \<Rightarrow> {})"
lemmas abs_substs_set_induct = abs_substs_set.induct[case_names Nil Cons]
fun transaction_poschecks_comp::
"(('fun,'atom,'sets) prot_fun, ('fun,'atom,'sets) prot_var) stateful_strand
\<Rightarrow> (('fun,'atom,'sets) prot_var \<Rightarrow> 'sets set)"
where
"transaction_poschecks_comp [] = (\<lambda>_. {})"
| "transaction_poschecks_comp (\<langle>_: Var x \<in> Fun (Set s) []\<rangle>#T) = (
let f = transaction_poschecks_comp T in f(x := insert s (f x)))"
| "transaction_poschecks_comp (_#T) = transaction_poschecks_comp T"
fun transaction_negchecks_comp::
"(('fun,'atom,'sets) prot_fun, ('fun,'atom,'sets) prot_var) stateful_strand
\<Rightarrow> (('fun,'atom,'sets) prot_var \<Rightarrow> 'sets set)"
where
"transaction_negchecks_comp [] = (\<lambda>_. {})"
| "transaction_negchecks_comp (\<langle>Var x not in Fun (Set s) []\<rangle>#T) = (
let f = transaction_negchecks_comp T in f(x := insert s (f x)))"
| "transaction_negchecks_comp (_#T) = transaction_negchecks_comp T"
definition transaction_check_pre where
"transaction_check_pre FP TI T \<delta> \<equiv>
let C = set (unlabel (transaction_checks T));
S = set (unlabel (transaction_selects T));
xs = fv_list\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T));
\<theta> = \<lambda>\<delta> x. if fst x = TAtom Value then (absc \<circ> \<delta>) x else Var x
in (\<forall>x \<in> set (transaction_fresh T). \<delta> x = {}) \<and>
(\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T). intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> \<delta>)) \<and>
(\<forall>u \<in> S \<union> C.
(is_InSet u \<longrightarrow> (
let x = the_elem_term u; s = the_set_term u
in (is_Var x \<and> is_Fun_Set s) \<longrightarrow> the_Set (the_Fun s) \<in> \<delta> (the_Var x))) \<and>
((is_NegChecks u \<and> bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p u = [] \<and> the_eqs u = [] \<and> length (the_ins u) = 1) \<longrightarrow> (
let x = fst (hd (the_ins u)); s = snd (hd (the_ins u))
in (is_Var x \<and> is_Fun_Set s) \<longrightarrow> the_Set (the_Fun s) \<notin> \<delta> (the_Var x))))"
definition transaction_check_post where
"transaction_check_post FP TI T \<delta> \<equiv>
let xs = fv_list\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T));
\<theta> = \<lambda>\<delta> x. if fst x = TAtom Value then (absc \<circ> \<delta>) x else Var x;
u = \<lambda>\<delta> x. absdbupd (unlabel (transaction_updates T)) x (\<delta> x)
in (\<forall>x \<in> set xs - set (transaction_fresh T). \<delta> x \<noteq> u \<delta> x \<longrightarrow> List.member TI (\<delta> x, u \<delta> x)) \<and>
(\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T). intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> (u \<delta>)))"
definition transaction_check_comp::
"[('fun,'atom,'sets) prot_term list,
'sets set list,
('sets set \<times> 'sets set) list,
('fun,'atom,'sets,'lbl) prot_transaction]
\<Rightarrow> ((('fun,'atom,'sets) prot_var \<times> 'sets set) list) list"
where
"transaction_check_comp FP OCC TI T \<equiv>
let S = unlabel (transaction_strand T);
C = unlabel (transaction_selects T@transaction_checks T);
xs = filter (\<lambda>x. x \<notin> set (transaction_fresh T) \<and> fst x = TAtom Value) (fv_list\<^sub>s\<^sub>s\<^sub>t S);
posconstrs = transaction_poschecks_comp C;
negconstrs = transaction_negchecks_comp C;
pre_check = transaction_check_pre FP TI T
in filter (\<lambda>\<delta>. pre_check (abs_substs_fun \<delta>)) (abs_substs_set xs OCC posconstrs negconstrs)"
definition transaction_check::
"[('fun,'atom,'sets) prot_term list,
'sets set list,
('sets set \<times> 'sets set) list,
('fun,'atom,'sets,'lbl) prot_transaction]
\<Rightarrow> bool"
where
"transaction_check FP OCC TI T \<equiv>
list_all (\<lambda>\<delta>. transaction_check_post FP TI T (abs_substs_fun \<delta>)) (transaction_check_comp FP OCC TI T)"
lemma abs_subst_fun_cons:
"abs_substs_fun ((x,b)#\<delta>) = (abs_substs_fun \<delta>)(x := b)"
unfolding abs_substs_fun_def by fastforce
lemma abs_substs_cons:
assumes "\<delta> \<in> set (abs_substs_set xs as poss negs)" "b \<in> set as" "poss x \<subseteq> b" "b \<inter> negs x = {}"
shows "(x,b)#\<delta> \<in> set (abs_substs_set (x#xs) as poss negs)"
using assms by auto
lemma abs_substs_cons':
assumes \<delta>: "\<delta> \<in> abs_substs_fun ` set (abs_substs_set xs as poss negs)"
and b: "b \<in> set as" "poss x \<subseteq> b" "b \<inter> negs x = {}"
shows "\<delta>(x := b) \<in> abs_substs_fun ` set (abs_substs_set (x#xs) as poss negs)"
proof -
obtain \<theta> where \<theta>: "\<delta> = abs_substs_fun \<theta>" "\<theta> \<in> set (abs_substs_set xs as poss negs)"
using \<delta> by moura
have "abs_substs_fun ((x, b)#\<theta>) \<in> abs_substs_fun ` set (abs_substs_set (x#xs) as poss negs)"
using abs_substs_cons[OF \<theta>(2) b] by blast
thus ?thesis
using \<theta>(1) abs_subst_fun_cons[of x b \<theta>] by argo
qed
lemma abs_substs_has_all_abs:
assumes "\<forall>x. x \<in> set xs \<longrightarrow> \<delta> x \<in> set as"
and "\<forall>x. x \<in> set xs \<longrightarrow> poss x \<subseteq> \<delta> x"
and "\<forall>x. x \<in> set xs \<longrightarrow> \<delta> x \<inter> negs x = {}"
and "\<forall>x. x \<notin> set xs \<longrightarrow> \<delta> x = {}"
shows "\<delta> \<in> abs_substs_fun ` set (abs_substs_set xs as poss negs)"
using assms
proof (induction xs arbitrary: \<delta>)
case (Cons x xs)
define \<theta> where "\<theta> \<equiv> \<lambda>y. if y \<in> set xs then \<delta> y else {}"
have "\<theta> \<in> abs_substs_fun ` set (abs_substs_set xs as poss negs)"
using Cons.prems Cons.IH by (simp add: \<theta>_def)
moreover have "\<delta> x \<in> set as" "poss x \<subseteq> \<delta> x" "\<delta> x \<inter> negs x = {}"
using Cons.prems(1,2,3) by fastforce+
ultimately have 0: "\<theta>(x := \<delta> x) \<in> abs_substs_fun ` set (abs_substs_set (x#xs) as poss negs)"
by (metis abs_substs_cons')
have "\<delta> = \<theta>(x := \<delta> x)"
proof
fix y show "\<delta> y = (\<theta>(x := \<delta> x)) y"
proof (cases "y \<in> set (x#xs)")
case False thus ?thesis using Cons.prems(4) by (fastforce simp add: \<theta>_def)
qed (auto simp add: \<theta>_def)
qed
thus ?case by (metis 0)
qed (auto simp add: abs_substs_fun_def)
lemma abs_substs_abss_bounded:
assumes "\<delta> \<in> abs_substs_fun ` set (abs_substs_set xs as poss negs)"
and "x \<in> set xs"
shows "\<delta> x \<in> set as"
and "poss x \<subseteq> \<delta> x"
and "\<delta> x \<inter> negs x = {}"
using assms
proof (induct xs as poss negs arbitrary: \<delta> rule: abs_substs_set_induct)
case (Cons y xs as poss negs)
{ case 1 thus ?case using Cons.hyps(1) unfolding abs_substs_fun_def by fastforce }
{ case 2 thus ?case
proof (cases "x = y")
case False
then obtain \<delta>' where \<delta>':
"\<delta>' \<in> abs_substs_fun ` set (abs_substs_set xs as poss negs)" "\<delta>' x = \<delta> x"
using 2 unfolding abs_substs_fun_def by force
moreover have "x \<in> set xs" using 2(2) False by simp
moreover have "\<exists>b. b \<in> set as \<and> poss y \<subseteq> b \<and> b \<inter> negs y = {}"
using 2 False by auto
ultimately show ?thesis using Cons.hyps(2) by fastforce
qed (auto simp add: abs_substs_fun_def)
}
{ case 3 thus ?case
proof (cases "x = y")
case False
then obtain \<delta>' where \<delta>':
"\<delta>' \<in> abs_substs_fun ` set (abs_substs_set xs as poss negs)" "\<delta>' x = \<delta> x"
using 3 unfolding abs_substs_fun_def by force
moreover have "x \<in> set xs" using 3(2) False by simp
moreover have "\<exists>b. b \<in> set as \<and> poss y \<subseteq> b \<and> b \<inter> negs y = {}"
using 3 False by auto
ultimately show ?thesis using Cons.hyps(3) by fastforce
qed (auto simp add: abs_substs_fun_def)
}
qed (simp_all add: abs_substs_fun_def)
lemma transaction_poschecks_comp_unfold:
"transaction_poschecks_comp C x = {s. \<exists>a. \<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> set C}"
proof (induction C)
case (Cons c C) thus ?case
proof (cases "\<exists>a y s. c = \<langle>a: Var y \<in> Fun (Set s) []\<rangle>")
case True
then obtain a y s where c: "c = \<langle>a: Var y \<in> Fun (Set s) []\<rangle>" by moura
define f where "f \<equiv> transaction_poschecks_comp C"
have "transaction_poschecks_comp (c#C) = f(y := insert s (f y))"
using c by (simp add: f_def Let_def)
moreover have "f x = {s. \<exists>a. \<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> set C}"
using Cons.IH unfolding f_def by blast
ultimately show ?thesis using c by auto
next
case False
hence "transaction_poschecks_comp (c#C) = transaction_poschecks_comp C" (is ?P)
using transaction_poschecks_comp.cases[of "c#C" ?P] by force
thus ?thesis using False Cons.IH by auto
qed
qed simp
lemma transaction_poschecks_comp_notin_fv_empty:
assumes "x \<notin> fv\<^sub>s\<^sub>s\<^sub>t C"
shows "transaction_poschecks_comp C x = {}"
using assms transaction_poschecks_comp_unfold[of C x] by fastforce
lemma transaction_negchecks_comp_unfold:
"transaction_negchecks_comp C x = {s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> set C}"
proof (induction C)
case (Cons c C) thus ?case
proof (cases "\<exists>y s. c = \<langle>Var y not in Fun (Set s) []\<rangle>")
case True
then obtain y s where c: "c = \<langle>Var y not in Fun (Set s) []\<rangle>" by moura
define f where "f \<equiv> transaction_negchecks_comp C"
have "transaction_negchecks_comp (c#C) = f(y := insert s (f y))"
using c by (simp add: f_def Let_def)
moreover have "f x = {s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> set C}"
using Cons.IH unfolding f_def by blast
ultimately show ?thesis using c by auto
next
case False
hence "transaction_negchecks_comp (c#C) = transaction_negchecks_comp C" (is ?P)
using transaction_negchecks_comp.cases[of "c#C" ?P]
by force
thus ?thesis using False Cons.IH by fastforce
qed
qed simp
lemma transaction_negchecks_comp_notin_fv_empty:
assumes "x \<notin> fv\<^sub>s\<^sub>s\<^sub>t C"
shows "transaction_negchecks_comp C x = {}"
using assms transaction_negchecks_comp_unfold[of C x] by fastforce
lemma transaction_check_preI[intro]:
fixes T
defines "\<theta> \<equiv> \<lambda>\<delta> x. if fst x = TAtom Value then (absc \<circ> \<delta>) x else Var x"
and "S \<equiv> set (unlabel (transaction_selects T))"
and "C \<equiv> set (unlabel (transaction_checks T))"
assumes a0: "\<forall>x \<in> set (transaction_fresh T). \<delta> x = {}"
and a1: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> \<delta> x \<in> set OCC"
and a2: "\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T). intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> \<delta>)"
and a3: "\<forall>a x s. \<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> S \<union> C \<longrightarrow> s \<in> \<delta> x"
and a4: "\<forall>x s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> S \<union> C \<longrightarrow> s \<notin> \<delta> x"
shows "transaction_check_pre FP TI T \<delta>"
proof -
let ?P = "\<lambda>u. is_InSet u \<longrightarrow> (
let x = the_elem_term u; s = the_set_term u
in (is_Var x \<and> is_Fun_Set s) \<longrightarrow> the_Set (the_Fun s) \<in> \<delta> (the_Var x))"
let ?Q = "\<lambda>u. (is_NegChecks u \<and> bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p u = [] \<and> the_eqs u = [] \<and> length (the_ins u) = 1) \<longrightarrow> (
let x = fst (hd (the_ins u)); s = snd (hd (the_ins u))
in (is_Var x \<and> is_Fun_Set s) \<longrightarrow> the_Set (the_Fun s) \<notin> \<delta> (the_Var x))"
have 1: "?P u" when u: "u \<in> S \<union> C" for u
apply (unfold Let_def, intro impI, elim conjE)
using u a3 Fun_Set_InSet_iff[of u] by metis
have 2: "?Q u" when u: "u \<in> S \<union> C" for u
apply (unfold Let_def, intro impI, elim conjE)
using u a4 Fun_Set_NotInSet_iff[of u] by metis
show ?thesis
using a0 a1 a2 1 2 fv_list\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t[of "unlabel (transaction_strand T)"]
unfolding transaction_check_pre_def \<theta>_def S_def C_def Let_def
by blast
qed
lemma transaction_check_pre_InSetE:
assumes T: "transaction_check_pre FP TI T \<delta>"
and u: "u = \<langle>a: Var x \<in> Fun (Set s) []\<rangle>"
"u \<in> set (unlabel (transaction_selects T)) \<union> set (unlabel (transaction_checks T))"
shows "s \<in> \<delta> x"
proof -
have "is_InSet u \<longrightarrow> is_Var (the_elem_term u) \<and> is_Fun_Set (the_set_term u) \<longrightarrow>
the_Set (the_Fun (the_set_term u)) \<in> \<delta> (the_Var (the_elem_term u))"
using T u unfolding transaction_check_pre_def Let_def by blast
thus ?thesis using Fun_Set_InSet_iff[of u a x s] u by argo
qed
lemma transaction_check_pre_NotInSetE:
assumes T: "transaction_check_pre FP TI T \<delta>"
and u: "u = \<langle>Var x not in Fun (Set s) []\<rangle>"
"u \<in> set (unlabel (transaction_selects T)) \<union> set (unlabel (transaction_checks T))"
shows "s \<notin> \<delta> x"
proof -
have "is_NegChecks u \<and> bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p u = [] \<and> the_eqs u = [] \<and> length (the_ins u) = 1 \<longrightarrow>
is_Var (fst (hd (the_ins u))) \<and> is_Fun_Set (snd (hd (the_ins u))) \<longrightarrow>
the_Set (the_Fun (snd (hd (the_ins u)))) \<notin> \<delta> (the_Var (fst (hd (the_ins u))))"
using T u unfolding transaction_check_pre_def Let_def by blast
thus ?thesis using Fun_Set_NotInSet_iff[of u x s] u by argo
qed
lemma transaction_check_compI[intro]:
assumes T: "transaction_check_pre FP TI T \<delta>"
and T_adm: "admissible_transaction T"
and x1: "\<forall>x. (x \<in> fv_transaction T - set (transaction_fresh T) \<and> fst x = TAtom Value)
\<longrightarrow> \<delta> x \<in> set OCC"
and x2: "\<forall>x. (x \<notin> fv_transaction T - set (transaction_fresh T) \<or> fst x \<noteq> TAtom Value)
\<longrightarrow> \<delta> x = {}"
shows "\<delta> \<in> abs_substs_fun ` set (transaction_check_comp FP OCC TI T)"
proof -
define S where "S \<equiv> unlabel (transaction_strand T)"
define C where "C \<equiv> unlabel (transaction_selects T@transaction_checks T)"
define C' where "C' \<equiv> set (unlabel (transaction_selects T)) \<union>
set (unlabel (transaction_checks T))"
let ?xs = "fv_list\<^sub>s\<^sub>s\<^sub>t S"
define poss where "poss \<equiv> transaction_poschecks_comp C"
define negs where "negs \<equiv> transaction_negchecks_comp C"
define ys where "ys \<equiv> filter (\<lambda>x. x \<notin> set (transaction_fresh T) \<and> fst x = TAtom Value) ?xs"
have C_C'_eq: "set C = C'"
using unlabel_append[of "transaction_selects T" "transaction_checks T"]
unfolding C_def C'_def by simp
have ys: "{x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value} = set ys"
using fv_list\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t[of S]
unfolding ys_def S_def by force
have "\<delta> x \<in> set OCC"
when x: "x \<in> set ys" for x
using x1 x ys by blast
moreover have "\<delta> x = {}"
when x: "x \<notin> set ys" for x
using x2 x ys by blast
moreover have "poss x \<subseteq> \<delta> x" when x: "x \<in> set ys" for x
proof -
have "s \<in> \<delta> x" when u: "u = \<langle>a: Var x \<in> Fun (Set s) []\<rangle>" "u \<in> C'" for u a s
using T u transaction_check_pre_InSetE[of FP TI T \<delta>]
unfolding C'_def by blast
thus ?thesis
using transaction_poschecks_comp_unfold[of C x] C_C'_eq
unfolding poss_def by blast
qed
moreover have "\<delta> x \<inter> negs x = {}" when x: "x \<in> set ys" for x
proof (cases "x \<in> fv\<^sub>s\<^sub>s\<^sub>t C")
case True
hence "s \<notin> \<delta> x" when u: "u = \<langle>Var x not in Fun (Set s) []\<rangle>" "u \<in> C'" for u s
using T u transaction_check_pre_NotInSetE[of FP TI T \<delta>]
unfolding C'_def by blast
thus ?thesis
using transaction_negchecks_comp_unfold[of C x] C_C'_eq
unfolding negs_def by blast
next
case False
hence "negs x = {}"
using x C_C'_eq transaction_negchecks_comp_notin_fv_empty
unfolding negs_def by blast
thus ?thesis by blast
qed
ultimately have "\<delta> \<in> abs_substs_fun ` set (abs_substs_set ys OCC poss negs)"
using abs_substs_has_all_abs[of ys \<delta> OCC poss negs]
by fast
thus ?thesis
using T
unfolding transaction_check_comp_def Let_def S_def C_def ys_def poss_def negs_def
by fastforce
qed
context
begin
private lemma transaction_check_comp_in_aux:
fixes T
defines "S \<equiv> set (unlabel (transaction_selects T))"
and "C \<equiv> set (unlabel (transaction_checks T))"
assumes T_adm: "admissible_transaction T"
and a1: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> (\<forall>s.
select\<langle>Var x, Fun (Set s) []\<rangle> \<in> S \<longrightarrow> s \<in> \<alpha> x)"
and a2: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> (\<forall>s.
\<langle>Var x in Fun (Set s) []\<rangle> \<in> C \<longrightarrow> s \<in> \<alpha> x)"
and a3: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> (\<forall>s.
\<langle>Var x not in Fun (Set s) []\<rangle> \<in> C \<longrightarrow> s \<notin> \<alpha> x)"
shows "\<forall>a x s. \<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> S \<union> C \<longrightarrow> s \<in> \<alpha> x" (is ?A)
and "\<forall>x s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> S \<union> C \<longrightarrow> s \<notin> \<alpha> x" (is ?B)
proof -
have T_valid: "wellformed_transaction T"
and T_adm_S: "admissible_transaction_selects T"
and T_adm_C: "admissible_transaction_checks T"
using T_adm unfolding admissible_transaction_def by blast+
note * = admissible_transaction_strand_step_cases(2,3)[OF T_adm]
have 1: "fst x = TAtom Value" "x \<in> fv_transaction T - set (transaction_fresh T)"
when x: "\<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> S \<union> C" for a x s
using * x unfolding S_def C_def by fast+
have 2: "fst x = TAtom Value" "x \<in> fv_transaction T - set (transaction_fresh T)"
when x: "\<langle>Var x not in Fun (Set s) []\<rangle> \<in> S \<union> C" for x s
using * x unfolding S_def C_def by fast+
have 3: "select\<langle>Var x, Fun (Set s) []\<rangle> \<in> S"
when x: "select\<langle>Var x, Fun (Set s) []\<rangle> \<in> S \<union> C" for x s
using * x unfolding S_def C_def by fast
have 4: "\<langle>Var x in Fun (Set s) []\<rangle> \<in> C"
when x: "\<langle>Var x in Fun (Set s) []\<rangle> \<in> S \<union> C" for x s
using * x unfolding S_def C_def by fast
have 5: "\<langle>Var x not in Fun (Set s) []\<rangle> \<in> C"
when x: "\<langle>Var x not in Fun (Set s) []\<rangle> \<in> S \<union> C" for x s
using * x unfolding S_def C_def by fast
show ?A
proof (intro allI impI)
fix a x s assume u: "\<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> S \<union> C"
thus "s \<in> \<alpha> x" using 1 3 4 a1 a2 by (cases a) metis+
qed
show ?B
proof (intro allI impI)
fix x s assume u: "\<langle>Var x not in Fun (Set s) []\<rangle> \<in> S \<union> C"
thus "s \<notin> \<alpha> x" using 2 5 a3 by meson
qed
qed
lemma transaction_check_comp_in:
fixes T
defines "\<theta> \<equiv> \<lambda>\<delta> x. if fst x = TAtom Value then (absc \<circ> \<delta>) x else Var x"
and "S \<equiv> set (unlabel (transaction_selects T))"
and "C \<equiv> set (unlabel (transaction_checks T))"
assumes T_adm: "admissible_transaction T"
and a1: "\<forall>x \<in> set (transaction_fresh T). \<alpha> x = {}"
and a2: "\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T). intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> \<alpha>)"
and a3: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). \<forall>s.
select\<langle>Var x, Fun (Set s) []\<rangle> \<in> S \<longrightarrow> s \<in> \<alpha> x"
and a4: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). \<forall>s.
\<langle>Var x in Fun (Set s) []\<rangle> \<in> C \<longrightarrow> s \<in> \<alpha> x"
and a5: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). \<forall>s.
\<langle>Var x not in Fun (Set s) []\<rangle> \<in> C \<longrightarrow> s \<notin> \<alpha> x"
and a6: "\<forall>x \<in> fv_transaction T - set (transaction_fresh T).
fst x = TAtom Value \<longrightarrow> \<alpha> x \<in> set OCC"
shows "\<exists>\<delta> \<in> abs_substs_fun ` set (transaction_check_comp FP OCC TI T). \<forall>x \<in> fv_transaction T.
fst x = TAtom Value \<longrightarrow> \<alpha> x = \<delta> x"
proof -
let ?xs = "fv_list\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T))"
let ?ys = "filter (\<lambda>x. x \<notin> set (transaction_fresh T)) ?xs"
define \<alpha>' where "\<alpha>' \<equiv> \<lambda>x.
if x \<in> fv_transaction T - set (transaction_fresh T) \<and> fst x = TAtom Value
then \<alpha> x
else {}"
have T_valid: "wellformed_transaction T"
using T_adm unfolding admissible_transaction_def by blast
have \<theta>\<alpha>_Fun: "is_Fun (t \<cdot> \<theta> \<alpha>) \<longleftrightarrow> is_Fun (t \<cdot> \<theta> \<alpha>')" for t
unfolding \<alpha>'_def \<theta>_def
by (induct t) auto
have "\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T). intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> \<alpha>')"
proof (intro ballI impI)
fix t assume t: "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T)"
have 1: "intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> \<alpha>)"
using t a2
by auto
obtain r where r:
"r \<in> set (unlabel (transaction_receive T))"
"t \<in> trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p r"
using t by auto
hence "r = receive\<langle>t\<rangle>"
using wellformed_transaction_unlabel_cases(1)[OF T_valid]
by fastforce
hence 2: "fv t \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T)" using r by force
have "fv t \<subseteq> fv_transaction T"
by (metis (no_types, lifting) 2 transaction_strand_def sst_vars_append_subset(1)
unlabel_append subset_Un_eq sup.bounded_iff)
moreover have "fv t \<inter> set (transaction_fresh T) = {}"
using 2 T_valid 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_receive T)"]
unfolding wellformed_transaction_def
by fast
ultimately have "\<theta> \<alpha> x = \<theta> \<alpha>' x" when "x \<in> fv t" for x
using that unfolding \<alpha>'_def \<theta>_def by fastforce
hence 3: "t \<cdot> \<theta> \<alpha> = t \<cdot> \<theta> \<alpha>'"
using term_subst_eq by blast
show "intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> \<alpha>')" using 1 3 by simp
qed
moreover have
"\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> (\<forall>s.
select\<langle>Var x, Fun (Set s) []\<rangle> \<in> S \<longrightarrow> s \<in> \<alpha>' x)"
"\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> (\<forall>s.
\<langle>Var x in Fun (Set s) []\<rangle> \<in> C \<longrightarrow> s \<in> \<alpha>' x)"
"\<forall>x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value \<longrightarrow> (\<forall>s.
\<langle>Var x not in Fun (Set s) []\<rangle> \<in> C \<longrightarrow> s \<notin> \<alpha>' x)"
using a3 a4 a5
unfolding \<alpha>'_def \<theta>_def S_def C_def
by meson+
hence "\<forall>a x s. \<langle>a: Var x \<in> Fun (Set s) []\<rangle> \<in> S \<union> C \<longrightarrow> s \<in> \<alpha>' x"
"\<forall>x s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> S \<union> C \<longrightarrow> s \<notin> \<alpha>' x"
using transaction_check_comp_in_aux[OF T_adm, of \<alpha>']
unfolding S_def C_def
by fast+
ultimately have 4: "transaction_check_pre FP TI T \<alpha>'"
using a6 transaction_check_preI[of T \<alpha>' OCC FP TI]
unfolding \<alpha>'_def \<theta>_def S_def C_def by simp
have 5: "\<forall>x \<in> fv_transaction T. fst x = TAtom Value \<longrightarrow> \<alpha> x = \<alpha>' x"
using a1 by (auto simp add: \<alpha>'_def)
have 6: "\<alpha>' \<in> abs_substs_fun ` set (transaction_check_comp FP OCC TI T)"
using transaction_check_compI[OF 4 T_adm] a6
unfolding \<alpha>'_def
by auto
show ?thesis using 5 6 by blast
qed
end
end
subsection \<open>Automatically Checking Protocol Security in a Typed Model\<close>
context stateful_protocol_model
begin
definition abs_intruder_knowledge ("\<alpha>\<^sub>i\<^sub>k") where
"\<alpha>\<^sub>i\<^sub>k S \<I> \<equiv> (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \<I>)"
definition abs_value_constants ("\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s") where
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s S \<I> \<equiv> {t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t S) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>. \<exists>n. t = Fun (Val n) []} \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \<I>)"
definition abs_term_implications ("\<alpha>\<^sub>t\<^sub>i") where
"\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I> \<equiv> {(s,t) | s t x.
s \<noteq> t \<and> x \<in> fv_transaction T \<and> x \<notin> set (transaction_fresh T) \<and>
Fun (Abs s) [] = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) \<and>
Fun (Abs t) [] = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>)}"
lemma abs_intruder_knowledge_append:
"\<alpha>\<^sub>i\<^sub>k (A@B) \<I> =
(ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@B) \<I>) \<union>
(ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@B) \<I>)"
by (metis unlabel_append abs_set_union image_Un ik\<^sub>s\<^sub>s\<^sub>t_append abs_intruder_knowledge_def)
lemma abs_value_constants_append:
fixes A B::"('a,'b,'c,'d) prot_strand"
shows "\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s (A@B) \<I> =
{t \<in> 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>. \<exists>n. t = Fun (Val n) []} \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@B) \<I>) \<union>
{t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>. \<exists>n. t = Fun (Val n) []} \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@B) \<I>)"
proof -
define a0 where "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>s\<^sub>s\<^sub>t (unlabel (A@B)) \<I>)"
define M where "M \<equiv> \<lambda>a::('a,'b,'c,'d) prot_strand.
{t \<in> 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>. \<exists>n. t = Fun (Val n) []}"
have "M (A@B) = M A \<union> M B"
using unlabel_append[of A B] trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel A" "unlabel B"]
image_Un[of "\<lambda>x. x \<cdot> \<I>" "subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" "subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"]
unfolding M_def by force
hence "M (A@B) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0 = (M A \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0) \<union> (M B \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0)" by (simp add: abs_set_union)
thus ?thesis unfolding abs_value_constants_def a0_def M_def by blast
qed
lemma transaction_renaming_subst_has_no_pubconsts_abss:
fixes \<alpha>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_renaming_subst \<alpha> P A"
shows "subst_range \<alpha> \<inter> pubval_terms = {}" (is ?A)
and "subst_range \<alpha> \<inter> abs_terms = {}" (is ?B)
proof -
{ fix t assume "t \<in> subst_range \<alpha>"
then obtain x where "t = Var x"
using transaction_renaming_subst_is_renaming[OF assms]
by force
hence "t \<notin> pubval_terms" "t \<notin> abs_terms" by simp_all
} thus ?A ?B by auto
qed
lemma transaction_fresh_subst_has_no_pubconsts_abss:
fixes \<sigma>::"('fun,'atom,'sets) prot_subst"
assumes "transaction_fresh_subst \<sigma> T \<A>"
shows "subst_range \<sigma> \<inter> pubval_terms = {}" (is ?A)
and "subst_range \<sigma> \<inter> abs_terms = {}" (is ?B)
proof -
{ fix t assume "t \<in> subst_range \<sigma>"
then obtain n where "t = Fun (Val (n,False)) []"
using assms unfolding transaction_fresh_subst_def
by force
hence "t \<notin> pubval_terms" "t \<notin> abs_terms" by simp_all
} thus ?A ?B by auto
qed
lemma reachable_constraints_no_pubconsts_abss:
assumes "\<A> \<in> reachable_constraints P"
and P: "\<forall>T \<in> set P. \<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` trms_transaction T)"
"\<forall>T \<in> set P. \<forall>n. Abs n \<notin> \<Union>(funs_term ` 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. bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) = {}"
and \<I>: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)"
"\<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
"\<forall>n. Abs n \<notin> \<Union>(funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
shows "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<subseteq> GSMP (\<Union>T \<in> set P. trms_transaction T) - (pubval_terms \<union> abs_terms)"
(is "?A \<subseteq> ?B")
using assms(1) \<I>(4,5)
proof (induction \<A> rule: reachable_constraints.induct)
case (step \<A> T \<sigma> \<alpha>)
define trms_P where "trms_P \<equiv> (\<Union>T \<in> set P. trms_transaction T)"
define T' where "T' \<equiv> transaction_strand T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
have \<I>': "\<forall>n. Val (n,True) \<notin> \<Union> (funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
"\<forall>n. Abs n \<notin> \<Union> (funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
using step.prems fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] unlabel_append[of \<A>]
by auto
have "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) P(3) wt_subst_compose)
hence "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>))" for X
using wt_subst_rm_vars[of "\<sigma> \<circ>\<^sub>s \<alpha>" "set X"]
by metis
hence wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t ((rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>)) \<circ>\<^sub>s \<I>)" for X
using \<I>(2) wt_subst_compose by fast
have "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)
hence wftrms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range ((rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>)) \<circ>\<^sub>s \<I>))" for X
using wf_trms_subst_compose[OF wf_trms_subst_rm_vars' \<I>(3)] by fast
have "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T') \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<subseteq> ?B"
proof
fix t assume "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T') \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
hence "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>" using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq by blast
then obtain s X where s:
"s \<in> trms_transaction T"
"t = s \<cdot> rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>) \<circ>\<^sub>s \<I>"
"set X \<subseteq> bvars_transaction T"
using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_subst'' unfolding T'_def by blast
define \<theta> where "\<theta> \<equiv> rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>)"
have 1: "s \<in> trms_P" using step.hyps(2) s(1) unfolding trms_P_def by auto
have s_nin: "s \<notin> pubval_terms" "s \<notin> abs_terms"
using 1 P(1,2) funs_term_Fun_subterm
unfolding trms_P_def is_Val_def is_Abs_def
by fastforce+
have 2: "(\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')) \<inter> pubval_terms = {}"
"(\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')) \<inter> abs_terms = {}"
"subst_range (\<sigma> \<circ>\<^sub>s \<alpha>) \<inter> pubval_terms = {}"
"subst_range (\<sigma> \<circ>\<^sub>s \<alpha>) \<inter> abs_terms = {}"
"subst_range \<theta> \<inter> pubval_terms = {}"
"subst_range \<theta> \<inter> abs_terms = {}"
"(\<theta> ` fv s) \<inter> pubval_terms = {}"
"(\<theta> ` fv s) \<inter> abs_terms = {}"
unfolding T'_def \<theta>_def
using step.prems funs_term_Fun_subterm
apply (fastforce simp add: is_Val_def,
fastforce simp add: is_Abs_def)
using pubval_terms_subst_range_comp[OF
transaction_fresh_subst_has_no_pubconsts_abss(1)[OF step.hyps(3)]
transaction_renaming_subst_has_no_pubconsts_abss(1)[OF step.hyps(4)]]
abs_terms_subst_range_comp[OF
transaction_fresh_subst_has_no_pubconsts_abss(2)[OF step.hyps(3)]
transaction_renaming_subst_has_no_pubconsts_abss(2)[OF step.hyps(4)]]
unfolding is_Val_def is_Abs_def
by force+
have "(\<I> ` fv (s \<cdot> \<theta>)) \<inter> pubval_terms = {}"
"(\<I> ` fv (s \<cdot> \<theta>)) \<inter> abs_terms = {}"
proof -
have "\<theta> = \<sigma> \<circ>\<^sub>s \<alpha>" "bvars_transaction T = {}" "vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' = fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'"
using s(3) P(4) step.hyps(2) rm_vars_empty
vars\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t_bvars\<^sub>s\<^sub>s\<^sub>t[of "unlabel T'"]
bvars\<^sub>s\<^sub>s\<^sub>t_subst[of "unlabel (transaction_strand T)" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
unfolding \<theta>_def T'_def by simp_all
hence "fv (s \<cdot> \<theta>) \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T'"
using trms\<^sub>s\<^sub>s\<^sub>t_fv_subst_subset[OF s(1), of \<theta>] unlabel_subst[of "transaction_strand T" \<theta>]
unfolding T'_def by auto
moreover have "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<subseteq> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')"
using fv\<^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'"]
fv\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq[of T']
by simp_all
hence "\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<inter> pubval_terms = {}" "\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<inter> abs_terms = {}"
using 2(1,2) by blast+
ultimately show "(\<I> ` fv (s \<cdot> \<theta>)) \<inter> pubval_terms = {}" "(\<I> ` fv (s \<cdot> \<theta>)) \<inter> abs_terms = {}"
by blast+
qed
hence \<sigma>\<alpha>\<I>_disj: "((\<theta> \<circ>\<^sub>s \<I>) ` fv s) \<inter> pubval_terms = {}"
"((\<theta> \<circ>\<^sub>s \<I>) ` fv s) \<inter> abs_terms = {}"
using pubval_terms_subst_range_comp'[of \<theta> "fv s" \<I>]
abs_terms_subst_range_comp'[of \<theta> "fv s" \<I>]
2(7,8)
by (simp_all add: subst_apply_fv_unfold)
have 3: "t \<notin> pubval_terms" "t \<notin> abs_terms"
using s(2) s_nin \<sigma>\<alpha>\<I>_disj
pubval_terms_subst[of s "rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>) \<circ>\<^sub>s \<I>"]
pubval_terms_subst_range_disj[of "rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>) \<circ>\<^sub>s \<I>" s]
abs_terms_subst[of s "rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>) \<circ>\<^sub>s \<I>"]
abs_terms_subst_range_disj[of "rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>) \<circ>\<^sub>s \<I>" s]
unfolding \<theta>_def
by blast+
have "t \<in> SMP trms_P" "fv t = {}"
by (metis s(2) SMP.Substitution[OF SMP.MP[OF 1] wt wftrms, of X],
metis s(2) subst_subst_compose[of s "rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>)" \<I>]
interpretation_grounds[OF \<I>(1), of "s \<cdot> rm_vars (set X) (\<sigma> \<circ>\<^sub>s \<alpha>)"])
hence 4: "t \<in> GSMP trms_P" unfolding GSMP_def by simp
show "t \<in> ?B" using 3 4 by (auto simp add: trms_P_def)
qed
thus ?case
using step.IH[OF \<I>'] trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] unlabel_append[of \<A>]
image_Un[of "\<lambda>x. x \<cdot> \<I>" "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"]
by (simp add: T'_def)
qed simp
lemma \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_aux:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
"t = Fun (Val n) [] \<or> t = Var x"
and neq:
"t \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) \<noteq>
t \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>)"
shows "\<exists>y \<in> fv_transaction T - set (transaction_fresh T).
t \<cdot> \<I> = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<and> \<Gamma>\<^sub>v y = TAtom Value"
proof -
let ?\<A>' = "\<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>)"
let ?\<B> = "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T))"
let ?\<B>' = "?\<B> \<cdot>\<^sub>s\<^sub>s\<^sub>t \<sigma> \<circ>\<^sub>s \<alpha>"
let ?\<B>'' = "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>))"
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: "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 T_adm: "admissible_transaction T"
using T P(1) by blast
hence T_valid: "wellformed_transaction T"
unfolding admissible_transaction_def by blast
have T_adm_upds: "admissible_transaction_updates T"
by (metis P(1) T admissible_transaction_def)
have T_fresh_vars_value_typed: "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
using T P(1) protocol_transaction_vars_TAtom_typed(3)[of T] P(1) by simp
have wt_\<sigma>\<alpha>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using wt_subst_compose transaction_fresh_subst_wt[OF \<sigma> T_fresh_vars_value_typed]
transaction_renaming_subst_wt[OF \<alpha>]
by blast
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(1) \<A>_reach)
hence t_wf: "wf\<^sub>t\<^sub>r\<^sub>m t" using t by auto
have \<A>_no_val_bvars: "\<not>TAtom Value \<sqsubseteq> \<Gamma>\<^sub>v x"
when "x \<in> bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" for x
using P(1) reachable_constraints_no_bvars \<A>_reach
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>"] that
unfolding admissible_transaction_def by fast
have x': "x \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" when "t = Var x"
using that t by (simp add: var_subterm_trms\<^sub>s\<^sub>s\<^sub>t_is_vars\<^sub>s\<^sub>s\<^sub>t)
have "\<exists>f \<in> funs_term (t \<cdot> \<I>). is_Val f"
using abs_eq_if_no_Val neq by metis
hence "\<exists>n T. Fun (Val n) T \<sqsubseteq> t \<cdot> \<I>"
using funs_term_Fun_subterm
unfolding is_Val_def by fast
hence "TAtom Value \<sqsubseteq> \<Gamma> (Var x)" when "t = Var x"
using wt_subst_trm''[OF \<I>_wt, of "Var x"] that
subtermeq_imp_subtermtypeeq[of "t \<cdot> \<I>"] wf_trm_subst[OF \<I>_wf, of t] t_wf
by fastforce
hence x_val: "\<Gamma>\<^sub>v x = TAtom Value" when "t = Var x"
using reachable_constraints_vars_TAtom_typed[OF \<A>_reach P x'] that
by fastforce
hence x_fv: "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" when "t = Var x" using x'
using reachable_constraints_Value_vars_are_fv[OF \<A>_reach P x'] that
by blast
then obtain m where m: "t \<cdot> \<I> = Fun (Val m) []"
using constraint_model_Value_term_is_Val[
OF \<A>_reach welltyped_constraint_model_prefix[OF \<I>] P, of x]
t(2) x_val
by force
hence 0: "\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) m \<noteq> \<alpha>\<^sub>0 (db\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>@?\<B>'') \<I>) m"
using neq by (simp add: unlabel_def)
have t_val: "\<Gamma> t = TAtom Value" using x_val t by force
obtain u s where s: "t \<cdot> \<I> = u \<cdot> \<I>" "insert\<langle>u,s\<rangle> \<in> set ?\<B>' \<or> delete\<langle>u,s\<rangle> \<in> set ?\<B>'"
using to_abs_neq_imp_db_update[OF 0] m
by (metis (no_types, lifting) dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst subst_lsst_unlabel)
then obtain u' s' where s':
"u = u' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>" "s = s' \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"
"insert\<langle>u',s'\<rangle> \<in> set ?\<B> \<or> delete\<langle>u',s'\<rangle> \<in> set ?\<B>"
using stateful_strand_step_subst_inv_cases(4,5)
by blast
hence s'': "insert\<langle>u',s'\<rangle> \<in> set (unlabel (transaction_strand T)) \<or>
delete\<langle>u',s'\<rangle> \<in> set (unlabel (transaction_strand T))"
using dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_unlabel_steps_iff(4,5)[of u' s' "transaction_strand T"]
by simp_all
then obtain y where y: "y \<in> fv_transaction T" "u' = Var y"
using transaction_inserts_are_Value_vars[OF T_valid T_adm_upds, of u' s']
transaction_deletes_are_Value_vars[OF T_valid T_adm_upds, of u' s']
stateful_strand_step_fv_subset_cases(4,5)[of u' s' "unlabel (transaction_strand T)"]
by auto
hence 1: "t \<cdot> \<I> = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>" using y s(1) s'(1) by (metis subst_apply_term.simps(1))
have 2: "y \<notin> set (transaction_fresh T)" when "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<noteq> \<sigma> y"
using transaction_fresh_subst_grounds_domain[OF \<sigma>, of y] subst_compose[of \<sigma> \<alpha> y] that
by (auto simp add: subst_ground_ident)
have 3: "y \<notin> set (transaction_fresh T)" when "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
using 2 that \<sigma> unfolding transaction_fresh_subst_def by fastforce
have 4: "\<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))"
by (metis welltyped_constraint_model_prefix[OF \<I>]
constraint_model_Value_var_in_constr_prefix[OF \<A>_reach _ P])
have 5: "\<Gamma>\<^sub>v y = TAtom Value"
using 1 t_val
wt_subst_trm''[OF wt_\<sigma>\<alpha>, of "Var y"]
wt_subst_trm''[OF \<I>_wt, of t]
wt_subst_trm''[OF \<I>_wt, of "(\<sigma> \<circ>\<^sub>s \<alpha>) y"]
by (auto simp del: subst_subst_compose)
have "y \<notin> set (transaction_fresh T)"
proof (cases "t = Var x")
case True (* \<I> x occurs in \<A> but not in subst_range \<sigma>, so y cannot be fresh *)
hence *: "\<I> x = Fun (Val m) []" "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" "\<I> x = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>"
using m t(1) 1 x_fv x' by (force, blast, force)
obtain B where B: "prefix B \<A>" "\<I> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
using *(2) 4 x_val[OF True] by fastforce
hence "\<forall>t \<in> subst_range \<sigma>. t \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
using transaction_fresh_subst_range_fresh(1)[OF \<sigma>] trms\<^sub>s\<^sub>s\<^sub>t_unlabel_prefix_subset(1)[of B]
unfolding prefix_def by fast
thus ?thesis using *(1,3) B(2) 2 by (metis subst_imgI term.distinct(1))
next
case False
hence "t \<cdot> \<I> \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" using t by simp
thus ?thesis using 1 3 by argo
qed
thus ?thesis using 1 5 y(1) by fast
qed
lemma \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_Var:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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 x: "x \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
shows "\<I> x \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>) \<in>
timpl_closure_set {\<I> x \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)} (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
proof -
define a0 where "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
define a0' where "a0' \<equiv> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>)"
define a3 where "a3 \<equiv> \<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>"
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(1) \<A>_reach)
have T_adm: "admissible_transaction T" by (metis P(1) T)
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 "\<Gamma>\<^sub>v x = Var Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = Var (prot_atom.Atom a))"
using reachable_constraints_vars_TAtom_typed[OF \<A>_reach P, of x]
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 auto
hence "\<I> x \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {\<I> x \<cdot>\<^sub>\<alpha> a0} a3"
proof
assume x_val: "\<Gamma>\<^sub>v x = TAtom Value"
show "\<I> x \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {\<I> x \<cdot>\<^sub>\<alpha> a0} a3"
proof (cases "\<I> x \<cdot>\<^sub>\<alpha> a0 = \<I> x \<cdot>\<^sub>\<alpha> a0'")
case False
hence "\<exists>y \<in> fv_transaction T - set (transaction_fresh T).
\<I> x = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<and> \<Gamma>\<^sub>v y = TAtom Value"
using \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_aux[OF \<A>_reach T \<I> \<sigma> \<alpha> P fv\<^sub>s\<^sub>s\<^sub>t_is_subterm_trms\<^sub>s\<^sub>s\<^sub>t[OF x], of _ x]
unfolding a0_def a0'_def
by fastforce
then obtain y where y:
"y \<in> fv_transaction T - set (transaction_fresh T)"
"\<I> x = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>"
"\<I> x \<cdot>\<^sub>\<alpha> a0 = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0"
"\<I> x \<cdot>\<^sub>\<alpha> a0' = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0'"
"\<Gamma>\<^sub>v y = TAtom Value"
by metis
then obtain n where n: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val (n,False)) []"
using \<Gamma>\<^sub>v_TAtom''(2)[of y] x x_val
transaction_var_becomes_Val[
OF reachable_constraints.step[OF \<A>_reach T \<sigma> \<alpha>] \<I> \<sigma> \<alpha> P T, of y]
by force
have "a0 (n,False) \<noteq> a0' (n,False)"
"y \<in> fv_transaction T"
"y \<notin> set (transaction_fresh T)"
"absc (a0 (n,False)) = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0"
"absc (a0' (n,False)) = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0'"
using y n False by force+
hence 1: "(a0 (n,False), a0' (n,False)) \<in> a3"
unfolding a0_def a0'_def a3_def abs_term_implications_def
by blast
have 2: "\<I> x \<cdot>\<^sub>\<alpha> a0' \<in> set \<langle>a0 (n,False) --\<guillemotright> a0' (n,False)\<rangle>\<langle>\<I> x \<cdot>\<^sub>\<alpha> a0\<rangle>"
using y n timpl_apply_const by auto
show ?thesis
using timpl_closure.TI[OF timpl_closure.FP 1] 2
term_variants_pred_iff_in_term_variants[
of "(\<lambda>_. [])(Abs (a0 (n, False)) := [Abs (a0' (n, False))])"]
unfolding timpl_closure_set_def timpl_apply_term_def
by auto
qed (auto intro: timpl_closure_setI)
next
assume "\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a)"
then obtain a where x_atom: "\<Gamma>\<^sub>v x = TAtom (Atom a)" by moura
obtain f T where fT: "\<I> x = Fun f T"
using interpretation_grounds[OF \<I>_interp, of "Var x"]
by (cases "\<I> x") auto
have fT_atom: "\<Gamma> (Fun f T) = TAtom (Atom a)"
using wt_subst_trm''[OF \<I>_wt, of "Var x"] x_atom fT
by simp
have T: "T = []"
using fT wf_trm_subst[OF \<I>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s, of "Var x"] const_type_inv_wf[OF fT_atom]
by fastforce
have f: "\<not>is_Val f" using fT_atom unfolding is_Val_def by auto
have "\<I> x \<cdot>\<^sub>\<alpha> b = \<I> x" for b
using T fT abs_term_apply_const(2)[OF f]
by auto
thus "\<I> x \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {\<I> x \<cdot>\<^sub>\<alpha> a0} a3"
by (auto intro: timpl_closure_setI)
qed
thus ?thesis by (metis a0_def a0'_def a3_def)
qed
lemma \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_Val:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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 n: "Fun (Val n) [] \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
shows "Fun (Val n) [] \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>) \<in>
timpl_closure_set {Fun (Val n) [] \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)} (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
proof -
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>)"
define a0 where "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
define a0' where "a0' \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T') \<I>)"
define a3 where "a3 \<equiv> \<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>"
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(1) \<A>_reach)
have T_adm: "admissible_transaction T" by (metis P(1) T)
have "Fun (Abs (a0' n)) [] \<in> timpl_closure_set {Fun (Abs (a0 n)) []} a3"
proof (cases "a0 n = a0' n")
case False
then obtain x where x:
"x \<in> fv_transaction T - set (transaction_fresh T)" "Fun (Val n) [] = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I>"
using \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_aux[OF \<A>_reach T \<I> \<sigma> \<alpha> P n]
by (fastforce simp add: a0_def a0'_def T'_def)
hence "absc (a0 n) = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0" "absc (a0' n) = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0'" by simp_all
hence 1: "(a0 n, a0' n) \<in> a3"
using False x(1)
unfolding a0_def a0'_def a3_def abs_term_implications_def T'_def
by blast
show ?thesis
using timpl_apply_Abs[of "[]" "[]" "a0 n" "a0' n"]
timpl_closure.TI[OF timpl_closure.FP[of "Fun (Abs (a0 n)) []" a3] 1]
term_variants_pred_iff_in_term_variants[of "(\<lambda>_. [])(Abs (a0 n) := [Abs (a0' n)])"]
unfolding timpl_closure_set_def timpl_apply_term_def
by force
qed (auto intro: timpl_closure_setI)
thus ?thesis by (simp add: a0_def a0'_def a3_def T'_def)
qed
lemma \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_ik:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
shows "t \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>) \<in>
timpl_closure_set {t \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)} (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
proof -
define a0 where "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
define a0' where "a0' \<equiv> \<alpha>\<^sub>0 (db\<^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 \<sigma> \<circ>\<^sub>s \<alpha>)) \<I>)"
define a3 where "a3 \<equiv> \<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>"
let ?U = "\<lambda>T a. map (\<lambda>s. s \<cdot> \<I> \<cdot>\<^sub>\<alpha> a) T"
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(1) \<A>_reach)
have T_adm: "admissible_transaction T" by (metis P(1) T)
have "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" "wf\<^sub>t\<^sub>r\<^sub>m t" using \<A>_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s t ik\<^sub>s\<^sub>s\<^sub>t_trms\<^sub>s\<^sub>s\<^sub>t_subset by force+
hence "\<forall>t0 \<in> subterms t. t0 \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {t0 \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0} a3"
proof (induction t)
case (Var x) thus ?case
using \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_Var[OF \<A>_reach T \<I> \<sigma> \<alpha> P, of x]
ik\<^sub>s\<^sub>s\<^sub>t_var_is_fv[of x "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 (simp add: a0_def a0'_def a3_def)
next
case (Fun f S)
have IH: "\<forall>t0 \<in> subterms t. t0 \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {t0 \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0} a3"
when "t \<in> set S" for t
using that Fun.prems(1) wf_trm_param[OF Fun.prems(2)] Fun.IH
by (meson in_subterms_subset_Union params_subterms subsetCE)
hence "t \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {t \<cdot>\<^sub>\<alpha> a0} a3"
when "t \<in> set (map (\<lambda>s. s \<cdot> \<I>) S)" for t
using that by auto
hence "t \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure (t \<cdot>\<^sub>\<alpha> a0) a3"
when "t \<in> set (map (\<lambda>s. s \<cdot> \<I>) S)" for t
using that timpl_closureton_is_timpl_closure by auto
hence "(t \<cdot>\<^sub>\<alpha> a0, t \<cdot>\<^sub>\<alpha> a0') \<in> timpl_closure' a3"
when "t \<in> set (map (\<lambda>s. s \<cdot> \<I>) S)" for t
using that timpl_closure_is_timpl_closure' by auto
hence IH': "((?U S a0) ! i, (?U S a0') ! i) \<in> timpl_closure' a3"
when "i < length (map (\<lambda>s. s \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0) S)" for i
using that by auto
show ?case
proof (cases "\<exists>n. f = Val n")
case True
then obtain n where "Fun f S = Fun (Val n) []"
using Fun.prems(2) unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by force
moreover have "Fun f S \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
using ik\<^sub>s\<^sub>s\<^sub>t_trms\<^sub>s\<^sub>s\<^sub>t_subset Fun.prems(1) by blast
ultimately show ?thesis
using \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_Val[OF \<A>_reach T \<I> \<sigma> \<alpha> P]
by (simp add: a0_def a0'_def a3_def)
next
case False
hence "Fun f S \<cdot> \<I> \<cdot>\<^sub>\<alpha> a = Fun f (map (\<lambda>t. t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a) S)" for a by (cases f) simp_all
hence "(Fun f S \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0, Fun f S \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0') \<in> timpl_closure' a3"
using timpl_closure_FunI[OF IH']
by simp
hence "Fun f S \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {Fun f S \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0} a3"
using timpl_closureton_is_timpl_closure
timpl_closure_is_timpl_closure'
by metis
thus ?thesis using IH by simp
qed
qed
thus ?thesis by (simp add: a0_def a0'_def a3_def)
qed
lemma transaction_prop1:
assumes "\<delta> \<in> abs_substs_fun ` set (transaction_check_comp FP OCC TI T)"
and "x \<in> fv_transaction T"
and "x \<notin> set (transaction_fresh T)"
and "\<delta> x \<noteq> absdbupd (unlabel (transaction_updates T)) x (\<delta> x)"
and "transaction_check FP OCC TI T"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
shows "(\<delta> x, absdbupd (unlabel (transaction_updates T)) x (\<delta> x)) \<in> (set TI)\<^sup>+"
proof -
let ?upd = "\<lambda>x. absdbupd (unlabel (transaction_updates T)) x (\<delta> x)"
have 0: "fv_transaction T = set (fv_list\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T)))"
by (metis fv_list\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t[of "unlabel (transaction_strand T)"])
have 1: "transaction_check_post FP TI T \<delta>"
using assms(1,5)
unfolding transaction_check_def list_all_iff
by blast
have "(\<delta> x, ?upd x) \<in> set TI \<longleftrightarrow> (\<delta> x, ?upd x) \<in> (set TI)\<^sup>+"
using TI using assms(4) by blast
thus ?thesis
using assms(2,3,4) 0 1 in_trancl_closure_iff_in_trancl_fun[of _ _ TI]
unfolding transaction_check_post_def List.member_def
by (metis (no_types, lifting) DiffI)
qed
lemma transaction_prop2:
assumes \<delta>: "\<delta> \<in> abs_substs_fun ` set (transaction_check_comp FP OCC TI T)"
and x: "x \<in> fv_transaction T" "fst x = TAtom Value"
and T_check: "transaction_check FP OCC TI T"
and T_adm: "admissible_transaction T"
and FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
shows "x \<notin> set (transaction_fresh T) \<Longrightarrow> \<delta> x \<in> set OCC" (is "?A' \<Longrightarrow> ?A")
and "absdbupd (unlabel (transaction_updates T)) x (\<delta> x) \<in> set OCC" (is ?B)
proof -
let ?xs = "fv_list\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T))"
let ?ys = "filter (\<lambda>x. x \<notin> set (transaction_fresh T) \<and> fst x = TAtom Value) ?xs"
let ?C = "unlabel (transaction_selects T@transaction_checks T)"
let ?poss = "transaction_poschecks_comp ?C"
let ?negs = "transaction_negchecks_comp ?C"
let ?\<delta>upd = "\<lambda>y. absdbupd (unlabel (transaction_updates T)) y (\<delta> y)"
have T_wf: "wellformed_transaction T"
and T_occ: "admissible_transaction_occurs_checks T"
using T_adm by (metis admissible_transaction_def)+
have 0: "{x \<in> fv_transaction T - set (transaction_fresh T). fst x = TAtom Value} = set ?ys"
using fv_list\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t[of "unlabel (transaction_strand T)"]
by force
have 1: "transaction_check_pre FP TI T \<delta>"
using \<delta> unfolding transaction_check_comp_def Let_def by fastforce
have 2: "transaction_check_post FP TI T \<delta>"
using \<delta> T_check unfolding transaction_check_def list_all_iff by blast
have 3: "\<delta> \<in> abs_substs_fun ` set (abs_substs_set ?ys OCC ?poss ?negs)"
using \<delta> unfolding transaction_check_comp_def Let_def by force
show A: ?A when ?A' using that 0 3 x abs_substs_abss_bounded by blast
have 4: "x \<in> 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)"
when x': "x \<in> set (transaction_fresh T)"
using T_wf x' unfolding wellformed_transaction_def by fast
have "intruder_synth_mod_timpls FP TI (occurs (absc (?\<delta>upd x)))"
when x': "x \<in> set (transaction_fresh T)"
using 2 x' x T_occ
unfolding transaction_check_post_def admissible_transaction_occurs_checks_def
by fastforce
hence "timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c occurs (absc (?\<delta>upd x))"
when x': "x \<in> set (transaction_fresh T)"
using x' intruder_synth_mod_timpls_is_synth_timpl_closure_set[
OF TI, of FP "occurs (absc (?\<delta>upd x))"]
by argo
hence "Abs (?\<delta>upd x) \<in> \<Union>(funs_term ` timpl_closure_set (set FP) (set TI))"
when x': "x \<in> set (transaction_fresh T)"
using x' ideduct_synth_priv_fun_in_ik[
of "timpl_closure_set (set FP) (set TI)" "occurs (absc (?\<delta>upd x))"]
by simp
hence "\<exists>t \<in> timpl_closure_set (set FP) (set TI). Abs (?\<delta>upd x) \<in> funs_term t"
when x': "x \<in> set (transaction_fresh T)"
using x' by force
hence 5: "?\<delta>upd x \<in> set OCC" when x': "x \<in> set (transaction_fresh T)"
using x' OCC by fastforce
have 6: "?\<delta>upd x \<in> set OCC" when x': "x \<notin> set (transaction_fresh T)"
proof (cases "\<delta> x = ?\<delta>upd x")
case False
hence "(\<delta> x, ?\<delta>upd x) \<in> (set TI)\<^sup>+" "\<delta> x \<in> set OCC"
using A 2 x' x TI
unfolding transaction_check_post_def fv_list\<^sub>s\<^sub>s\<^sub>t_is_fv\<^sub>s\<^sub>s\<^sub>t Let_def
in_trancl_closure_iff_in_trancl_fun[symmetric]
List.member_def
by blast+
thus ?thesis using timpl_closure_set_absc_subset_in[OF OCC(2)] by blast
qed (simp add: A x' x(1))
show ?B by (metis 5 6)
qed
lemma transaction_prop3:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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 FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
shows "\<forall>x \<in> set (transaction_fresh T). (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc {}" (is ?A)
and "\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T).
intruder_synth_mod_timpls FP TI (t \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>) \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>))" (is ?B)
and "\<forall>x \<in> fv_transaction T - set (transaction_fresh T).
\<forall>s. select\<langle>Var x,Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_selects T))
\<longrightarrow> (\<exists>ss. (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc ss \<and> s \<in> ss)" (is ?C)
and "\<forall>x \<in> fv_transaction T - set (transaction_fresh T).
\<forall>s. \<langle>Var x in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T))
\<longrightarrow> (\<exists>ss. (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc ss \<and> s \<in> ss)" (is ?D)
and "\<forall>x \<in> fv_transaction T - set (transaction_fresh T).
\<forall>s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T))
\<longrightarrow> (\<exists>ss. (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc ss \<and> s \<notin> ss)" (is ?E)
and "\<forall>x \<in> fv_transaction T - set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value \<longrightarrow>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) \<in> absc ` set OCC" (is ?F)
proof -
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>)"
define a0 where "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
define a0' where "a0' \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@?T') \<I>)"
define fv_AT' where "fv_AT' \<equiv> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@?T')"
have T_adm: "admissible_transaction T"
using T P(1) by blast
hence T_valid: "wellformed_transaction T"
unfolding admissible_transaction_def by blast
have T_adm':
"admissible_transaction_selects T"
"admissible_transaction_checks T"
"admissible_transaction_updates T"
using T_adm unfolding admissible_transaction_def by simp_all
have \<I>': "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)"
"\<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
"\<forall>n. Abs n \<notin> \<Union>(funs_term ` (\<I> ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))"
"\<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` (\<I> ` fv_AT'))"
"\<forall>n. Abs n \<notin> \<Union>(funs_term ` (\<I> ` fv_AT'))"
using \<I> admissible_transaction_occurs_checks_prop'[
OF \<A>_reach welltyped_constraint_model_prefix[OF \<I>] P]
admissible_transaction_occurs_checks_prop'[
OF reachable_constraints.step[OF \<A>_reach T \<sigma> \<alpha>] \<I> P]
unfolding welltyped_constraint_model_def constraint_model_def is_Val_def is_Abs_def fv_AT'_def
by fastforce+
have \<P>': "\<forall>T \<in> set P. \<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` trms_transaction T)"
"\<forall>T \<in> set P. \<forall>n. Abs n \<notin> \<Union>(funs_term ` trms_transaction T)"
"\<forall>T \<in> set P. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
and "\<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 protocol_transaction_vars_TAtom_typed
protocol_transactions_no_pubconsts
protocol_transactions_no_abss
funs_term_Fun_subterm P
by fast+
hence T_no_pubconsts: "\<forall>n. Val (n,True) \<notin> \<Union>(funs_term ` trms_transaction T)"
and T_no_abss: "\<forall>n. Abs n \<notin> \<Union>(funs_term ` trms_transaction T)"
and T_fresh_vars_value_typed: "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
and T_fv_const_typed: "\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
using T by simp_all
have wt_\<sigma>\<alpha>\<I>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>)"
using \<I>'(2) wt_subst_compose transaction_fresh_subst_wt[OF \<sigma> T_fresh_vars_value_typed]
transaction_renaming_subst_wt[OF \<alpha>]
by blast
have 1: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = \<sigma> y" when "y \<in> set (transaction_fresh T)" for y
using transaction_fresh_subst_grounds_domain[OF \<sigma> that] subst_compose[of \<sigma> \<alpha> y]
by (simp add: subst_ground_ident)
have 2: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" when "y \<in> set (transaction_fresh T)" for y
using 1[OF that] that \<sigma> unfolding transaction_fresh_subst_def by auto
have 3: "\<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))"
by (metis welltyped_constraint_model_prefix[OF \<I>]
constraint_model_Value_var_in_constr_prefix[OF \<A>_reach _ P])
have 4: "\<exists>n. (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val n) []"
when "y \<in> fv_transaction T" "\<Gamma>\<^sub>v y = TAtom Value" for y
using transaction_var_becomes_Val[OF reachable_constraints.step[OF \<A>_reach T \<sigma> \<alpha>] \<I> \<sigma> \<alpha> P T]
that T_fv_const_typed \<Gamma>\<^sub>v_TAtom''[of y]
by metis
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 \<I> 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: welltyped_constraint_model_def constraint_model_def db\<^sub>s\<^sub>s\<^sub>t_def)
have T_rcv_no_val_bvars: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T) \<inter> subst_domain (\<sigma> \<circ>\<^sub>s \<alpha>) = {}"
using transaction_no_bvars[OF T_adm] bvars_transaction_unfold[of T] by blast
show ?A
proof
fix y assume y: "y \<in> set (transaction_fresh T)"
then obtain yn where yn: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val yn) []" "Fun (Val yn) [] \<in> subst_range \<sigma>"
by (metis transaction_fresh_subst_sends_to_val'[OF \<sigma>])
{ \<comment> \<open>since \<open>y\<close> is fresh \<open>(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>\<close> cannot be part of the database state of \<open>\<I> \<A>\<close>\<close>
fix t' s assume t': "insert\<langle>t',s\<rangle> \<in> set (unlabel \<A>)" "t' \<cdot> \<I> = Fun (Val yn) []"
then obtain z where t'_z: "t' = Var z" using 2[OF y] yn(1) by (cases t') auto
hence z: "z \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" "\<I> z = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>" using t' yn(1) by force+
hence z': "\<Gamma>\<^sub>v z = TAtom Value"
by (metis \<Gamma>.simps(1) \<Gamma>_consts_simps(2) t'(2) t'_z wt_subst_trm'' \<I>'(2))
obtain B where B: "prefix B \<A>" "\<I> z \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)" using z z' 3 by fastforce
hence "\<forall>t \<in> subst_range \<sigma>. t \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
using transaction_fresh_subst_range_fresh(1)[OF \<sigma>] trms\<^sub>s\<^sub>s\<^sub>t_unlabel_prefix_subset(1)[of B]
unfolding prefix_def by fast
hence False using B(2) 1[OF y] z yn(1) by (metis subst_imgI term.distinct(1))
} hence "\<nexists>s. ((\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>, s) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using db\<^sub>s\<^sub>s\<^sub>t_in_cases[of "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>" _ "unlabel \<A>" \<I> "[]"] yn(1)
by (force simp add: db\<^sub>s\<^sub>s\<^sub>t_def)
thus "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc {}"
using to_abs_empty_iff_notin_db[of yn "db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I> []"] yn(1)
by (simp add: db\<^sub>s\<^sub>s\<^sub>t_def)
qed
show receives_covered: ?B
proof
fix t assume t: "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T)"
hence t_in_T: "t \<in> trms_transaction T"
using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_prefix_subset(1)[of "transaction_receive T"]
unfolding transaction_strand_def by fast
have t_rcv: "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>"]
wellformed_transaction_unlabel_cases(1)[OF T_valid] trms\<^sub>s\<^sub>s\<^sub>t_in[OF t]
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 \<I>_is_T_model]
by simp
have t_fv: "fv (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>) \<subseteq> fv_AT'"
using fv\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] unlabel_append[of \<A>]
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>"]
t_rcv fv_transaction_subst_unfold[of T " \<sigma> \<circ>\<^sub>s \<alpha>"]
unfolding fv_AT'_def by force
have **: "\<forall>t \<in> (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
using FP(3) by (auto simp add: a0_def abs_intruder_knowledge_def)
note lms1 = pubval_terms_subst[OF _ pubval_terms_subst_range_disj[
OF transaction_fresh_subst_has_no_pubconsts_abss(1)[OF \<sigma>], of t]]
pubval_terms_subst[OF _ pubval_terms_subst_range_disj[
OF transaction_renaming_subst_has_no_pubconsts_abss(1)[OF \<alpha>], of "t \<cdot> \<sigma>"]]
note lms2 = abs_terms_subst[OF _ abs_terms_subst_range_disj[
OF transaction_fresh_subst_has_no_pubconsts_abss(2)[OF \<sigma>], of t]]
abs_terms_subst[OF _ abs_terms_subst_range_disj[
OF transaction_renaming_subst_has_no_pubconsts_abss(2)[OF \<alpha>], of "t \<cdot> \<sigma>"]]
have "t \<in> (\<Union>T\<in>set P. trms_transaction T)" "fv (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I>) = {}"
using t_in_T T interpretation_grounds[OF \<I>'(1)] by fast+
moreover have "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>))"
using wf_trm_subst_rangeI[of \<sigma>, OF transaction_fresh_subst_is_wf_trm[OF \<sigma>]]
wf_trm_subst_rangeI[of \<alpha>, OF transaction_renaming_subst_is_wf_trm[OF \<alpha>]]
wf_trms_subst_compose[of \<sigma> \<alpha>, THEN wf_trms_subst_compose[OF _ \<I>'(3)]]
by blast
moreover
have "t \<notin> pubval_terms"
using t_in_T T_no_pubconsts funs_term_Fun_subterm
unfolding is_Val_def by fastforce
hence "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<notin> pubval_terms"
using lms1
by auto
hence "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<notin> pubval_terms"
using \<I>'(6) t_fv pubval_terms_subst'[of "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>" \<I>]
by auto
moreover have "t \<notin> abs_terms"
using t_in_T T_no_abss funs_term_Fun_subterm
unfolding is_Abs_def by force
hence "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<notin> abs_terms"
using lms2
by auto
hence "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<notin> abs_terms"
using \<I>'(7) t_fv abs_terms_subst'[of "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>" \<I>]
by auto
ultimately have ***:
"t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<in> GSMP (\<Union>T\<in>set P. trms_transaction T) - (pubval_terms \<union> abs_terms)"
using SMP.Substitution[OF SMP.MP[of t "\<Union>T\<in>set P. trms_transaction T"], of "\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>"]
subst_subst_compose[of t "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>] wt_\<sigma>\<alpha>\<I>
unfolding GSMP_def by fastforce
have "\<forall>T\<in>set P. bvars_transaction T = {}"
using transaction_no_bvars P unfolding list_all_iff by blast
hence ****:
"ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<subseteq> GSMP (\<Union>T\<in>set P. trms_transaction T) - (pubval_terms \<union> abs_terms)"
using reachable_constraints_no_pubconsts_abss[OF \<A>_reach \<P>' _ \<I>'(1,2,3,4,5)]
ik\<^sub>s\<^sub>s\<^sub>t_trms\<^sub>s\<^sub>s\<^sub>t_subset[of "unlabel \<A>"]
by blast
show "intruder_synth_mod_timpls FP TI (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>))"
using deduct_FP_if_deduct[OF **** ** * ***] deducts_eq_if_analyzed[OF FP(1)]
intruder_synth_mod_timpls_is_synth_timpl_closure_set[OF TI, of FP]
unfolding a0_def by force
qed
show ?C
proof (intro ballI allI impI)
fix y s
assume y: "y \<in> fv_transaction T - set (transaction_fresh T)"
and s: "select\<langle>Var y, Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_selects T))"
hence "select\<langle>Var y, Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_strand T))"
unfolding transaction_strand_def unlabel_def by auto
hence y_val: "\<Gamma>\<^sub>v y = TAtom Value"
using transaction_selects_are_Value_vars[OF T_valid T_adm'(1)]
by fastforce
have "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[OF s]
by fastforce
hence "((\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>, Fun (Set s) []) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using wellformed_transaction_sem_selects[
OF T_valid \<I>_is_T_model,
of "(\<sigma> \<circ>\<^sub>s \<alpha>) y" "Fun (Set s) []"]
by simp
thus "\<exists>ss. (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc ss \<and> s \<in> ss"
using to_abs_alt_def[of "db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>"] 4[of y] y y_val by auto
qed
show ?D
proof (intro ballI allI impI)
fix y s
assume y: "y \<in> fv_transaction T - set (transaction_fresh T)"
and s: "\<langle>Var y in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T))"
hence "\<langle>Var y in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_strand T))"
unfolding transaction_strand_def unlabel_def by auto
hence y_val: "\<Gamma>\<^sub>v y = TAtom Value"
using transaction_inset_checks_are_Value_vars[OF T_valid T_adm'(2)]
by fastforce
have "\<langle>(\<sigma> \<circ>\<^sub>s \<alpha>) y in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)))"
using subst_lsst_unlabel_member[OF s]
by fastforce
hence "((\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>, Fun (Set s) []) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using wellformed_transaction_sem_pos_checks[
OF T_valid \<I>_is_T_model,
of "(\<sigma> \<circ>\<^sub>s \<alpha>) y" "Fun (Set s) []"]
by simp
thus "\<exists>ss. (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc ss \<and> s \<in> ss"
using to_abs_alt_def[of "db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>"] 4[of y] y y_val by auto
qed
show ?E
proof (intro ballI allI impI)
fix y s
assume y: "y \<in> fv_transaction T - set (transaction_fresh T)"
and s: "\<langle>Var y not in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T))"
hence "\<langle>Var y not in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_strand T))"
unfolding transaction_strand_def unlabel_def by auto
hence y_val: "\<Gamma>\<^sub>v y = TAtom Value"
using transaction_notinset_checks_are_Value_vars[OF T_valid T_adm'(2)]
by fastforce
have "\<langle>(\<sigma> \<circ>\<^sub>s \<alpha>) y not in Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_checks T \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)))"
using subst_lsst_unlabel_member[OF s]
by fastforce
hence "((\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>, Fun (Set s) []) \<notin> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using wellformed_transaction_sem_neg_checks(2)[
OF T_valid \<I>_is_T_model,
of "[]" "(\<sigma> \<circ>\<^sub>s \<alpha>) y" "Fun (Set s) []"]
by simp
moreover have "list_all admissible_transaction_updates P"
using Ball_set[of P "admissible_transaction"] P(1)
Ball_set[of P admissible_transaction_updates]
unfolding admissible_transaction_def
by fast
moreover have "list_all wellformed_transaction P"
using P(1) Ball_set[of P "admissible_transaction"] Ball_set[of P wellformed_transaction]
unfolding admissible_transaction_def
by blast
ultimately have "((\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>, Fun (Set s) S) \<notin> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)" for S
using reachable_constraints_db\<^sub>l\<^sub>s\<^sub>s\<^sub>t_set_args_empty[OF \<A>_reach]
unfolding admissible_transaction_updates_def
by auto
thus "\<exists>ss. (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = absc ss \<and> s \<notin> ss"
using to_abs_alt_def[of "db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>"] 4[of y] y y_val by auto
qed
show ?F
proof (intro ballI impI)
fix y assume y: "y \<in> fv_transaction T - set (transaction_fresh T)" "\<Gamma>\<^sub>v y = TAtom Value"
then obtain yn where yn: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val yn) []" using 4 by moura
hence y_abs: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) = Fun (Abs (\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) yn)) []" by simp
have *: "\<forall>r \<in> set (unlabel (transaction_selects T)). \<exists>x s. r = select\<langle>Var x, Fun (Set s) []\<rangle>"
using admissible_transaction_strand_step_cases(2)[OF T_adm] by fast
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 by blast
thus "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) \<in> absc ` set OCC"
proof
assume "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 wellformed_transaction_unlabel_cases(1)[OF T_valid]
by (force simp add: unlabel_def)
have **: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<in> subterms (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>)"
"timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using fv_subterms_substI[OF t(2), of "\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>"] subst_compose[of "\<sigma> \<circ>\<^sub>s \<alpha>" \<I> y]
subterms_subst_subset[of "\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>" t] receives_covered t(1)
unfolding intruder_synth_mod_timpls_is_synth_timpl_closure_set[OF TI, symmetric]
by auto
have "Abs (\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) yn) \<in> \<Union>(funs_term ` (timpl_closure_set (set FP) (set TI)))"
using y_abs abs_subterms_in[OF **(1), of "\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"]
ideduct_synth_priv_fun_in_ik[
OF **(2) funs_term_Fun_subterm'[of "Abs (\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) yn)" "[]"]]
by force
hence "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) \<in> subterms\<^sub>s\<^sub>e\<^sub>t (timpl_closure_set (set FP) (set TI))"
using y_abs wf_trms_subterms[OF timpl_closure_set_wf_trms[OF FP(2), of "set TI"]]
funs_term_Fun_subterm[of "Abs (\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>) yn)"]
unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by fastforce
hence "funs_term ((\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>))
\<subseteq> (\<Union>t \<in> timpl_closure_set (set FP) (set TI). funs_term t)"
using funs_term_subterms_eq(2)[of "timpl_closure_set (set FP) (set TI)"] by blast
thus ?thesis using y_abs OCC(1) by fastforce
next
assume "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
then obtain l s where "(l,select\<langle>Var y, Fun (Set s) []\<rangle>) \<in> set (transaction_selects T)"
using * by (auto simp add: unlabel_def)
then obtain U where U:
"prefix (U@[(l,select\<langle>Var y, Fun (Set s) []\<rangle>)]) (transaction_selects T)"
using in_set_conv_decomp[of "(l, select\<langle>Var y,Fun (Set s) []\<rangle>)" "transaction_selects T"]
by (auto simp add: prefix_def)
hence "select\<langle>Var y, Fun (Set s) []\<rangle> \<in> set (unlabel (transaction_selects T))"
by (force simp add: prefix_def unlabel_def)
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 "(Fun (Val yn) [], Fun (Set s) []) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using yn wellformed_transaction_sem_selects[
OF T_valid \<I>_is_T_model, of "(\<sigma> \<circ>\<^sub>s \<alpha>) y" "Fun (Set s) []"]
by fastforce
hence "Fun (Val yn) [] \<in> 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>"
using db\<^sub>s\<^sub>s\<^sub>t_in_cases[of "Fun (Val yn) []"]
by (fastforce simp add: db\<^sub>s\<^sub>s\<^sub>t_def)
thus ?thesis
using OCC(3) yn abs_in[of "Fun (Val yn) []" _ "\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"]
unfolding abs_value_constants_def
by (metis (mono_tags, lifting) mem_Collect_eq subsetCE)
qed
qed
qed
lemma transaction_prop4:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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 x: "x \<in> set (transaction_fresh T)"
and y: "y \<in> fv_transaction T - set (transaction_fresh T)" "\<Gamma>\<^sub>v y = TAtom Value"
shows "(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<notin> 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>))" (is ?A)
and "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<in> 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>))" (is ?B)
proof -
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>)"
from \<I> have \<I>': "welltyped_constraint_model \<I> \<A>"
using welltyped_constraint_model_prefix by auto
have T_P_addm: "admissible_transaction T'" when T': "T' \<in> set P " for T'
by (meson T' P)
have T_adm: "admissible_transaction T"
by (metis (full_types) P T)
from T_adm have T_valid: "wellformed_transaction T"
unfolding admissible_transaction_def by blast
have be: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> = {}"
using T_P_addm \<A>_reach reachable_constraints_no_bvars transaction_no_bvars(2) by blast
have T_no_bvars: "fv_transaction T = vars_transaction T"
using transaction_no_bvars[OF T_adm] by simp
have \<I>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" by (metis \<I> welltyped_constraint_model_def)
obtain xn where xn: "\<sigma> x = Fun (Val xn) []"
using \<sigma> x unfolding transaction_fresh_subst_def by force
then have xnxn: "(\<sigma> \<circ>\<^sub>s \<alpha>) x = Fun (Val xn) []"
unfolding subst_compose_def by auto
from xn xnxn have a0: "(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> = Fun (Val xn) []"
by auto
have b0: "\<Gamma>\<^sub>v x = TAtom Value"
using P x T protocol_transaction_vars_TAtom_typed(3)
by metis
note 0 = a0 b0
have xT: "x \<in> fv_transaction T"
using x transaction_fresh_vars_subset[OF T_valid]
by fast
have \<sigma>_x_nin_A: "\<sigma> x \<notin> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
proof -
have "\<sigma> x \<in> subst_range \<sigma>"
by (metis \<sigma> transaction_fresh_subst_sends_to_val x)
moreover
have "(\<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>))"
using \<sigma> transaction_fresh_subst_def[of \<sigma> T \<A>] by auto
ultimately
show ?thesis
by auto
qed
have *: "y \<notin> set (transaction_fresh T)"
using assms by auto
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 * y wellformed_transaction_fv_in_receives_or_selects[OF T_valid]
by blast
have y_fv: "y \<in> fv_transaction T" using y fv_transaction_unfold by blast
have y_val: "fst y = TAtom Value" using y(2) \<Gamma>\<^sub>v_TAtom''(2) by blast
have "list_all (\<lambda>x. fst x = Var Value) (transaction_fresh T)"
using x T_adm unfolding admissible_transaction_def by fast
hence x_val: "fst x = TAtom Value" using x unfolding list_all_iff by blast
have "\<sigma> x \<cdot> \<I> \<notin> 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>))"
proof (rule ccontr)
assume "\<not>\<sigma> x \<cdot> \<I> \<notin> 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>))"
then have a: "\<sigma> x \<cdot> \<I> \<in> 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>))"
by auto
then have \<sigma>_x_I_in_A: "\<sigma> x \<cdot> \<I> \<in> 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>"
using reachable_constraints_subterms_subst[OF \<A>_reach \<I>' P] by blast
have "\<exists>u. u \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<and> \<I> u = \<sigma> x"
proof -
from \<sigma>_x_I_in_A have "\<exists>tu. tu \<in> \<Union> (subterms ` (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)) \<and> tu \<cdot> \<I> = \<sigma> x \<cdot> \<I>"
by force
then obtain tu where tu: "tu \<in> \<Union> (subterms ` (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)) \<and> tu \<cdot> \<I> = \<sigma> x \<cdot> \<I>"
by auto
then have "tu \<noteq> \<sigma> x"
using \<sigma>_x_nin_A by auto
moreover
have "tu \<cdot> \<I> = \<sigma> x"
using tu by (simp add: xn)
ultimately
have "\<exists>u. tu = Var u"
unfolding xn by (cases tu) auto
then obtain u where "tu = Var u"
by auto
have "u \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<and> \<I> u = \<sigma> x"
proof -
have "u \<in> vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
using \<open>tu = Var u\<close> tu var_subterm_trms\<^sub>s\<^sub>s\<^sub>t_is_vars\<^sub>s\<^sub>s\<^sub>t by fastforce
then have "u \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"
using be 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
moreover
have "\<I> u = \<sigma> x"
using \<open>tu = Var u\<close> \<open>tu \<cdot> \<I> = \<sigma> x\<close> by auto
ultimately
show ?thesis
by auto
qed
then show "\<exists>u. u \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<and> \<I> u = \<sigma> x"
by metis
qed
then obtain u where u:
"u \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" "\<I> u = \<sigma> x"
by auto
then have u_TA: "\<Gamma>\<^sub>v u = TAtom Value"
using P(1) T x_val \<Gamma>\<^sub>v_TAtom''(2)[of x]
wt_subst_trm''[OF \<I>_wt, of "Var u"] wt_subst_trm''[of \<sigma> "Var x"]
transaction_fresh_subst_wt[OF \<sigma>] protocol_transaction_vars_TAtom_typed(3)
by force
have "\<exists>B. prefix B \<A> \<and> u \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<and> \<I> u \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
using u u_TA
by (metis welltyped_constraint_model_prefix[OF \<I>]
constraint_model_Value_var_in_constr_prefix[OF \<A>_reach _ P])
then obtain B where "prefix B \<A> \<and> u \<notin> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t B \<and> \<I> u \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t B)"
by blast
moreover have "\<Union>(subterms ` trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t xs) \<subseteq> \<Union>(subterms ` trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ys)"
when "prefix xs ys"
for xs ys::"('fun,'atom,'sets,'lbl) prot_strand"
using that subterms\<^sub>s\<^sub>e\<^sub>t_mono trms\<^sub>s\<^sub>s\<^sub>t_mono unlabel_mono set_mono_prefix by metis
ultimately have "\<I> u \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
by blast
then have "\<sigma> x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
using u by auto
then show "False"
using \<sigma>_x_nin_A by auto
qed
then show ?A
unfolding subst_compose_def xn by auto
from ** show ?B
proof
define T' where "T' \<equiv> transaction_receive T"
define \<theta> where "\<theta> \<equiv> \<sigma> \<circ>\<^sub>s \<alpha>"
assume y: "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T)"
hence "Var y \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')" by (metis T'_def fv\<^sub>s\<^sub>s\<^sub>t_is_subterm_trms\<^sub>s\<^sub>s\<^sub>t)
then obtain z where z: "z \<in> set (unlabel T')" "Var y \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p z)"
by (induct T') auto
have "is_Receive z"
using T_adm Ball_set[of "unlabel T'" is_Receive] z(1)
unfolding admissible_transaction_def wellformed_transaction_def T'_def
by blast
then obtain ty where "z = receive\<langle>ty\<rangle>" by (cases z) auto
hence ty: "receive\<langle>ty \<cdot> \<theta>\<rangle> \<in> set (unlabel (T' \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))" "\<theta> y \<in> subterms (ty \<cdot> \<theta>)"
using z subst_mono unfolding subst_apply_labeled_stateful_strand_def unlabel_def by force+
hence y_deduct: "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<turnstile> ty \<cdot> \<theta> \<cdot> \<I>"
using transaction_receive_deduct[OF T_adm _ \<sigma> \<alpha>]
by (metis \<I> T'_def \<theta>_def welltyped_constraint_model_def)
obtain zn where zn: "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val (zn, False)) []"
using transaction_var_becomes_Val[
OF reachable_constraints.step[OF \<A>_reach T \<sigma> \<alpha>] \<I> \<sigma> \<alpha> P T, of y]
transaction_fresh_subst_transaction_renaming_subst_range(2)[OF \<sigma> \<alpha> *]
y_fv y_val
by (metis subst_apply_term.simps(1))
have "(\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> \<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 y_deduct, of "Val (zn, False)"]
by (metis \<theta>_def ty(2) zn subst_mono public.simps(3) snd_eqD)
thus ?B
using ik\<^sub>s\<^sub>s\<^sub>t_subst[of "unlabel \<A>" \<I>] unlabel_subst[of \<A> \<I>]
subterms\<^sub>s\<^sub>e\<^sub>t_mono[OF ik\<^sub>s\<^sub>s\<^sub>t_trms\<^sub>s\<^sub>s\<^sub>t_subset[of "unlabel (\<A> \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<I>)"]]
by fastforce
next
assume y': "y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_selects T)"
then obtain s where s: "select\<langle>Var y,s\<rangle> \<in> set (unlabel (transaction_selects T))"
"fst y = TAtom Value"
using admissible_transaction_strand_step_cases(1,2)[OF T_adm] by fastforce
obtain z zn where zn: "(\<sigma> \<circ>\<^sub>s \<alpha>) y = Var z" "\<I> z = Fun (Val zn) []"
using transaction_var_becomes_Val[
OF reachable_constraints.step[OF \<A>_reach T \<sigma> \<alpha>] \<I> \<sigma> \<alpha> P T]
transaction_fresh_subst_transaction_renaming_subst_range(2)[OF \<sigma> \<alpha> *]
y_fv T_no_bvars(1) s(2)
by (metis subst_apply_term.simps(1))
have transaction_selects_db_here:
"\<And>n s. 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>)"
using transaction_selects_db[OF T_adm _ \<sigma> \<alpha>] \<I>
unfolding welltyped_constraint_model_def by auto
have "\<exists>n. y = (Var Value, n)"
using T \<Gamma>\<^sub>v_TAtom_inv(2) y_fv y(2)
by blast
moreover
have "admissible_transaction_selects T"
using T_adm admissible_transaction_def
by blast
then have "is_Fun_Set (the_set_term (select\<langle>Var y,s\<rangle>))"
using s unfolding admissible_transaction_selects_def
by auto
then have "\<exists>ss. s = Fun (Set ss) []"
using is_Fun_Set_exi
by auto
ultimately
obtain n ss where nss: "y = (TAtom Value, n)" "s = Fun (Set ss) []"
by auto
then have "select\<langle>Var (TAtom Value, n), Fun (Set ss) []\<rangle> \<in> set (unlabel (transaction_selects T))"
using s by auto
then have in_db: "(\<alpha> (TAtom Value, n) \<cdot> \<I>, Fun (Set ss) []) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using transaction_selects_db_here[of n ss] by auto
have "(\<I> z, s) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
proof -
have "(\<alpha> y \<cdot> \<I>, s) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
using in_db nss by auto
moreover
have "\<alpha> y = Var z"
using zn
by (metis (no_types, hide_lams) \<sigma> subst_compose_def subst_imgI subst_to_var_is_var
term.distinct(1) transaction_fresh_subst_def var_comp(2))
then have "\<alpha> y \<cdot> \<I> = \<I> z"
by auto
ultimately
show "(\<I> z, s) \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
by auto
qed
then have "\<exists>t' s'. insert\<langle>t',s'\<rangle> \<in> set (unlabel \<A>) \<and> \<I> z = t' \<cdot> \<I> \<and> s = s' \<cdot> \<I>"
using db\<^sub>s\<^sub>s\<^sub>t_in_cases[of "\<I> z" s "unlabel \<A>" \<I> "[]"] unfolding db\<^sub>s\<^sub>s\<^sub>t_def by auto
then obtain t' s' where t's': "insert\<langle>t',s'\<rangle> \<in> set (unlabel \<A>) \<and> \<I> z = t' \<cdot> \<I> \<and> s = s' \<cdot> \<I>"
by auto
then have "t' \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
by force
then have "t' \<cdot> \<I> \<in> (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>"
by auto
then have "\<I> z \<in> (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>"
using t's' by auto
then have "\<I> z \<in> 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>))"
using reachable_constraints_subterms_subst[
OF \<A>_reach welltyped_constraint_model_prefix[OF \<I>] P]
by auto
then show ?B
using zn(1) by simp
qed
qed
lemma transaction_prop5:
fixes T \<sigma> \<alpha> \<A> \<I> T' a0 a0' \<theta>
defines "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>)"
and "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
and "a0' \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T') \<I>)"
and "\<theta> \<equiv> \<lambda>\<delta> x. if fst x = TAtom Value then (absc \<circ> \<delta>) x else Var x"
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set P"
and \<I>: "welltyped_constraint_model \<I> (\<A>@T')"
and \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
and FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
and step: "list_all (transaction_check FP OCC TI) P"
shows "\<exists>\<delta> \<in> abs_substs_fun ` set (transaction_check_comp FP OCC TI T).
\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<longrightarrow>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 = absc (\<delta> x) \<and>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' = absc (absdbupd (unlabel (transaction_updates T)) x (\<delta> x))"
proof -
define comp0 where "comp0 \<equiv> abs_substs_fun ` set (transaction_check_comp FP OCC TI T)"
define check0 where "check0 \<equiv> transaction_check FP OCC TI T"
define upd where "upd \<equiv> \<lambda>\<delta> x. absdbupd (unlabel (transaction_updates T)) x (\<delta> x)"
define b0 where "b0 \<equiv> \<lambda>x. THE b. absc b = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0"
note all_defs = comp0_def check0_def a0_def a0'_def upd_def b0_def \<theta>_def T'_def
have \<theta>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<theta> \<delta>)" for \<delta>
unfolding \<theta>_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def
by fastforce
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(1) \<A>_reach)
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_trms: "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 \<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 \<I> 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: welltyped_constraint_model_def constraint_model_def db\<^sub>s\<^sub>s\<^sub>t_def)
have T_adm: "admissible_transaction T"
using T P(1) Ball_set[of P "admissible_transaction"]
by blast
hence T_valid: "wellformed_transaction T"
unfolding admissible_transaction_def by blast
have T_no_bvars: "fv_transaction T = vars_transaction T" "bvars_transaction T = {}"
using transaction_no_bvars[OF T_adm] by simp_all
have T_vars_const_typed: "\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<or> (\<exists>a. \<Gamma>\<^sub>v x = TAtom (Atom a))"
and T_fresh_vars_value_typed: "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
using T P protocol_transaction_vars_TAtom_typed(2,3)[of T] by simp_all
have wt_\<sigma>\<alpha>\<I>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>)" and wt_\<sigma>\<alpha>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using \<I>_wt wt_subst_compose transaction_fresh_subst_wt[OF \<sigma> T_fresh_vars_value_typed]
transaction_renaming_subst_wt[OF \<alpha>]
by blast+
have T_vars_vals: "\<forall>x \<in> fv_transaction T. \<exists>n. (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> = Fun (Val (n, False)) []"
proof
fix x assume x: "x \<in> fv_transaction T"
show "\<exists>n. (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> = Fun (Val (n, False)) []"
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 moura
thus ?thesis by (simp add: subst_compose_def)
next
case False
hence *: "(\<sigma> \<circ>\<^sub>s \<alpha>) x = \<alpha> x" by (auto simp add: subst_compose_def)
obtain y where y: "\<Gamma>\<^sub>v x = \<Gamma>\<^sub>v y" "\<alpha> x = Var y"
using transaction_renaming_subst_wt[OF \<alpha>]
transaction_renaming_subst_is_renaming[OF \<alpha>]
by (metis \<Gamma>.simps(1) prod.exhaust wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def)
hence "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>)"
using x * T_no_bvars(2) unlabel_subst[of "transaction_strand T" "\<sigma> \<circ>\<^sub>s \<alpha>"]
fv\<^sub>s\<^sub>s\<^sub>t_subst_fv_subset[of x "unlabel (transaction_strand T)" "\<sigma> \<circ>\<^sub>s \<alpha>"]
by auto
hence "y \<in> fv\<^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 \<sigma> \<circ>\<^sub>s \<alpha>))"
using 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 auto
thus ?thesis
using x y * T P (* T_vars_const_typed *)
constraint_model_Value_term_is_Val[
OF reachable_constraints.step[OF \<A>_reach T \<sigma> \<alpha>] \<I>[unfolded T'_def] P(1), of y]
admissible_transaction_Value_vars[of T]
by simp
qed
qed
have T_vars_absc: "\<forall>x \<in> fv_transaction T. \<exists>!n. (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 = absc n"
using T_vars_vals by fastforce
hence "(absc \<circ> b0) x = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0" when "x \<in> fv_transaction T" for x
using that unfolding b0_def by fastforce
hence T_vars_absc': "t \<cdot> (absc \<circ> b0) = t \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>) \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0"
when "fv t \<subseteq> fv_transaction T" "\<nexists>n T. Fun (Val n) T \<in> subterms t" for t
using that(1) abs_term_subst_eq'[OF _ that(2), of "\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>" a0 "absc \<circ> b0"]
subst_compose[of "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>] subst_subst_compose[of t "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>]
by fastforce
have "\<exists>\<delta> \<in> comp0. \<forall>x \<in> fv_transaction T. fst x = TAtom Value \<longrightarrow> b0 x = \<delta> x"
proof -
let ?S = "set (unlabel (transaction_selects T))"
let ?C = "set (unlabel (transaction_checks T))"
let ?xs = "fv_transaction T - set (transaction_fresh T)"
note * = transaction_prop3[OF \<A>_reach T \<I>[unfolded T'_def] \<sigma> \<alpha> FP OCC TI P(1)]
have **:
"\<forall>x \<in> set (transaction_fresh T). b0 x = {}"
"\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T). intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> b0)"
(is ?B)
proof -
show ?B
proof (intro ballI impI)
fix t assume t: "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_receive T)"
hence t': "fv t \<subseteq> fv_transaction T" "\<nexists>n T. Fun (Val n) T \<in> subterms t"
using trms_transaction_unfold[of T] vars_transaction_unfold[of T]
trms\<^sub>s\<^sub>s\<^sub>t_fv_vars\<^sub>s\<^sub>s\<^sub>t_subset[of t "unlabel (transaction_strand T)"]
transactions_have_no_Value_consts'[OF T_adm]
wellformed_transaction_send_receive_fv_subset(1)[OF T_valid t(1)]
by blast+
have "intruder_synth_mod_timpls FP TI (t \<cdot> (absc \<circ> b0))"
using t(1) t' *(2) T_vars_absc'
by (metis a0_def)
moreover have "(absc \<circ> b0) x = (\<theta> b0) x" when "x \<in> fv t" for x
using that T P admissible_transaction_Value_vars[of T]
\<open>fv t \<subseteq> fv_transaction T\<close> \<Gamma>\<^sub>v_TAtom''(2)[of x]
unfolding \<theta>_def by fastforce
hence "t \<cdot> (absc \<circ> b0) = t \<cdot> \<theta> b0"
using term_subst_eq[of t "absc \<circ> b0" "\<theta> b0"] by argo
ultimately show "intruder_synth_mod_timpls FP TI (t \<cdot> \<theta> b0)"
using intruder_synth.simps[of "set FP"] by (cases "t \<cdot> \<theta> b0") metis+
qed
qed (simp add: *(1) a0_def b0_def)
have ***: "\<forall>x \<in> ?xs. \<forall>s. select\<langle>Var x,Fun (Set s) []\<rangle> \<in> ?S \<longrightarrow> s \<in> b0 x"
"\<forall>x \<in> ?xs. \<forall>s. \<langle>Var x in Fun (Set s) []\<rangle> \<in> ?C \<longrightarrow> s \<in> b0 x"
"\<forall>x \<in> ?xs. \<forall>s. \<langle>Var x not in Fun (Set s) []\<rangle> \<in> ?C \<longrightarrow> s \<notin> b0 x"
"\<forall>x \<in> ?xs. fst x = TAtom Value \<longrightarrow> b0 x \<in> set OCC"
unfolding a0_def b0_def
using *(3,4) apply (force, force)
using *(5) apply force
using *(6) admissible_transaction_Value_vars[OF bspec[OF P T]] by force
show ?thesis
using transaction_check_comp_in[OF T_adm **[unfolded \<theta>_def] ***]
unfolding comp0_def
by metis
qed
hence 1: "\<exists>\<delta> \<in> comp0. \<forall>x \<in> fv_transaction T.
fst x = TAtom Value \<longrightarrow> (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 = absc (\<delta> x)"
using T_vars_absc unfolding b0_def a0_def by fastforce
obtain \<delta> where \<delta>:
"\<delta> \<in> comp0" "\<forall>x \<in> fv_transaction T. fst x = TAtom Value \<longrightarrow> (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 = absc (\<delta> x)"
using 1 by moura
have 2: "\<theta> x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) = absc (absdbupd (unlabel A) x d)"
when "\<theta> x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 D = absc d"
and "\<forall>t u. insert\<langle>t,u\<rangle> \<in> set (unlabel A) \<longrightarrow> (\<exists>y s. t = Var y \<and> u = Fun (Set s) [])"
and "\<forall>t u. delete\<langle>t,u\<rangle> \<in> set (unlabel A) \<longrightarrow> (\<exists>y s. t = Var y \<and> u = Fun (Set s) [])"
and "\<forall>y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \<theta> x \<cdot> \<I> = \<theta> y \<cdot> \<I> \<longrightarrow> x = y"
and "\<forall>y \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \<exists>n. \<theta> y \<cdot> \<I> = Fun (Val n) []"
and x: "\<theta> x \<cdot> \<I> = Fun (Val n) []"
and D: "\<forall>d \<in> set D. \<exists>s. snd d = Fun (Set s) []"
for A::"('fun,'atom,'sets,'nat) prot_strand" and x \<theta> D n d
using that(2,3,4,5)
proof (induction A rule: List.rev_induct)
case (snoc a A)
then obtain l b where a: "a = (l,b)" by (metis surj_pair)
have IH: "\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n = absdbupd (unlabel A) x d"
using snoc unlabel_append[of A "[a]"] a x
by (simp del: unlabel_append)
have b_prems: "\<forall>y \<in> fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p b. \<theta> x \<cdot> \<I> = \<theta> y \<cdot> \<I> \<longrightarrow> x = y"
"\<forall>y \<in> fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p b. \<exists>n. \<theta> y \<cdot> \<I> = Fun (Val n) []"
using snoc.prems(3,4) a by (simp_all add: unlabel_def)
have *: "filter is_Update (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))) =
filter is_Update (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)))"
"filter is_Update (unlabel (A@[a])) = filter is_Update (unlabel A)"
when "\<not>is_Update b"
using that a
by (cases b, simp_all add: dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def unlabel_def subst_apply_labeled_stateful_strand_def)+
note ** = IH a dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst_append[of A "[a]" \<theta>]
note *** = * absdbupd_filter[of "unlabel (A@[a])"]
absdbupd_filter[of "unlabel A"]
db\<^sub>s\<^sub>s\<^sub>t_filter[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"]
db\<^sub>s\<^sub>s\<^sub>t_filter[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>))"]
note **** = **(2,3) dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst_snoc[of A a \<theta>]
unlabel_append[of "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>" "[dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p a \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>]"]
db\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)" "unlabel [dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p a \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>]" \<I> D]
have "\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n = absdbupd (unlabel (A@[a])) x d" using ** ***
proof (cases b)
case (Insert t t')
then obtain y s m where y: "t = Var y" "t' = Fun (Set s) []" "\<theta> y \<cdot> \<I> = Fun (Val m) []"
using snoc.prems(1) b_prems(2) a by (fastforce simp add: unlabel_def)
hence a': "db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D =
List.insert ((Fun (Val m) [], Fun (Set s) [])) (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>) \<I> D)"
"unlabel [dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p a \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>] = [insert\<langle>\<theta> y, Fun (Set s) []\<rangle>]"
"unlabel [a] = [insert\<langle>Var y, Fun (Set s) []\<rangle>]"
using **** Insert by simp_all
show ?thesis
proof (cases "x = y")
case True
hence "\<theta> x \<cdot> \<I> = \<theta> y \<cdot> \<I>" by simp
hence "\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n =
insert s (\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n)"
by (metis (no_types, lifting) y(3) a'(1) x dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst to_abs_list_insert')
thus ?thesis using True IH a'(3) absdbupd_append[of "unlabel A"] by (simp add: unlabel_def)
next
case False
hence "\<theta> x \<cdot> \<I> \<noteq> \<theta> y \<cdot> \<I>" using b_prems(1) y Insert by simp
hence "\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n = \<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n"
by (metis (no_types, lifting) y(3) a'(1) x dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst to_abs_list_insert)
thus ?thesis using False IH a'(3) absdbupd_append[of "unlabel A"] by (simp add: unlabel_def)
qed
next
case (Delete t t')
then obtain y s m where y: "t = Var y" "t' = Fun (Set s) []" "\<theta> y \<cdot> \<I> = Fun (Val m) []"
using snoc.prems(2) b_prems(2) a by (fastforce simp add: unlabel_def)
hence a': "db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D =
List.removeAll ((Fun (Val m) [], Fun (Set s) [])) (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>) \<I> D)"
"unlabel [dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p a \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<theta>] = [delete\<langle>\<theta> y, Fun (Set s) []\<rangle>]"
"unlabel [a] = [delete\<langle>Var y, Fun (Set s) []\<rangle>]"
using **** Delete by simp_all
have "\<exists>s S. snd d = Fun (Set s) []" when "d \<in> set (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>) \<I> D)" for d
using snoc.prems(1,2) db\<^sub>l\<^sub>s\<^sub>s\<^sub>t_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_set_ex[OF that _ _ D] by (simp add: unlabel_def)
moreover {
fix t::"('fun,'atom,'sets) prot_term"
and D::"(('fun,'atom,'sets) prot_term \<times> ('fun,'atom,'sets) prot_term) list"
assume "\<forall>d \<in> set D. \<exists>s. snd d = Fun (Set s) []"
hence "removeAll (t, Fun (Set s) []) D = filter (\<lambda>d. \<nexists>S. d = (t, Fun (Set s) S)) D"
by (induct D) auto
} ultimately have a'':
"List.removeAll ((Fun (Val m) [], Fun (Set s) [])) (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>) \<I> D) =
filter (\<lambda>d. \<nexists>S. d = (Fun (Val m) [], Fun (Set s) S)) (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>) \<I> D)"
by simp
show ?thesis
proof (cases "x = y")
case True
hence "\<theta> x \<cdot> \<I> = \<theta> y \<cdot> \<I>" by simp
hence "\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n =
(\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n) - {s}"
using y(3) a'' a'(1) x by (simp add: dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst to_abs_list_remove_all')
thus ?thesis using True IH a'(3) absdbupd_append[of "unlabel A"] by (simp add: unlabel_def)
next
case False
hence "\<theta> x \<cdot> \<I> \<noteq> \<theta> y \<cdot> \<I>" using b_prems(1) y Delete by simp
hence "\<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@[a] \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n = \<alpha>\<^sub>0 (db'\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \<cdot>\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<theta>)) \<I> D) n"
by (metis (no_types, lifting) y(3) a'(1) x dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst to_abs_list_remove_all)
thus ?thesis using False IH a'(3) absdbupd_append[of "unlabel A"] by (simp add: unlabel_def)
qed
qed simp_all
thus ?case by (simp add: x)
qed (simp add: that(1))
have 3: "x = y"
when xy: "(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> = (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I>" "x \<in> fv_transaction T" "y \<in> fv_transaction T"
for x y
proof -
have "x \<notin> set (transaction_fresh T) \<Longrightarrow> y \<notin> set (transaction_fresh T) \<Longrightarrow> ?thesis"
using xy admissible_transaction_strand_sem_fv_ineq[OF T_adm \<I>_is_T_model[unfolded T'_def]]
by fast
moreover {
assume *: "x \<in> set (transaction_fresh T)" "y \<in> set (transaction_fresh T)"
then obtain xn yn where "\<sigma> x = Fun (Val xn) []" "\<sigma> y = Fun (Val yn) []"
by (metis transaction_fresh_subst_sends_to_val[OF \<sigma>])
hence "\<sigma> x = \<sigma> y" using that(1) by (simp add: subst_compose)
moreover have "inj_on \<sigma> (subst_domain \<sigma>)" "x \<in> subst_domain \<sigma>" "y \<in> subst_domain \<sigma>"
using * \<sigma> unfolding transaction_fresh_subst_def by auto
ultimately have ?thesis unfolding inj_on_def by blast
} moreover have False when "x \<in> set (transaction_fresh T)" "y \<notin> set (transaction_fresh T)"
using that(2) xy T_no_bvars admissible_transaction_Value_vars[OF bspec[OF P T], of y]
transaction_prop4[OF \<A>_reach T \<I>[unfolded T'_def] \<sigma> \<alpha> P that(1), of y]
by auto
moreover have False when "x \<notin> set (transaction_fresh T)" "y \<in> set (transaction_fresh T)"
using that(1) xy T_no_bvars admissible_transaction_Value_vars[OF bspec[OF P T], of x]
transaction_prop4[OF \<A>_reach T \<I>[unfolded T'_def] \<sigma> \<alpha> P that(2), of x]
by fastforce
ultimately show ?thesis by metis
qed
have 4: "\<exists>y s. t = Var y \<and> u = Fun (Set s) []"
when "insert\<langle>t,u\<rangle> \<in> set (unlabel (transaction_strand T))" for t u
using that admissible_transaction_strand_step_cases(4)[OF T_adm] T_valid
by blast
have 5: "\<exists>y s. t = Var y \<and> u = Fun (Set s) []"
when "delete\<langle>t,u\<rangle> \<in> set (unlabel (transaction_strand T))" for t u
using that admissible_transaction_strand_step_cases(4)[OF T_adm] T_valid
by blast
have 6: "\<exists>n. (\<sigma> \<circ>\<^sub>s \<alpha>) y \<cdot> \<I> = Fun (Val (n, False)) []" when "y \<in> fv_transaction T" for y
using that by (simp add: T_vars_vals)
have "list_all wellformed_transaction P" "list_all admissible_transaction_updates P"
using P(1) Ball_set[of P "admissible_transaction"] Ball_set[of P wellformed_transaction]
Ball_set[of P admissible_transaction_updates]
unfolding admissible_transaction_def by fastforce+
hence 7: "\<exists>s. snd d = Fun (Set s) []" when "d \<in> set (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)" for d
using that reachable_constraints_db\<^sub>l\<^sub>s\<^sub>s\<^sub>t_set_args_empty[OF \<A>_reach]
unfolding admissible_transaction_updates_def by (cases d) simp
have "(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' = absc (upd \<delta> x)"
when x: "x \<in> fv_transaction T" "fst x = TAtom Value" for x
proof -
have "(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> \<alpha>\<^sub>0 (db'\<^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>)) \<I> (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>))
= absc (absdbupd (unlabel (transaction_strand T)) x (\<delta> x))"
using 2[of "\<sigma> \<circ>\<^sub>s \<alpha>" x "db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>" "\<delta> x" "transaction_strand T"]
3[OF _ x(1)] 4 5 6[OF that(1)] 6 7 x \<delta>(2)
unfolding all_defs by blast
thus ?thesis
using x db\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>"] absdbupd_wellformed_transaction[OF T_valid]
unfolding all_defs db\<^sub>s\<^sub>s\<^sub>t_def by force
qed
thus ?thesis using \<delta> \<Gamma>\<^sub>v_TAtom''(2) unfolding all_defs by blast
qed
lemma transaction_prop6:
fixes T \<sigma> \<alpha> \<A> \<I> T' a0 a0'
defines "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>)"
and "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
and "a0' \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T') \<I>)"
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set P"
and \<I>: "welltyped_constraint_model \<I> (\<A>@T')"
and \<sigma>: "transaction_fresh_subst \<sigma> T \<A>"
and \<alpha>: "transaction_renaming_subst \<alpha> P \<A>"
and FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
and step: "list_all (transaction_check FP OCC TI) P"
shows "\<forall>t \<in> timpl_closure_set (\<alpha>\<^sub>i\<^sub>k \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>).
timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t" (is ?A)
and "timpl_closure_set (\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>) \<subseteq> absc ` set OCC" (is ?B)
and "\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T). is_Fun (t \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>) \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0') \<longrightarrow>
timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>) \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0'" (is ?C)
and "\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<longrightarrow>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> absc ` set OCC" (is ?D)
proof -
define comp0 where "comp0 \<equiv> abs_substs_fun ` set (transaction_check_comp FP OCC TI T)"
define check0 where "check0 \<equiv> transaction_check FP OCC TI T"
define upd where "upd \<equiv> \<lambda>\<delta> x. absdbupd (unlabel (transaction_updates T)) x (\<delta> x)"
define \<theta> where "\<theta> \<equiv> \<lambda>\<delta> x. if fst x = TAtom Value then (absc \<circ> \<delta>) x else Var x"
have T_adm: "admissible_transaction T" using T P(1) by metis
hence T_valid: "wellformed_transaction T" by (metis admissible_transaction_def)
have \<theta>_prop: "\<theta> \<sigma> x = absc (\<sigma> x)" when "\<Gamma>\<^sub>v x = TAtom Value" for \<sigma> x
using that \<Gamma>\<^sub>v_TAtom''(2)[of x] unfolding \<theta>_def by simp
(* The set-membership status of all value constants in T under \<I>, \<sigma>, \<alpha> are covered by the check *)
have 0: "\<exists>\<delta> \<in> comp0. \<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<longrightarrow>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 = absc (\<delta> x) \<and>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' = absc (upd \<delta> x)"
using transaction_prop5[OF \<A>_reach T \<I>[unfolded T'_def] \<sigma> \<alpha> FP OCC TI P step]
unfolding a0_def a0'_def T'_def upd_def comp0_def
by blast
(* All set-membership changes are covered by the term implication graph *)
have 1: "(\<delta> x, upd \<delta> x) \<in> (set TI)\<^sup>+"
when "\<delta> \<in> comp0" "\<delta> x \<noteq> upd \<delta> x" "x \<in> fv_transaction T" "x \<notin> set (transaction_fresh T)"
for x \<delta>
using T that step Ball_set[of P "transaction_check FP OCC TI"]
transaction_prop1[of \<delta> FP OCC TI T x] TI
unfolding upd_def comp0_def
by blast
(* All set-membership changes are covered by the fixed point *)
have 2: (* "\<delta> x \<in> set OCC" *) "upd \<delta> x \<in> set OCC"
when "\<delta> \<in> comp0" "x \<in> fv_transaction T" "fst x = TAtom Value" for x \<delta>
using T that step Ball_set[of P "transaction_check FP OCC TI"]
T_adm FP OCC TI transaction_prop2[of \<delta> FP OCC TI T x]
unfolding upd_def comp0_def
by blast+
obtain \<delta> where \<delta>:
"\<delta> \<in> comp0"
"\<forall>x \<in> fv_transaction T. \<Gamma>\<^sub>v x = TAtom Value \<longrightarrow>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 = absc (\<delta> x) \<and>
(\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' = absc (upd \<delta> x)"
using 0 by moura
have "\<exists>x. ab = (\<delta> x, upd \<delta> x) \<and> x \<in> fv_transaction T - set (transaction_fresh T) \<and> \<delta> x \<noteq> upd \<delta> x"
when ab: "ab \<in> \<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>" for ab
proof -
obtain a b where ab': "ab = (a,b)" by (metis surj_pair)
then obtain x where x:
"a \<noteq> b" "x \<in> fv_transaction T" "x \<notin> set (transaction_fresh T)"
"absc a = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0" "absc b = (\<sigma> \<circ>\<^sub>s \<alpha>) x \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0'"
using ab unfolding abs_term_implications_def a0_def a0'_def T'_def by blast
hence "absc a = absc (\<delta> x)" "absc b = absc (upd \<delta> x)"
using \<delta>(2) admissible_transaction_Value_vars[OF bspec[OF P T] x(2)]
by metis+
thus ?thesis using x ab' by blast
qed
hence \<alpha>\<^sub>t\<^sub>i_TI_subset: "\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I> \<subseteq> {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}" using 1[OF \<delta>(1)] by blast
have "timpl_closure_set (timpl_closure_set (set FP) (set TI)) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>) \<turnstile>\<^sub>c t"
when t: "t \<in> timpl_closure_set (\<alpha>\<^sub>i\<^sub>k \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)" for t
using timpl_closure_set_is_timpl_closure_union[of "\<alpha>\<^sub>i\<^sub>k \<A> \<I>" "\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>"]
intruder_synth_timpl_closure_set FP(3) t
by blast
thus ?A
using ideduct_synth_mono[OF _ timpl_closure_set_mono[OF
subset_refl[of "timpl_closure_set (set FP) (set TI)"]
\<alpha>\<^sub>t\<^sub>i_TI_subset]]
timpl_closure_set_timpls_trancl_eq'[of "timpl_closure_set (set FP) (set TI)" "set TI"]
unfolding timpl_closure_set_idem
by force
have "timpl_closure_set (\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>) \<subseteq>
timpl_closure_set (absc ` set OCC) {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
using timpl_closure_set_mono[OF _ \<alpha>\<^sub>t\<^sub>i_TI_subset] OCC(3) by blast
thus ?B using OCC(2) timpl_closure_set_timpls_trancl_subset' by blast
have "transaction_check_post FP TI T \<delta>"
using T \<delta>(1) step
unfolding transaction_check_def comp0_def list_all_iff
by blast
hence 3: "timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t \<cdot> \<theta> (upd \<delta>)"
when "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)" "is_Fun (t \<cdot> \<theta> (upd \<delta>))" for t
using that
unfolding transaction_check_post_def upd_def \<theta>_def
intruder_synth_mod_timpls_is_synth_timpl_closure_set[OF TI, symmetric]
by meson
have 4: "\<forall>x \<in> fv t. (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>) x \<cdot>\<^sub>\<alpha> a0' = \<theta> (upd \<delta>) x"
when "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)" for t
using wellformed_transaction_send_receive_fv_subset(2)[OF T_valid that]
\<delta>(2) subst_compose[of "\<sigma> \<circ>\<^sub>s \<alpha>" \<I>] \<theta>_prop
admissible_transaction_Value_vars[OF bspec[OF P T]]
by fastforce
have 5: "\<nexists>n T. Fun (Val n) T \<in> subterms t" when "t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_send T)" for t
using that transactions_have_no_Value_consts'[OF T_adm] trms_transaction_unfold[of T]
by blast
show ?D using 2[OF \<delta>(1)] \<delta>(2) \<Gamma>\<^sub>v_TAtom''(2) unfolding a0'_def T'_def by blast
show ?C using 3 abs_term_subst_eq'[OF 4 5] by simp
qed
lemma reachable_constraints_covered_step:
fixes \<A>::"('fun,'atom,'sets,'lbl) prot_constr"
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and T: "T \<in> set 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 FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
"ground (set FP)"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
and transactions_covered: "list_all (transaction_check FP OCC TI) P"
shows "\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k (\<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>)) \<I>.
timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t" (is ?A)
and "\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s (\<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>)) \<I> \<subseteq> absc ` set OCC" (is ?B)
proof -
note step_props = transaction_prop6[OF \<A>_reach T \<I> \<sigma> \<alpha> FP(1,2,3) OCC TI P transactions_covered]
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>)"
define a0 where "a0 \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)"
define a0' where "a0' \<equiv> \<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@T') \<I>)"
define vals where "vals \<equiv> \<lambda>S::('fun,'atom,'sets,'lbl) prot_constr.
{t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t S) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>. \<exists>n. t = Fun (Val n) []}"
define vals_sym where "vals_sym \<equiv> \<lambda>S::('fun,'atom,'sets,'lbl) prot_constr.
{t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t S). (\<exists>n. t = Fun (Val n) []) \<or> (\<exists>m. t = Var (TAtom Value,m))}"
have \<I>_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" by (metis \<I> welltyped_constraint_model_def)
have \<I>_grounds: "fv (t \<cdot> \<I>) = {}" for t
using \<I> interpretation_grounds[of \<I>]
unfolding welltyped_constraint_model_def constraint_model_def by auto
have T_fresh_vars_value_typed: "\<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
using protocol_transaction_vars_TAtom_typed[OF bspec[OF P(1) T]] by simp_all
have wt_\<sigma>\<alpha>\<I>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>)" and wt_\<sigma>\<alpha>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\<sigma> \<circ>\<^sub>s \<alpha>)"
using \<I>_wt wt_subst_compose transaction_fresh_subst_wt[OF \<sigma> T_fresh_vars_value_typed]
transaction_renaming_subst_wt[OF \<alpha>]
by blast+
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
have \<I>_vals: "\<exists>n. \<I> (TAtom Value, m) = Fun (Val n) []"
when "(TAtom Value, m) \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" for m
using constraint_model_Value_term_is_Val'[
OF \<A>_reach welltyped_constraint_model_prefix[OF \<I>] P(1)]
\<A>_no_bvars 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>"] that
by blast
have vals_sym_vals: "t \<cdot> \<I> \<in> vals \<A>" when t: "t \<in> vals_sym \<A>" for t
proof (cases t)
case (Var x)
then obtain m where *: "x = (TAtom Value,m)" using t unfolding vals_sym_def by blast
moreover have "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" using t unfolding vals_sym_def by blast
hence "t \<cdot> \<I> \<in> 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>" "\<exists>n. \<I> (Var Value, m) = Fun (Val n) []"
using Var * \<I>_vals[of m] var_subterm_trms\<^sub>s\<^sub>s\<^sub>t_is_vars\<^sub>s\<^sub>s\<^sub>t[of x "unlabel \<A>"]
\<Gamma>\<^sub>v_TAtom[of Value m] reachable_constraints_Value_vars_are_fv[OF \<A>_reach P(1), of x]
by blast+
ultimately show ?thesis using Var unfolding vals_def by auto
next
case (Fun f T)
then obtain n where "f = Val n" "T = []" using t unfolding vals_sym_def by blast
moreover have "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" using t unfolding vals_sym_def by blast
hence "t \<cdot> \<I> \<in> 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>" using Fun by blast
ultimately show ?thesis using Fun unfolding vals_def by auto
qed
have vals_vals_sym: "\<exists>s. s \<in> vals_sym \<A> \<and> t = s \<cdot> \<I>" when "t \<in> vals \<A>" for t
using that constraint_model_Val_is_Value_term[OF \<I>]
unfolding vals_def vals_sym_def by fast
have T_adm: "admissible_transaction T" and T_valid: "wellformed_transaction T"
apply (metis P(1) T)
using P(1) T Ball_set[of P "admissible_transaction"]
unfolding admissible_transaction_def by fastforce
have 0:
"\<alpha>\<^sub>i\<^sub>k (\<A>@T') \<I> = (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0' \<union> (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0'"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s (\<A>@T') \<I> = vals \<A> \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0' \<union> vals T' \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0'"
by (metis abs_intruder_knowledge_append a0'_def,
metis abs_value_constants_append[of \<A> T' \<I>] a0'_def vals_def)
have 1: "(ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t T' \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0' =
(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>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0'"
by (metis T'_def dual_transaction_ik_is_transaction_send''[OF T_valid])
have 2: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) \<inter> subst_domain \<sigma> = {}"
"bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T) \<inter> subst_domain \<alpha> = {}"
using T_adm unfolding admissible_transaction_def
by blast+
have "vals T' \<subseteq> (\<sigma> \<circ>\<^sub>s \<alpha>) ` fv_transaction T \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
proof
fix t assume "t \<in> vals T'"
then obtain s n where s:
"s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t T')" "t = s \<cdot> \<I>" "t = Fun (Val n) []"
unfolding vals_def by fast
then obtain u where u:
"u \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (transaction_strand T))"
"s = u \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha>)"
using transaction_fresh_subst_transaction_renaming_subst_trms[OF \<sigma> \<alpha> 2]
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 blast
have *: "t = u \<cdot> (\<sigma> \<circ>\<^sub>s \<alpha> \<circ>\<^sub>s \<I>)" by (metis subst_subst_compose s(2) u(2))
then obtain x where x: "u = Var x"
using s(3) transactions_have_no_Value_consts(1)[OF T_adm u(1)] by (cases u) force+
hence **: "x \<in> vars_transaction T"
by (metis u(1) var_subterm_trms\<^sub>s\<^sub>s\<^sub>t_is_vars\<^sub>s\<^sub>s\<^sub>t)
have "\<Gamma>\<^sub>v x = TAtom Value"
using * x s(3) wt_subst_trm''[OF wt_\<sigma>\<alpha>\<I>, of u]
by simp
thus "t \<in> (\<sigma> \<circ>\<^sub>s \<alpha>) ` fv_transaction T \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
using transaction_Value_vars_are_fv[OF T_adm **] x *
by (metis subst_comp_set_image rev_image_eqI subst_apply_term.simps(1))
qed
hence 3: "vals T' \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0' \<subseteq> ((\<sigma> \<circ>\<^sub>s \<alpha>) ` fv_transaction T \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0'"
by (simp add: abs_apply_terms_def image_mono)
have "t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set (\<alpha>\<^sub>i\<^sub>k \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
when "t \<in> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>" for t
using that abs_in[OF imageI[OF that]]
\<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_ik[OF \<A>_reach T \<I> \<sigma> \<alpha> P(1)]
timpl_closure_set_mono[of "{t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0}" "\<alpha>\<^sub>i\<^sub>k \<A> \<I>" "\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>" "\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>"]
unfolding a0_def a0'_def T'_def abs_intruder_knowledge_def by fast
hence A: "\<alpha>\<^sub>i\<^sub>k (\<A>@T') \<I> \<subseteq>
timpl_closure_set (\<alpha>\<^sub>i\<^sub>k \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>) \<union>
(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>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0'"
using 0(1) 1 by (auto simp add: abs_apply_terms_def)
have "t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set {t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0} (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
when t: "t \<in> vals_sym \<A>" for t
proof -
have "(\<exists>n. t = Fun (Val n) [] \<and> t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)) \<or>
(\<exists>n. t = Var (TAtom Value,n) \<and> (TAtom Value,n) \<in> fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)"
(is "?P \<or> ?Q")
using t var_subterm_trms\<^sub>s\<^sub>s\<^sub>t_is_vars\<^sub>s\<^sub>s\<^sub>t[of _ "unlabel \<A>"]
\<Gamma>\<^sub>v_TAtom[of Value] reachable_constraints_Value_vars_are_fv[OF \<A>_reach P(1)]
unfolding vals_sym_def by fast
thus ?thesis
proof
assume ?P
then obtain n where n: "t = Fun (Val n) []" "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" by moura
thus ?thesis
using \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_Val[OF \<A>_reach T \<I> \<sigma> \<alpha> P(1), of n]
unfolding a0_def a0'_def T'_def by fastforce
next
assume ?Q
thus ?thesis
using \<alpha>\<^sub>t\<^sub>i_covers_\<alpha>\<^sub>0_Var[OF \<A>_reach T \<I> \<sigma> \<alpha> P(1)]
unfolding a0_def a0'_def T'_def by fastforce
qed
qed
moreover have "t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0 \<in> \<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>"
when "t \<in> vals_sym \<A>" for t
using that abs_in vals_sym_vals
unfolding a0_def abs_value_constants_def vals_sym_def vals_def
by (metis (mono_tags, lifting))
ultimately have "t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set (\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
when t: "t \<in> vals_sym \<A>" for t
using t timpl_closure_set_mono[of "{t \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0}" "\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>" "\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>" "\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>"]
by blast
hence "t \<cdot>\<^sub>\<alpha> a0' \<in> timpl_closure_set (\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>)"
when t: "t \<in> vals \<A>" for t
using vals_vals_sym[OF t] by blast
hence B: "\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s (\<A>@T') \<I> \<subseteq>
timpl_closure_set (\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I>) (\<alpha>\<^sub>t\<^sub>i \<A> T \<sigma> \<alpha> \<I>) \<union>
((\<sigma> \<circ>\<^sub>s \<alpha>) ` fv_transaction T \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>) \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a0'"
using 0(2) 3
by (simp add: abs_apply_terms_def image_subset_iff)
have 4: "fv (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<cdot>\<^sub>\<alpha> a) = {}" for t a
using \<I>_grounds[of "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha>"] abs_fv[of "t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I>" a]
by argo
have "is_Fun (t \<cdot> \<sigma> \<circ>\<^sub>s \<alpha> \<cdot> \<I> \<cdot>\<^sub>\<alpha> a0')" for t
using 4[of t a0'] by force
thus ?A
using A step_props(1,3)
unfolding T'_def a0_def a0'_def abs_apply_terms_def
by blast
show ?B
using B step_props(2,4) admissible_transaction_Value_vars[OF bspec[OF P T]]
by (auto simp add: T'_def a0_def a0'_def abs_apply_terms_def)
qed
lemma reachable_constraints_covered:
assumes \<A>_reach: "\<A> \<in> reachable_constraints P"
and \<I>: "welltyped_constraint_model \<I> \<A>"
and FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"ground (set FP)"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
and transactions_covered: "list_all (transaction_check FP OCC TI) P"
shows "\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
and "\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
using \<A>_reach \<I>
proof (induction rule: reachable_constraints.induct)
case init
{ case 1 show ?case by (simp add: abs_intruder_knowledge_def) }
{ case 2 show ?case by (simp add: abs_value_constants_def) }
next
case (step \<A> T \<sigma> \<alpha>)
{ case 1
hence "welltyped_constraint_model \<I> \<A>"
by (metis welltyped_constraint_model_prefix)
hence IH: "\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
using step.IH by metis+
show ?case
using reachable_constraints_covered_step[
OF step.hyps(1,2) "1.prems" step.hyps(3,4) FP(1,2) IH(1)
FP(3) OCC IH(2) TI P transactions_covered]
by metis
}
{ case 2
hence "welltyped_constraint_model \<I> \<A>"
by (metis welltyped_constraint_model_prefix)
hence IH: "\<forall>t \<in> \<alpha>\<^sub>i\<^sub>k \<A> \<I>. timpl_closure_set (set FP) (set TI) \<turnstile>\<^sub>c t"
"\<alpha>\<^sub>v\<^sub>a\<^sub>l\<^sub>s \<A> \<I> \<subseteq> absc ` set OCC"
using step.IH by metis+
show ?case
using reachable_constraints_covered_step[
OF step.hyps(1,2) "2.prems" step.hyps(3,4) FP(1,2) IH(1)
FP(3) OCC IH(2) TI P transactions_covered]
by metis
}
qed
lemma attack_in_fixpoint_if_attack_in_ik:
fixes FP::"('fun,'atom,'sets) prot_terms"
assumes "\<forall>t \<in> IK \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a. FP \<turnstile>\<^sub>c t"
and "attack\<langle>n\<rangle> \<in> IK"
shows "attack\<langle>n\<rangle> \<in> FP"
proof -
have "attack\<langle>n\<rangle> \<cdot>\<^sub>\<alpha> a \<in> IK \<cdot>\<^sub>\<alpha>\<^sub>s\<^sub>e\<^sub>t a" by (rule abs_in[OF assms(2)])
hence "FP \<turnstile>\<^sub>c attack\<langle>n\<rangle> \<cdot>\<^sub>\<alpha> a" using assms(1) by blast
moreover have "attack\<langle>n\<rangle> \<cdot>\<^sub>\<alpha> a = attack\<langle>n\<rangle>" by simp
ultimately have "FP \<turnstile>\<^sub>c attack\<langle>n\<rangle>" by metis
thus ?thesis using ideduct_synth_priv_const_in_ik[of FP "Attack n"] by simp
qed
lemma attack_in_fixpoint_if_attack_in_timpl_closure_set:
fixes FP::"('fun,'atom,'sets) prot_terms"
assumes "attack\<langle>n\<rangle> \<in> timpl_closure_set FP TI"
shows "attack\<langle>n\<rangle> \<in> FP"
proof -
have "\<forall>f \<in> funs_term (attack\<langle>n\<rangle>). \<not>is_Abs f" by auto
thus ?thesis using timpl_closure_set_no_Abs_in_set[OF assms] by blast
qed
theorem prot_secure_if_fixpoint_covered_typed:
assumes FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"ground (set FP)"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and P:
"\<forall>T \<in> set P. admissible_transaction T"
and transactions_covered: "list_all (transaction_check FP OCC TI) P"
and attack_notin_FP: "attack\<langle>n\<rangle> \<notin> set FP"
and \<A>: "\<A> \<in> reachable_constraints P"
shows "\<nexists>\<I>. welltyped_constraint_model \<I> (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)])" (is "\<nexists>\<I>. ?P \<I>")
proof
assume "\<exists>\<I>. ?P \<I>"
then obtain \<I> where \<I>: "welltyped_constraint_model \<I> (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)])"
by moura
hence \<I>': "constr_sem_stateful \<I> (unlabel (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)]))"
"interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>"
unfolding welltyped_constraint_model_def constraint_model_def by metis+
have 0: "attack\<langle>n\<rangle> \<notin> ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
using welltyped_constraint_model_prefix[OF \<I>]
reachable_constraints_covered(1)[OF \<A> _ FP OCC TI P transactions_covered]
attack_in_fixpoint_if_attack_in_ik[
of "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>" "\<alpha>\<^sub>0 (db\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<I>)" "timpl_closure_set (set FP) (set TI)" n]
attack_in_fixpoint_if_attack_in_timpl_closure_set
attack_notin_FP
unfolding abs_intruder_knowledge_def by blast
have 1: "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I> \<turnstile> attack\<langle>n\<rangle>"
using \<I> strand_sem_append_stateful[of "{}" "{}" "unlabel \<A>" _ \<I>]
unfolding welltyped_constraint_model_def constraint_model_def by force
have 2: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>)"
using reachable_constraints_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s[OF _ \<A>] admissible_transactions_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s P(1)
ik\<^sub>s\<^sub>s\<^sub>t_trms\<^sub>s\<^sub>s\<^sub>t_subset[of "unlabel \<A>"] wf_trms_subst[OF \<I>'(3)]
by fast
have 3: "\<forall>x \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>). \<not>TAtom AttackType \<sqsubseteq> \<Gamma>\<^sub>v x"
using reachable_constraints_vars_TAtom_typed[OF \<A> P(1)]
fv_ik_subset_vars_sst'[of "unlabel \<A>"]
by fastforce
have 4: "attack\<langle>n\<rangle> \<notin> set (snd (Ana t)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>" when t: "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" for t
proof
assume "attack\<langle>n\<rangle> \<in> set (snd (Ana t)) \<cdot>\<^sub>s\<^sub>e\<^sub>t \<I>"
then obtain s where s: "s \<in> set (snd (Ana t))" "s \<cdot> \<I> = attack\<langle>n\<rangle>" by moura
obtain x where x: "s = Var x"
by (cases s) (use s reachable_constraints_no_Ana_Attack[OF \<A> P(1) t] in auto)
have "x \<in> fv t" using x Ana_subterm'[OF s(1)] vars_iff_subtermeq by force
hence "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" using t fv_subterms by fastforce
hence "\<Gamma>\<^sub>v x \<noteq> TAtom AttackType" using 3 by fastforce
thus False using s(2) x wt_subst_trm''[OF \<I>'(4), of "Var x"] by fastforce
qed
have 5: "attack\<langle>n\<rangle> \<notin> set (snd (Ana t))" when t: "t \<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>)" for t
proof
assume "attack\<langle>n\<rangle> \<in> set (snd (Ana t))"
then obtain s where s:
"s \<in> subterms\<^sub>s\<^sub>e\<^sub>t (\<I> ` fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>))" "attack\<langle>n\<rangle> \<in> set (snd (Ana s))"
using Ana_subst_subterms_cases[OF t] 4 by fast
then obtain x where x: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>)" "s \<sqsubseteq> \<I> x" by moura
hence "\<I> x \<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 var_is_subterm[of x] subterms_subst_subset'[of \<I> "ik\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A>"]
by force
hence *: "wf\<^sub>t\<^sub>r\<^sub>m (\<I> x)" "wf\<^sub>t\<^sub>r\<^sub>m s"
using wf_trms_subterms[OF 2] wf_trm_subtermeq[OF _ x(2)]
by auto
show False
using term.order_trans[
OF subtermeq_imp_subtermtypeeq[OF *(2) Ana_subterm'[OF s(2)]]
subtermeq_imp_subtermtypeeq[OF *(1) x(2)]]
3 x(1) wt_subst_trm''[OF \<I>'(4), of "Var x"]
by force
qed
show False
using 0 private_const_deduct[OF _ 1] 5
by simp
qed
end
subsection \<open>Theorem: A Protocol is Secure if it is Covered by a Fixed-Point\<close>
context stateful_protocol_model
begin
theorem prot_secure_if_fixpoint_covered:
fixes P
assumes FP:
"analyzed (timpl_closure_set (set FP) (set TI))"
"wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
"ground (set FP)"
and OCC:
"\<forall>t \<in> timpl_closure_set (set FP) (set TI). \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
"timpl_closure_set (absc ` set OCC) (set TI) \<subseteq> absc ` set OCC"
and TI:
"set TI = {(a,b) \<in> (set TI)\<^sup>+. a \<noteq> b}"
and M:
"has_all_wt_instances_of \<Gamma> (\<Union>T \<in> set P. trms_transaction T) 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 transactions_covered: "list_all (transaction_check FP OCC TI) P"
and attack_notin_FP: "attack\<langle>n\<rangle> \<notin> set FP"
and A: "\<A> \<in> reachable_constraints P"
shows "\<nexists>\<I>. constraint_model \<I> (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)])"
(is "\<nexists>\<I>. ?P \<A> \<I>")
proof
assume "\<exists>\<I>. ?P \<A> \<I>"
then obtain \<I> where I:
"interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<I>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<I>)"
"constr_sem_stateful \<I> (unlabel (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)]))"
unfolding constraint_model_def by moura
let ?n = "[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)]"
let ?A = "\<A>@?n"
have "\<forall>T \<in> set P. wellformed_transaction T"
"\<forall>T \<in> set P. admissible_transaction_terms T"
using P(1) unfolding admissible_transaction_def by blast+
moreover have "\<forall>T \<in> set P. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
using P(1) unfolding admissible_transaction_def admissible_transaction_terms_def by blast
ultimately have 0: "wf\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>)" "tfr\<^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>)"
using reachable_constraints_tfr[OF _ M P A] reachable_constraints_wf[OF _ _ A] by metis+
have 1: "wf\<^sub>s\<^sub>s\<^sub>t (unlabel ?A)" "tfr\<^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)"
proof -
show "wf\<^sub>s\<^sub>s\<^sub>t (unlabel ?A)"
using 0(1) wf\<^sub>s\<^sub>s\<^sub>t_append_suffix'[of "{}" "unlabel \<A>" "unlabel ?n"] unlabel_append[of \<A> ?n]
by simp
show "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?A)"
using 0(3) trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel ?n"] unlabel_append[of \<A> ?n]
by fastforce
have "\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?n \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ?n). \<exists>c. t = Fun c []"
"\<forall>t \<in> trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?n \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ?n). Ana t = ([],[])"
by (simp_all add: setops\<^sub>s\<^sub>s\<^sub>t_def)
hence "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \<A> \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel \<A>) \<union>
(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ?n \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ?n)))"
using 0(2) tfr_consts_mono unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by blast
hence "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\<A>@?n) \<union> pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel (\<A>@?n)))"
using unlabel_append[of \<A> ?n] trms\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel ?n"]
setops\<^sub>s\<^sub>s\<^sub>t_append[of "unlabel \<A>" "unlabel ?n"]
by (simp add: setops\<^sub>s\<^sub>s\<^sub>t_def)
thus "tfr\<^sub>s\<^sub>s\<^sub>t (unlabel ?A)"
using 0(2) unlabel_append[of ?A ?n]
unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by auto
qed
obtain \<I>\<^sub>\<tau> where I':
"welltyped_constraint_model \<I>\<^sub>\<tau> ?A"
using stateful_typing_result[OF 1 I(1,3)]
by (metis welltyped_constraint_model_def constraint_model_def)
note a = FP OCC TI P(1) transactions_covered attack_notin_FP A
show False
using prot_secure_if_fixpoint_covered_typed[OF a] I'
by force
qed
end
subsection \<open>Automatic Fixed-Point Computation\<close>
context stateful_protocol_model
begin
definition compute_fixpoint_fun' where
"compute_fixpoint_fun' P (n::nat option) enable_traces S0 \<equiv>
let sy = intruder_synth_mod_timpls;
FP' = \<lambda>S. fst (fst S);
TI' = \<lambda>S. snd (fst S);
OCC' = \<lambda>S. remdups (
(map (\<lambda>t. the_Abs (the_Fun (args t ! 1)))
(filter (\<lambda>t. is_Fun t \<and> the_Fun t = OccursFact) (FP' S)))@
(map snd (TI' S)));
equal_states = \<lambda>S S'. set (FP' S) = set (FP' S') \<and> set (TI' S) = set (TI' S');
trace' = \<lambda>S. snd S;
close = \<lambda>M f. let g = remdups \<circ> f in while (\<lambda>A. set (g A) \<noteq> set A) g M;
close' = \<lambda>M f. let g = remdups \<circ> f in while (\<lambda>A. set (g A) \<noteq> set A) g M;
trancl_minus_refl = \<lambda>TI.
let aux = \<lambda>ts p. map (\<lambda>q. (fst p,snd q)) (filter ((=) (snd p) \<circ> fst) ts)
in filter (\<lambda>p. fst p \<noteq> snd p) (close' TI (\<lambda>ts. concat (map (aux ts) ts)@ts));
snd_Ana = \<lambda>N M TI. let N' = filter (\<lambda>t. \<forall>k \<in> set (fst (Ana t)). sy M TI k) N in
filter (\<lambda>t. \<not>sy M TI t)
(concat (map (\<lambda>t. filter (\<lambda>s. s \<in> set (snd (Ana t))) (args t)) N'));
Ana_cl = \<lambda>FP TI.
close FP (\<lambda>M. (M@snd_Ana M M TI));
TI_cl = \<lambda>FP TI.
close FP (\<lambda>M. (M@filter (\<lambda>t. \<not>sy M TI t)
(concat (map (\<lambda>m. concat (map (\<lambda>(a,b). \<langle>a --\<guillemotright> b\<rangle>\<langle>m\<rangle>) TI)) M))));
Ana_cl' = \<lambda>FP TI.
let N = \<lambda>M. comp_timpl_closure_list (filter (\<lambda>t. \<exists>k\<in>set (fst (Ana t)). \<not>sy M TI k) M) TI
in close FP (\<lambda>M. M@snd_Ana (N M) M TI);
\<Delta> = \<lambda>S. transaction_check_comp (FP' S) (OCC' S) (TI' S);
result = \<lambda>S T \<delta>.
let not_fresh = \<lambda>x. x \<notin> set (transaction_fresh T);
xs = filter not_fresh (fv_list\<^sub>s\<^sub>s\<^sub>t (unlabel (transaction_strand T)));
u = \<lambda>\<delta> x. absdbupd (unlabel (transaction_strand T)) x (\<delta> x)
in (remdups (filter (\<lambda>t. \<not>sy (FP' S) (TI' S) t)
(map (\<lambda>t. the_msg t \<cdot> (absc \<circ> u \<delta>))
(filter is_Send (unlabel (transaction_send T))))),
remdups (filter (\<lambda>s. fst s \<noteq> snd s) (map (\<lambda>x. (\<delta> x, u \<delta> x)) xs)));
update_state = \<lambda>S. if list_ex (\<lambda>t. is_Fun t \<and> is_Attack (the_Fun t)) (FP' S) then S
else let results = map (\<lambda>T. map (\<lambda>\<delta>. result S T (abs_substs_fun \<delta>)) (\<Delta> S T)) P;
newtrace_flt = (\<lambda>n. let x = results ! n; y = map fst x; z = map snd x
in set (concat y) - set (FP' S) \<noteq> {} \<or> set (concat z) - set (TI' S) \<noteq> {});
trace =
if enable_traces
then trace' S@[filter newtrace_flt [0..<length results]]
else [];
U = concat results;
V = ((remdups (concat (map fst U)@FP' S),
remdups (filter (\<lambda>x. fst x \<noteq> snd x) (concat (map snd U)@TI' S))),
trace);
W = ((Ana_cl (TI_cl (FP' V) (TI' V)) (TI' V),
trancl_minus_refl (TI' V)),
trace' V)
in if \<not>equal_states W S then W
else ((Ana_cl' (FP' W) (TI' W), TI' W), trace' W);
S = ((\<lambda>h. case n of None \<Rightarrow> while (\<lambda>S. \<not>equal_states S (h S)) h | Some m \<Rightarrow> h ^^ m)
update_state S0)
in ((FP' S, OCC' S, TI' S), trace' S)"
definition compute_fixpoint_fun where
"compute_fixpoint_fun P \<equiv> fst (compute_fixpoint_fun' P None False (([],[]),[]))"
end
subsection \<open>Locales for Protocols Proven Secure through Fixed-Point Coverage\<close>
type_synonym ('f,'a,'s) fixpoint_triple =
"('f,'a,'s) prot_term list \<times> 's set list \<times> ('s set \<times> 's set) list"
context stateful_protocol_model
begin
definition "attack_notin_fixpoint (FPT::('fun,'atom,'sets) fixpoint_triple) \<equiv>
list_all (\<lambda>t. \<forall>f \<in> funs_term t. \<not>is_Attack f) (fst FPT)"
definition "protocol_covered_by_fixpoint (FPT::('fun,'atom,'sets) fixpoint_triple) P \<equiv>
let (FP, OCC, TI) = FPT
in list_all (transaction_check FP OCC TI) P"
definition "analyzed_fixpoint (FPT::('fun,'atom,'sets) fixpoint_triple) \<equiv>
let (FP, _, TI) = FPT
in analyzed_closed_mod_timpls FP TI"
definition "wellformed_protocol' (P::('fun,'atom,'sets,'lbl) prot) N \<equiv>
list_all admissible_transaction P \<and>
has_all_wt_instances_of \<Gamma> (\<Union>T \<in> set P. trms_transaction T) (set N) \<and>
comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \<Gamma> N \<and>
list_all (\<lambda>T. list_all (comp_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<Gamma> Pair) (unlabel (transaction_strand T))) P"
definition "wellformed_protocol (P::('fun,'atom,'sets,'lbl) prot) \<equiv>
let f = \<lambda>M. remdups (concat (map subterms_list M@map (fst \<circ> Ana) M));
N0 = remdups (concat (map (trms_list\<^sub>s\<^sub>s\<^sub>t \<circ> unlabel \<circ> transaction_strand) P));
N = while (\<lambda>A. set (f A) \<noteq> set A) f N0
in wellformed_protocol' P N"
definition "wellformed_fixpoint (FPT::('fun,'atom,'sets) fixpoint_triple) \<equiv>
let (FP, OCC, TI) = FPT; OCC' = set OCC
in list_all (\<lambda>t. wf\<^sub>t\<^sub>r\<^sub>m' arity t \<and> fv t = {}) FP \<and>
list_all (\<lambda>a. a \<in> OCC') (map snd TI) \<and>
list_all (\<lambda>(a,b). list_all (\<lambda>(c,d). b = c \<and> a \<noteq> d \<longrightarrow> List.member TI (a,d)) TI) TI \<and>
list_all (\<lambda>p. fst p \<noteq> snd p) TI \<and>
list_all (\<lambda>t. \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> the_Abs f \<in> OCC') FP"
lemma protocol_covered_by_fixpoint_I1[intro]:
assumes "list_all (protocol_covered_by_fixpoint FPT) P"
shows "protocol_covered_by_fixpoint FPT (concat P)"
using assms by (auto simp add: protocol_covered_by_fixpoint_def list_all_iff)
lemma protocol_covered_by_fixpoint_I2[intro]:
assumes "protocol_covered_by_fixpoint FPT P1"
and "protocol_covered_by_fixpoint FPT P2"
shows "protocol_covered_by_fixpoint FPT (P1@P2)"
using assms by (auto simp add: protocol_covered_by_fixpoint_def)
lemma protocol_covered_by_fixpoint_I3[intro]:
assumes "\<forall>T \<in> set P. \<forall>\<delta>::('fun,'atom,'sets) prot_var \<Rightarrow> 'sets set.
transaction_check_pre FP TI T \<delta> \<longrightarrow> transaction_check_post FP TI T \<delta>"
shows "protocol_covered_by_fixpoint (FP,OCC,TI) P"
using assms
unfolding protocol_covered_by_fixpoint_def transaction_check_def transaction_check_comp_def
list_all_iff Let_def case_prod_unfold Product_Type.fst_conv Product_Type.snd_conv
by fastforce
lemmas protocol_covered_by_fixpoint_intros =
protocol_covered_by_fixpoint_I1
protocol_covered_by_fixpoint_I2
protocol_covered_by_fixpoint_I3
lemma prot_secure_if_prot_checks:
fixes P::"('fun, 'atom, 'sets, 'lbl) prot_transaction list"
and FP_OCC_TI:: "('fun, 'atom, 'sets) fixpoint_triple"
assumes attack_notin_fixpoint: "attack_notin_fixpoint FP_OCC_TI"
and transactions_covered: "protocol_covered_by_fixpoint FP_OCC_TI P"
and analyzed_fixpoint: "analyzed_fixpoint FP_OCC_TI"
and wellformed_protocol: "wellformed_protocol' P N"
and wellformed_fixpoint: "wellformed_fixpoint FP_OCC_TI"
shows "\<forall>\<A> \<in> reachable_constraints P. \<nexists>\<I>. constraint_model \<I> (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)])"
proof -
define FP where "FP \<equiv> let (FP,_,_) = FP_OCC_TI in FP"
define OCC where "OCC \<equiv> let (_,OCC,_) = FP_OCC_TI in OCC"
define TI where "TI \<equiv> let (_,_,TI) = FP_OCC_TI in TI"
have attack_notin_FP: "attack\<langle>n\<rangle> \<notin> set FP"
using attack_notin_fixpoint[unfolded attack_notin_fixpoint_def]
unfolding list_all_iff FP_def by force
have 1: "\<forall>(a,b) \<in> set TI. \<forall>(c,d) \<in> set TI. b = c \<and> a \<noteq> d \<longrightarrow> (a,d) \<in> set TI"
using wellformed_fixpoint
unfolding wellformed_fixpoint_def wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_code[symmetric] Let_def TI_def
list_all_iff member_def case_prod_unfold
by auto
have 0: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set FP)"
and 2: "\<forall>(a,b) \<in> set TI. a \<noteq> b"
and 3: "snd ` set TI \<subseteq> set OCC"
and 4: "\<forall>t \<in> set FP. \<forall>f \<in> funs_term t. is_Abs f \<longrightarrow> f \<in> Abs ` set OCC"
and 5: "ground (set FP)"
using wellformed_fixpoint
unfolding wellformed_fixpoint_def wf\<^sub>t\<^sub>r\<^sub>m_code[symmetric] is_Abs_def the_Abs_def
list_all_iff Let_def case_prod_unfold set_map FP_def OCC_def TI_def
by (fast, fast, blast, fastforce, simp)
have 8: "finite (set N)"
and 9: "has_all_wt_instances_of \<Gamma> (\<Union>T \<in> set P. trms_transaction T) (set N)"
and 10: "tfr\<^sub>s\<^sub>e\<^sub>t (set N)"
and 11: "\<forall>T \<in> set P. list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (transaction_strand T))"
and 12: "\<forall>T \<in> set P. admissible_transaction T"
using wellformed_protocol tfr\<^sub>s\<^sub>e\<^sub>t_if_comp_tfr\<^sub>s\<^sub>e\<^sub>t[of N]
unfolding Let_def list_all_iff wellformed_protocol_def wellformed_protocol'_def
wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_code[symmetric] tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p_is_comp_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p[symmetric]
by fast+
have 13: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set N)"
using wellformed_protocol
unfolding wellformed_protocol_def wellformed_protocol'_def
wf\<^sub>t\<^sub>r\<^sub>m_code[symmetric] comp_tfr\<^sub>s\<^sub>e\<^sub>t_def list_all_iff
finite_SMP_representation_def
by blast
note TI0 = trancl_eqI'[OF 1 2]
have "analyzed (timpl_closure_set (set FP) (set TI))"
using analyzed_fixpoint[unfolded analyzed_fixpoint_def]
analyzed_closed_mod_timpls_is_analyzed_timpl_closure_set[OF TI0 0]
unfolding FP_def TI_def
by force
note FP0 = this 0 5
note OCC0 = funs_term_OCC_TI_subset(1)[OF 4 3]
timpl_closure_set_supset'[OF funs_term_OCC_TI_subset(2)[OF 4 3]]
note M0 = 9 8 10 13
have "list_all (transaction_check FP OCC TI) P"
using transactions_covered[unfolded protocol_covered_by_fixpoint_def]
unfolding FP_def OCC_def TI_def
by force
note P0 = 12 11 this attack_notin_FP
show ?thesis by (metis prot_secure_if_fixpoint_covered[OF FP0 OCC0 TI0 M0 P0])
qed
end
locale secure_stateful_protocol =
pm: stateful_protocol_model arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2
for 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"
+
fixes P::"('fun, 'atom, 'sets, 'lbl) prot_transaction list"
and FP_OCC_TI:: "('fun, 'atom, 'sets) fixpoint_triple"
and P_SMP::"('fun, 'atom, 'sets) prot_term list"
assumes attack_notin_fixpoint: "pm.attack_notin_fixpoint FP_OCC_TI"
and transactions_covered: "pm.protocol_covered_by_fixpoint FP_OCC_TI P"
and analyzed_fixpoint: "pm.analyzed_fixpoint FP_OCC_TI"
and wellformed_protocol: "pm.wellformed_protocol' P P_SMP"
and wellformed_fixpoint: "pm.wellformed_fixpoint FP_OCC_TI"
begin
theorem protocol_secure:
"\<forall>\<A> \<in> pm.reachable_constraints P. \<nexists>\<I>. pm.constraint_model \<I> (\<A>@[(l, send\<langle>attack\<langle>n\<rangle>\<rangle>)])"
by (rule pm.prot_secure_if_prot_checks[OF
attack_notin_fixpoint transactions_covered
analyzed_fixpoint wellformed_protocol wellformed_fixpoint])
end
locale secure_stateful_protocol' =
pm: stateful_protocol_model arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2
for 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"
+
fixes P::"('fun, 'atom, 'sets, 'lbl) prot_transaction list"
and FP_OCC_TI:: "('fun, 'atom, 'sets) fixpoint_triple"
assumes attack_notin_fixpoint': "pm.attack_notin_fixpoint FP_OCC_TI"
and transactions_covered': "pm.protocol_covered_by_fixpoint FP_OCC_TI P"
and analyzed_fixpoint': "pm.analyzed_fixpoint FP_OCC_TI"
and wellformed_protocol': "pm.wellformed_protocol P"
and wellformed_fixpoint': "pm.wellformed_fixpoint FP_OCC_TI"
begin
sublocale secure_stateful_protocol
arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2 P
FP_OCC_TI
"let f = \<lambda>M. remdups (concat (map subterms_list M@map (fst \<circ> pm.Ana) M));
N0 = remdups (concat (map (trms_list\<^sub>s\<^sub>s\<^sub>t \<circ> unlabel \<circ> transaction_strand) P))
in while (\<lambda>A. set (f A) \<noteq> set A) f N0"
apply unfold_locales
using attack_notin_fixpoint' transactions_covered' analyzed_fixpoint'
wellformed_protocol'[unfolded pm.wellformed_protocol_def Let_def] wellformed_fixpoint'
unfolding Let_def by blast+
end
locale secure_stateful_protocol'' =
pm: stateful_protocol_model arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2
for 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"
+
fixes P::"('fun, 'atom, 'sets, 'lbl) prot_transaction list"
assumes checks: "let FPT = pm.compute_fixpoint_fun P
in pm.attack_notin_fixpoint FPT \<and> pm.protocol_covered_by_fixpoint FPT P \<and>
pm.analyzed_fixpoint FPT \<and> pm.wellformed_protocol P \<and> pm.wellformed_fixpoint FPT"
begin
sublocale secure_stateful_protocol'
arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2 P "pm.compute_fixpoint_fun P"
using checks[unfolded Let_def case_prod_unfold] by unfold_locales meson+
end
locale secure_stateful_protocol''' =
pm: stateful_protocol_model arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2
for 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"
+
fixes P::"('fun, 'atom, 'sets, 'lbl) prot_transaction list"
and FP_OCC_TI:: "('fun, 'atom, 'sets) fixpoint_triple"
and P_SMP::"('fun, 'atom, 'sets) prot_term list"
assumes checks': "let P' = P; FPT = FP_OCC_TI; P'_SMP = P_SMP
in pm.attack_notin_fixpoint FPT \<and>
pm.protocol_covered_by_fixpoint FPT P' \<and>
pm.analyzed_fixpoint FPT \<and>
pm.wellformed_protocol' P' P'_SMP \<and>
pm.wellformed_fixpoint FPT"
begin
sublocale secure_stateful_protocol
arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2 P FP_OCC_TI P_SMP
using checks'[unfolded Let_def case_prod_unfold] by unfold_locales meson+
end
locale secure_stateful_protocol'''' =
pm: stateful_protocol_model arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2
for 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"
+
fixes P::"('fun, 'atom, 'sets, 'lbl) prot_transaction list"
and FP_OCC_TI:: "('fun, 'atom, 'sets) fixpoint_triple"
assumes checks'': "let P' = P; FPT = FP_OCC_TI
in pm.attack_notin_fixpoint FPT \<and>
pm.protocol_covered_by_fixpoint FPT P' \<and>
pm.analyzed_fixpoint FPT \<and>
pm.wellformed_protocol P' \<and>
pm.wellformed_fixpoint FPT"
begin
sublocale secure_stateful_protocol'
arity\<^sub>f arity\<^sub>s public\<^sub>f Ana\<^sub>f \<Gamma>\<^sub>f label_witness1 label_witness2 P FP_OCC_TI
using checks''[unfolded Let_def case_prod_unfold] by unfold_locales meson+
end
subsection \<open>Automatic Protocol Composition\<close>
context stateful_protocol_model
begin
definition wellformed_composable_protocols where
"wellformed_composable_protocols (P::('fun,'atom,'sets,'lbl) prot list) N \<equiv>
let
Ts = concat P;
steps = concat (map transaction_strand Ts);
MP0 = \<Union>T \<in> set Ts. trms_transaction T \<union> pair' Pair ` setops_transaction T
in
list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) N \<and>
has_all_wt_instances_of \<Gamma> MP0 (set N) \<and>
comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \<Gamma> N \<and>
list_all (comp_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p \<Gamma> Pair \<circ> snd) steps \<and>
list_all (\<lambda>T. wellformed_transaction T) Ts \<and>
list_all (\<lambda>T. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)) Ts \<and>
list_all (\<lambda>T. list_all (\<lambda>x. \<Gamma>\<^sub>v x = TAtom Value) (transaction_fresh T)) Ts"
definition composable_protocols where
"composable_protocols (P::('fun,'atom,'sets,'lbl) prot list) Ms S \<equiv>
let
Ts = concat P;
steps = concat (map transaction_strand Ts);
MP0 = \<Union>T \<in> set Ts. trms_transaction T \<union> pair' Pair ` setops_transaction T;
M_fun = (\<lambda>l. case find ((=) l \<circ> fst) Ms of Some M \<Rightarrow> snd M | None \<Rightarrow> [])
in comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t public arity Ana \<Gamma> Pair steps M_fun S"
lemma composable_protocols_par_comp_constr:
fixes S f
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 "Sec \<equiv> (f (set S)) - {m. intruder_synth {} m}"
assumes Ps_pc: "wellformed_composable_protocols Ps N" "composable_protocols Ps Ms S"
shows "\<forall>\<A> \<in> reachable_constraints (concat Ps). \<forall>\<I>. constraint_model \<I> \<A> \<longrightarrow>
(\<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>)))"
(is "\<forall>\<A> \<in> _. \<forall>_. _ \<longrightarrow> ?Q \<A> \<I>")
proof (intro allI ballI impI)
fix \<A> \<I>
assume \<A>: "\<A> \<in> reachable_constraints (concat Ps)" and \<I>: "constraint_model \<I> \<A>"
let ?Ts = "concat Ps"
let ?steps = "concat (map transaction_strand ?Ts)"
let ?MP0 = "\<Union>T \<in> set ?Ts. trms_transaction T \<union> pair' Pair ` setops_transaction T"
let ?M_fun = "\<lambda>l. case find ((=) l \<circ> fst) Ms of Some M \<Rightarrow> snd M | None \<Rightarrow> []"
have M:
"has_all_wt_instances_of \<Gamma> ?MP0 (set N)"
"finite (set N)" "tfr\<^sub>s\<^sub>e\<^sub>t (set N)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set N)"
using Ps_pc tfr\<^sub>s\<^sub>e\<^sub>t_if_comp_tfr\<^sub>s\<^sub>e\<^sub>t[of N]
unfolding composable_protocols_def wellformed_composable_protocols_def
Let_def list_all_iff wf\<^sub>t\<^sub>r\<^sub>m_code[symmetric]
by fast+
have P:
"\<forall>T \<in> set ?Ts. wellformed_transaction T"
"\<forall>T \<in> set ?Ts. wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s' arity (trms_transaction T)"
"\<forall>T \<in> set ?Ts. \<forall>x \<in> set (transaction_fresh T). \<Gamma>\<^sub>v x = TAtom Value"
"\<forall>T \<in> set ?Ts. 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 ?steps ?M_fun S"
using Ps_pc tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p_is_comp_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p
unfolding wellformed_composable_protocols_def composable_protocols_def
Let_def list_all_iff unlabel_def wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_code[symmetric]
by (meson, meson, meson, fastforce, blast)
show "?Q \<A> \<I>"
using reachable_constraints_par_comp_constr[OF M P \<A> \<I>]
unfolding Sec_def f_def by fast
qed
end
end