(* (C) Copyright Andreas Viktor Hess, DTU, 2018-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_Compositionality.thy Author: Andreas Viktor Hess, DTU *) section \Stateful Protocol Compositionality\ text \\label{Stateful-Compositionality}\ theory Stateful_Compositionality imports Stateful_Typing Parallel_Compositionality Labeled_Stateful_Strands begin subsection \Small Lemmata\ lemma (in typed_model) wt_subst_sstp_vars_type_subset: fixes a::"('fun,'var) stateful_strand_step" assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and "\t \ subst_range \. fv t = {} \ (\x. t = Var x)" shows "\ ` Var ` fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \) \ \ ` Var ` fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" (is ?A) and "\ ` Var ` set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)) = \ ` Var ` set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a)" (is ?B) and "\ ` Var ` vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \) \ \ ` Var ` vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" (is ?C) proof - show ?A proof fix \ assume \: "\ \ \ ` Var ` fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" then obtain x where x: "x \ fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" "\ (Var x) = \" by moura show "\ \ \ ` Var ` fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" proof (cases "x \ fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p a") case False hence "\y \ fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p a. \ y = Var x" proof (cases a) case (NegChecks X F G) hence *: "x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (F \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (G \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \)" "x \ set X" using fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p_NegCheck(1)[of X "F \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \" "G \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \"] fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p_NegCheck(1)[of X F G] False x(1) by fastforce+ obtain y where y: "y \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s G" "x \ fv (rm_vars (set X) \ y)" using fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subst_obtain_var[of _ _ "rm_vars (set X) \"] fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subst_obtain_var[of _ _ "rm_vars (set X) \"] *(1) by blast have "fv (rm_vars (set X) \ z) = {} \ (\u. rm_vars (set X) \ z = Var u)" for z using assms(2) rm_vars_img_subset[of "set X" \] by blast hence "rm_vars (set X) \ y = Var x" using y(2) by fastforce hence "\y \ fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p a. rm_vars (set X) \ y = Var x" using y fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p_NegCheck(1)[of X F G] NegChecks *(2) by fastforce thus ?thesis by (metis (full_types) *(2) term.inject(1)) qed (use assms(2) x(1) subst_apply_img_var'[of x _ \] in fastforce)+ then obtain y where y: "y \ fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" "\ y = Var x" by moura hence "\ (Var y) = \" using x(2) assms(1) by (simp add: wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) thus ?thesis using y(1) by auto qed (use x in auto) qed show ?B by (metis bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p_subst) show ?C proof fix \ assume \: "\ \ \ ` Var ` vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" then obtain x where x: "x \ vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" "\ (Var x) = \" by moura show "\ \ \ ` Var ` vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" proof (cases "x \ vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a") case False hence "\y \ vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a. \ y = Var x" proof (cases a) case (NegChecks X F G) hence *: "x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (F \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (G \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \)" "x \ set X" using vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p_NegCheck[of X "F \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \" "G \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s rm_vars (set X) \"] vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p_NegCheck[of X F G] False x(1) by (fastforce, blast) obtain y where y: "y \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s G" "x \ fv (rm_vars (set X) \ y)" using fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subst_obtain_var[of _ _ "rm_vars (set X) \"] fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subst_obtain_var[of _ _ "rm_vars (set X) \"] *(1) by blast have "fv (rm_vars (set X) \ z) = {} \ (\u. rm_vars (set X) \ z = Var u)" for z using assms(2) rm_vars_img_subset[of "set X" \] by blast hence "rm_vars (set X) \ y = Var x" using y(2) by fastforce hence "\y \ vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a. rm_vars (set X) \ y = Var x" using y vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p_NegCheck[of X F G] NegChecks by blast thus ?thesis by (metis (full_types) *(2) term.inject(1)) qed (use assms(2) x(1) subst_apply_img_var'[of x _ \] in fastforce)+ then obtain y where y: "y \ vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" "\ y = Var x" by moura hence "\ (Var y) = \" using x(2) assms(1) by (simp add: wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) thus ?thesis using y(1) by auto qed (use x in auto) qed qed lemma (in typed_model) wt_subst_lsst_vars_type_subset: fixes A::"('fun,'var,'a) labeled_stateful_strand" assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and "\t \ subst_range \. fv t = {} \ (\x. t = Var x)" shows "\ ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) \ \ ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" (is ?A) and "\ ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = \ ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" (is ?B) and "\ ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) \ \ ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" (is ?C) proof - have "vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \) \ vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" "vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p b \ vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p (b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \) \ fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p b \ fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)) \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p b) \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" when "a = (l,b)" for a l b and A::"('fun,'var,'a) labeled_stateful_strand" using that unlabel_Cons(1)[of l b A] unlabel_subst[of "a#A" \] subst_lsst_cons[of a A \] subst_sst_cons[of b "unlabel A" \] subst_apply_labeled_stateful_strand_step.simps(1)[of l b \] vars\<^sub>s\<^sub>s\<^sub>t_unlabel_Cons[of l b A] vars\<^sub>s\<^sub>s\<^sub>t_unlabel_Cons[of l "b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \" "A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \"] fv\<^sub>s\<^sub>s\<^sub>t_unlabel_Cons[of l b A] fv\<^sub>s\<^sub>s\<^sub>t_unlabel_Cons[of l "b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \" "A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \"] bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_Cons[of l b A] bvars\<^sub>s\<^sub>s\<^sub>t_unlabel_Cons[of l "b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \" "A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \"] by simp_all hence *: "\ ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = \ ` Var ` vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \) \ \ ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" "\ ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = \ ` Var ` vars\<^sub>s\<^sub>s\<^sub>t\<^sub>p b \ \ ` Var ` vars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "\ ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = \ ` Var ` fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p (b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \) \ \ ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" "\ ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = \ ` Var ` fv\<^sub>s\<^sub>s\<^sub>t\<^sub>p b \ \ ` Var ` fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "\ ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = \ ` Var ` set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (b \\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)) \ \ ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" "\ ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = \ ` Var ` set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p b) \ \ ` Var ` bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" when "a = (l,b)" for a l b and A::"('fun,'var,'a) labeled_stateful_strand" using that by fast+ have "?A \ ?B \ ?C" proof (induction A) case (Cons a A) obtain l b where a: "a = (l,b)" by (metis surj_pair) show ?case using Cons.IH wt_subst_sstp_vars_type_subset[OF assms, of b] *[OF a, of A] by (metis Un_mono) qed simp thus ?A ?B ?C by metis+ qed lemma (in stateful_typed_model) fv_pair_fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subset: assumes "d \ set D" shows "fv (pair (snd d)) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" using assms unfolding pair_def by (induct D) (auto simp add: unlabel_def) lemma (in stateful_typed_model) labeled_sat_ineq_lift: assumes "\M; map (\d. \X\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\dbproj i D. d \ set Di]\\<^sub>d \" (is "?R1 D") and "\(j,p) \ {(i,t,s)} \ set D \ set Di. \(k,q) \ {(i,t,s)} \ set D \ set Di. (\\. Unifier \ (pair p) (pair q)) \ j = k" (is "?R2 D") shows "\M; map (\d. \X\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\D. d \ set Di]\\<^sub>d \" using assms proof (induction D) case (Cons dl D) obtain d l where dl: "dl = (l,d)" by (metis surj_pair) have 1: "?R1 D" proof (cases "i = l") case True thus ?thesis using Cons.prems(1) dl by (cases "dl \ set Di") auto next case False thus ?thesis using Cons.prems(1) dl by auto qed have "set D \ set (dl#D)" by auto hence 2: "?R2 D" using Cons.prems(2) by blast have "i \ l \ dl \ set Di \ \M; [\X\\\: [(pair (t,s), pair (snd dl))]\\<^sub>s\<^sub>t]\\<^sub>d \" using Cons.prems(1) dl by (auto simp add: ineq_model_def) moreover have "\\. Unifier \ (pair (t,s)) (pair d) \ i = l" using Cons.prems(2) dl by force ultimately have 3: "dl \ set Di \ \M; [\X\\\: [(pair (t,s), pair (snd dl))]\\<^sub>s\<^sub>t]\\<^sub>d \" using strand_sem_not_unif_is_sat_ineq[of "pair (t,s)" "pair d"] dl by fastforce show ?case using Cons.IH[OF 1 2] 3 dl by auto qed simp lemma (in stateful_typed_model) labeled_sat_ineq_dbproj: assumes "\M; map (\d. \X\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\D. d \ set Di]\\<^sub>d \" (is "?P D") shows "\M; map (\d. \X\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\dbproj i D. d \ set Di]\\<^sub>d \" (is "?Q D") using assms proof (induction D) case (Cons di D) obtain d j where di: "di = (j,d)" by (metis surj_pair) have "?P D" using Cons.prems by (cases "di \ set Di") auto hence IH: "?Q D" by (metis Cons.IH) show ?case using di IH proof (cases "i = j \ di \ set Di") case True have 1: "\M; [\X\\\: [(pair (t,s), pair (snd di))]\\<^sub>s\<^sub>t]\\<^sub>d \" using Cons.prems True by auto have 2: "dbproj i (di#D) = di#dbproj i D" using True dbproj_Cons(1) di by auto show ?thesis using 1 2 IH by auto qed auto qed simp lemma (in stateful_typed_model) labeled_sat_ineq_dbproj_sem_equiv: assumes "\(j,p) \ ((\(t, s). (i, t, s)) ` set F') \ set D. \(k,q) \ ((\(t, s). (i, t, s)) ` set F') \ set D. (\\. Unifier \ (pair p) (pair q)) \ j = k" and "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (map snd D) \ set X = {}" shows "\M; map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D))\\<^sub>d \ \ \M; map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))\\<^sub>d \" proof - let ?A = "set (map snd D) \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \" let ?B = "set (map snd (dbproj i D)) \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \" let ?C = "set (map snd D) - set (map snd (dbproj i D))" let ?F = "(\(t, s). (i, t, s)) ` set F'" let ?P = "\\. subst_domain \ = set X \ ground (subst_range \)" have 1: "\(t, t') \ set (map snd D). (fv t \ fv t') \ set X = {}" "\(t, t') \ set (map snd (dbproj i D)). (fv t \ fv t') \ set X = {}" using assms(2) dbproj_subset[of i D] unfolding unlabel_def by force+ have 2: "?B \ ?A" by auto have 3: "\Unifier \ (pair f) (pair d)" when f: "f \ set F'" and d: "d \ set (map snd D) - set (map snd (dbproj i D))" for f d and \::"('fun,'var) subst" proof - obtain k where k: "(k,d) \ set D - set (dbproj i D)" using d by force have "(i,f) \ ((\(t, s). (i, t, s)) ` set F') \ set D" "(k,d) \ ((\(t, s). (i, t, s)) ` set F') \ set D" using f k by auto hence "i = k" when "Unifier \ (pair f) (pair d)" for \ using assms(1) that by blast moreover have "k \ i" using k d by simp ultimately show ?thesis by metis qed have "f \\<^sub>p \ \ d \\<^sub>p \" when "f \ set F'" "d \ ?C" for f d and \::"('fun,'var) subst" by (metis fun_pair_eq_subst 3[OF that]) hence "f \\<^sub>p (\ \\<^sub>s \) \ ?C \\<^sub>p\<^sub>s\<^sub>e\<^sub>t (\ \\<^sub>s \)" when "f \ set F'" for f and \::"('fun,'var) subst" using that by blast moreover have "?C \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \ \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \ = ?C \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \" when "?P \" for \ using assms(2) that pairs_substI[of \ "(set (map snd D) - set (map snd (dbproj i D)))"] by blast ultimately have 4: "f \\<^sub>p (\ \\<^sub>s \) \ ?C \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \" when "f \ set F'" "?P \" for f and \::"('fun,'var) subst" by (metis that subst_pairs_compose) { fix f and \::"('fun,'var) subst" assume "f \ set F'" "?P \" hence "f \\<^sub>p (\ \\<^sub>s \) \ ?C \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \" by (metis 4) hence "f \\<^sub>p (\ \\<^sub>s \) \ ?A - ?B" by force } hence 5: "\f\set F'. \\. ?P \ \ f \\<^sub>p (\ \\<^sub>s \) \ ?A - ?B" by metis show ?thesis using negchecks_model_db_subset[OF 2] negchecks_model_db_supset[OF 2 5] tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_sem_equiv[OF 1(1)] tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_sem_equiv[OF 1(2)] tr_NegChecks_constr_iff(1) strand_sem_eq_defs(2) by (metis (no_types, lifting)) qed lemma (in stateful_typed_model) labeled_sat_eqs_list_all: assumes "\(j, p) \ {(i,t,s)} \ set D. \(k,q) \ {(i,t,s)} \ set D. (\\. Unifier \ (pair p) (pair q)) \ j = k" (is "?P D") and "\M; map (\d. \ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t) D\\<^sub>d \" (is "?Q D") shows "list_all (\d. fst d = i) D" using assms proof (induction D rule: List.rev_induct) case (snoc di D) obtain d j where di: "di = (j,d)" by (metis surj_pair) have "pair (t,s) \ \ = pair d \ \" using di snoc.prems(2) by auto hence "\\. Unifier \ (pair (t,s)) (pair d)" by auto hence 1: "i = j" using snoc.prems(1) di by fastforce have "set D \ set (D@[di])" by auto hence 2: "?P D" using snoc.prems(1) by blast have 3: "?Q D" using snoc.prems(2) by auto show ?case using di 1 snoc.IH[OF 2 3] by simp qed simp lemma (in stateful_typed_model) labeled_sat_eqs_subseqs: assumes "Di \ set (subseqs D)" and "\(j, p) \ {(i,t,s)} \ set D. \(k, q) \ {(i,t,s)} \ set D. (\\. Unifier \ (pair p) (pair q)) \ j = k" (is "?P D") and "\M; map (\d. \ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t) Di\\<^sub>d \" shows "Di \ set (subseqs (dbproj i D))" proof - have "set Di \ set D" by (rule subseqs_subset[OF assms(1)]) hence "?P Di" using assms(2) by blast thus ?thesis using labeled_sat_eqs_list_all[OF _ assms(3)] subseqs_mem_dbproj[OF assms(1)] by simp qed lemma (in stateful_typed_model) dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p: assumes "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel S)" shows "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t S))" using assms proof (induction S) case (Cons a S) have prems: "tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (snd a)" "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel S)" using Cons.prems unlabel_Cons(2)[of a S] by simp_all hence IH: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t S))" by (metis Cons.IH) obtain l b where a: "a = (l,b)" by (metis surj_pair) with Cons show ?case proof (cases b) case (Equality c t t') hence "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#S) = a#dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t S" by (metis dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_Cons(3) a) thus ?thesis using a IH prems by fastforce next case (NegChecks X F G) hence "dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#S) = a#dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t S" by (metis dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_Cons(7) a) thus ?thesis using a IH prems by fastforce qed auto qed simp lemma (in stateful_typed_model) setops\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq: "setops\<^sub>s\<^sub>s\<^sub>t (unlabel (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)) = setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" proof (induction A) case (Cons a A) obtain l b where a: "a = (l,b)" by (metis surj_pair) thus ?case using Cons.IH by (cases b) (simp_all add: setops\<^sub>s\<^sub>s\<^sub>t_def) qed simp subsection \Locale Setup and Definitions\ locale labeled_stateful_typed_model = stateful_typed_model arity public Ana \ Pair + labeled_typed_model arity public Ana \ label_witness1 label_witness2 for arity::"'fun \ nat" and public::"'fun \ bool" and Ana::"('fun,'var) term \ (('fun,'var) term list \ ('fun,'var) term list)" and \::"('fun,'var) term \ ('fun,'atom::finite) term_type" and Pair::"'fun" and label_witness1::"'lbl" and label_witness2::"'lbl" begin definition lpair where "lpair lp \ case lp of (i,p) \ (i,pair p)" lemma setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_pair_image[simp]: "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,send\t\)) = {}" "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,receive\t\)) = {}" "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,\ac: t \ t'\)) = {}" "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,insert\t,s\)) = {(i, pair (t,s))}" "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,delete\t,s\)) = {(i, pair (t,s))}" "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,\ac: t \ s\)) = {(i, pair (t,s))}" "lpair ` (setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (i,\X\\\: F \\: F'\)) = ((\(t,s). (i, pair (t,s))) ` set F')" unfolding lpair_def by force+ definition par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t where "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (\::('fun,'var,'lbl) labeled_stateful_strand) (Secrets::('fun,'var) terms) \ (\l1 l2. l1 \ l2 \ GSMP_disjoint (trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \)) (trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \)) Secrets) \ ground Secrets \ (\s \ Secrets. \s' \ subterms s. {} \\<^sub>c s' \ s' \ Secrets) \ (\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t \. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t \. (\\. Unifier \ (pair p) (pair q)) \ i = j)" definition declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t where "declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ \ {t. \\, receive\t\\ \ set \} \\<^sub>s\<^sub>e\<^sub>t \" definition strand_leaks\<^sub>l\<^sub>s\<^sub>s\<^sub>t ("_ leaks _ under _") where "(\::('fun,'var,'lbl) labeled_stateful_strand) leaks Secrets under \ \ (\t \ Secrets - declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \. \n. \ \\<^sub>s (proj_unl n \@[send\t\]))" definition typing_cond\<^sub>s\<^sub>s\<^sub>t where "typing_cond\<^sub>s\<^sub>s\<^sub>t \ \ wf\<^sub>s\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>s\<^sub>s\<^sub>t \) \ tfr\<^sub>s\<^sub>s\<^sub>t \" type_synonym ('a,'b,'c) labeleddbstate = "('c strand_label \ (('a,'b) term \ ('a,'b) term)) set" type_synonym ('a,'b,'c) labeleddbstatelist = "('c strand_label \ (('a,'b) term \ ('a,'b) term)) list" text \ For proving the compositionality theorem for stateful constraints the idea is to first define a variant of the reduction technique that was used to establish the stateful typing result. This variant performs database-state projections, and it allows us to reduce the compositionality problem for stateful constraints to ordinary constraints. \ fun tr\<^sub>p\<^sub>c:: "('fun,'var,'lbl) labeled_stateful_strand \ ('fun,'var,'lbl) labeleddbstatelist \ ('fun,'var,'lbl) labeled_strand list" where "tr\<^sub>p\<^sub>c [] D = [[]]" | "tr\<^sub>p\<^sub>c ((i,send\t\)#A) D = map ((#) (i,send\t\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>c A D)" | "tr\<^sub>p\<^sub>c ((i,receive\t\)#A) D = map ((#) (i,receive\t\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>c A D)" | "tr\<^sub>p\<^sub>c ((i,\ac: t \ t'\)#A) D = map ((#) (i,\ac: t \ t'\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>c A D)" | "tr\<^sub>p\<^sub>c ((i,insert\t,s\)#A) D = tr\<^sub>p\<^sub>c A (List.insert (i,(t,s)) D)" | "tr\<^sub>p\<^sub>c ((i,delete\t,s\)#A) D = ( concat (map (\Di. map (\B. (map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d \ set Di])@B) (tr\<^sub>p\<^sub>c A [d\D. d \ set Di])) (subseqs (dbproj i D))))" | "tr\<^sub>p\<^sub>c ((i,\ac: t \ s\)#A) D = concat (map (\B. map (\d. (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#B) (dbproj i D)) (tr\<^sub>p\<^sub>c A D))" | "tr\<^sub>p\<^sub>c ((i,\X\\\: F \\: F' \)#A) D = map ((@) (map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D))))) (tr\<^sub>p\<^sub>c A D)" subsection \Small Lemmata\ lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_nil: assumes "ground Sec" "\s \ Sec. \s'\subterms s. {} \\<^sub>c s' \ s' \ Sec" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t [] Sec" using assms unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by simp lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subset: assumes A: "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A Sec" and BA: "set B \ set A" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t B Sec" proof - let ?L = "\n A. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl n A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl n A)" have "?L n B \ ?L n A" for n using trms\<^sub>s\<^sub>s\<^sub>t_mono[OF proj_set_mono(2)[OF BA]] setops\<^sub>s\<^sub>s\<^sub>t_mono[OF proj_set_mono(2)[OF BA]] by blast hence "GSMP_disjoint (?L m B) (?L n B) Sec" when nm: "m \ n" for n m::'lbl using GSMP_disjoint_subset[of "?L m A" "?L n A" Sec "?L m B" "?L n B"] A nm unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by simp thus "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t B Sec" using A setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_mono[OF BA] unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by blast qed lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_split: assumes "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A@B) Sec" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A Sec" "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t B Sec" using par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subset[OF assms] by simp_all lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_proj: assumes "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A Sec" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj n A) Sec" using par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subset[OF assms] by simp lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t: assumes A: "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A S" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A) S" proof (unfold par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def case_prod_unfold; intro conjI) show "ground S" "\s \ S. \s' \ subterms s. {} \\<^sub>c s' \ s' \ S" using A unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by fast+ let ?M = "\l B. (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj l B) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l B))" let ?P = "\B. \l1 l2. l1 \ l2 \ GSMP_disjoint (?M l1 B) (?M l2 B) S" let ?Q = "\B. \p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. \q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. (\\. Unifier \ (pair (snd p)) (pair (snd q))) \ fst p = fst q" have "?P A" "?Q A" using A unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def case_prod_unfold by blast+ thus "?P (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" "?Q (dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" by (metis setops\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq trms\<^sub>s\<^sub>s\<^sub>t_unlabel_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq proj_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t, metis setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_dual\<^sub>l\<^sub>s\<^sub>s\<^sub>t_eq) qed lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_subst: assumes A: "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A S" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "subst_domain \ \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A = {}" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) S" proof (unfold par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def case_prod_unfold; intro conjI) show "ground S" "\s \ S. \s' \ subterms s. {} \\<^sub>c s' \ s' \ S" using A unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by fast+ let ?N = "\l B. trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj l B) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l B)" define M where "M \ \l (B::('fun,'var,'lbl) labeled_stateful_strand). ?N l B" let ?P = "\p q. \\. Unifier \ (pair (snd p)) (pair (snd q))" let ?Q = "\B. \p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. \q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. ?P p q \ fst p = fst q" let ?R = "\B. \l1 l2. l1 \ l2 \ GSMP_disjoint (?N l1 B) (?N l2 B) S" have d: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj l A) \ subst_domain \ = {}" for l using \(3) unfolding proj_def bvars\<^sub>s\<^sub>s\<^sub>t_def unlabel_def by auto have "GSMP_disjoint (M l1 A) (M l2 A) S" when l: "l1 \ l2" for l1 l2 using l A unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def M_def by presburger moreover have "M l (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) = (M l A) \\<^sub>s\<^sub>e\<^sub>t \" for l using fun_pair_subst_set[of \ "setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l A)", symmetric] trms\<^sub>s\<^sub>s\<^sub>t_subst[OF d[of l]] setops\<^sub>s\<^sub>s\<^sub>t_subst[OF d[of l]] proj_subst[of l A \] unfolding M_def unlabel_subst by auto ultimately have "GSMP_disjoint (M l1 (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)) (M l2 (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)) S" when l: "l1 \ l2" for l1 l2 using l GSMP_wt_subst_subset[OF _ \(1,2), of _ "M l1 A"] GSMP_wt_subst_subset[OF _ \(1,2), of _ "M l2 A"] unfolding GSMP_disjoint_def by fastforce thus "?R (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" unfolding M_def by blast have "?Q A" using A unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by force thus "?Q (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" using \(3) proof (induction A) case (Cons a A) obtain l b where a: "a = (l,b)" by (metis surj_pair) have 0: "bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A) = set (bvars\<^sub>s\<^sub>s\<^sub>t\<^sub>p (snd a)) \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" unfolding bvars\<^sub>s\<^sub>s\<^sub>t_def unlabel_def by simp have "?Q A" "subst_domain \ \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t A = {}" using Cons.prems 0 unfolding setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by auto hence IH: "?Q (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" using Cons.IH unfolding setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by blast have 1: "fst p = fst q" when p: "p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" and q: "q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" and pq: "?P p q" for p q using a p q pq by (cases b) auto have 2: "fst p = fst q" when p: "p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" and q: "q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p (a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \)" and pq: "?P p q" for p q proof - obtain p' X where p': "p' \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "fst p = fst p'" "X \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A)" "snd p = snd p' \\<^sub>p rm_vars X \" using setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_in_subst[OF p] 0 by blast obtain q' Y where q': "q' \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p a" "fst q = fst q'" "Y \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A)" "snd q = snd q' \\<^sub>p rm_vars Y \" using setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p_in_subst[OF q] 0 by blast have "pair (snd p) = pair (snd p') \ \" "pair (snd q) = pair (snd q') \ \" using fun_pair_subst[of "snd p'" "rm_vars X \"] fun_pair_subst[of "snd q'" "rm_vars Y \"] p'(3,4) q'(3,4) Cons.prems(2) rm_vars_apply'[of \ X] rm_vars_apply'[of \ Y] by fastforce+ hence "\\. Unifier \ (pair (snd p')) (pair (snd q'))" using pq Unifier_comp' by metis thus ?thesis using Cons.prems p'(1,2) q'(1,2) by simp qed show ?case by (metis 1 2 IH Un_iff setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_cons subst_lsst_cons) qed simp qed lemma wf_pair_negchecks_map': assumes "wf\<^sub>s\<^sub>t X (unlabel A)" shows "wf\<^sub>s\<^sub>t X (unlabel (map (\G. (i,\Y\\\: (F@G)\\<^sub>s\<^sub>t)) M@A))" using assms by (induct M) auto lemma wf_pair_eqs_ineqs_map': fixes A::"('fun,'var,'lbl) labeled_strand" assumes "wf\<^sub>s\<^sub>t X (unlabel A)" "Di \ set (subseqs (dbproj i D))" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" shows "wf\<^sub>s\<^sub>t X (unlabel ( (map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d \ set Di])@A))" proof - let ?f = "[d\dbproj i D. d \ set Di]" define c1 where c1: "c1 = map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di" define c2 where c2: "c2 = map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) ?f" define c3 where c3: "c3 = map (\d. \check: (pair (t,s)) \ (pair d)\\<^sub>s\<^sub>t) (unlabel Di)" define c4 where c4: "c4 = map (\d. \[]\\\: [(pair (t,s), pair d)]\\<^sub>s\<^sub>t) (unlabel ?f)" have ci_eqs: "c3 = unlabel c1" "c4 = unlabel c2" unfolding c1 c2 c3 c4 unlabel_def by auto have 1: "wf\<^sub>s\<^sub>t X (unlabel (c2@A))" using wf_fun_pair_ineqs_map[OF assms(1)] ci_eqs(2) unlabel_append[of c2 A] c4 by metis have 2: "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel Di) \ X" using assms(3) subseqs_set_subset(1)[OF assms(2)] unfolding unlabel_def by fastforce { fix B::"('fun,'var) strand" assume "wf\<^sub>s\<^sub>t X B" hence "wf\<^sub>s\<^sub>t X (unlabel c1@B)" using 2 unfolding c1 unlabel_def by (induct Di) auto } thus ?thesis using 1 unfolding c1 c2 unlabel_def by simp qed lemma trms\<^sub>s\<^sub>s\<^sub>t_setops\<^sub>s\<^sub>s\<^sub>t_wt_instance_ex: defines "M \ \A. trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" assumes B: "\b \ set B. \a \ set A. \\. b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "\t \ M B. \s \ M A. \\. t = s \ \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" proof let ?P = "\\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" fix t assume "t \ M B" then obtain b where b: "b \ set B" "t \ trms\<^sub>s\<^sub>s\<^sub>t\<^sub>p (snd b) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t\<^sub>p (snd b)" unfolding M_def unfolding unlabel_def trms\<^sub>s\<^sub>s\<^sub>t_def setops\<^sub>s\<^sub>s\<^sub>t_def by auto then obtain a \ where a: "a \ set A" "b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using B by meson note \' = wt_subst_rm_vars[OF \(1)] wf_trms_subst_rm_vars'[OF \(2)] have "t \ M (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" using b(2) a unfolding M_def subst_apply_labeled_stateful_strand_def unlabel_def trms\<^sub>s\<^sub>s\<^sub>t_def setops\<^sub>s\<^sub>s\<^sub>t_def by auto moreover have "\s \ M A. \\. t = s \ \ \ ?P \" when "t \ trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" using trms\<^sub>s\<^sub>s\<^sub>t_unlabel_subst'[OF that] \' unfolding M_def by blast moreover have "\s \ M A. \\. t = s \ \ \ ?P \" when t: "t \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A \\<^sub>s\<^sub>s\<^sub>t \)" proof - obtain p where p: "p \ setops\<^sub>s\<^sub>s\<^sub>t (unlabel A \\<^sub>s\<^sub>s\<^sub>t \)" "t = pair p" using t by blast then obtain q X where q: "q \ setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "p = q \\<^sub>p rm_vars (set X) \" using setops\<^sub>s\<^sub>s\<^sub>t_subst'[OF p(1)] by blast hence "t = pair q \ rm_vars (set X) \" using fun_pair_subst[of q "rm_vars (set X) \"] p(2) by presburger thus ?thesis using \'[of "set X"] q(1) unfolding M_def by blast qed ultimately show "\s \ M A. \\. t = s \ \ \ ?P \" unfolding M_def unlabel_subst by fast qed lemma setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_wt_instance_ex: assumes B: "\b \ set B. \a \ set A. \\. b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "\p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. \q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \\. fst p = fst q \ snd p = snd q \\<^sub>p \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" proof let ?P = "\\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" fix p assume "p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B" then obtain b where b: "b \ set B" "p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p b" unfolding setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by blast then obtain a \ where a: "a \ set A" "b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using B by meson hence p: "p \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t (A \\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" using b(2) unfolding setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def subst_apply_labeled_stateful_strand_def by auto obtain X q where q: "q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "fst p = fst q" "snd p = snd q \\<^sub>p rm_vars X \" using setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_in_subst[OF p] by blast show "\q \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \\. fst p = fst q \ snd p = snd q \\<^sub>p \ \ ?P \" using q wt_subst_rm_vars[OF \(1)] wf_trms_subst_rm_vars'[OF \(2)] by blast qed subsection \Lemmata: Properties of the Constraint Translation Function\ lemma tr_par_labeled_rcv_iff: "B \ set (tr\<^sub>p\<^sub>c A D) \ (i, receive\t\\<^sub>s\<^sub>t) \ set B \ (i, receive\t\) \ set A" by (induct A D arbitrary: B rule: tr\<^sub>p\<^sub>c.induct) auto lemma tr_par_declassified_eq: "B \ set (tr\<^sub>p\<^sub>c A D) \ declassified\<^sub>l\<^sub>s\<^sub>t B I = declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t A I" using tr_par_labeled_rcv_iff unfolding declassified\<^sub>l\<^sub>s\<^sub>t_def declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by simp lemma tr_par_ik_eq: assumes "B \ set (tr\<^sub>p\<^sub>c A D)" shows "ik\<^sub>s\<^sub>t (unlabel B) = ik\<^sub>s\<^sub>s\<^sub>t (unlabel A)" proof - have "{t. \i. (i, receive\t\\<^sub>s\<^sub>t) \ set B} = {t. \i. (i, receive\t\) \ set A}" using tr_par_labeled_rcv_iff[OF assms] by simp moreover have "\C. {t. \i. (i, receive\t\\<^sub>s\<^sub>t) \ set C} = {t. receive\t\\<^sub>s\<^sub>t \ set (unlabel C)}" "\C. {t. \i. (i, receive\t\) \ set C} = {t. receive\t\ \ set (unlabel C)}" unfolding unlabel_def by force+ ultimately show ?thesis by (metis ik\<^sub>s\<^sub>s\<^sub>t_def ik\<^sub>s\<^sub>t_is_rcv_set) qed lemma tr_par_deduct_iff: assumes "B \ set (tr\<^sub>p\<^sub>c A D)" shows "ik\<^sub>s\<^sub>t (unlabel B) \\<^sub>s\<^sub>e\<^sub>t I \ t \ ik\<^sub>s\<^sub>s\<^sub>t (unlabel A) \\<^sub>s\<^sub>e\<^sub>t I \ t" using tr_par_ik_eq[OF assms] by metis lemma tr_par_vars_subset: assumes "A' \ set (tr\<^sub>p\<^sub>c A D)" shows "fv\<^sub>l\<^sub>s\<^sub>t A' \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" (is ?P) and "bvars\<^sub>l\<^sub>s\<^sub>t A' \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A)" (is ?Q) proof - show ?P using assms proof (induction "unlabel A" arbitrary: A A' D rule: strand_sem_stateful_induct) case (ConsIn A' D ac t s AA A A') then obtain i B where iB: "A = (i,\ac: t \ s\)#B" "AA = unlabel B" unfolding unlabel_def by moura then obtain A'' d where *: "d \ set (dbproj i D)" "A' = (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c B D)" using ConsIn.prems(1) by moura hence "fv\<^sub>l\<^sub>s\<^sub>t A'' \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel B) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" "fv (pair (snd d)) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" apply (metis ConsIn.hyps(1)[OF iB(2)]) using fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_mono[OF dbproj_subset[of i D]] fv_pair_fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subset[OF *(1)] by blast thus ?case using * iB unfolding pair_def by auto next case (ConsDel A' D t s AA A A') then obtain i B where iB: "A = (i,delete\t,s\)#B" "AA = unlabel B" unfolding unlabel_def by moura define fltD1 where "fltD1 = (\Di. filter (\d. d \ set Di) D)" define fltD2 where "fltD2 = (\Di. filter (\d. d \ set Di) (dbproj i D))" define constr where "constr = (\Di. (map (\d. (i, \check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i, \[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) (fltD2 Di)))" from iB obtain A'' Di where *: "Di \ set (subseqs (dbproj i D))" "A' = (constr Di)@A''" "A'' \ set (tr\<^sub>p\<^sub>c B (fltD1 Di))" using ConsDel.prems(1) unfolding constr_def fltD1_def fltD2_def by moura hence "fv\<^sub>l\<^sub>s\<^sub>t A'' \ fv\<^sub>s\<^sub>s\<^sub>t AA \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel (fltD1 Di))" unfolding constr_def fltD1_def by (metis ConsDel.hyps(1) iB(2)) hence 1: "fv\<^sub>l\<^sub>s\<^sub>t A'' \ fv\<^sub>s\<^sub>s\<^sub>t AA \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" using fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_mono[of "unlabel (fltD1 Di)" "unlabel D"] unfolding unlabel_def fltD1_def by force have 2: "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel Di) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel (fltD1 Di)) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" using subseqs_set_subset(1)[OF *(1)] unfolding fltD1_def unlabel_def by auto have 5: "fv\<^sub>l\<^sub>s\<^sub>t A' = fv\<^sub>l\<^sub>s\<^sub>t (constr Di) \ fv\<^sub>l\<^sub>s\<^sub>t A''" using * unfolding unlabel_def by force have "fv\<^sub>l\<^sub>s\<^sub>t (constr Di) \ fv t \ fv s \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel Di) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel (fltD1 Di))" unfolding unlabel_def constr_def fltD1_def fltD2_def pair_def by auto hence 3: "fv\<^sub>l\<^sub>s\<^sub>t (constr Di) \ fv t \ fv s \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" using 2 by blast have 4: "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) = fv t \ fv s \ fv\<^sub>s\<^sub>s\<^sub>t AA" using iB by auto have "fv\<^sub>s\<^sub>t (unlabel A') \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" using 1 3 4 5 by blast thus ?case by metis next case (ConsNegChecks A' D X F F' AA A A') then obtain i B where iB: "A = (i,NegChecks X F F')#B" "AA = unlabel B" unfolding unlabel_def by moura define D' where "D' \ \(fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ` set (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (unlabel (dbproj i D))))" define constr where "constr = map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" from iB obtain A'' where *: "A'' \ set (tr\<^sub>p\<^sub>c B D)" "A' = constr@A''" using ConsNegChecks.prems(1) unfolding constr_def by moura hence "fv\<^sub>l\<^sub>s\<^sub>t A'' \ fv\<^sub>s\<^sub>s\<^sub>t AA \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" by (metis ConsNegChecks.hyps(1) iB(2)) hence **: "fv\<^sub>l\<^sub>s\<^sub>t A'' \ fv\<^sub>s\<^sub>s\<^sub>t AA \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" by auto have 1: "fv\<^sub>l\<^sub>s\<^sub>t constr \ (D' \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) - set X" unfolding D'_def constr_def unlabel_def by auto have "set (unlabel (dbproj i D)) \ set (unlabel D)" unfolding unlabel_def by auto hence 2: "D' \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" using tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_vars_subset'[of F' "unlabel (dbproj i D)"] fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_mono unfolding D'_def by blast have 3: "fv\<^sub>l\<^sub>s\<^sub>t A' \ ((fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) - set X) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ fv\<^sub>l\<^sub>s\<^sub>t A''" using 1 2 *(2) unfolding unlabel_def by fastforce have 4: "fv\<^sub>s\<^sub>s\<^sub>t AA \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel A)" by (metis ConsNegChecks.hyps(2) fv\<^sub>s\<^sub>s\<^sub>t_cons_subset) have 5: "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel A)" using ConsNegChecks.hyps(2) unfolding unlabel_def by force show ?case using ** 3 4 5 by blast qed (fastforce simp add: unlabel_def)+ show ?Q using assms apply (induct "unlabel A" arbitrary: A A' D rule: strand_sem_stateful_induct) by (fastforce simp add: unlabel_def)+ qed lemma tr_par_vars_disj: assumes "A' \ set (tr\<^sub>p\<^sub>c A D)" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" and "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" shows "fv\<^sub>l\<^sub>s\<^sub>t A' \ bvars\<^sub>l\<^sub>s\<^sub>t A' = {}" using assms tr_par_vars_subset by fast lemma tr_par_trms_subset: assumes "A' \ set (tr\<^sub>p\<^sub>c A D)" shows "trms\<^sub>l\<^sub>s\<^sub>t A' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" using assms proof (induction A D arbitrary: A' rule: tr\<^sub>p\<^sub>c.induct) case 1 thus ?case by simp next case (2 i t A D) then obtain A'' where A'': "A' = (i,send\t\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" by moura hence "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" by (metis "2.IH") thus ?case using A'' by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) next case (3 i t A D) then obtain A'' where A'': "A' = (i,receive\t\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" by moura hence "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" by (metis "3.IH") thus ?case using A'' by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) next case (4 i ac t t' A D) then obtain A'' where A'': "A' = (i,\ac: t \ t'\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" by moura hence "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" by (metis "4.IH") thus ?case using A'' by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) next case (5 i t s A D) hence "A' \ set (tr\<^sub>p\<^sub>c A (List.insert (i,t,s) D))" by simp hence "trms\<^sub>l\<^sub>s\<^sub>t A' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set (List.insert (i,t,s) D)" by (metis "5.IH") thus ?case by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) next case (6 i t s A D) from 6 obtain Di A'' B C where A'': "Di \ set (subseqs (dbproj i D))" "A'' \ set (tr\<^sub>p\<^sub>c A [d\D. d \ set Di])" "A' = (B@C)@A''" "B = map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di" "C = map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d \ set Di]" by moura hence "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set [d\D. d \ set Di]" by (metis "6.IH") moreover have "set [d\D. d \ set Di] \ set D" using set_filter by auto ultimately have "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" by blast hence "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel ((i,delete\t,s\)#A)) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ((i,delete\t,s\)#A)) \ pair ` snd ` set D" using setops\<^sub>s\<^sub>s\<^sub>t_cons_subset trms\<^sub>s\<^sub>s\<^sub>t_cons by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) moreover have "set Di \ set D" "set [d\dbproj i D . d \ set Di] \ set D" using subseqs_set_subset[OF A''(1)] by auto hence "trms\<^sub>s\<^sub>t (unlabel B) \ insert (pair (t, s)) (pair ` snd ` set D)" "trms\<^sub>s\<^sub>t (unlabel C) \ insert (pair (t, s)) (pair ` snd ` set D)" using A''(4,5) unfolding unlabel_def by auto hence "trms\<^sub>s\<^sub>t (unlabel (B@C)) \ insert (pair (t,s)) (pair ` snd ` set D)" using unlabel_append[of B C] by auto moreover have "pair (t,s) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (delete\t,s\#unlabel A)" by (simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) ultimately show ?case using A''(3) trms\<^sub>s\<^sub>t_append[of "unlabel (B@C)" "unlabel A'"] unlabel_append[of "B@C" A''] by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) next case (7 i ac t s A D) from 7 obtain d A'' where A'': "d \ set (dbproj i D)" "A'' \ set (tr\<^sub>p\<^sub>c A D)" "A' = (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#A''" by moura hence "trms\<^sub>l\<^sub>s\<^sub>t A'' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" by (metis "7.IH") moreover have "trms\<^sub>s\<^sub>t (unlabel A') = {pair (t,s), pair (snd d)} \ trms\<^sub>s\<^sub>t (unlabel A'')" using A''(1,3) by auto ultimately show ?case using A''(1) by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) next case (8 i X F F' A D) define constr where "constr = map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" define B where "B \ \(trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ` set (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D))))" from 8 obtain A'' where A'': "A'' \ set (tr\<^sub>p\<^sub>c A D)" "A' = constr@A''" unfolding constr_def by moura have "trms\<^sub>s\<^sub>t (unlabel A'') \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair`snd`set D" by (metis A''(1) "8.IH") moreover have "trms\<^sub>s\<^sub>t (unlabel constr) \ B \ trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ pair ` snd ` set D" unfolding unlabel_def constr_def B_def by auto ultimately have "trms\<^sub>s\<^sub>t (unlabel A') \ B \ trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D" using A'' unlabel_append[of constr A''] by auto moreover have "set (dbproj i D) \ set D" by auto hence "B \ pair ` set F' \ pair ` snd ` set D" using tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_trms_subset'[of F' "map snd (dbproj i D)"] unfolding B_def by force moreover have "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ((i, \X\\\: F \\: F'\)#A)) = pair ` set F' \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" by auto ultimately show ?case by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) qed lemma tr_par_wf_trms: assumes "A' \ set (tr\<^sub>p\<^sub>c A [])" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>s\<^sub>s\<^sub>t (unlabel A))" shows "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>t A')" using tr_par_trms_subset[OF assms(1)] setops\<^sub>s\<^sub>s\<^sub>t_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s(2)[OF assms(2)] by auto lemma tr_par_wf': assumes "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" and "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" and "wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" and "A' \ set (tr\<^sub>p\<^sub>c A D)" shows "wf\<^sub>l\<^sub>s\<^sub>t X A'" proof - define P where "P = (\(D::('fun,'var,'lbl) labeleddbstatelist) (A::('fun,'var,'lbl) labeled_stateful_strand). (fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}) \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {})" have "P D A" using assms(1,4) by (simp add: P_def) with assms(5,3,2) show ?thesis proof (induction A arbitrary: X A' D) case Nil thus ?case by simp next case (Cons a A) obtain i s where i: "a = (i,s)" by (metis surj_pair) note prems = Cons.prems note IH = Cons.IH show ?case proof (cases s) case (Receive t) note si = Receive i then obtain A'' where A'': "A' = (i,receive\t\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" "fv t \ X" using prems unlabel_Cons(1)[of i s A] by moura have *: "wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" "P D A" using prems si apply (force, force) using prems(4) si unfolding P_def by fastforce show ?thesis using IH[OF A''(2) *] A''(1,3) by simp next case (Send t) note si = Send i then obtain A'' where A'': "A' = (i,send\t\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" using prems by moura have *: "wf'\<^sub>s\<^sub>s\<^sub>t (X \ fv t) (unlabel A)" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X \ fv t" "P D A" using prems si apply (force, force) using prems(4) si unfolding P_def by fastforce show ?thesis using IH[OF A''(2) *] A''(1) by simp next case (Equality ac t t') note si = Equality i then obtain A'' where A'': "A' = (i,\ac: t \ t'\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" "ac = Assign \ fv t' \ X" using prems unlabel_Cons(1)[of i s] by moura have *: "ac = Assign \ wf'\<^sub>s\<^sub>s\<^sub>t (X \ fv t) (unlabel A)" "ac = Check \ wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "ac = Assign \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X \ fv t" "ac = Check \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" "P D A" using prems si apply (force, force, force, force) using prems(4) si unfolding P_def by fastforce show ?thesis using IH[OF A''(2) *(1,3,5)] IH[OF A''(2) *(2,4,5)] A''(1,3) by (cases ac) simp_all next case (Insert t t') note si = Insert i hence A': "A' \ set (tr\<^sub>p\<^sub>c A (List.insert (i,t,t') D))" "fv t \ X" "fv t' \ X" using prems by auto have *: "wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel (List.insert (i,t,t') D)) \ X" using prems si by (auto simp add: unlabel_def) have **: "P (List.insert (i,t,t') D) A" using prems(4) si unfolding P_def unlabel_def by fastforce show ?thesis using IH[OF A'(1) * **] A'(2,3) by simp next case (Delete t t') note si = Delete i define constr where "constr = (\Di. (map (\d. (i,\check: (pair (t,t')) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t,t'), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d \ set Di]))" from prems si obtain Di A'' where A'': "A' = constr Di@A''" "A'' \ set (tr\<^sub>p\<^sub>c A [d\D. d \ set Di])" "Di \ set (subseqs (dbproj i D))" unfolding constr_def by auto have *: "wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel (filter (\d. d \ set Di) D)) \ X" using prems si apply simp using prems si by (fastforce simp add: unlabel_def) have "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel (filter (\d. d \ set Di) D)) \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D)" by (auto simp add: unlabel_def) hence **: "P [d\D. d \ set Di] A" using prems si unfolding P_def by fastforce have ***: "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" using prems si by auto show ?thesis using IH[OF A''(2) * **] A''(1) wf_pair_eqs_ineqs_map'[OF _ A''(3) ***] unfolding constr_def by simp next case (InSet ac t t') note si = InSet i then obtain d A'' where A'': "A' = (i,\ac: (pair (t,t')) \ (pair (snd d))\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" "d \ set D" using prems by moura have *: "ac = Assign \ wf'\<^sub>s\<^sub>s\<^sub>t (X \ fv t \ fv t') (unlabel A)" "ac = Check \ wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "ac = Assign \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X \ fv t \ fv t'" "ac = Check \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" "P D A" using prems si apply (force, force, force, force) using prems(4) si unfolding P_def by fastforce have **: "fv (pair (snd d)) \ X" using A''(3) prems(3) fv_pair_fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subset by fast have ***: "fv (pair (t,t')) = fv t \ fv t'" unfolding pair_def by auto show ?thesis using IH[OF A''(2) *(1,3,5)] IH[OF A''(2) *(2,4,5)] A''(1) ** *** by (cases ac) (simp_all add: Un_assoc) next case (NegChecks Y F F') note si = NegChecks i then obtain A'' where A'': "A' = (map (\G. (i,\Y\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D))))@A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" using prems by moura have *: "wf'\<^sub>s\<^sub>s\<^sub>t X (unlabel A)" "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ X" using prems si by auto have "bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel ((i,\Y\\\: F \\: F'\)#A))" "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel ((i,\Y\\\: F \\: F'\)#A))" by auto hence **: "P D A" using prems si unfolding P_def by blast show ?thesis using IH[OF A''(2) * **] A''(1) wf_pair_negchecks_map' by simp qed qed qed lemma tr_par_wf: assumes "A' \ set (tr\<^sub>p\<^sub>c A [])" and "wf\<^sub>s\<^sub>s\<^sub>t (unlabel A)" and "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A)" shows "wf\<^sub>l\<^sub>s\<^sub>t {} A'" and "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>t A')" and "fv\<^sub>l\<^sub>s\<^sub>t A' \ bvars\<^sub>l\<^sub>s\<^sub>t A' = {}" using tr_par_wf'[OF _ _ _ _ assms(1)] tr_par_wf_trms[OF assms(1,3)] tr_par_vars_disj[OF assms(1)] assms(2) by fastforce+ lemma tr_par_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p: assumes "A' \ set (tr\<^sub>p\<^sub>c A D)" "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel A)" and "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" (is "?P0 A D") and "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel D) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" (is "?P1 A D") and "\t \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D. \t' \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` snd ` set D. (\\. Unifier \ t t') \ \ t = \ t'" (is "?P3 A D") shows "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A')" proof - have sublmm: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel A)" "?P0 A D" "?P1 A D" "?P3 A D" when p: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel (a#A))" "?P0 (a#A) D" "?P1 (a#A) D" "?P3 (a#A) D" for a A D proof - show "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel A)" using p(1) by (simp add: unlabel_def tfr\<^sub>s\<^sub>s\<^sub>t_def) show "?P0 A D" using p(2) fv\<^sub>s\<^sub>s\<^sub>t_cons_subset unfolding unlabel_def by fastforce show "?P1 A D" using p(3) bvars\<^sub>s\<^sub>s\<^sub>t_cons_subset unfolding unlabel_def by fastforce have "setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ setops\<^sub>s\<^sub>s\<^sub>t (unlabel (a#A))" using setops\<^sub>s\<^sub>s\<^sub>t_cons_subset unfolding unlabel_def by auto thus "?P3 A D" using p(4) by blast qed show ?thesis using assms proof (induction A D arbitrary: A' rule: tr\<^sub>p\<^sub>c.induct) case 1 thus ?case by simp next case (2 i t A D) note prems = "2.prems" note IH = "2.IH" from prems(1) obtain A'' where A'': "A' = (i,send\t\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" by moura have "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A'')" using IH[OF A''(2)] prems(5) sublmm[OF prems(2,3,4,5)] by meson thus ?case using A''(1) by simp next case (3 i t A D) note prems = "3.prems" note IH = "3.IH" from prems(1) obtain A'' where A'': "A' = (i,receive\t\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" by moura have "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A'')" using IH[OF A''(2)] prems(5) sublmm[OF prems(2,3,4,5)] by meson thus ?case using A''(1) by simp next case (4 i ac t t' A D) note prems = "4.prems" note IH = "4.IH" from prems(1) obtain A'' where A'': "A' = (i,\ac: t \ t'\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" by moura have "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A'')" using IH[OF A''(2)] prems(5) sublmm[OF prems(2,3,4,5)] by meson thus ?case using A''(1) prems(2) by simp next case (5 i t s A D) note prems = "5.prems" note IH = "5.IH" from prems(1) have A': "A' \ set (tr\<^sub>p\<^sub>c A (List.insert (i,t,s) D))" by simp have 1: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel A)" using sublmm[OF prems(2,3,4,5)] by simp have "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ((i,insert\t,s\)#A)) \ pair`snd`set D = pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair`snd`set (List.insert (i,t,s) D)" by (auto simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) hence 3: "?P3 A (List.insert (i,t,s) D)" using prems(5) by metis moreover have "?P1 A (List.insert (i,t,s) D)" using prems(3,4) bvars\<^sub>s\<^sub>s\<^sub>t_cons_subset[of "unlabel A" "insert\t,s\"] unfolding unlabel_def by fastforce ultimately have "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A')" using IH[OF A' sublmm(1,2)[OF prems(2,3,4,5)] _ 3] by metis thus ?case using A'(1) by auto next case (6 i t s A D) note prems = "6.prems" note IH = "6.IH" define constr where constr: "constr \ (\Di. (map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) (filter (\d. d \ set Di) (dbproj i D))))" from prems(1) obtain Di A'' where A'': "A' = constr Di@A''" "A'' \ set (tr\<^sub>p\<^sub>c A (filter (\d. d \ set Di) D))" "Di \ set (subseqs (dbproj i D))" unfolding constr by fastforce define Q1 where "Q1 \ (\(F::(('fun,'var) term \ ('fun,'var) term) list) X. \x \ (fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) - set X. \a. \ (Var x) = TAtom a)" define Q2 where "Q2 \ (\(F::(('fun,'var) term \ ('fun,'var) term) list) X. \f T. Fun f T \ subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) \ T = [] \ (\s \ set T. s \ Var ` set X))" have "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair`snd`set [d\D. d \ set Di] \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel ((i,delete\t,s\)#A)) \ pair`snd`set D" using subseqs_set_subset[OF A''(3)] by (force simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) moreover have "\a\M. \b\M. P a b" when "M \ N" "\a\N. \b\N. P a b" for M N::"('fun, 'var) terms" and P using that by blast ultimately have *: "?P3 A (filter (\d. d \ set Di) D)" using prems(5) by presburger have **: "?P1 A (filter (\d. d \ set Di) D)" using prems(4) bvars\<^sub>s\<^sub>s\<^sub>t_cons_subset[of "unlabel A" "delete\t,s\"] unfolding unlabel_def by fastforce have 1: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A'')" using IH[OF A''(3,2) sublmm(1,2)[OF prems(2,3,4,5)] ** *] by metis have 2: "\ac: u \ u'\\<^sub>s\<^sub>t \ set (unlabel A'') \ (\d \ set Di. u = pair (t,s) \ u' = pair (snd d))" when "\ac: u \ u'\\<^sub>s\<^sub>t \ set (unlabel A')" for ac u u' using that A''(1) unfolding constr unlabel_def by force have 3: "\X\\\: u\\<^sub>s\<^sub>t \ set (unlabel A'') \ (\d \ set (filter (\d. d \ set Di) D). u = [(pair (t,s), pair (snd d))] \ Q2 u X)" when "\X\\\: u\\<^sub>s\<^sub>t \ set (unlabel A')" for X u using that A''(1) unfolding Q2_def constr unlabel_def by force have 4: "\d\set D. (\\. Unifier \ (pair (t,s)) (pair (snd d))) \ \ (pair (t,s)) = \ (pair (snd d))" using prems(5) by (simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) { fix ac u u' assume a: "\ac: u \ u'\\<^sub>s\<^sub>t \ set (unlabel A')" "\\. Unifier \ u u'" hence "\ac: u \ u'\\<^sub>s\<^sub>t \ set (unlabel A'') \ (\d \ set Di. u = pair (t,s) \ u' = pair (snd d))" using 2 by metis moreover { assume "\ac: u \ u'\\<^sub>s\<^sub>t \ set (unlabel A'')" hence "tfr\<^sub>s\<^sub>t\<^sub>p (\ac: u \ u'\\<^sub>s\<^sub>t)" using 1 Ball_set_list_all[of "unlabel A''" tfr\<^sub>s\<^sub>t\<^sub>p] by fast } moreover { fix d assume "d \ set Di" "u = pair (t,s)" "u' = pair (snd d)" hence "\\. Unifier \ u u' \ \ u = \ u'" using 4 dbproj_subseq_subset A''(3) by fast hence "tfr\<^sub>s\<^sub>t\<^sub>p (\ac: u \ u'\\<^sub>s\<^sub>t)" using Ball_set_list_all[of "unlabel A''" tfr\<^sub>s\<^sub>t\<^sub>p] by simp hence "\ u = \ u'" using tfr\<^sub>s\<^sub>t\<^sub>p_list_all_alt_def[of "unlabel A''"] using a(2) unfolding unlabel_def by auto } ultimately have "\ u = \ u'" using tfr\<^sub>s\<^sub>t\<^sub>p_list_all_alt_def[of "unlabel A''"] a(2) unfolding unlabel_def by auto } moreover { fix u U assume "\U\\\: u\\<^sub>s\<^sub>t \ set (unlabel A')" hence "\U\\\: u\\<^sub>s\<^sub>t \ set (unlabel A'') \ (\d \ set (filter (\d. d \ set Di) D). u = [(pair (t,s), pair (snd d))] \ Q2 u U)" using 3 by metis hence "Q1 u U \ Q2 u U" using 1 4 subseqs_set_subset[OF A''(3)] tfr\<^sub>s\<^sub>t\<^sub>p_list_all_alt_def[of "unlabel A''"] unfolding Q1_def Q2_def by blast } ultimately show ?case using tfr\<^sub>s\<^sub>t\<^sub>p_list_all_alt_def[of "unlabel A'"] unfolding Q1_def Q2_def unlabel_def by blast next case (7 i ac t s A D) note prems = "7.prems" note IH = "7.IH" from prems(1) obtain d A'' where A'': "A' = (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" "d \ set (dbproj i D)" by moura have 1: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A'')" using IH[OF A''(2) sublmm(1,2,3)[OF prems(2,3,4,5)] sublmm(4)[OF prems(2,3,4,5)]] by metis have 2: "\ (pair (t,s)) = \ (pair (snd d))" when "\\. Unifier \ (pair (t,s)) (pair (snd d))" using that prems(2,5) A''(3) unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by (simp add: setops\<^sub>s\<^sub>s\<^sub>t_def) show ?case using A''(1) 1 2 by fastforce next case (8 i X F F' A D) note prems = "8.prems" note IH = "8.IH" define constr where "constr = map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" define Q1 where "Q1 \ (\(F::(('fun,'var) term \ ('fun,'var) term) list) X. \x \ (fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) - set X. \a. \ (Var x) = TAtom a)" define Q2 where "Q2 \ (\(M::('fun,'var) terms) X. \f T. Fun f T \ subterms\<^sub>s\<^sub>e\<^sub>t M \ T = [] \ (\s \ set T. s \ Var ` set X))" have Q2_subset: "Q2 M' X" when "M' \ M" "Q2 M X" for X M M' using that unfolding Q2_def by auto have Q2_supset: "Q2 (M \ M') X" when "Q2 M X" "Q2 M' X" for X M M' using that unfolding Q2_def by auto from prems obtain A'' where A'': "A' = constr@A''" "A'' \ set (tr\<^sub>p\<^sub>c A D)" using constr_def by moura have 0: "constr = [(i,\X\\\: F\\<^sub>s\<^sub>t)]" when "F' = []" using that unfolding constr_def by simp have 1: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A'')" using IH[OF A''(2) sublmm(1,2,3)[OF prems(2,3,4,5)] sublmm(4)[OF prems(2,3,4,5)]] by metis have 2: "(F' = [] \ Q1 F X) \ Q2 (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ pair ` set F') X" using prems(2) unfolding Q1_def Q2_def by simp have 3: "F' = [] \ Q1 F X \ list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel constr)" using 0 2 tfr\<^sub>s\<^sub>t\<^sub>p_list_all_alt_def[of "unlabel constr"] unfolding Q1_def by auto { fix c assume "c \ set (unlabel constr)" hence "\G \ set (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D))). c = \X\\\: (F@G)\\<^sub>s\<^sub>t" unfolding constr_def unlabel_def by force } moreover { fix G assume G: "G \ set (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" and c: "\X\\\: (F@G)\\<^sub>s\<^sub>t \ set (unlabel constr)" and e: "Q2 (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ pair ` set F') X" have d_Q2: "Q2 (pair ` set (map snd D)) X" unfolding Q2_def proof (intro allI impI) fix f T assume "Fun f T \ subterms\<^sub>s\<^sub>e\<^sub>t (pair ` set (map snd D))" then obtain d where d: "d \ set (map snd D)" "Fun f T \ subterms (pair d)" by force hence "fv (pair d) \ set X = {}" using prems(4) unfolding pair_def by (force simp add: unlabel_def) thus "T = [] \ (\s \ set T. s \ Var ` set X)" by (metis fv_disj_Fun_subterm_param_cases d(2)) qed have "trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (F@G) \ trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ pair ` set F' \ pair ` set (map snd D)" using tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_trms_subset[OF G] by force hence "Q2 (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (F@G)) X" using Q2_subset[OF _ Q2_supset[OF e d_Q2]] by metis hence "tfr\<^sub>s\<^sub>t\<^sub>p (\X\\\: (F@G)\\<^sub>s\<^sub>t)" by (metis Q2_def tfr\<^sub>s\<^sub>t\<^sub>p.simps(2)) } ultimately have 4: "Q2 (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F \ pair ` set F') X \ list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel constr)" using Ball_set by blast have 5: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel constr)" using 2 3 4 by metis show ?case using 1 5 A''(1) by (simp add: unlabel_def) qed qed lemma tr_par_tfr: assumes "A' \ set (tr\<^sub>p\<^sub>c A [])" and "tfr\<^sub>s\<^sub>s\<^sub>t (unlabel A)" and "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" shows "tfr\<^sub>s\<^sub>t (unlabel A')" proof - have *: "trms\<^sub>l\<^sub>s\<^sub>t A' \ trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" using tr_par_trms_subset[OF assms(1)] by simp hence "SMP (trms\<^sub>l\<^sub>s\<^sub>t A') \ SMP (trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A))" using SMP_mono by simp moreover have "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A))" using assms(2) unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by fast ultimately have 1: "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>t A')" by (metis tfr_subset(2)[OF _ *]) have **: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel A)" using assms(2) unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def by fast have "pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ SMP (trms\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)) - Var`\" using setops\<^sub>s\<^sub>s\<^sub>t_are_pairs unfolding pair_def by auto hence "\ t = \ t'" when "\\. Unifier \ t t'" "t \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "t' \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A)" for t t' using that assms(2) unfolding tfr\<^sub>s\<^sub>s\<^sub>t_def tfr\<^sub>s\<^sub>e\<^sub>t_def by blast moreover have "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (unlabel []) = {}" "pair ` snd ` set [] = {}" by auto ultimately have 2: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (unlabel A')" using tr_par_tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p[OF assms(1) ** assms(3)] by simp show ?thesis by (metis 1 2 tfr\<^sub>s\<^sub>t_def) qed lemma tr_par_proj: assumes "B \ set (tr\<^sub>p\<^sub>c A D)" shows "proj n B \ set (tr\<^sub>p\<^sub>c (proj n A) (proj n D))" using assms proof (induction A D arbitrary: B rule: tr\<^sub>p\<^sub>c.induct) case (5 i t s S D) note prems = "5.prems" note IH = "5.IH" have IH': "proj n B \ set (tr\<^sub>p\<^sub>c (proj n S) (proj n (List.insert (i,t,s) D)))" using prems IH by auto show ?case proof (cases "(i = ln n) \ (i = \)") case True thus ?thesis using IH' proj_list_insert(1,2)[of n "(t,s)" D] proj_list_Cons(1,2)[of n _ S] by auto next case False then obtain m where "i = ln m" "n \ m" by (cases i) simp_all thus ?thesis using IH' proj_list_insert(3)[of n _ "(t,s)" D] proj_list_Cons(3)[of n _ "insert\t,s\" S] by auto qed next case (6 i t s S D) note prems = "6.prems" note IH = "6.IH" define constr where "constr = (\Di D. (map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d \ set Di]))" obtain Di B' where B': "B = constr Di D@B'" "Di \ set (subseqs (dbproj i D))" "B' \ set (tr\<^sub>p\<^sub>c S [d\D. d \ set Di])" using prems constr_def by fastforce hence "proj n B' \ set (tr\<^sub>p\<^sub>c (proj n S) (proj n [d\D. d \ set Di]))" using IH by simp hence IH': "proj n B' \ set (tr\<^sub>p\<^sub>c (proj n S) [d\proj n D. d \ set Di])" by (metis proj_filter) show ?case proof (cases "(i = ln n) \ (i = \)") case True hence "proj n B = constr Di D@proj n B'" "Di \ set (subseqs (dbproj i (proj n D)))" using B'(1,2) proj_dbproj(1,2)[of n D] unfolding proj_def constr_def by auto moreover have "constr Di (proj n D) = constr Di D" using True proj_dbproj(1,2)[of n D] unfolding constr_def by presburger ultimately have "proj n B \ set (tr\<^sub>p\<^sub>c ((i, delete\t,s\)#proj n S) (proj n D))" using IH' unfolding constr_def by force thus ?thesis by (metis proj_list_Cons(1,2) True) next case False then obtain m where m: "i = ln m" "n \ m" by (cases i) simp_all hence *: "(ln n) \ i" by simp have "proj n B = proj n B'" using B'(1) False unfolding constr_def proj_def by auto moreover have "[d\proj n D. d \ set Di] = proj n D" using proj_subseq[OF _ m(2)[symmetric]] m(1) B'(2) by simp ultimately show ?thesis using m(1) IH' proj_list_Cons(3)[OF m(2), of _ S] by auto qed next case (7 i ac t s S D) note prems = "7.prems" note IH = "7.IH" define constr where "constr = ( \d::'lbl strand_label \ ('fun,'var) term \ ('fun,'var) term. (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t))" obtain d B' where B': "B = constr d#B'" "d \ set (dbproj i D)" "B' \ set (tr\<^sub>p\<^sub>c S D)" using prems constr_def by fastforce hence IH': "proj n B' \ set (tr\<^sub>p\<^sub>c (proj n S) (proj n D))" using IH by auto show ?case proof (cases "(i = ln n) \ (i = \)") case True hence "proj n B = constr d#proj n B'" "d \ set (dbproj i (proj n D))" using B' proj_list_Cons(1,2)[of n _ B'] unfolding constr_def by (force, metis proj_dbproj(1,2)) hence "proj n B \ set (tr\<^sub>p\<^sub>c ((i, InSet ac t s)#proj n S) (proj n D))" using IH' unfolding constr_def by auto thus ?thesis using proj_list_Cons(1,2)[of n _ S] True by metis next case False then obtain m where m: "i = ln m" "n \ m" by (cases i) simp_all hence "proj n B = proj n B'" using B'(1) proj_list_Cons(3) unfolding constr_def by auto thus ?thesis using IH' m proj_list_Cons(3)[OF m(2), of "InSet ac t s" S] unfolding constr_def by auto qed next case (8 i X F F' S D) note prems = "8.prems" note IH = "8.IH" define constr where "constr = (\D. map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D))))" obtain B' where B': "B = constr D@B'" "B' \ set (tr\<^sub>p\<^sub>c S D)" using prems constr_def by fastforce hence IH': "proj n B' \ set (tr\<^sub>p\<^sub>c (proj n S) (proj n D))" using IH by auto show ?case proof (cases "(i = ln n) \ (i = \)") case True hence "proj n B = constr (proj n D)@proj n B'" using B'(1,2) proj_dbproj(1,2)[of n D] unfolding proj_def constr_def by auto hence "proj n B \ set (tr\<^sub>p\<^sub>c ((i, NegChecks X F F')#proj n S) (proj n D))" using IH' unfolding constr_def by auto thus ?thesis using proj_list_Cons(1,2)[of n _ S] True by metis next case False then obtain m where m: "i = ln m" "n \ m" by (cases i) simp_all hence "proj n B = proj n B'" using B'(1) unfolding constr_def proj_def by auto thus ?thesis using IH' m proj_list_Cons(3)[OF m(2), of "NegChecks X F F'" S] unfolding constr_def by auto qed qed (force simp add: proj_def)+ lemma tr_par_preserves_typing_cond: assumes "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A Sec" "typing_cond\<^sub>s\<^sub>s\<^sub>t (unlabel A)" "A' \ set (tr\<^sub>p\<^sub>c A [])" shows "typing_cond (unlabel A')" proof - have "wf'\<^sub>s\<^sub>s\<^sub>t {} (unlabel A)" "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>s\<^sub>s\<^sub>t (unlabel A))" using assms(2) unfolding typing_cond\<^sub>s\<^sub>s\<^sub>t_def by simp_all hence 1: "wf\<^sub>s\<^sub>t {} (unlabel A')" "fv\<^sub>s\<^sub>t (unlabel A') \ bvars\<^sub>s\<^sub>t (unlabel A') = {}" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>s\<^sub>t (unlabel A'))" "Ana_invar_subst (ik\<^sub>s\<^sub>t (unlabel A') \ assignment_rhs\<^sub>s\<^sub>t (unlabel A'))" using tr_par_wf[OF assms(3)] Ana_invar_subst' by metis+ have 2: "tfr\<^sub>s\<^sub>t (unlabel A')" by (metis tr_par_tfr assms(2,3) typing_cond\<^sub>s\<^sub>s\<^sub>t_def) show ?thesis by (metis 1 2 typing_cond_def) qed lemma tr_par_preserves_par_comp: assumes "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A Sec" "A' \ set (tr\<^sub>p\<^sub>c A [])" shows "par_comp A' Sec" proof - let ?M = "\l. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l A)" let ?N = "\l. trms_proj\<^sub>l\<^sub>s\<^sub>t l A'" have 0: "\l1 l2. l1 \ l2 \ GSMP_disjoint (?M l1) (?M l2) Sec" using assms(1) unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by simp_all { fix l1 l2::'lbl assume *: "l1 \ l2" hence "GSMP_disjoint (?M l1) (?M l2) Sec" using 0(1) by metis moreover have "pair ` snd ` set (proj n []) = {}" for n::'lbl unfolding proj_def by simp hence "?N l1 \ ?M l1" "?N l2 \ ?M l2" using tr_par_trms_subset[OF tr_par_proj[OF assms(2)]] by (metis Un_empty_right)+ ultimately have "GSMP_disjoint (?N l1) (?N l2) Sec" using GSMP_disjoint_subset by presburger } hence 1: "\l1 l2. l1 \ l2 \ GSMP_disjoint (trms_proj\<^sub>l\<^sub>s\<^sub>t l1 A') (trms_proj\<^sub>l\<^sub>s\<^sub>t l2 A') Sec" using 0(1) by metis have 2: "ground Sec" "\s \ Sec. \s' \ subterms s. {} \\<^sub>c s' \ s' \ Sec" using assms(1) unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by metis+ show ?thesis using 1 2 unfolding par_comp_def by metis qed lemma tr_leaking_prefix_exists: assumes "A' \ set (tr\<^sub>p\<^sub>c A [])" "prefix B A'" "ik\<^sub>s\<^sub>t (proj_unl n B) \\<^sub>s\<^sub>e\<^sub>t \ \ t \ \" shows "\C D. prefix C B \ prefix D A \ C \ set (tr\<^sub>p\<^sub>c D []) \ (ik\<^sub>s\<^sub>t (proj_unl n C) \\<^sub>s\<^sub>e\<^sub>t \ \ t \ \)" proof - let ?P = "\B C C'. B = C@C' \ (\n t. (n, receive\t\\<^sub>s\<^sub>t) \ set C') \ (C = [] \ (\n t. suffix [(n,receive\t\\<^sub>s\<^sub>t)] C))" have "\C C'. ?P B C C'" proof (induction B) case (Cons b B) then obtain C C' n s where *: "?P B C C'" "b = (n,s)" by moura show ?case proof (cases "C = []") case True note T = True show ?thesis proof (cases "\t. s = receive\t\\<^sub>s\<^sub>t") case True hence "?P (b#B) [b] C'" using * T by auto thus ?thesis by metis next case False hence "?P (b#B) [] (b#C')" using * T by auto thus ?thesis by metis qed next case False hence "?P (b#B) (b#C) C'" using * unfolding suffix_def by auto thus ?thesis by metis qed qed simp then obtain C C' where C: "B = C@C'" "\n t. (n, receive\t\\<^sub>s\<^sub>t) \ set C'" "C = [] \ (\n t. suffix [(n,receive\t\\<^sub>s\<^sub>t)] C)" by moura hence 1: "prefix C B" by simp hence 2: "prefix C A'" using assms(2) by simp have "\m t. (m,receive\t\\<^sub>s\<^sub>t) \ set B \ (m,receive\t\\<^sub>s\<^sub>t) \ set C" using C by auto hence "\t. receive\t\\<^sub>s\<^sub>t \ set (proj_unl n B) \ receive\t\\<^sub>s\<^sub>t \ set (proj_unl n C)" unfolding unlabel_def proj_def by force hence "ik\<^sub>s\<^sub>t (proj_unl n B) \ ik\<^sub>s\<^sub>t (proj_unl n C)" using ik\<^sub>s\<^sub>t_is_rcv_set by auto hence 3: "ik\<^sub>s\<^sub>t (proj_unl n C) \\<^sub>s\<^sub>e\<^sub>t \ \ t \ \" by (metis ideduct_mono[OF assms(3)] subst_all_mono) { fix D E m t assume "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E" "prefix E A'" "A' \ set (tr\<^sub>p\<^sub>c A D)" hence "\F. prefix F A \ E \ set (tr\<^sub>p\<^sub>c F D)" proof (induction A D arbitrary: A' E rule: tr\<^sub>p\<^sub>c.induct) case (1 D) thus ?case by simp next case (2 i t' S D) note prems = "2.prems" note IH = "2.IH" obtain A'' where *: "A' = (i,send\t'\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c S D)" using prems(3) by auto have "E \ []" using prems(1) by auto then obtain E' where **: "E = (i,send\t'\\<^sub>s\<^sub>t)#E'" using *(1) prems(2) by (cases E) auto hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using *(1) prems(1,2) suffix_Cons[of _ _ E'] by auto then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F D)" using *(2) ** IH by metis hence "prefix ((i,Send t')#F) ((i,Send t')#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,Send t')#F) D)" using ** by auto thus ?case by metis next case (3 i t' S D) note prems = "3.prems" note IH = "3.IH" obtain A'' where *: "A' = (i,receive\t'\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c S D)" using prems(3) by auto have "E \ []" using prems(1) by auto then obtain E' where **: "E = (i,receive\t'\\<^sub>s\<^sub>t)#E'" using *(1) prems(2) by (cases E) auto show ?case proof (cases "(m, receive\t\\<^sub>s\<^sub>t) = (i, receive\t'\\<^sub>s\<^sub>t)") case True note T = True show ?thesis proof (cases "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'") case True hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using ** *(1) prems(1,2) by auto then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F D)" using *(2) ** IH by metis hence "prefix ((i,receive\t'\)#F) ((i,receive\t'\)#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,receive\t'\)#F) D)" using ** by auto thus ?thesis by metis next case False hence "E' = []" using **(1) T prems(1) suffix_Cons[of "[(m, receive\t\\<^sub>s\<^sub>t)]" "(m, receive\t\\<^sub>s\<^sub>t)" E'] by auto hence "prefix [(i,receive\t'\)] ((i,receive\t'\) # S) \ E \ set (tr\<^sub>p\<^sub>c [(i,receive\t'\)] D)" using * ** prems by auto thus ?thesis by metis qed next case False hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using ** *(1) prems(1,2) suffix_Cons[of _ _ E'] by auto then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F D)" using *(2) ** IH by metis hence "prefix ((i,receive\t'\)#F) ((i,receive\t'\)#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,receive\t'\)#F) D)" using ** by auto thus ?thesis by metis qed next case (4 i ac t' t'' S D) note prems = "4.prems" note IH = "4.IH" obtain A'' where *: "A' = (i,\ac: t' \ t''\\<^sub>s\<^sub>t)#A''" "A'' \ set (tr\<^sub>p\<^sub>c S D)" using prems(3) by auto have "E \ []" using prems(1) by auto then obtain E' where **: "E = (i,\ac: t' \ t''\\<^sub>s\<^sub>t)#E'" using *(1) prems(2) by (cases E) auto hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using *(1) prems(1,2) suffix_Cons[of _ _ E'] by auto then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F D)" using *(2) ** IH by metis hence "prefix ((i,Equality ac t' t'')#F) ((i,Equality ac t' t'')#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,Equality ac t' t'')#F) D)" using ** by auto thus ?case by metis next case (5 i t' s S D) note prems = "5.prems" note IH = "5.IH" have *: "A' \ set (tr\<^sub>p\<^sub>c S (List.insert (i,t',s) D))" using prems(3) by auto have "E \ []" using prems(1) by auto hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E" "prefix E A'" using *(1) prems(1,2) suffix_Cons[of _ _ E] by auto then obtain F where "prefix F S" "E \ set (tr\<^sub>p\<^sub>c F (List.insert (i,t',s) D))" using * IH by metis hence "prefix ((i,insert\t',s\)#F) ((i,insert\t',s\)#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,insert\t',s\)#F) D)" by auto thus ?case by metis next case (6 i t' s S D) note prems = "6.prems" note IH = "6.IH" define constr where "constr = (\Di. (map (\d. (i,\check: (pair (t',s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t',s), pair (snd d))]\\<^sub>s\<^sub>t)) (filter (\d. d \ set Di) (dbproj i D))))" obtain A'' Di where *: "A' = constr Di@A''" "A'' \ set (tr\<^sub>p\<^sub>c S (filter (\d. d \ set Di) D))" "Di \ set (subseqs (dbproj i D))" using prems(3) constr_def by auto have ***: "(m, receive\t\\<^sub>s\<^sub>t) \ set (constr Di)" using constr_def by auto have "E \ []" using prems(1) by auto then obtain E' where **: "E = constr Di@E'" using *(1) prems(1,2) *** by (metis (mono_tags, lifting) Un_iff list.set_intros(1) prefixI prefix_def prefix_same_cases set_append suffix_def) hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using *(1) prems(1,2) suffix_append[of "[(m,receive\t\\<^sub>s\<^sub>t)]" "constr Di" E'] *** by (metis (no_types, hide_lams) Nil_suffix append_Nil2 in_set_conv_decomp rev_exhaust snoc_suffix_snoc suffix_appendD, auto) then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F (filter (\d. d \ set Di) D))" using *(2,3) ** IH by metis hence "prefix ((i,delete\t',s\)#F) ((i,delete\t',s\)#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,delete\t',s\)#F) D)" using *(3) ** constr_def by auto thus ?case by metis next case (7 i ac t' s S D) note prems = "7.prems" note IH = "7.IH" define constr where "constr = ( \d::(('lbl strand_label \ ('fun,'var) term \ ('fun,'var) term)). (i,\ac: (pair (t',s)) \ (pair (snd d))\\<^sub>s\<^sub>t))" obtain A'' d where *: "A' = constr d#A''" "A'' \ set (tr\<^sub>p\<^sub>c S D)" "d \ set (dbproj i D)" using prems(3) constr_def by auto have "E \ []" using prems(1) by auto then obtain E' where **: "E = constr d#E'" using *(1) prems(2) by (cases E) auto hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using *(1) prems(1,2) suffix_Cons[of _ _ E'] using constr_def by auto then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F D)" using *(2) ** IH by metis hence "prefix ((i,InSet ac t' s)#F) ((i,InSet ac t' s)#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,InSet ac t' s)#F) D)" using *(3) ** unfolding constr_def by auto thus ?case by metis next case (8 i X G G' S D) note prems = "8.prems" note IH = "8.IH" define constr where "constr = map (\H. (i,\X\\\: (G@H)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s G' (map snd (dbproj i D)))" obtain A'' where *: "A' = constr@A''" "A'' \ set (tr\<^sub>p\<^sub>c S D)" using prems(3) constr_def by auto have ***: "(m, receive\t\\<^sub>s\<^sub>t) \ set constr" using constr_def by auto have "E \ []" using prems(1) by auto then obtain E' where **: "E = constr@E'" using *(1) prems(1,2) *** by (metis (mono_tags, lifting) Un_iff list.set_intros(1) prefixI prefix_def prefix_same_cases set_append suffix_def) hence "suffix [(m, receive\t\\<^sub>s\<^sub>t)] E'" "prefix E' A''" using *(1) prems(1,2) suffix_append[of "[(m,receive\t\\<^sub>s\<^sub>t)]" constr E'] *** by (metis (no_types, hide_lams) Nil_suffix append_Nil2 in_set_conv_decomp rev_exhaust snoc_suffix_snoc suffix_appendD, auto) then obtain F where "prefix F S" "E' \ set (tr\<^sub>p\<^sub>c F D)" using *(2) ** IH by metis hence "prefix ((i,NegChecks X G G')#F) ((i,NegChecks X G G')#S)" "E \ set (tr\<^sub>p\<^sub>c ((i,NegChecks X G G')#F) D)" using ** constr_def by auto thus ?case by metis qed } moreover have "prefix [] A" "[] \ set (tr\<^sub>p\<^sub>c [] [])" by auto ultimately have 4: "\D. prefix D A \ C \ set (tr\<^sub>p\<^sub>c D [])" using C(3) assms(1) 2 by blast show ?thesis by (metis 1 3 4) qed subsection \Theorem: Semantic Equivalence of Translation\ context begin text \ An alternative version of the translation that does not perform database-state projections. It is used as an intermediate step in the proof of semantic equivalence. \ private fun tr'\<^sub>p\<^sub>c:: "('fun,'var,'lbl) labeled_stateful_strand \ ('fun,'var,'lbl) labeleddbstatelist \ ('fun,'var,'lbl) labeled_strand list" where "tr'\<^sub>p\<^sub>c [] D = [[]]" | "tr'\<^sub>p\<^sub>c ((i,send\t\)#A) D = map ((#) (i,send\t\\<^sub>s\<^sub>t)) (tr'\<^sub>p\<^sub>c A D)" | "tr'\<^sub>p\<^sub>c ((i,receive\t\)#A) D = map ((#) (i,receive\t\\<^sub>s\<^sub>t)) (tr'\<^sub>p\<^sub>c A D)" | "tr'\<^sub>p\<^sub>c ((i,\ac: t \ t'\)#A) D = map ((#) (i,\ac: t \ t'\\<^sub>s\<^sub>t)) (tr'\<^sub>p\<^sub>c A D)" | "tr'\<^sub>p\<^sub>c ((i,insert\t,s\)#A) D = tr'\<^sub>p\<^sub>c A (List.insert (i,(t,s)) D)" | "tr'\<^sub>p\<^sub>c ((i,delete\t,s\)#A) D = ( concat (map (\Di. map (\B. (map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di)@ (map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\D. d \ set Di])@B) (tr'\<^sub>p\<^sub>c A [d\D. d \ set Di])) (subseqs D)))" | "tr'\<^sub>p\<^sub>c ((i,\ac: t \ s\)#A) D = concat (map (\B. map (\d. (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#B) D) (tr'\<^sub>p\<^sub>c A D))" | "tr'\<^sub>p\<^sub>c ((i,\X\\\: F \\: F'\)#A) D = map ((@) (map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D)))) (tr'\<^sub>p\<^sub>c A D)" subsubsection \Part 1\ private lemma tr'_par_iff_unlabel_tr: assumes "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. p = q \ i = j" shows "(\C \ set (tr'\<^sub>p\<^sub>c A D). B = unlabel C) \ B \ set (tr (unlabel A) (unlabel D))" (is "?A \ ?B") proof { fix C have "C \ set (tr'\<^sub>p\<^sub>c A D) \ unlabel C \ set (tr (unlabel A) (unlabel D))" using assms proof (induction A D arbitrary: C rule: tr'\<^sub>p\<^sub>c.induct) case (5 i t s S D) hence "unlabel C \ set (tr (unlabel S) (unlabel (List.insert (i, t, s) D)))" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) moreover have "insert (i,t,s) (set D) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i,insert\t,s\)#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "\(j,p) \ insert (i,t,s) (set D). \(k,q) \ insert (i,t,s) (set D). p = q \ j = k" using "5.prems"(2) by blast hence "unlabel (List.insert (i, t, s) D) = (List.insert (t, s) (unlabel D))" using map_snd_list_insert_distrib[of "(i,t,s)" D] unfolding unlabel_def by simp ultimately show ?case by auto next case (6 i t s S D) let ?f1 = "\d. \check: (pair (t,s)) \ (pair d)\\<^sub>s\<^sub>t" let ?g1 = "\d. \[]\\\: [(pair (t,s), pair d)]\\<^sub>s\<^sub>t" let ?f2 = "\d. (i, ?f1 (snd d))" let ?g2 = "\d. (i, ?g1 (snd d))" define constr1 where "constr1 = (\Di. (map ?f1 Di)@(map ?g1 [d\unlabel D. d \ set Di]))" define constr2 where "constr2 = (\Di. (map ?f2 Di)@(map ?g2 [d\D. d \ set Di]))" obtain C' Di where C': "Di \ set (subseqs D)" "C = constr2 Di@C'" "C' \ set (tr'\<^sub>p\<^sub>c S [d\D. d \ set Di])" using "6.prems"(1) unfolding constr2_def by moura have 0: "set [d\D. d \ set Di] \ set D" "setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S)" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence 1: "\(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set [d\D. d \ set Di]. \(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set [d\D. d \ set Di]. p = q \ j = k" using "6.prems"(2) by blast have "\(i,p) \ set D \ set Di. \(j,q) \ set D \ set Di. p = q \ i = j" using "6.prems"(2) subseqs_set_subset(1)[OF C'(1)] by blast hence 2: "unlabel [d\D. d \ set Di] = [d\unlabel D. d \ set (unlabel Di)]" using unlabel_filter_eq[of D "set Di"] unfolding unlabel_def by simp have 3: "\f g::('a \ 'a \ 'c). \A B::(('b \ 'a \ 'a) list). map snd ((map (\d. (i, f (snd d))) A)@(map (\d. (i, g (snd d))) B)) = map f (map snd A)@map g (map snd B)" by simp have "unlabel (constr2 Di) = constr1 (unlabel Di)" using 2 3[of ?f1 Di ?g1 "[d\D. d \ set Di]"] by (simp add: constr1_def constr2_def unlabel_def) hence 4: "unlabel C = constr1 (unlabel Di)@unlabel C'" using C'(2) unlabel_append by metis have "unlabel Di \ set (map unlabel (subseqs D))" using C'(1) unfolding unlabel_def by simp hence 5: "unlabel Di \ set (subseqs (unlabel D))" using map_subseqs[of snd D] unfolding unlabel_def by simp show ?case using "6.IH"[OF C'(1,3) 1] 2 4 5 unfolding constr1_def by auto next case (7 i ac t s S D) obtain C' d where C': "C = (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" "d \ set D" using "7.prems"(1) by moura have "setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i,InSet ac t s)#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "\(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D. \(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D. p = q \ j = k" using "7.prems"(2) by blast hence "unlabel C' \ set (tr (unlabel S) (unlabel D))" using "7.IH"[OF C'(2)] by auto thus ?case using C' unfolding unlabel_def by force next case (8 i X F F' S D) obtain C' where C': "C = map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D))@C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" using "8.prems"(1) by moura have "setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i,NegChecks X F F')#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "\(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D. \(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D. p = q \ j = k" using "8.prems"(2) by blast hence "unlabel C' \ set (tr (unlabel S) (unlabel D))" using "8.IH"[OF C'(2)] by auto thus ?case using C' unfolding unlabel_def by auto qed (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) } thus "?A \ ?B" by blast show "?B \ ?A" using assms proof (induction A arbitrary: B D) case (Cons a A) obtain ia sa where a: "a = (ia,sa)" by moura have "setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t (a#A)" using a by (cases sa) (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence 1: "\(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. \(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. p = q \ j = k" using Cons.prems(2) by blast show ?case proof (cases sa) case (Send t) then obtain B' where B': "B = send\t\\<^sub>s\<^sub>t#B'" "B' \ set (tr (unlabel A) (unlabel D))" using Cons.prems(1) a by auto thus ?thesis using Cons.IH[OF B'(2) 1] a B'(1) Send by auto next case (Receive t) then obtain B' where B': "B = receive\t\\<^sub>s\<^sub>t#B'" "B' \ set (tr (unlabel A) (unlabel D))" using Cons.prems(1) a by auto thus ?thesis using Cons.IH[OF B'(2) 1] a B'(1) Receive by auto next case (Equality ac t t') then obtain B' where B': "B = \ac: t \ t'\\<^sub>s\<^sub>t#B'" "B' \ set (tr (unlabel A) (unlabel D))" using Cons.prems(1) a by auto thus ?thesis using Cons.IH[OF B'(2) 1] a B'(1) Equality by auto next case (Insert t s) hence B: "B \ set (tr (unlabel A) (List.insert (t,s) (unlabel D)))" using Cons.prems(1) a by auto let ?P = "\i. List.insert (t,s) (unlabel D) = unlabel (List.insert (i,t,s) D)" { obtain j where j: "?P j" "j = ia \ (j,t,s) \ set D" using labeled_list_insert_eq_ex_cases[of "(t,s)" D ia] by moura hence "j = ia" using Cons.prems(2) a Insert by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "?P ia" using j(1) by metis } hence j: "?P ia" by metis have 2: "\(k1, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set (List.insert (ia,t,s) D). \(k2, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set (List.insert (ia,t,s) D). p = q \ k1 = k2" using Cons.prems(2) a Insert by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) show ?thesis using Cons.IH[OF _ 2] j(1) B Insert a by auto next case (Delete t s) define c where "c \ (\(i::'lbl strand_label) Di. map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di@ map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\D. d \ set Di])" define d where "d \ (\Di. map (\d. \check: (pair (t,s)) \ (pair d)\\<^sub>s\<^sub>t) Di@ map (\d. \[]\\\: [(pair (t,s), pair d)]\\<^sub>s\<^sub>t) [d\unlabel D. d \ set Di])" obtain B' Di where B': "B = d Di@B'" "Di \ set (subseqs (unlabel D))" "B' \ set (tr (unlabel A) [d\unlabel D. d \ set Di])" using Cons.prems(1) a Delete unfolding d_def by auto obtain Di' where Di': "Di' \ set (subseqs D)" "unlabel Di' = Di" using unlabel_subseqsD[OF B'(2)] by moura have 2: "\(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set [d\D. d \ set Di']. \(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set [d\D. d \ set Di']. p = q \ j = k" using 1 subseqs_subset[OF Di'(1)] filter_is_subset[of "\d. d \ set Di'"] by blast have "set Di' \ set D" by (rule subseqs_subset[OF Di'(1)]) hence "\(j, p)\set D \ set Di'. \(k, q)\set D \ set Di'. p = q \ j = k" using Cons.prems(2) by blast hence 3: "[d\unlabel D. d \ set Di] = unlabel [d\D. d \ set Di']" using Di'(2) unlabel_filter_eq[of D "set Di'"] unfolding unlabel_def by auto obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c A [d\D. d \ set Di'])" "B' = unlabel C" using 3 Cons.IH[OF _ 2] B'(3) by auto hence 4: "c ia Di'@C \ set (tr'\<^sub>p\<^sub>c (a#A) D)" using Di'(1) a Delete unfolding c_def by auto have "unlabel (c ia Di') = d Di" using Di' 3 unfolding c_def d_def unlabel_def by auto hence 5: "B = unlabel (c ia Di'@C)" using B'(1) C(2) unlabel_append[of "c ia Di'" C] by simp show ?thesis using 4 5 by blast next case (InSet ac t s) then obtain B' d where B': "B = \ac: (pair (t,s)) \ (pair d)\\<^sub>s\<^sub>t#B'" "B' \ set (tr (unlabel A) (unlabel D))" "d \ set (unlabel D)" using Cons.prems(1) a by auto thus ?thesis using Cons.IH[OF _ 1] a InSet unfolding unlabel_def by auto next case (NegChecks X F F') then obtain B' where B': "B = map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (unlabel D))@B'" "B' \ set (tr (unlabel A) (unlabel D))" using Cons.prems(1) a by auto thus ?thesis using Cons.IH[OF _ 1] a NegChecks unfolding unlabel_def by auto qed qed simp qed subsubsection \Part 2\ private lemma tr_par_iff_tr'_par: assumes "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. (\\. Unifier \ (pair p) (pair q)) \ i = j" (is "?R3 A D") and "\(l,t,s) \ set D. (fv t \ fv s) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" (is "?R4 A D") and "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" (is "?R5 A D") shows "(\B \ set (tr\<^sub>p\<^sub>c A D). \M; unlabel B\\<^sub>d \) \ (\C \ set (tr'\<^sub>p\<^sub>c A D). \M; unlabel C\\<^sub>d \)" (is "?P \ ?Q") proof { fix B assume "B \ set (tr\<^sub>p\<^sub>c A D)" "\M; unlabel B\\<^sub>d \" hence ?Q using assms proof (induction A D arbitrary: B M rule: tr\<^sub>p\<^sub>c.induct) case (1 D) thus ?case by simp next case (2 i t S D) note prems = "2.prems" note IH = "2.IH" obtain B' where B': "B = (i,send\t\\<^sub>s\<^sub>t)#B'" "B' \ set (tr\<^sub>p\<^sub>c S D)" using prems(1) by moura have 1: "\M; unlabel B'\\<^sub>d \" using prems(2) B'(1) by simp have 4: "?R3 S D" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force have 7: "M \ t \ \" using prems(2) B'(1) by simp obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c S D)" "\M; unlabel C\\<^sub>d \" using IH[OF B'(2) 1 4 5 6] by moura hence "((i,send\t\\<^sub>s\<^sub>t)#C) \ set (tr'\<^sub>p\<^sub>c ((i,Send t)#S) D)" "\M; unlabel ((i,send\t\\<^sub>s\<^sub>t)#C)\\<^sub>d \" using 7 by auto thus ?case by metis next case (3 i t S D) note prems = "3.prems" note IH = "3.IH" obtain B' where B': "B = (i,receive\t\\<^sub>s\<^sub>t)#B'" "B' \ set (tr\<^sub>p\<^sub>c S D)" using prems(1) by moura have 1: "\insert (t \ \) M; unlabel B'\\<^sub>d \ " using prems(2) B'(1) by simp have 4: "?R3 S D" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c S D)" "\insert (t \ \) M; unlabel C\\<^sub>d \" using IH[OF B'(2) 1 4 5 6] by moura hence "((i,receive\t\\<^sub>s\<^sub>t)#C) \ set (tr'\<^sub>p\<^sub>c ((i,receive\t\)#S) D)" "\insert (t \ \) M; unlabel ((i,receive\t\\<^sub>s\<^sub>t)#C)\\<^sub>d \" by auto thus ?case by auto next case (4 i ac t t' S D) note prems = "4.prems" note IH = "4.IH" obtain B' where B': "B = (i,\ac: t \ t'\\<^sub>s\<^sub>t)#B'" "B' \ set (tr\<^sub>p\<^sub>c S D)" using prems(1) by moura have 1: "\M; unlabel B'\\<^sub>d \ " using prems(2) B'(1) by simp have 4: "?R3 S D" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force have 7: "t \ \ = t' \ \" using prems(2) B'(1) by simp obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c S D)" "\M; unlabel C\\<^sub>d \" using IH[OF B'(2) 1 4 5 6] by moura hence "((i,\ac: t \ t'\\<^sub>s\<^sub>t)#C) \ set (tr'\<^sub>p\<^sub>c ((i,Equality ac t t')#S) D)" "\M; unlabel ((i,\ac: t \ t'\\<^sub>s\<^sub>t)#C)\\<^sub>d \" using 7 by auto thus ?case by metis next case (5 i t s S D) note prems = "5.prems" note IH = "5.IH" have B: "B \ set (tr\<^sub>p\<^sub>c S (List.insert (i,t,s) D))" using prems(1) by simp have 1: "\M; unlabel B\\<^sub>d \ " using prems(2) B(1) by simp have 4: "?R3 S (List.insert (i,t,s) D)" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S (List.insert (i,t,s) D)" using prems(4,5) by force have 6: "?R5 S D" using prems(5) by force show ?case using IH[OF B(1) 1 4 5 6] by simp next case (6 i t s S D) note prems = "6.prems" note IH = "6.IH" let ?cl1 = "\Di. map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di" let ?cu1 = "\Di. map (\d. \check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t) Di" let ?cl2 = "\Di. map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d\set Di]" let ?cu2 = "\Di. map (\d. \[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\dbproj i D. d\set Di]" let ?dl1 = "\Di. map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di" let ?du1 = "\Di. map (\d. \check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t) Di" let ?dl2 = "\Di. map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\D. d\set Di]" let ?du2 = "\Di. map (\d. \[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\D. d\set Di]" define c where c: "c = (\Di. ?cl1 Di@?cl2 Di)" define d where d: "d = (\Di. ?dl1 Di@?dl2 Di)" obtain B' Di where B': "Di \ set (subseqs (dbproj i D))" "B = c Di@B'" "B' \ set (tr\<^sub>p\<^sub>c S [d\D. d \ set Di])" using prems(1) c by moura have 0: "ik\<^sub>s\<^sub>t (unlabel (c Di)) = {}" "ik\<^sub>s\<^sub>t (unlabel (d Di)) = {}" "unlabel (?cl1 Di) = ?cu1 Di" "unlabel (?cl2 Di) = ?cu2 Di" "unlabel (?dl1 Di) = ?du1 Di" "unlabel (?dl2 Di) = ?du2 Di" unfolding c d unlabel_def by force+ have 1: "\M; unlabel B'\\<^sub>d \ " using prems(2) B'(2) 0(1) unfolding unlabel_def by auto { fix j p k q assume "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set [d\D. d \ set Di]" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set [d\D. d \ set Di]" hence "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" using dbproj_subseq_subset[OF B'(1)] by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence 4: "?R3 S [d\D. d \ set Di]" by blast have 5: "?R4 S (filter (\d. d \ set Di) D)" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c S [d\D . d \ set Di])" "\M; unlabel C\\<^sub>d \" using IH[OF B'(1,3) 1 4 5 6] by moura have 7: "\M; unlabel (c Di)\\<^sub>d \" "\M; unlabel B'\\<^sub>d \" using prems(2) B'(2) 0(1) strand_sem_split(3,4)[of M "unlabel (c Di)" "unlabel B'"] unfolding c unlabel_def by auto have "\M; unlabel (?cl2 Di)\\<^sub>d \" using 7(1) 0(1) unfolding c unlabel_def by auto hence "\M; ?cu2 Di\\<^sub>d \" by (metis 0(4)) moreover { fix j p k q assume "(j, p) \ {(i, t, s)} \ set D \ set Di" "(k, q) \ {(i, t, s)} \ set D \ set Di" hence "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" using dbproj_subseq_subset[OF B'(1)] by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence "\(j, p) \ {(i, t, s)} \ set D \ set Di. \(k, q) \ {(i, t, s)} \ set D \ set Di. (\\. Unifier \ (pair p) (pair q)) \ j = k" by blast ultimately have "\M; ?du2 Di\\<^sub>d \" using labeled_sat_ineq_lift by simp hence "\M; unlabel (?dl2 Di)\\<^sub>d \" by (metis 0(6)) moreover have "\M; unlabel (?cl1 Di)\\<^sub>d \" using 7(1) unfolding c unlabel_def by auto hence "\M; unlabel (?dl1 Di)\\<^sub>d \" by (metis 0(3,5)) ultimately have "\M; unlabel (d Di)\\<^sub>d \" using 0(2) unfolding c d unlabel_def by force hence 8: "\M; unlabel (d Di@C)\\<^sub>d \" using 0(2) C(2) unfolding unlabel_def by auto have 9: "d Di@C \ set (tr'\<^sub>p\<^sub>c ((i,delete\t,s\)#S) D)" using C(1) dbproj_subseq_in_subseqs[OF B'(1)] unfolding d unlabel_def by auto show ?case by (metis 8 9) next case (7 i ac t s S D) note prems = "7.prems" note IH = "7.IH" obtain B' d where B': "B = (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#B'" "B' \ set (tr\<^sub>p\<^sub>c S D)" "d \ set (dbproj i D)" using prems(1) by moura have 1: "\M; unlabel B'\\<^sub>d \ " using prems(2) B'(1) by simp { fix j p k q assume "(j,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D" "(k,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D" hence "(j,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, InSet ac t s)#S) \ set D" "(k,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, InSet ac t s)#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence 4: "?R3 S D" by blast have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force have 7: "pair (t,s) \ \ = pair (snd d) \ \" using prems(2) B'(1) by simp obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c S D)" "\M; unlabel C\\<^sub>d \" using IH[OF B'(2) 1 4 5 6] by moura hence "((i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#C) \ set (tr'\<^sub>p\<^sub>c ((i,InSet ac t s)#S) D)" "\M; unlabel ((i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#C)\\<^sub>d \" using 7 B'(3) by auto thus ?case by metis next case (8 i X F F' S D) note prems = "8.prems" note IH = "8.IH" let ?cl = "map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" let ?cu = "map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" let ?dl = "map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D))" let ?du = "map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D))" define c where c: "c = ?cl" define d where d: "d = ?dl" obtain B' where B': "B = c@B'" "B' \ set (tr\<^sub>p\<^sub>c S D)" using prems(1) c by moura have 0: "ik\<^sub>s\<^sub>t (unlabel c) = {}" "ik\<^sub>s\<^sub>t (unlabel d) = {}" "unlabel ?cl = ?cu" "unlabel ?dl = ?du" unfolding c d unlabel_def by force+ have "ik\<^sub>s\<^sub>t (unlabel c) = {}" unfolding c unlabel_def by force hence 1: "\M; unlabel B'\\<^sub>d \ " using prems(2) B'(1) unfolding unlabel_def by auto have "setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, NegChecks X F F')#S)" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence 4: "?R3 S D" using prems(3) by blast have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain C where C: "C \ set (tr'\<^sub>p\<^sub>c S D)" "\M; unlabel C\\<^sub>d \" using IH[OF B'(2) 1 4 5 6] by moura have 7: "\M; unlabel c\\<^sub>d \" "\M; unlabel B'\\<^sub>d \" using prems(2) B'(1) 0(1) strand_sem_split(3,4)[of M "unlabel c" "unlabel B'"] unfolding c unlabel_def by auto have 8: "d@C \ set (tr'\<^sub>p\<^sub>c ((i,NegChecks X F F')#S) D)" using C(1) unfolding d unlabel_def by auto have "\M; unlabel ?cl\\<^sub>d \" using 7(1) unfolding c unlabel_def by auto hence "\M; ?cu\\<^sub>d \" by (metis 0(3)) moreover { fix j p k q assume "(j, p) \ ((\(t,s). (i,t,s)) ` set F') \ set D" "(k, q) \ ((\(t,s). (i,t,s)) ` set F') \ set D" hence "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, NegChecks X F F')#S) \ set D" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, NegChecks X F F')#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence "\(j, p) \ ((\(t,s). (i,t,s)) ` set F') \ set D. \(k, q) \ ((\(t,s). (i,t,s)) ` set F') \ set D. (\\. Unifier \ (pair p) (pair q)) \ j = k" by blast moreover have "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (map snd D) \ set X = {}" using prems(4) by fastforce ultimately have "\M; ?du\\<^sub>d \" using labeled_sat_ineq_dbproj_sem_equiv[of i] by simp hence "\M; unlabel ?dl\\<^sub>d \" by (metis 0(4)) hence "\M; unlabel d\\<^sub>d \" using 0(2) unfolding c d unlabel_def by force hence 9: "\M; unlabel (d@C)\\<^sub>d \" using 0(2) C(2) unfolding unlabel_def by auto show ?case by (metis 8 9) qed } thus "?P \ ?Q" by metis { fix C assume "C \ set (tr'\<^sub>p\<^sub>c A D)" "\M; unlabel C\\<^sub>d \" hence ?P using assms proof (induction A D arbitrary: C M rule: tr'\<^sub>p\<^sub>c.induct) case (1 D) thus ?case by simp next case (2 i t S D) note prems = "2.prems" note IH = "2.IH" obtain C' where C': "C = (i,send\t\\<^sub>s\<^sub>t)#C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" using prems(1) by moura have 1: "\M; unlabel C'\\<^sub>d \ " using prems(2) C'(1) by simp have 4: "?R3 S D" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force have 7: "M \ t \ \" using prems(2) C'(1) by simp obtain B where B: "B \ set (tr\<^sub>p\<^sub>c S D)" "\M; unlabel B\\<^sub>d \" using IH[OF C'(2) 1 4 5 6] by moura hence "((i,send\t\\<^sub>s\<^sub>t)#B) \ set (tr\<^sub>p\<^sub>c ((i,Send t)#S) D)" "\M; unlabel ((i,send\t\\<^sub>s\<^sub>t)#B)\\<^sub>d \" using 7 by auto thus ?case by metis next case (3 i t S D) note prems = "3.prems" note IH = "3.IH" obtain C' where C': "C = (i,receive\t\\<^sub>s\<^sub>t)#C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" using prems(1) by moura have 1: "\insert (t \ \) M; unlabel C'\\<^sub>d \ " using prems(2) C'(1) by simp have 4: "?R3 S D" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain B where B: "B \ set (tr\<^sub>p\<^sub>c S D)" "\insert (t \ \) M; unlabel B\\<^sub>d \" using IH[OF C'(2) 1 4 5 6] by moura hence "((i,receive\t\\<^sub>s\<^sub>t)#B) \ set (tr\<^sub>p\<^sub>c ((i,receive\t\)#S) D)" "\insert (t \ \) M; unlabel ((i,receive\t\\<^sub>s\<^sub>t)#B)\\<^sub>d \" by auto thus ?case by auto next case (4 i ac t t' S D) note prems = "4.prems" note IH = "4.IH" obtain C' where C': "C = (i,\ac: t \ t'\\<^sub>s\<^sub>t)#C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" using prems(1) by moura have 1: "\M; unlabel C'\\<^sub>d \ " using prems(2) C'(1) by simp have 4: "?R3 S D" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force have 7: "t \ \ = t' \ \" using prems(2) C'(1) by simp obtain B where B: "B \ set (tr\<^sub>p\<^sub>c S D)" "\M; unlabel B\\<^sub>d \" using IH[OF C'(2) 1 4 5 6] by moura hence "((i,\ac: t \ t'\\<^sub>s\<^sub>t)#B) \ set (tr\<^sub>p\<^sub>c ((i,Equality ac t t')#S) D)" "\M; unlabel ((i,\ac: t \ t'\\<^sub>s\<^sub>t)#B)\\<^sub>d \" using 7 by auto thus ?case by metis next case (5 i t s S D) note prems = "5.prems" note IH = "5.IH" have C: "C \ set (tr'\<^sub>p\<^sub>c S (List.insert (i,t,s) D))" using prems(1) by simp have 1: "\M; unlabel C\\<^sub>d \ " using prems(2) C(1) by simp have 4: "?R3 S (List.insert (i,t,s) D)" using prems(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) have 5: "?R4 S (List.insert (i,t,s) D)" using prems(4,5) by force have 6: "?R5 S (List.insert (i,t,s) D)" using prems(5) by force show ?case using IH[OF C(1) 1 4 5 6] by simp next case (6 i t s S D) note prems = "6.prems" note IH = "6.IH" let ?dl1 = "\Di. map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di" let ?du1 = "\Di. map (\d. \check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t) Di" let ?dl2 = "\Di. map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\dbproj i D. d\set Di]" let ?du2 = "\Di. map (\d. \[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\dbproj i D. d\set Di]" let ?cl1 = "\Di. map (\d. (i,\check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)) Di" let ?cu1 = "\Di. map (\d. \check: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t) Di" let ?cl2 = "\Di. map (\d. (i,\[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t)) [d\D. d\set Di]" let ?cu2 = "\Di. map (\d. \[]\\\: [(pair (t,s), pair (snd d))]\\<^sub>s\<^sub>t) [d\D. d\set Di]" define c where c: "c = (\Di. ?cl1 Di@?cl2 Di)" define d where d: "d = (\Di. ?dl1 Di@?dl2 Di)" obtain C' Di where C': "Di \ set (subseqs D)" "C = c Di@C'" "C' \ set (tr'\<^sub>p\<^sub>c S [d\D. d \ set Di])" using prems(1) c by moura have 0: "ik\<^sub>s\<^sub>t (unlabel (c Di)) = {}" "ik\<^sub>s\<^sub>t (unlabel (d Di)) = {}" "unlabel (?cl1 Di) = ?cu1 Di" "unlabel (?cl2 Di) = ?cu2 Di" "unlabel (?dl1 Di) = ?du1 Di" "unlabel (?dl2 Di) = ?du2 Di" unfolding c d unlabel_def by force+ have 1: "\M; unlabel C'\\<^sub>d \ " using prems(2) C'(2) 0(1) unfolding unlabel_def by auto { fix j p k q assume "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set [d\D. d \ set Di]" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set [d\D. d \ set Di]" hence "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence 4: "?R3 S [d\D. d \ set Di]" by blast have 5: "?R4 S (filter (\d. d \ set Di) D)" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain B where B: "B \ set (tr\<^sub>p\<^sub>c S [d\D. d \ set Di])" "\M; unlabel B\\<^sub>d \" using IH[OF C'(1,3) 1 4 5 6] by moura have 7: "\M; unlabel (c Di)\\<^sub>d \" "\M; unlabel C'\\<^sub>d \" using prems(2) C'(2) 0(1) strand_sem_split(3,4)[of M "unlabel (c Di)" "unlabel C'"] unfolding c unlabel_def by auto { fix j p k q assume "(j, p) \ {(i, t, s)} \ set D" "(k, q) \ {(i, t, s)} \ set D" hence "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, delete\t,s\)#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence "\(j, p) \ {(i, t, s)} \ set D. \(k, q) \ {(i, t, s)} \ set D. (\\. Unifier \ (pair p) (pair q)) \ j = k" by blast moreover have "\M; unlabel (?cl1 Di)\\<^sub>d \" using 7(1) unfolding c unlabel_append by auto hence "\M; ?cu1 Di\\<^sub>d \" by (metis 0(3)) ultimately have *: "Di \ set (subseqs (dbproj i D))" using labeled_sat_eqs_subseqs[OF C'(1)] by simp hence 8: "d Di@B \ set (tr\<^sub>p\<^sub>c ((i,delete\t,s\)#S) D)" using B(1) unfolding d unlabel_def by auto have "\M; unlabel (?cl2 Di)\\<^sub>d \" using 7(1) 0(1) unfolding c unlabel_def by auto hence "\M; ?cu2 Di\\<^sub>d \" by (metis 0(4)) hence "\M; ?du2 Di\\<^sub>d \" by (metis labeled_sat_ineq_dbproj) hence "\M; unlabel (?dl2 Di)\\<^sub>d \" by (metis 0(6)) moreover have "\M; unlabel (?cl1 Di)\\<^sub>d \" using 7(1) unfolding c unlabel_def by auto hence "\M; unlabel (?dl1 Di)\\<^sub>d \" by (metis 0(3,5)) ultimately have "\M; unlabel (d Di)\\<^sub>d \" using 0(2) unfolding c d unlabel_def by force hence 9: "\M; unlabel (d Di@B)\\<^sub>d \" using 0(2) B(2) unfolding unlabel_def by auto show ?case by (metis 8 9) next case (7 i ac t s S D) note prems = "7.prems" note IH = "7.IH" obtain C' d where C': "C = (i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" "d \ set D" using prems(1) by moura have 1: "\M; unlabel C'\\<^sub>d \ " using prems(2) C'(1) by simp { fix j p k q assume "(j,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D" "(k,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ set D" hence "(j,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, InSet ac t s)#S) \ set D" "(k,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, InSet ac t s)#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence 4: "?R3 S D" by blast have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain B where B: "B \ set (tr\<^sub>p\<^sub>c S D)" "\M; unlabel B\\<^sub>d \" using IH[OF C'(2) 1 4 5 6] by moura have 7: "pair (t,s) \ \ = pair (snd d) \ \" using prems(2) C'(1) by simp have "(i,t,s) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, InSet ac t s)#S) \ set D" "(fst d, snd d) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, InSet ac t s)#S) \ set D" using C'(3) by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "\\. Unifier \ (pair (t,s)) (pair (snd d)) \ i = fst d" using prems(3) by blast hence "fst d = i" using 7 by auto hence 8: "d \ set (dbproj i D)" using C'(3) by auto have 9: "((i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#B) \ set (tr\<^sub>p\<^sub>c ((i,InSet ac t s)#S) D)" using B 8 by auto have 10: "\M; unlabel ((i,\ac: (pair (t,s)) \ (pair (snd d))\\<^sub>s\<^sub>t)#B)\\<^sub>d \" using B 7 8 by auto show ?case by (metis 9 10) next case (8 i X F F' S D) note prems = "8.prems" note IH = "8.IH" let ?dl = "map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" let ?du = "map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd (dbproj i D)))" let ?cl = "map (\G. (i,\X\\\: (F@G)\\<^sub>s\<^sub>t)) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D))" let ?cu = "map (\G. \X\\\: (F@G)\\<^sub>s\<^sub>t) (tr\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F' (map snd D))" define c where c: "c = ?cl" define d where d: "d = ?dl" obtain C' where C': "C = c@C'" "C' \ set (tr'\<^sub>p\<^sub>c S D)" using prems(1) c by moura have 0: "ik\<^sub>s\<^sub>t (unlabel c) = {}" "ik\<^sub>s\<^sub>t (unlabel d) = {}" "unlabel ?cl = ?cu" "unlabel ?dl = ?du" unfolding c d unlabel_def by force+ have "ik\<^sub>s\<^sub>t (unlabel c) = {}" unfolding c unlabel_def by force hence 1: "\M; unlabel C'\\<^sub>d \ " using prems(2) C'(1) unfolding unlabel_def by auto have "setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t S \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, NegChecks X F F')#S)" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence 4: "?R3 S D" using prems(3) by blast have 5: "?R4 S D" using prems(4) by force have 6: "?R5 S D" using prems(5) by force obtain B where B: "B \ set (tr\<^sub>p\<^sub>c S D)" "\M; unlabel B\\<^sub>d \" using IH[OF C'(2) 1 4 5 6] by moura have 7: "\M; unlabel c\\<^sub>d \" "\M; unlabel C'\\<^sub>d \" using prems(2) C'(1) 0(1) strand_sem_split(3,4)[of M "unlabel c" "unlabel C'"] unfolding c unlabel_def by auto have 8: "d@B \ set (tr\<^sub>p\<^sub>c ((i,NegChecks X F F')#S) D)" using B(1) unfolding d unlabel_def by auto have "\M; unlabel ?cl\\<^sub>d \" using 7(1) unfolding c unlabel_def by auto hence "\M; ?cu\\<^sub>d \" by (metis 0(3)) moreover { fix j p k q assume "(j, p) \ ((\(t,s). (i,t,s)) ` set F') \ set D" "(k, q) \ ((\(t,s). (i,t,s)) ` set F') \ set D" hence "(j, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, NegChecks X F F')#S) \ set D" "(k, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t ((i, NegChecks X F F')#S) \ set D" by (auto simp add: setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def) hence "(\\. Unifier \ (pair p) (pair q)) \ j = k" using prems(3) by blast } hence "\(j, p) \ ((\(t,s). (i,t,s)) ` set F') \ set D. \(k, q) \ ((\(t,s). (i,t,s)) ` set F') \ set D. (\\. Unifier \ (pair p) (pair q)) \ j = k" by blast moreover have "fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (map snd D) \ set X = {}" using prems(4) by fastforce ultimately have "\M; ?du\\<^sub>d \" using labeled_sat_ineq_dbproj_sem_equiv[of i] by simp hence "\M; unlabel ?dl\\<^sub>d \" by (metis 0(4)) hence "\M; unlabel d\\<^sub>d \" using 0(2) unfolding c d unlabel_def by force hence 9: "\M; unlabel (d@B)\\<^sub>d \" using 0(2) B(2) unfolding unlabel_def by auto show ?case by (metis 8 9) qed } thus "?Q \ ?P" by metis qed subsubsection \Part 3\ private lemma tr'_par_sem_equiv: assumes "\(l,t,s) \ set D. (fv t \ fv s) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" and "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" "ground M" and "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. (\\. Unifier \ (pair p) (pair q)) \ i = j" (is "?R A D") and \: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" shows "\M; set (unlabel D) \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \; unlabel A\\<^sub>s \ \ (\B \ set (tr'\<^sub>p\<^sub>c A D). \M; unlabel B\\<^sub>d \)" (is "?P \ ?Q") proof - have 1: "\(t,s) \ set (unlabel D). (fv t \ fv s) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" using assms(1) unfolding unlabel_def by force have 2: "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. p = q \ i = j" using assms(4) subst_apply_term_empty by blast show ?thesis by (metis tr_sem_equiv'[OF 1 assms(2,3) \] tr'_par_iff_unlabel_tr[OF 2]) qed subsubsection \Part 4\ lemma tr_par_sem_equiv: assumes "\(l,t,s) \ set D. (fv t \ fv s) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" and "fv\<^sub>s\<^sub>s\<^sub>t (unlabel A) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel A) = {}" "ground M" and "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ set D. (\\. Unifier \ (pair p) (pair q)) \ i = j" and \: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" shows "\M; set (unlabel D) \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \; unlabel A\\<^sub>s \ \ (\B \ set (tr\<^sub>p\<^sub>c A D). \M; unlabel B\\<^sub>d \)" (is "?P \ ?Q") using tr_par_iff_tr'_par[OF assms(4,1,2), of M \] tr'_par_sem_equiv[OF assms] by metis end subsection \Theorem: The Stateful Compositionality Result, on the Constraint Level\ theorem par_comp_constr_stateful: assumes \: "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ Sec" "typing_cond\<^sub>s\<^sub>s\<^sub>t (unlabel \)" and \: "\ \\<^sub>s unlabel \" "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" shows "\\\<^sub>\. interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\) \ (\\<^sub>\ \\<^sub>s unlabel \) \ ((\n. \\<^sub>\ \\<^sub>s proj_unl n \) \ (\\'. prefix \' \ \ (\' leaks Sec under \\<^sub>\)))" proof - let ?P = "\n A D. \(i, p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj n A) \ set D. \(j, q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj n A) \ set D. (\\. Unifier \ (pair p) (pair q)) \ i = j" have 1: "\(l, t, t')\set []. (fv t \ fv t') \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel \) = {}" "fv\<^sub>s\<^sub>s\<^sub>t (unlabel \) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel \) = {}" "ground {}" using \(2) unfolding typing_cond\<^sub>s\<^sub>s\<^sub>t_def by simp_all have 2: "\n. \(l, t, t')\set []. (fv t \ fv t') \ bvars\<^sub>s\<^sub>s\<^sub>t (proj_unl n \) = {}" "\n. fv\<^sub>s\<^sub>s\<^sub>t (proj_unl n \) \ bvars\<^sub>s\<^sub>s\<^sub>t (proj_unl n \) = {}" using 1(1,2) sst_vars_proj_subset[of _ \] by fast+ have 3: "\n. par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj n \) Sec" using par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_proj[OF \(1)] by metis have 4: "\{}; set (unlabel []) \\<^sub>p\<^sub>s\<^sub>e\<^sub>t \'; unlabel \\\<^sub>s \' \ (\B\set (tr\<^sub>p\<^sub>c \ []). \{}; unlabel B\\<^sub>d \')" when \': "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \'" for \' using tr_par_sem_equiv[OF 1 _ \'] \(1) unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def constr_sem_d_def by auto obtain \' where \': "\' \ set (tr\<^sub>p\<^sub>c \ [])" "\ \ \unlabel \'\" using 4[OF \(2)] \(1) unfolding constr_sem_d_def by moura obtain \\<^sub>\ where \\<^sub>\: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\)" "\\<^sub>\ \ \unlabel \'\" "(\n. (\\<^sub>\ \ \proj_unl n \'\)) \ (\\''. prefix \'' \' \ (strand_leaks\<^sub>l\<^sub>s\<^sub>t \'' Sec \\<^sub>\))" using par_comp_constr[OF tr_par_preserves_par_comp[OF \(1) \'(1)] tr_par_preserves_typing_cond[OF \ \'(1)] \'(2) \(2)] by moura have \\<^sub>\': "\\<^sub>\ \\<^sub>s unlabel \" using 4[OF \\<^sub>\(1)] \'(1) \\<^sub>\(4) unfolding constr_sem_d_def by auto show ?thesis proof (cases "\n. (\\<^sub>\ \ \proj_unl n \'\)") case True { fix n assume "\\<^sub>\ \ \proj_unl n \'\" hence "\{}; {}; unlabel (proj n \)\\<^sub>s \\<^sub>\" using tr_par_proj[OF \'(1), of n] tr_par_sem_equiv[OF 2(1,2) 1(3) _ \\<^sub>\(1), of n] 3(1) unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def proj_def constr_sem_d_def by force } thus ?thesis using True \\<^sub>\(1,2,3) \\<^sub>\' by metis next case False then obtain \''::"('fun,'var,'lbl) labeled_strand" where \'': "prefix \'' \'" "strand_leaks\<^sub>l\<^sub>s\<^sub>t \'' Sec \\<^sub>\" using \\<^sub>\ by blast moreover { fix t l assume *: "\{}; unlabel (proj l \'')@[send\t\\<^sub>s\<^sub>t]\\<^sub>d \\<^sub>\" have "\\<^sub>\ \ \unlabel (proj l \'')\" "ik\<^sub>s\<^sub>t (unlabel (proj l \'')) \\<^sub>s\<^sub>e\<^sub>t \\<^sub>\ \ t \ \\<^sub>\" using strand_sem_split(3,4)[OF *] unfolding constr_sem_d_def by auto } ultimately have "\t \ Sec - declassified\<^sub>l\<^sub>s\<^sub>t \'' \\<^sub>\. \l. (\\<^sub>\ \ \unlabel (proj l \'')\) \ ik\<^sub>s\<^sub>t (unlabel (proj l \'')) \\<^sub>s\<^sub>e\<^sub>t \\<^sub>\ \ t \ \\<^sub>\" unfolding strand_leaks\<^sub>l\<^sub>s\<^sub>t_def constr_sem_d_def by metis then obtain s m where sm: "s \ Sec - declassified\<^sub>l\<^sub>s\<^sub>t \'' \\<^sub>\" "\\<^sub>\ \ \unlabel (proj m \'')\" "ik\<^sub>s\<^sub>t (unlabel (proj m \'')) \\<^sub>s\<^sub>e\<^sub>t \\<^sub>\ \ s \ \\<^sub>\" by moura \ \ We now need to show that there is some prefix \B\ of \\''\ that also leaks and where \B \ set (tr C D)\ for some prefix \C\ of \\\ \ obtain B::"('fun,'var,'lbl) labeled_strand" and C::"('fun,'var,'lbl) labeled_stateful_strand" where BC: "prefix B \'" "prefix C \" "B \ set (tr\<^sub>p\<^sub>c C [])" "ik\<^sub>s\<^sub>t (unlabel (proj m B)) \\<^sub>s\<^sub>e\<^sub>t \\<^sub>\ \ s \ \\<^sub>\" "prefix B \''" using tr_leaking_prefix_exists[OF \'(1) \''(1) sm(3)] prefix_order.order_trans[OF _ \''(1)] by auto have "\{}; unlabel (proj m B)\\<^sub>d \\<^sub>\" using sm(2) BC(5) unfolding prefix_def unlabel_def proj_def constr_sem_d_def by auto hence BC': "\\<^sub>\ \ \proj_unl m B@[send\s\\<^sub>s\<^sub>t]\" using BC(4) unfolding constr_sem_d_def by auto have BC'': "s \ Sec - declassified\<^sub>l\<^sub>s\<^sub>t B \\<^sub>\" using BC(5) sm(1) unfolding prefix_def declassified\<^sub>l\<^sub>s\<^sub>t_def by auto have 5: "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj n C) Sec" for n using \(1) BC(2) par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_split(1)[THEN par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_proj] unfolding prefix_def by auto have "fv\<^sub>s\<^sub>s\<^sub>t (unlabel \) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel \) = {}" "fv\<^sub>s\<^sub>s\<^sub>t (unlabel C) \ fv\<^sub>s\<^sub>s\<^sub>t (unlabel \)" "bvars\<^sub>s\<^sub>s\<^sub>t (unlabel C) \ bvars\<^sub>s\<^sub>s\<^sub>t (unlabel \)" using \(2) BC(2) sst_vars_append_subset(1,2)[of "unlabel C"] unfolding typing_cond\<^sub>s\<^sub>s\<^sub>t_def prefix_def unlabel_def by auto hence "fv\<^sub>s\<^sub>s\<^sub>t (proj_unl n C) \ bvars\<^sub>s\<^sub>s\<^sub>t (proj_unl n C) = {}" for n using sst_vars_proj_subset[of _ C] sst_vars_proj_subset[of _ \] by blast hence 6: "\(l, t, t')\set []. (fv t \ fv t') \ bvars\<^sub>s\<^sub>s\<^sub>t (proj_unl n C) = {}" "fv\<^sub>s\<^sub>s\<^sub>t (proj_unl n C) \ bvars\<^sub>s\<^sub>s\<^sub>t (proj_unl n C) = {}" "ground {}" for n using 2 by auto have 7: "?P n C []" for n using 5 unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by simp have "s \ \\<^sub>\ = s" using \\<^sub>\(1) BC'' \(1) unfolding par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by auto hence "\n. (\\<^sub>\ \\<^sub>s proj_unl n C) \ ik\<^sub>s\<^sub>s\<^sub>t (proj_unl n C) \\<^sub>s\<^sub>e\<^sub>t \\<^sub>\ \ s \ \\<^sub>\" using tr_par_proj[OF BC(3), of m] BC'(1) tr_par_sem_equiv[OF 6 7 \\<^sub>\(1), of m] tr_par_deduct_iff[OF tr_par_proj(1)[OF BC(3)], of \\<^sub>\ m s] unfolding proj_def constr_sem_d_def by auto hence "\n. \\<^sub>\ \\<^sub>s (proj_unl n C@[Send s])" using strand_sem_append_stateful by simp moreover have "s \ Sec - declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t C \\<^sub>\" by (metis tr_par_declassified_eq BC(3) BC'') ultimately show ?thesis using \\<^sub>\(1,2,3) \\<^sub>\' BC(2) unfolding strand_leaks\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by metis qed qed subsection \Theorem: The Stateful Compositionality Result, on the Protocol Level\ abbreviation wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t where "wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t V \ \ wf'\<^sub>s\<^sub>s\<^sub>t V (unlabel \)" text \ We state our result on the level of protocol traces (i.e., the constraints reachable in a symbolic execution of the actual protocol). Hence, we do not need to convert protocol strands to intruder constraints in the following well-formedness definitions. \ definition wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s::"('fun,'var,'lbl) labeled_stateful_strand set \ bool" where "wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s \ \ (\\ \ \. wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t {} \) \ (\\ \ \. \\' \ \. fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' = {})" definition wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s':: "('fun,'var,'lbl) labeled_stateful_strand set \ ('fun,'var,'lbl) labeled_stateful_strand \ bool" where "wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s' \ \ \ (\\' \ \. wf'\<^sub>s\<^sub>s\<^sub>t (wfrestrictedvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \) (unlabel \')) \ (\\' \ \. \\'' \ \. fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \'' = {}) \ (\\' \ \. fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ = {}) \ (\\' \ \. fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' = {})" definition typing_cond_prot_stateful where "typing_cond_prot_stateful \

\ wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s \

\ tfr\<^sub>s\<^sub>e\<^sub>t (\(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

) \ pair ` \(setops\<^sub>s\<^sub>s\<^sub>t ` unlabel ` \

)) \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

)) \ (\S \ \

. list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel S))" definition par_comp_prot_stateful where "par_comp_prot_stateful \

Sec \ (\l1 l2. l1 \ l2 \ GSMP_disjoint (\\ \ \

. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \)) (\\ \ \

. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \)) Sec) \ ground Sec \ (\s \ Sec. \s' \ subterms s. {} \\<^sub>c s' \ s' \ Sec) \ (\(i,p) \ \\ \ \

. setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t \. \(j,q) \ \\ \ \

. setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t \. (\\. Unifier \ (pair p) (pair q)) \ i = j) \ typing_cond_prot_stateful \

" definition component_secure_prot_stateful where "component_secure_prot_stateful n P Sec attack \ (\\ \ P. suffix [(ln n, Send (Fun attack []))] \ \ (\\\<^sub>\. (interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\)) \ \(\\<^sub>\ \\<^sub>s (proj_unl n \)) \ (\\'. prefix \' \ \ (\t \ Sec-declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \\<^sub>\. \(\\<^sub>\ \\<^sub>s (proj_unl n \'@[Send t]))))))" definition component_leaks_stateful where "component_leaks_stateful n \ Sec \ (\\' \\<^sub>\. interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\) \ prefix \' \ \ (\t \ Sec - declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \\<^sub>\. (\\<^sub>\ \\<^sub>s (proj_unl n \'@[Send t]))))" definition unsat_stateful where "unsat_stateful \ \ (\\. interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ \(\ \\<^sub>s unlabel \))" lemma wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s_eqs_wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s'[simp]: "wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s S = wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s' S []" unfolding wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s_def wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s'_def unlabel_def wfrestrictedvars\<^sub>s\<^sub>s\<^sub>t_def by simp lemma par_comp_prot_impl_par_comp_stateful: assumes "par_comp_prot_stateful \

Sec" "\ \ \

" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ Sec" proof - have *: "\l1 l2. l1 \ l2 \ GSMP_disjoint (\\ \ \

. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \)) (\\ \ \

. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \)) Sec" using assms(1) unfolding par_comp_prot_stateful_def by argo { fix l1 l2::'lbl assume **: "l1 \ l2" hence ***: "GSMP_disjoint (\\ \ \

. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \)) (\\ \ \

. trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \)) Sec" using * by auto have "GSMP_disjoint (trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \)) (trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \)) Sec" using GSMP_disjoint_subset[OF ***] assms(2) by auto } hence "\l1 l2. l1 \ l2 \ GSMP_disjoint (trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l1 \)) (trms\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l2 \)) Sec" by metis moreover have "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t \. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t \. (\\. Unifier \ (pair p) (pair q)) \ i = j" using assms(1,2) unfolding par_comp_prot_stateful_def by blast ultimately show ?thesis using assms unfolding par_comp_prot_stateful_def par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by fast qed lemma typing_cond_prot_impl_typing_cond_stateful: assumes "typing_cond_prot_stateful \

" "\ \ \

" shows "typing_cond\<^sub>s\<^sub>s\<^sub>t (unlabel \)" proof - have 1: "wf'\<^sub>s\<^sub>s\<^sub>t {} (unlabel \)" "fv\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ bvars\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ = {}" using assms unfolding typing_cond_prot_stateful_def wf\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>s_def by auto have "tfr\<^sub>s\<^sub>e\<^sub>t (\(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

) \ pair ` \(setops\<^sub>s\<^sub>s\<^sub>t ` unlabel ` \

))" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

))" "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ \(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

)" "SMP (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel \)) - Var`\ \ SMP (\(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

) \ pair ` \(setops\<^sub>s\<^sub>s\<^sub>t ` unlabel ` \

)) - Var`\" using assms SMP_mono[of "trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel \)" "\(trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t ` \

) \ pair ` \(setops\<^sub>s\<^sub>s\<^sub>t ` unlabel ` \

)"] unfolding typing_cond_prot_stateful_def by (metis, metis, auto) hence 2: "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel \))" and 3: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t \)" unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by (meson subsetD)+ have 4: "list_all tfr\<^sub>s\<^sub>s\<^sub>t\<^sub>p (unlabel \)" using assms unfolding typing_cond_prot_stateful_def by auto show ?thesis using 1 2 3 4 unfolding typing_cond\<^sub>s\<^sub>s\<^sub>t_def tfr\<^sub>s\<^sub>s\<^sub>t_def by blast qed theorem par_comp_constr_prot_stateful: assumes P: "P = composed_prot Pi" "par_comp_prot_stateful P Sec" "\n. component_prot n (Pi n)" and left_secure: "component_secure_prot_stateful n (Pi n) Sec attack" shows "\\ \ P. suffix [(ln n, Send (Fun attack []))] \ \ unsat_stateful \ \ (\m. n \ m \ component_leaks_stateful m \ Sec)" proof - { fix \ \' assume \: "\ = \'@[(ln n, Send (Fun attack []))]" "\ \ P" let ?P = "\\' \\<^sub>\. interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\) \ prefix \' \ \ (\t \ Sec-declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \\<^sub>\. \m. n \ m \ (\\<^sub>\ \\<^sub>s (proj_unl m \'@[Send t])))" have tcp: "typing_cond_prot_stateful P" using P(2) unfolding par_comp_prot_stateful_def by simp have par_comp: "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t \ Sec" "typing_cond\<^sub>s\<^sub>s\<^sub>t (unlabel \)" using par_comp_prot_impl_par_comp_stateful[OF P(2) \(2)] typing_cond_prot_impl_typing_cond_stateful[OF tcp \(2)] by metis+ have "unlabel (proj n \) = proj_unl n \" "proj_unl n \ = proj_unl n (proj n \)" "\A. A \ Pi n \ proj n A = A" "proj n \ = (proj n \')@[(ln n, Send (Fun attack []))]" using P(1,3) \ by (auto simp add: proj_def unlabel_def component_prot_def composed_prot_def) moreover have "proj n \ \ Pi n" using P(1) \ unfolding composed_prot_def by blast moreover { fix A assume "prefix A \" hence *: "prefix (proj n A) (proj n \)" unfolding proj_def prefix_def by force hence "proj_unl n A = proj_unl n (proj n A)" "\I. declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t A I = declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj n A) I" unfolding proj_def declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by auto hence "\B. prefix B (proj n \) \ proj_unl n A = proj_unl n B \ (\I. declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t A I = declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t B I)" using * by metis } ultimately have *: "\\\<^sub>\. interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\) \ \(\\<^sub>\ \\<^sub>s (proj_unl n \)) \ (\\'. prefix \' \ \ (\t \ Sec - declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \\<^sub>\. \(\\<^sub>\ \\<^sub>s (proj_unl n \'@[Send t]))))" using left_secure unfolding component_secure_prot_stateful_def composed_prot_def suffix_def by metis { fix \ assume \: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "\ \\<^sub>s unlabel \" obtain \\<^sub>\ where \\<^sub>\: "interpretation\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\<^sub>\" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \\<^sub>\)" "\\'. prefix \' \ \ (\' leaks Sec under \\<^sub>\)" using par_comp_constr_stateful[OF par_comp \(2,1)] * by moura hence "\\'. prefix \' \ \ (\t \ Sec - declassified\<^sub>l\<^sub>s\<^sub>s\<^sub>t \' \\<^sub>\. \m. n \ m \ (\\<^sub>\ \\<^sub>s (proj_unl m \'@[Send t])))" using \\<^sub>\(4) * unfolding strand_leaks\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def by metis hence ?P using \\<^sub>\(1,2,3) by auto } hence "unsat_stateful \ \ (\m. n \ m \ component_leaks_stateful m \ Sec)" by (metis unsat_stateful_def component_leaks_stateful_def) } thus ?thesis unfolding suffix_def by metis qed end subsection \Automated Compositionality Conditions\ definition comp_GSMP_disjoint where "comp_GSMP_disjoint public arity Ana \ A' B' A B C \ let B\ = B \\<^sub>l\<^sub>i\<^sub>s\<^sub>t var_rename (max_var_set (fv\<^sub>s\<^sub>e\<^sub>t (set A))) in has_all_wt_instances_of \ (set A') (set A) \ has_all_wt_instances_of \ (set B') (set B\) \ finite_SMP_representation arity Ana \ A \ finite_SMP_representation arity Ana \ B\ \ (\t \ set A. \s \ set B\. \ t = \ s \ mgu t s \ None \ (intruder_synth' public arity {} t \ intruder_synth' public arity {} s) \ (\u \ set C. is_wt_instance_of_cond \ t u) \ (\u \ set C. is_wt_instance_of_cond \ s u))" definition comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t where "comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t public arity Ana \ pair_fun A M C \ let L = remdups (map (the_LabelN \ fst) (filter (Not \ is_LabelS) A)); MP0 = \B. remdups (trms_list\<^sub>s\<^sub>s\<^sub>t B@map (pair' pair_fun) (setops_list\<^sub>s\<^sub>s\<^sub>t B)); pr = \l. MP0 (proj_unl l A) in length L > 1 \ list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) (MP0 (unlabel A)) \ list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) C \ has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set C)) (set C) \ is_TComp_var_instance_closed \ C \ (\i \ set L. \j \ set L. i \ j \ comp_GSMP_disjoint public arity Ana \ (pr i) (pr j) (M i) (M j) C) \ (\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. i \ j \ (let s = pair' pair_fun p; t = pair' pair_fun q in mgu s (t \ var_rename (max_var s)) = None))" locale labeled_stateful_typed_model' = stateful_typed_model' arity public Ana \ Pair + labeled_typed_model' arity public Ana \ label_witness1 label_witness2 for arity::"'fun \ nat" and public::"'fun \ bool" and Ana::"('fun,(('fun,'atom::finite) term_type \ nat)) term \ (('fun,(('fun,'atom) term_type \ nat)) term list \ ('fun,(('fun,'atom) term_type \ nat)) term list)" and \::"('fun,(('fun,'atom) term_type \ nat)) term \ ('fun,'atom) term_type" and Pair::"'fun" and label_witness1::"'lbl" and label_witness2::"'lbl" begin sublocale labeled_stateful_typed_model by unfold_locales lemma GSMP_disjoint_if_comp_GSMP_disjoint: defines "f \ \M. {t \ \ | t \. t \ M \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ fv (t \ \) = {}}" assumes AB'_wf: "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) A'" "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) B'" and C_wf: "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) C" and AB'_disj: "comp_GSMP_disjoint public arity Ana \ A' B' A B C" shows "GSMP_disjoint (set A') (set B') ((f (set C)) - {m. {} \\<^sub>c m})" using GSMP_disjointI[of A' B' A B] AB'_wf AB'_disj C_wf unfolding comp_GSMP_disjoint_def f_def wf\<^sub>t\<^sub>r\<^sub>m_code list_all_iff Let_def by fast lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_if_comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t: defines "f \ \M. {t \ \ | t \. t \ M \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ fv (t \ \) = {}}" assumes A: "comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t public arity Ana \ Pair A M C" shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t A ((f (set C)) - {m. {} \\<^sub>c m})" proof (unfold par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def; intro conjI) let ?Sec = "(f (set C)) - {m. {} \\<^sub>c m}" let ?L = "remdups (map (the_LabelN \ fst) (filter (Not \ is_LabelS) A))" let ?N1 = "\B. remdups (trms_list\<^sub>s\<^sub>s\<^sub>t B@map (pair' Pair) (setops_list\<^sub>s\<^sub>s\<^sub>t B))" let ?N2 = "\B. trms\<^sub>s\<^sub>s\<^sub>t B \ pair ` setops\<^sub>s\<^sub>s\<^sub>t B" let ?pr = "\l. ?N1 (proj_unl l A)" let ?\ = "\p. var_rename (max_var (pair p))" have 0: "length ?L > 1" "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) (?N1 (unlabel A))" "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) C" "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set C)) (set C)" "is_TComp_var_instance_closed \ C" "\i \ set ?L. \j \ set ?L. i \ j \ comp_GSMP_disjoint public arity Ana \ (?pr i) (?pr j) (M i) (M j) C" "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. i \ j \ mgu (pair p) (pair q \ ?\ p) = None" using A unfolding comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def pair_code by meson+ have L_in_iff: "l \ set ?L \ (\a \ set A. is_LabelN l a)" for l by force have A_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t A \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (unlabel A))" using 0(2) unfolding pair_code wf\<^sub>t\<^sub>r\<^sub>m_code list_all_iff trms_list\<^sub>s\<^sub>s\<^sub>t_is_trms\<^sub>s\<^sub>s\<^sub>t setops_list\<^sub>s\<^sub>s\<^sub>t_is_setops\<^sub>s\<^sub>s\<^sub>t by auto hence A_proj_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>l\<^sub>s\<^sub>s\<^sub>t (proj l A) \ pair ` setops\<^sub>s\<^sub>s\<^sub>t (proj_unl l A))" for l using trms\<^sub>s\<^sub>s\<^sub>t_proj_subset(1)[of l A] setops\<^sub>s\<^sub>s\<^sub>t_proj_subset(1)[of l A] by blast hence A_proj_wf_trms': "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) (?N1 (proj_unl l A))" for l unfolding pair_code wf\<^sub>t\<^sub>r\<^sub>m_code list_all_iff trms_list\<^sub>s\<^sub>s\<^sub>t_is_trms\<^sub>s\<^sub>s\<^sub>t setops_list\<^sub>s\<^sub>s\<^sub>t_is_setops\<^sub>s\<^sub>s\<^sub>t by auto note C_wf_trms = 0(3)[unfolded list_all_iff wf\<^sub>t\<^sub>r\<^sub>m_code[symmetric]] note 1 = has_all_wt_instances_ofD'[OF wf_trms_subterms[OF C_wf_trms] C_wf_trms 0(4)] have 2: "GSMP (?N2 (proj_unl l A)) \ GSMP (?N2 (proj_unl l' A))" when "l \ set ?L" for l l' using that L_in_iff GSMP_mono[of "?N2 (proj_unl l A)" "?N2 (proj_unl l' A)"] trms\<^sub>s\<^sub>s\<^sub>t_unlabel_subset_if_no_label[of l A] setops\<^sub>s\<^sub>s\<^sub>t_unlabel_subset_if_no_label[of l A] unfolding list_ex_iff by fast have 3: "GSMP_disjoint (?N2 (proj_unl l1 A)) (?N2 (proj_unl l2 A)) ?Sec" when "l1 \ set ?L" "l2 \ set ?L" "l1 \ l2" for l1 l2 proof - have "GSMP_disjoint (set (?N1 (proj_unl l1 A))) (set (?N1 (proj_unl l2 A))) ?Sec" using 0(6) that GSMP_disjoint_if_comp_GSMP_disjoint[ OF A_proj_wf_trms'[of l1] A_proj_wf_trms'[of l2] 0(3), of "M l1" "M l2"] unfolding f_def by blast thus ?thesis unfolding pair_code trms_list\<^sub>s\<^sub>s\<^sub>t_is_trms\<^sub>s\<^sub>s\<^sub>t setops_list\<^sub>s\<^sub>s\<^sub>t_is_setops\<^sub>s\<^sub>s\<^sub>t by simp qed obtain a1 a2 where a: "a1 \ set ?L" "a2 \ set ?L" "a1 \ a2" using remdups_ex2[OF 0(1)] by moura show "ground ?Sec" unfolding f_def by fastforce { fix i p j q assume p: "(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" and q: "(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" and pq: "\\. Unifier \ (pair p) (pair q)" have "\\. Unifier \ (pair p) (pair q \ ?\ p)" using pq vars_term_disjoint_imp_unifier[OF var_rename_fv_disjoint[of "pair p"], of _ "pair q"] by (metis (no_types, lifting) subst_subst_compose var_rename_inv_comp) hence "i = j" using 0(7) mgu_None_is_subst_neq[of "pair p" "pair q \ ?\ p"] p q by fast } thus "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. (\\. Unifier \ (pair p) (pair q)) \ i = j" by blast show "\l1 l2. l1 \ l2 \ GSMP_disjoint (?N2 (proj_unl l1 A)) (?N2 (proj_unl l2 A)) ?Sec" using 2 3 3[OF a] unfolding GSMP_disjoint_def by blast show "\s \ ?Sec. \s' \ subterms s. {} \\<^sub>c s' \ s' \ ?Sec" proof (intro ballI) fix s s' assume s: "s \ ?Sec" and s': "s' \ s" then obtain t \ where t: "t \ set C" "s = t \ \" "fv s = {}" "\{} \\<^sub>c s" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" unfolding f_def by blast obtain m \ where m: "m \ set C" "s' = m \ \" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using TComp_var_and_subterm_instance_closed_has_subterms_instances[ OF 0(5,4) C_wf_trms in_subterms_Union[OF t(1)] s'[unfolded t(2)] \] by blast thus "{} \\<^sub>c s' \ s' \ ?Sec" using ground_subterm[OF t(3) s'] unfolding f_def by blast qed qed lemma par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_if_comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t': defines "f \ \M. {t \ \ | t \. t \ M \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ fv (t \ \) = {}}" assumes a: "comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t public arity Ana \ Pair A M C" and B: "\b \ set B. \a \ set A. \\. b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" (is "\b \ set B. \a \ set A. \\. b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \ \ ?D \") shows "par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t B ((f (set C)) - {m. {} \\<^sub>c m})" proof (unfold par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def; intro conjI) define N1 where "N1 \ \B::('fun, ('fun,'atom) term_type \ nat) stateful_strand. remdups (trms_list\<^sub>s\<^sub>s\<^sub>t B@map (pair' Pair) (setops_list\<^sub>s\<^sub>s\<^sub>t B))" define N2 where "N2 \ \B::('fun, ('fun,'atom) term_type \ nat) stateful_strand. trms\<^sub>s\<^sub>s\<^sub>t B \ pair ` setops\<^sub>s\<^sub>s\<^sub>t B" define L where "L \ \A::('fun, ('fun,'atom) term_type \ nat, 'lbl) labeled_stateful_strand. remdups (map (the_LabelN \ fst) (filter (Not \ is_LabelS) A))" define \ where "\ \ \p. var_rename (max_var (pair p::('fun, ('fun,'atom) term_type \ nat) term)) ::('fun, ('fun,'atom) term_type \ nat) subst" let ?Sec = "(f (set C)) - {m. {} \\<^sub>c m}" have 0: "length (L A) > 1" "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) (N1 (unlabel A))" "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) C" "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set C)) (set C)" "is_TComp_var_instance_closed \ C" "\i \ set (L A). \j \ set (L A). i \ j \ comp_GSMP_disjoint public arity Ana \ (N1 (proj_unl i A)) (N1 (proj_unl j A)) (M i) (M j) C" "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A. i \ j \ mgu (pair p) (pair q \ \ p) = None" using a unfolding comp_par_comp\<^sub>l\<^sub>s\<^sub>s\<^sub>t_def pair_code L_def N1_def \_def by meson+ note 1 = trms\<^sub>s\<^sub>s\<^sub>t_proj_subset(1) setops\<^sub>s\<^sub>s\<^sub>t_proj_subset(1) have N1_iff_N2: "set (N1 A) = N2 A" for A unfolding pair_code trms_list\<^sub>s\<^sub>s\<^sub>t_is_trms\<^sub>s\<^sub>s\<^sub>t setops_list\<^sub>s\<^sub>s\<^sub>t_is_setops\<^sub>s\<^sub>s\<^sub>t N1_def N2_def by simp have N2_proj_subset: "N2 (proj_unl l A) \ N2 (unlabel A)" for l::'lbl and A::"('fun, ('fun,'atom) term_type \ nat, 'lbl) labeled_stateful_strand" using 1(1)[of l A] image_mono[OF 1(2)[of l A], of pair] unfolding N2_def by blast have L_in_iff: "l \ set (L A) \ (\a \ set A. is_LabelN l a)" for l A unfolding L_def by force have L_B_subset_A: "l \ set (L A)" when l: "l \ set (L B)" for l using L_in_iff[of l B] L_in_iff[of l A] B l by fastforce note B_setops = setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t_wt_instance_ex[OF B] have B_proj: "\b \ set (proj l B). \a \ set (proj l A). \\. b = a \\<^sub>l\<^sub>s\<^sub>s\<^sub>t\<^sub>p \ \ ?D \" for l using proj_instance_ex[OF B] by fast have B': "\t \ N2 (unlabel B). \s \ N2 (unlabel A). \\. t = s \ \ \ ?D \" using trms\<^sub>s\<^sub>s\<^sub>t_setops\<^sub>s\<^sub>s\<^sub>t_wt_instance_ex[OF B] unfolding N2_def by blast have B'_proj: "\t \ N2 (proj_unl l B). \s \ N2 (proj_unl l A). \\. t = s \ \ \ ?D \" for l using trms\<^sub>s\<^sub>s\<^sub>t_setops\<^sub>s\<^sub>s\<^sub>t_wt_instance_ex[OF B_proj] unfolding N2_def by presburger have A_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (N2 (unlabel A))" using N1_iff_N2[of "unlabel A"] 0(2) unfolding wf\<^sub>t\<^sub>r\<^sub>m_code list_all_iff by auto hence A_proj_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (N2 (proj_unl l A))" for l using 1[of l] unfolding N2_def by blast hence A_proj_wf_trms': "list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) (N1 (proj_unl l A))" for l using N1_iff_N2[of "proj_unl l A"] unfolding wf\<^sub>t\<^sub>r\<^sub>m_code list_all_iff by presburger note C_wf_trms = 0(3)[unfolded list_all_iff wf\<^sub>t\<^sub>r\<^sub>m_code[symmetric]] have 2: "GSMP (N2 (proj_unl l A)) \ GSMP (N2 (proj_unl l' A))" when "l \ set (L A)" for l l' and A::"('fun, ('fun,'atom) term_type \ nat, 'lbl) labeled_stateful_strand" using that L_in_iff[of _ A] GSMP_mono[of "N2 (proj_unl l A)" "N2 (proj_unl l' A)"] trms\<^sub>s\<^sub>s\<^sub>t_unlabel_subset_if_no_label[of l A] setops\<^sub>s\<^sub>s\<^sub>t_unlabel_subset_if_no_label[of l A] unfolding list_ex_iff N2_def by fast have 3: "GSMP (N2 (proj_unl l B)) \ GSMP (N2 (proj_unl l A))" (is "?X \ ?Y") for l proof fix t assume "t \ ?X" hence t: "t \ SMP (N2 (proj_unl l B))" "fv t = {}" unfolding GSMP_def by simp_all have "t \ SMP (N2 (proj_unl l A))" using t(1) B'_proj[of l] SMP_wt_instances_subset[of "N2 (proj_unl l B)" "N2 (proj_unl l A)"] by metis thus "t \ ?Y" using t(2) unfolding GSMP_def by fast qed have "GSMP_disjoint (N2 (proj_unl l1 A)) (N2 (proj_unl l2 A)) ?Sec" when "l1 \ set (L A)" "l2 \ set (L A)" "l1 \ l2" for l1 l2 proof - have "GSMP_disjoint (set (N1 (proj_unl l1 A))) (set (N1 (proj_unl l2 A))) ?Sec" using 0(6) that GSMP_disjoint_if_comp_GSMP_disjoint[ OF A_proj_wf_trms'[of l1] A_proj_wf_trms'[of l2] 0(3), of "M l1" "M l2"] unfolding f_def by blast thus ?thesis using N1_iff_N2 by simp qed hence 4: "GSMP_disjoint (N2 (proj_unl l1 B)) (N2 (proj_unl l2 B)) ?Sec" when "l1 \ set (L A)" "l2 \ set (L A)" "l1 \ l2" for l1 l2 using that 3 unfolding GSMP_disjoint_def by blast { fix i p j q assume p: "(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B" and q: "(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B" and pq: "\\. Unifier \ (pair p) (pair q)" obtain p' \p where p': "(i,p') \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "p = p' \\<^sub>p \p" "pair p = pair p' \ \p" using p B_setops unfolding pair_def by auto obtain q' \q where q': "(j,q') \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t A" "q = q' \\<^sub>p \q" "pair q = pair q' \ \q" using q B_setops unfolding pair_def by auto obtain \ where "Unifier \ (pair p) (pair q)" using pq by blast hence "\\. Unifier \ (pair p') (pair q' \ \ p')" using p'(3) q'(3) var_rename_inv_comp[of "pair q'"] subst_subst_compose vars_term_disjoint_imp_unifier[ OF var_rename_fv_disjoint[of "pair p'"], of "\p \\<^sub>s \" "pair q'" "var_rename_inv (max_var_set (fv (pair p'))) \\<^sub>s \q \\<^sub>s \"] unfolding \_def by fastforce hence "i = j" using mgu_None_is_subst_neq[of "pair p'" "pair q' \ \ p'"] p'(1) q'(1) 0(7) unfolding \_def by fast } thus "\(i,p) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. \(j,q) \ setops\<^sub>l\<^sub>s\<^sub>s\<^sub>t B. (\\. Unifier \ (pair p) (pair q)) \ i = j" by blast obtain a1 a2 where a: "a1 \ set (L A)" "a2 \ set (L A)" "a1 \ a2" using remdups_ex2[OF 0(1)[unfolded L_def]] unfolding L_def by moura show "\l1 l2. l1 \ l2 \ GSMP_disjoint (N2 (proj_unl l1 B)) (N2 (proj_unl l2 B)) ?Sec" using 2[of _ B] 4 4[OF a] L_B_subset_A unfolding GSMP_disjoint_def by blast show "ground ?Sec" unfolding f_def by fastforce show "\s \ ?Sec. \s' \ subterms s. {} \\<^sub>c s' \ s' \ ?Sec" proof (intro ballI) fix s s' assume s: "s \ ?Sec" and s': "s' \ s" then obtain t \ where t: "t \ set C" "s = t \ \" "fv s = {}" "\{} \\<^sub>c s" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" unfolding f_def by blast obtain m \ where m: "m \ set C" "s' = m \ \" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using TComp_var_and_subterm_instance_closed_has_subterms_instances[ OF 0(5,4) C_wf_trms in_subterms_Union[OF t(1)] s'[unfolded t(2)] \] by blast thus "{} \\<^sub>c s' \ s' \ ?Sec" using ground_subterm[OF t(3) s'] unfolding f_def by blast qed qed end end