(* (C) Copyright Andreas Viktor Hess, DTU, 2015-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: Typed_Model.thy Author: Andreas Viktor Hess, DTU *) section \The Typed Model\ theory Typed_Model imports Lazy_Intruder begin text \Term types\ type_synonym ('f,'v) term_type = "('f,'v) term" text \Constructors for term types\ abbreviation (input) TAtom::"'v \ ('f,'v) term_type" where "TAtom a \ Var a" abbreviation (input) TComp::"['f, ('f,'v) term_type list] \ ('f,'v) term_type" where "TComp f T \ Fun f T" text \ The typed model extends the intruder model with a typing function \\\ that assigns types to terms. \ locale typed_model = intruder_model arity public Ana for arity::"'fun \ nat" and public::"'fun \ bool" and Ana::"('fun,'var) term \ (('fun,'var) term list \ ('fun,'var) term list)" + fixes \::"('fun,'var) term \ ('fun,'atom::finite) term_type" assumes const_type: "\c. arity c = 0 \ \a. \T. \ (Fun c T) = TAtom a" and fun_type: "\f T. arity f > 0 \ \ (Fun f T) = TComp f (map \ T)" and infinite_typed_consts: "\a. infinite {c. \ (Fun c []) = TAtom a \ public c}" and \_wf: "\t f T. TComp f T \ \ t \ arity f > 0" "\x. wf\<^sub>t\<^sub>r\<^sub>m (\ (Var x))" and no_private_funs[simp]: "\f. arity f > 0 \ public f" begin subsection \Definitions\ text \The set of atomic types\ abbreviation "\\<^sub>a \ UNIV::('atom set)" text \Well-typed substitutions\ definition wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t where "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ (\v. \ (Var v) = \ (\ v))" text \The set of sub-message patterns (SMP)\ inductive_set SMP::"('fun,'var) terms \ ('fun,'var) terms" for M where MP[intro]: "t \ M \ t \ SMP M" | Subterm[intro]: "\t \ SMP M; t' \ t\ \ t' \ SMP M" | Substitution[intro]: "\t \ SMP M; wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \; wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)\ \ (t \ \) \ SMP M" | Ana[intro]: "\t \ SMP M; Ana t = (K,T); k \ set K\ \ k \ SMP M" text \ Type-flaw resistance for sets: Unifiable sub-message patterns must have the same type (unless they are variables) \ definition tfr\<^sub>s\<^sub>e\<^sub>t where "tfr\<^sub>s\<^sub>e\<^sub>t M \ (\s \ SMP M - (Var`\). \t \ SMP M - (Var`\). (\\. Unifier \ s t) \ \ s = \ t)" text \ Type-flaw resistance for strand steps: - The terms in a satisfiable equality step must have the same types - Inequality steps must satisfy the conditions of the "inequality lemma"\ fun tfr\<^sub>s\<^sub>t\<^sub>p where "tfr\<^sub>s\<^sub>t\<^sub>p (Equality a t t') = ((\\. Unifier \ t t') \ \ t = \ t')" | "tfr\<^sub>s\<^sub>t\<^sub>p (Inequality X F) = ( (\x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \a. \ (Var x) = TAtom a) \ (\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)))" | "tfr\<^sub>s\<^sub>t\<^sub>p _ = True" text \ Type-flaw resistance for strands: - The set of terms in strands must be type-flaw resistant - The steps of strands must be type-flaw resistant \ definition tfr\<^sub>s\<^sub>t where "tfr\<^sub>s\<^sub>t S \ tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>t S) \ list_all tfr\<^sub>s\<^sub>t\<^sub>p S" subsection \Small Lemmata\ lemma tfr\<^sub>s\<^sub>t\<^sub>p_list_all_alt_def: "list_all tfr\<^sub>s\<^sub>t\<^sub>p S \ ((\a t t'. Equality a t t' \ set S \ (\\. Unifier \ t t') \ \ t = \ t') \ (\X F. Inequality X F \ set S \ (\x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \a. \ (Var x) = TAtom a) \ (\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))))" (is "?P S \ ?Q S") proof show "?P S \ ?Q S" proof (induction S) case (Cons x S) thus ?case by (cases x) auto qed simp show "?Q S \ ?P S" proof (induction S) case (Cons x S) thus ?case by (cases x) auto qed simp qed lemma \_wf': "wf\<^sub>t\<^sub>r\<^sub>m t \ wf\<^sub>t\<^sub>r\<^sub>m (\ t)" proof (induction t) case (Fun f T) hence *: "arity f = length T" "\t. t \ set T \ wf\<^sub>t\<^sub>r\<^sub>m (\ t)" unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto { assume "arity f = 0" hence ?case using const_type[of f] by auto } moreover { assume "arity f > 0" hence ?case using fun_type[of f] * by force } ultimately show ?case by auto qed (metis \_wf(2)) lemma fun_type_inv: assumes "\ t = TComp f T" shows "arity f > 0" "public f" using \_wf(1)[of f T t] assms by simp_all lemma fun_type_inv_wf: assumes "\ t = TComp f T" "wf\<^sub>t\<^sub>r\<^sub>m t" shows "arity f = length T" using \_wf'[OF assms(2)] assms(1) unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto lemma const_type_inv: "\ (Fun c X) = TAtom a \ arity c = 0" by (rule ccontr, simp add: fun_type) lemma const_type_inv_wf: assumes "\ (Fun c X) = TAtom a" and "wf\<^sub>t\<^sub>r\<^sub>m (Fun c X)" shows "X = []" by (metis assms const_type_inv length_0_conv subtermeqI' wf\<^sub>t\<^sub>r\<^sub>m_def) lemma const_type': "\c \ \. \a \ \\<^sub>a. \X. \ (Fun c X) = TAtom a" using const_type by simp lemma fun_type': "\f \ \\<^sub>f. \X. \ (Fun f X) = TComp f (map \ X)" using fun_type by simp lemma infinite_public_consts[simp]: "infinite {c. public c \ arity c = 0}" proof - fix a::'atom define A where "A \ {c. \ (Fun c []) = TAtom a \ public c}" define B where "B \ {c. public c \ arity c = 0}" have "arity c = 0" when c: "c \ A" for c using c const_type_inv unfolding A_def by blast hence "A \ B" unfolding A_def B_def by blast hence "infinite B" using infinite_typed_consts[of a, unfolded A_def[symmetric]] by (metis infinite_super) thus ?thesis unfolding B_def by blast qed lemma infinite_fun_syms[simp]: "infinite {c. public c \ arity c > 0} \ infinite \\<^sub>f" "infinite \" "infinite \\<^sub>p\<^sub>u\<^sub>b" "infinite (UNIV::'fun set)" by (metis \\<^sub>f_unfold finite_Collect_conjI, metis infinite_public_consts finite_Collect_conjI, use infinite_public_consts \pub_unfold in \force simp add: Collect_conj_eq\, metis UNIV_I finite_subset subsetI infinite_public_consts(1)) lemma id_univ_proper_subset[simp]: "\\<^sub>f \ UNIV" "(\f. arity f > 0) \ \ \ UNIV" by (metis finite.emptyI inf_top.right_neutral top.not_eq_extremum disjoint_fun_syms infinite_fun_syms(2) inf_commute) (metis top.not_eq_extremum UNIV_I const_arity_eq_zero less_irrefl) lemma exists_fun_notin_funs_term: "\f::'fun. f \ funs_term t" by (metis UNIV_eq_I finite_fun_symbols infinite_fun_syms(4)) lemma exists_fun_notin_funs_terms: assumes "finite M" shows "\f::'fun. f \ \(funs_term ` M)" by (metis assms finite_fun_symbols infinite_fun_syms(4) ex_new_if_finite finite_UN) lemma exists_notin_funs\<^sub>s\<^sub>t: "\f. f \ funs\<^sub>s\<^sub>t (S::('fun,'var) strand)" by (metis UNIV_eq_I finite_funs\<^sub>s\<^sub>t infinite_fun_syms(4)) lemma infinite_typed_consts': "infinite {c. \ (Fun c []) = TAtom a \ public c \ arity c = 0}" proof - { fix c assume "\ (Fun c []) = TAtom a" "public c" hence "arity c = 0" using const_type[of c] fun_type[of c "[]"] by auto } hence "{c. \ (Fun c []) = TAtom a \ public c \ arity c = 0} = {c. \ (Fun c []) = TAtom a \ public c}" by auto thus "infinite {c. \ (Fun c []) = TAtom a \ public c \ arity c = 0}" using infinite_typed_consts[of a] by metis qed lemma atypes_inhabited: "\c. \ (Fun c []) = TAtom a \ wf\<^sub>t\<^sub>r\<^sub>m (Fun c []) \ public c \ arity c = 0" proof - obtain c where "\ (Fun c []) = TAtom a" "public c" "arity c = 0" using infinite_typed_consts'(1)[of a] not_finite_existsD by blast thus ?thesis using const_type_inv[OF \\ (Fun c []) = TAtom a\] unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto qed lemma atype_ground_term_ex: "\t. fv t = {} \ \ t = TAtom a \ wf\<^sub>t\<^sub>r\<^sub>m t" using atypes_inhabited[of a] by force lemma fun_type_id_eq: "\ (Fun f X) = TComp g Y \ f = g" by (metis const_type fun_type neq0_conv "term.inject"(2) "term.simps"(4)) lemma fun_type_length_eq: "\ (Fun f X) = TComp g Y \ length X = length Y" by (metis fun_type fun_type_id_eq fun_type_inv(1) length_map term.inject(2)) lemma type_ground_inhabited: "\t'. fv t' = {} \ \ t = \ t'" proof - { fix \::"('fun, 'atom) term_type" assume "\f T. Fun f T \ \ \ 0 < arity f" hence "\t'. fv t' = {} \ \ = \ t'" proof (induction \) case (Fun f T) hence "arity f > 0" by auto from Fun.IH Fun.prems(1) have "\Y. map \ Y = T \ (\x \ set Y. fv x = {})" proof (induction T) case (Cons x X) hence "\g Y. Fun g Y \ Fun f X \ 0 < arity g" by auto hence "\Y. map \ Y = X \ (\x\set Y. fv x = {})" using Cons by auto moreover have "\t'. fv t' = {} \ x = \ t'" using Cons by auto ultimately obtain y Y where "fv y = {}" "\ y = x" "map \ Y = X" "\x\set Y. fv x = {}" using Cons by moura hence "map \ (y#Y) = x#X \ (\x\set (y#Y). fv x = {})" by auto thus ?case by meson qed simp then obtain Y where "map \ Y = T" "\x \ set Y. fv x = {}" by metis hence "fv (Fun f Y) = {}" "\ (Fun f Y) = TComp f T" using fun_type[OF \arity f > 0\] by auto thus ?case by (metis exI[of "\t. fv t = {} \ \ t = TComp f T" "Fun f Y"]) qed (metis atype_ground_term_ex) } thus ?thesis by (metis \_wf(1)) qed lemma type_wfttype_inhabited: assumes "\f T. Fun f T \ \ \ 0 < arity f" "wf\<^sub>t\<^sub>r\<^sub>m \" shows "\t. \ t = \ \ wf\<^sub>t\<^sub>r\<^sub>m t" using assms proof (induction \) case (Fun f Y) have IH: "\t. \ t = y \ wf\<^sub>t\<^sub>r\<^sub>m t" when y: "y \ set Y " for y proof - have "wf\<^sub>t\<^sub>r\<^sub>m y" using Fun y unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by (metis Fun_param_is_subterm term.le_less_trans) moreover have "Fun g Z \ y \ 0 < arity g" for g Z using Fun y by auto ultimately show ?thesis using Fun.IH[OF y] by auto qed from Fun have "arity f = length Y" "arity f > 0" unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by force+ moreover from IH have "\X. map \ X = Y \ (\x \ set X. wf\<^sub>t\<^sub>r\<^sub>m x)" by (induct Y, simp_all, metis list.simps(9) set_ConsD) ultimately show ?case by (metis fun_type length_map wf_trmI) qed (use atypes_inhabited wf\<^sub>t\<^sub>r\<^sub>m_def in blast) lemma type_pgwt_inhabited: "wf\<^sub>t\<^sub>r\<^sub>m t \ \t'. \ t = \ t' \ public_ground_wf_term t'" proof - assume "wf\<^sub>t\<^sub>r\<^sub>m t" { fix \ assume "\ t = \" hence "\t'. \ t = \ t' \ public_ground_wf_term t'" using \wf\<^sub>t\<^sub>r\<^sub>m t\ proof (induction \ arbitrary: t) case (Var a t) then obtain c where "\ t = \ (Fun c [])" "arity c = 0" "public c" using const_type_inv[of _ "[]" a] infinite_typed_consts(1)[of a] not_finite_existsD by force thus ?case using PGWT[OF \public c\, of "[]"] by auto next case (Fun f Y t) have *: "arity f > 0" "public f" "arity f = length Y" using fun_type_inv[OF \\ t = TComp f Y\] fun_type_inv_wf[OF \\ t = TComp f Y\ \wf\<^sub>t\<^sub>r\<^sub>m t\] by auto have "\y. y \ set Y \ \t'. y = \ t' \ public_ground_wf_term t'" using Fun.prems(1) Fun.IH \_wf(1)[of _ _ t] \_wf'[OF \wf\<^sub>t\<^sub>r\<^sub>m t\] type_wfttype_inhabited by (metis Fun_param_is_subterm term.order_trans wf_trm_subtermeq) hence "\X. map \ X = Y \ (\x \ set X. public_ground_wf_term x)" by (induct Y, simp_all, metis list.simps(9) set_ConsD) then obtain X where X: "map \ X = Y" "\x. x \ set X \ public_ground_wf_term x" by moura hence "arity f = length X" using *(3) by auto have "\ t = \ (Fun f X)" "public_ground_wf_term (Fun f X)" using fun_type[OF *(1), of X] Fun.prems(1) X(1) apply simp using PGWT[OF *(2) \arity f = length X\ X(2)] by metis thus ?case by metis qed } thus ?thesis using \wf\<^sub>t\<^sub>r\<^sub>m t\ by auto qed lemma pgwt_type_map: assumes "public_ground_wf_term t" shows "\ t = TAtom a \ \f. t = Fun f []" "\ t = TComp g Y \ \X. t = Fun g X \ map \ X = Y" proof - let ?A = "\ t = TAtom a \ (\f. t = Fun f [])" let ?B = "\ t = TComp g Y \ (\X. t = Fun g X \ map \ X = Y)" have "?A \ ?B" proof (cases "\ t") case (Var a) obtain f X where "t = Fun f X" "arity f = length X" using pgwt_fun[OF assms(1)] pgwt_arity[OF assms(1)] by fastforce+ thus ?thesis using const_type_inv \\ t = TAtom a\ by auto next case (Fun g Y) obtain f X where *: "t = Fun f X" using pgwt_fun[OF assms(1)] by force hence "f = g" "map \ X = Y" using fun_type_id_eq \\ t = TComp g Y\ fun_type[OF fun_type_inv(1)[OF \\ t = TComp g Y\]] by fastforce+ thus ?thesis using *(1) \\ t = TComp g Y\ by auto qed thus "\ t = TAtom a \ \f. t = Fun f []" "\ t = TComp g Y \ \X. t = Fun g X \ map \ X = Y" by auto qed lemma wt_subst_Var[simp]: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t Var" by (metis wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) lemma wt_subst_trm: "(\v. v \ fv t \ \ (Var v) = \ (\ v)) \ \ t = \ (t \ \)" proof (induction t) case (Fun f X) hence *: "\x. x \ set X \ \ x = \ (x \ \)" by auto show ?case proof (cases "f \ \\<^sub>f") case True hence "\X. \ (Fun f X) = TComp f (map \ X)" using fun_type' by auto thus ?thesis using * by auto next case False hence "\a \ \\<^sub>a. \X. \ (Fun f X) = TAtom a" using const_type' by auto thus ?thesis by auto qed qed auto lemma wt_subst_trm': "\wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \; \ s = \ t\ \ \ (s \ \) = \ (t \ \)" by (metis wt_subst_trm wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) lemma wt_subst_trm'': "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ \ t = \ (t \ \)" by (metis wt_subst_trm wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) lemma wt_subst_compose: assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\ \\<^sub>s \)" proof - have "\v. \ (\ v) = \ (\ v \ \)" using wt_subst_trm \wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\ unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by metis moreover have "\v. \ (Var v) = \ (\ v)" using \wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \\ unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by metis ultimately have "\v. \ (Var v) = \ (\ v \ \)" by metis thus ?thesis unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def subst_compose_def by metis qed lemma wt_subst_TAtom_Var_cases: assumes \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" and x: "\ (Var x) = TAtom a" shows "(\y. \ x = Var y) \ (\c. \ x = Fun c [])" proof (cases "(\y. \ x = Var y)") case False then obtain c T where c: "\ x = Fun c T" by (cases "\ x") simp_all hence "wf\<^sub>t\<^sub>r\<^sub>m (Fun c T)" using \(2) by fastforce hence "T = []" using const_type_inv_wf[of c T a] x c wt_subst_trm''[OF \(1), of "Var x"] by fastforce thus ?thesis using c by blast qed simp lemma wt_subst_TAtom_fv: assumes \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "\x. wf\<^sub>t\<^sub>r\<^sub>m (\ x)" and "\x \ fv t - X. \a. \ (Var x) = TAtom a" shows "\x \ fv (t \ \) - fv\<^sub>s\<^sub>e\<^sub>t (\ ` X). \a. \ (Var x) = TAtom a" using assms(3) proof (induction t) case (Var x) thus ?case proof (cases "x \ X") case False with Var obtain a where "\ (Var x) = TAtom a" by moura hence *: "\ (\ x) = TAtom a" "wf\<^sub>t\<^sub>r\<^sub>m (\ x)" using \ unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by auto show ?thesis proof (cases "\ x") case (Var y) thus ?thesis using * by auto next case (Fun f T) hence "T = []" using * const_type_inv[of f T a] unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto thus ?thesis using Fun by auto qed qed auto qed fastforce lemma wt_subst_TAtom_subterms_subst: assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "\x \ fv t. \a. \ (Var x) = TAtom a" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\ ` fv t)" shows "subterms (t \ \) = subterms t \\<^sub>s\<^sub>e\<^sub>t \" using assms(2,3) proof (induction t) case (Var x) obtain a where a: "\ (Var x) = TAtom a" using Var.prems(1) by moura hence "\ (\ x) = TAtom a" using wt_subst_trm''[OF assms(1), of "Var x"] by simp hence "(\y. \ x = Var y) \ (\c. \ x = Fun c [])" using const_type_inv_wf Var.prems(2) by (cases "\ x") auto thus ?case by auto next case (Fun f T) have "subterms (t \ \) = subterms t \\<^sub>s\<^sub>e\<^sub>t \" when "t \ set T" for t using that Fun.prems(1,2) Fun.IH[OF that] by auto thus ?case by auto qed lemma wt_subst_TAtom_subterms_set_subst: assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "\x \ fv\<^sub>s\<^sub>e\<^sub>t M. \a. \ (Var x) = TAtom a" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\ ` fv\<^sub>s\<^sub>e\<^sub>t M)" shows "subterms\<^sub>s\<^sub>e\<^sub>t (M \\<^sub>s\<^sub>e\<^sub>t \) = subterms\<^sub>s\<^sub>e\<^sub>t M \\<^sub>s\<^sub>e\<^sub>t \" proof show "subterms\<^sub>s\<^sub>e\<^sub>t (M \\<^sub>s\<^sub>e\<^sub>t \) \ subterms\<^sub>s\<^sub>e\<^sub>t M \\<^sub>s\<^sub>e\<^sub>t \" proof fix t assume "t \ subterms\<^sub>s\<^sub>e\<^sub>t (M \\<^sub>s\<^sub>e\<^sub>t \)" then obtain s where s: "s \ M" "t \ subterms (s \ \)" by auto thus "t \ subterms\<^sub>s\<^sub>e\<^sub>t M \\<^sub>s\<^sub>e\<^sub>t \" using assms(2,3) wt_subst_TAtom_subterms_subst[OF assms(1), of s] by auto qed show "subterms\<^sub>s\<^sub>e\<^sub>t M \\<^sub>s\<^sub>e\<^sub>t \ \ subterms\<^sub>s\<^sub>e\<^sub>t (M \\<^sub>s\<^sub>e\<^sub>t \)" proof fix t assume "t \ subterms\<^sub>s\<^sub>e\<^sub>t M \\<^sub>s\<^sub>e\<^sub>t \" then obtain s where s: "s \ M" "t \ subterms s \\<^sub>s\<^sub>e\<^sub>t \" by auto thus "t \ subterms\<^sub>s\<^sub>e\<^sub>t (M \\<^sub>s\<^sub>e\<^sub>t \)" using assms(2,3) wt_subst_TAtom_subterms_subst[OF assms(1), of s] by auto qed qed lemma wt_subst_subst_upd: assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and "\ (Var x) = \ t" shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\(x := t))" using assms unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by (metis fun_upd_other fun_upd_same) lemma wt_subst_const_fv_type_eq: assumes "\x \ fv t. \a. \ (Var x) = TAtom a" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "\x \ fv (t \ \). \y \ fv t. \ (Var x) = \ (Var y)" using assms(1) proof (induction t) case (Var x) then obtain a where a: "\ (Var x) = TAtom a" by moura show ?case proof (cases "\ x") case (Fun f T) hence "wf\<^sub>t\<^sub>r\<^sub>m (Fun f T)" "\ (Fun f T) = TAtom a" using a wt_subst_trm''[OF \(1), of "Var x"] \(2) by fastforce+ thus ?thesis using const_type_inv_wf Fun by fastforce qed (use a wt_subst_trm''[OF \(1), of "Var x"] in simp) qed fastforce lemma TComp_term_cases: assumes "wf\<^sub>t\<^sub>r\<^sub>m t" "\ t = TComp f T" shows "(\v. t = Var v) \ (\T'. t = Fun f T' \ T = map \ T' \ T' \ [])" proof (cases "\v. t = Var v") case False then obtain T' where T': "t = Fun f T'" "T = map \ T'" using assms fun_type[OF fun_type_inv(1)[OF assms(2)]] fun_type_id_eq by (cases t) force+ thus ?thesis using assms fun_type_inv(1) fun_type_inv_wf by fastforce qed metis lemma TAtom_term_cases: assumes "wf\<^sub>t\<^sub>r\<^sub>m t" "\ t = TAtom \" shows "(\v. t = Var v) \ (\f. t = Fun f [])" using assms const_type_inv unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by (cases t) auto lemma subtermeq_imp_subtermtypeeq: assumes "wf\<^sub>t\<^sub>r\<^sub>m t" "s \ t" shows "\ s \ \ t" using assms(2,1) proof (induction t) case (Fun f T) thus ?case proof (cases "s = Fun f T") case False then obtain x where x: "x \ set T" "s \ x" using Fun.prems(1) by auto hence "wf\<^sub>t\<^sub>r\<^sub>m x" using wf_trm_subtermeq[OF Fun.prems(2)] Fun_param_is_subterm[of _ T f] by auto hence "\ s \ \ x" using Fun.IH[OF x] by simp moreover have "arity f > 0" using x fun_type_inv_wf Fun.prems by (metis length_pos_if_in_set term.order_refl wf\<^sub>t\<^sub>r\<^sub>m_def) ultimately show ?thesis using x Fun.prems fun_type[of f T] by auto qed simp qed simp lemma subterm_funs_term_in_type: assumes "wf\<^sub>t\<^sub>r\<^sub>m t" "Fun f T \ t" "\ (Fun f T) = TComp f (map \ T)" shows "f \ funs_term (\ t)" using assms(2,1,3) proof (induction t) case (Fun f' T') hence [simp]: "wf\<^sub>t\<^sub>r\<^sub>m (Fun f T)" by (metis wf_trm_subtermeq) { fix a assume \: "\ (Fun f' T') = TAtom a" hence "Fun f T = Fun f' T'" using Fun TAtom_term_cases subtermeq_Var_const by metis hence False using Fun.prems(3) \ by simp } moreover { fix g S assume \: "\ (Fun f' T') = TComp g S" hence "g = f'" "S = map \ T'" using Fun.prems(2) fun_type_id_eq[OF \] fun_type[OF fun_type_inv(1)[OF \]] by auto hence \': "\ (Fun f' T') = TComp f' (map \ T')" using \ by auto hence "g \ funs_term (\ (Fun f' T'))" using \ by auto moreover { assume "Fun f T \ Fun f' T'" then obtain x where "x \ set T'" "Fun f T \ x" using Fun.prems(1) by auto hence "f \ funs_term (\ x)" using Fun.IH[OF _ _ _ Fun.prems(3), of x] wf_trm_subtermeq[OF \wf\<^sub>t\<^sub>r\<^sub>m (Fun f' T')\, of x] by force moreover have "\ x \ set (map \ T')" using \' \x \ set T'\ by auto ultimately have "f \ funs_term (\ (Fun f' T'))" using \' by auto } ultimately have ?case by (cases "Fun f T = Fun f' T'") (auto simp add: \g = f'\) } ultimately show ?case by (cases "\ (Fun f' T')") auto qed simp lemma wt_subst_fv_termtype_subterm: assumes "x \ fv (\ y)" and "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and "wf\<^sub>t\<^sub>r\<^sub>m (\ y)" shows "\ (Var x) \ \ (Var y)" using subtermeq_imp_subtermtypeeq[OF assms(3) var_is_subterm[OF assms(1)]] wt_subst_trm''[OF assms(2), of "Var y"] by auto lemma wt_subst_fv\<^sub>s\<^sub>e\<^sub>t_termtype_subterm: assumes "x \ fv\<^sub>s\<^sub>e\<^sub>t (\ ` Y)" and "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "\y \ Y. \ (Var x) \ \ (Var y)" using wt_subst_fv_termtype_subterm[OF _ assms(2), of x] assms(1,3) by fastforce lemma funs_term_type_iff: assumes t: "wf\<^sub>t\<^sub>r\<^sub>m t" and f: "arity f > 0" shows "f \ funs_term (\ t) \ (f \ funs_term t \ (\x \ fv t. f \ funs_term (\ (Var x))))" (is "?P t \ ?Q t") using t proof (induction t) case (Fun g T) hence IH: "?P s \ ?Q s" when "s \ set T" for s using that wf_trm_subterm[OF _ Fun_param_is_subterm] by blast have 0: "arity g = length T" using Fun.prems unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto show ?case proof (cases "f = g") case True thus ?thesis using fun_type[OF f] by simp next case False have "?P (Fun g T) \ (\s \ set T. ?P s)" proof assume *: "?P (Fun g T)" hence "\ (Fun g T) = TComp g (map \ T)" using const_type[of g] fun_type[of g] by force thus "\s \ set T. ?P s" using False * by force next assume *: "\s \ set T. ?P s" hence "\ (Fun g T) = TComp g (map \ T)" using 0 const_type[of g] fun_type[of g] by force thus "?P (Fun g T)" using False * by force qed thus ?thesis using False f IH by auto qed qed simp lemma funs_term_type_iff': assumes M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M" and f: "arity f > 0" shows "f \ \(funs_term ` \ ` M) \ (f \ \(funs_term ` M) \ (\x \ fv\<^sub>s\<^sub>e\<^sub>t M. f \ funs_term (\ (Var x))))" (is "?A \ ?B") proof assume ?A then obtain t where "t \ M" "wf\<^sub>t\<^sub>r\<^sub>m t" "f \ funs_term (\ t)" using M by moura thus ?B using funs_term_type_iff[OF _ f, of t] by auto next assume ?B then obtain t where "t \ M" "wf\<^sub>t\<^sub>r\<^sub>m t" "f \ funs_term t \ (\x \ fv t. f \ funs_term (\ (Var x)))" using M by auto thus ?A using funs_term_type_iff[OF _ f, of t] by blast qed lemma Ana_subterm_type: assumes "Ana t = (K,M)" and "wf\<^sub>t\<^sub>r\<^sub>m t" and "m \ set M" shows "\ m \ \ t" proof - have "m \ t" using Ana_subterm[OF assms(1)] assms(3) by auto thus ?thesis using subtermeq_imp_subtermtypeeq[OF assms(2)] by simp qed lemma wf_trm_TAtom_subterms: assumes "wf\<^sub>t\<^sub>r\<^sub>m t" "\ t = TAtom \" shows "subterms t = {t}" using assms const_type_inv unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by (cases t) force+ lemma wf_trm_TComp_subterm: assumes "wf\<^sub>t\<^sub>r\<^sub>m s" "t \ s" obtains f T where "\ s = TComp f T" proof (cases s) case (Var x) thus ?thesis using \t \ s\ by simp next case (Fun g S) hence "length S > 0" using assms Fun_subterm_inside_params[of t g S] by auto hence "arity g > 0" by (metis \wf\<^sub>t\<^sub>r\<^sub>m s\ \s = Fun g S\ term.order_refl wf\<^sub>t\<^sub>r\<^sub>m_def) thus ?thesis using fun_type \s = Fun g S\ that by auto qed lemma SMP_empty[simp]: "SMP {} = {}" proof (rule ccontr) assume "SMP {} \ {}" then obtain t where "t \ SMP {}" by auto thus False by (induct t rule: SMP.induct) auto qed lemma SMP_I: assumes "s \ M" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "t \ s \ \" "\v. wf\<^sub>t\<^sub>r\<^sub>m (\ v)" shows "t \ SMP M" using SMP.Substitution[OF SMP.MP[OF assms(1)] assms(2)] SMP.Subterm[of "s \ \" M t] assms(3,4) by (cases "t = s \ \") simp_all lemma SMP_wf_trm: assumes "t \ SMP M" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M" shows "wf\<^sub>t\<^sub>r\<^sub>m t" using assms(1) by (induct t rule: SMP.induct) (use assms(2) in blast, use wf_trm_subtermeq in blast, use wf_trm_subst in blast, use Ana_keys_wf' in blast) lemma SMP_ikI[intro]: "t \ ik\<^sub>s\<^sub>t S \ t \ SMP (trms\<^sub>s\<^sub>t S)" by force lemma MP_setI[intro]: "x \ set S \ trms\<^sub>s\<^sub>t\<^sub>p x \ trms\<^sub>s\<^sub>t S" by force lemma SMP_setI[intro]: "x \ set S \ trms\<^sub>s\<^sub>t\<^sub>p x \ SMP (trms\<^sub>s\<^sub>t S)" by force lemma SMP_subset_I: assumes M: "\t \ M. \s \. s \ N \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = s \ \" shows "SMP M \ SMP N" proof fix t show "t \ SMP M \ t \ SMP N" proof (induction t rule: SMP.induct) case (MP t) then obtain s \ where s: "s \ N" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "t = s \ \" using M by moura show ?case using SMP_I[OF s(1,2), of "s \ \"] s(3,4) wf_trm_subst_range_iff by fast qed (auto intro!: SMP.Substitution[of _ N]) qed lemma SMP_union: "SMP (A \ B) = SMP A \ SMP B" proof show "SMP (A \ B) \ SMP A \ SMP B" proof fix t assume "t \ SMP (A \ B)" thus "t \ SMP A \ SMP B" by (induct rule: SMP.induct) blast+ qed { fix t assume "t \ SMP A" hence "t \ SMP (A \ B)" by (induct rule: SMP.induct) blast+ } moreover { fix t assume "t \ SMP B" hence "t \ SMP (A \ B)" by (induct rule: SMP.induct) blast+ } ultimately show "SMP A \ SMP B \ SMP (A \ B)" by blast qed lemma SMP_append[simp]: "SMP (trms\<^sub>s\<^sub>t (S@S')) = SMP (trms\<^sub>s\<^sub>t S) \ SMP (trms\<^sub>s\<^sub>t S')" (is "?A = ?B") using SMP_union by simp lemma SMP_mono: "A \ B \ SMP A \ SMP B" proof - assume "A \ B" then obtain C where "B = A \ C" by moura thus "SMP A \ SMP B" by (simp add: SMP_union) qed lemma SMP_Union: "SMP (\m \ M. f m) = (\m \ M. SMP (f m))" proof show "SMP (\m\M. f m) \ (\m\M. SMP (f m))" proof fix t assume "t \ SMP (\m\M. f m)" thus "t \ (\m\M. SMP (f m))" by (induct t rule: SMP.induct) force+ qed show "(\m\M. SMP (f m)) \ SMP (\m\M. f m)" proof fix t assume "t \ (\m\M. SMP (f m))" then obtain m where "m \ M" "t \ SMP (f m)" by moura thus "t \ SMP (\m\M. f m)" using SMP_mono[of "f m" "\m\M. f m"] by auto qed qed lemma SMP_singleton_ex: "t \ SMP M \ (\m \ M. t \ SMP {m})" "m \ M \ t \ SMP {m} \ t \ SMP M" using SMP_Union[of "\t. {t}" M] by auto lemma SMP_Cons: "SMP (trms\<^sub>s\<^sub>t (x#S)) = SMP (trms\<^sub>s\<^sub>t [x]) \ SMP (trms\<^sub>s\<^sub>t S)" using SMP_append[of "[x]" S] by auto lemma SMP_Nil[simp]: "SMP (trms\<^sub>s\<^sub>t []) = {}" proof - { fix t assume "t \ SMP (trms\<^sub>s\<^sub>t [])" hence False by induct auto } thus ?thesis by blast qed lemma SMP_subset_union_eq: assumes "M \ SMP N" shows "SMP N = SMP (M \ N)" proof - { fix t assume "t \ SMP (M \ N)" hence "t \ SMP N" using assms by (induction rule: SMP.induct) blast+ } thus ?thesis using SMP_union by auto qed lemma SMP_subterms_subset: "subterms\<^sub>s\<^sub>e\<^sub>t M \ SMP M" proof fix t assume "t \ subterms\<^sub>s\<^sub>e\<^sub>t M" then obtain m where "m \ M" "t \ m" by auto thus "t \ SMP M" using SMP_I[of _ _ Var] by auto qed lemma SMP_SMP_subset: "N \ SMP M \ SMP N \ SMP M" by (metis SMP_mono SMP_subset_union_eq Un_commute Un_upper2) lemma wt_subst_rm_vars: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (rm_vars X \)" using rm_vars_dom unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by auto lemma wt_subst_SMP_subset: assumes "trms\<^sub>s\<^sub>t S \ SMP S'" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "trms\<^sub>s\<^sub>t (S \\<^sub>s\<^sub>t \) \ SMP S'" proof fix t assume *: "t \ trms\<^sub>s\<^sub>t (S \\<^sub>s\<^sub>t \)" show "t \ SMP S'" using trm_strand_subst_cong(2)[OF *] proof assume "\t'. t = t' \ \ \ t' \ trms\<^sub>s\<^sub>t S" thus "t \ SMP S'" using assms SMP.Substitution by auto next assume "\X F. Inequality X F \ set S \ (\t'\trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F. t = t' \ rm_vars (set X) \)" then obtain X F t' where **: "Inequality X F \ set S" "t'\trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F" "t = t' \ rm_vars (set X) \" by force then obtain s where s: "s \ trms\<^sub>s\<^sub>t\<^sub>p (Inequality X F)" "t = s \ rm_vars (set X) \" by moura hence "s \ SMP (trms\<^sub>s\<^sub>t S)" using **(1) by force hence "t \ SMP (trms\<^sub>s\<^sub>t S)" using SMP.Substitution[OF _ wt_subst_rm_vars[OF assms(2)] wf_trms_subst_rm_vars'[OF assms(3)]] unfolding s(2) by blast thus "t \ SMP S'" by (metis SMP_union SMP_subset_union_eq UnCI assms(1)) qed qed lemma MP_subset_SMP: "\(trms\<^sub>s\<^sub>t\<^sub>p ` set S) \ SMP (trms\<^sub>s\<^sub>t S)" "trms\<^sub>s\<^sub>t S \ SMP (trms\<^sub>s\<^sub>t S)" "M \ SMP M" by auto lemma SMP_fun_map_snd_subset: "SMP (trms\<^sub>s\<^sub>t (map Send X)) \ SMP (trms\<^sub>s\<^sub>t [Send (Fun f X)])" proof fix t assume "t \ SMP (trms\<^sub>s\<^sub>t (map Send X))" thus "t \ SMP (trms\<^sub>s\<^sub>t [Send (Fun f X)])" proof (induction t rule: SMP.induct) case (MP t) hence "t \ set X" by auto hence "t \ Fun f X" by (metis subtermI') thus ?case using SMP.Subterm[of "Fun f X" "trms\<^sub>s\<^sub>t [Send (Fun f X)]" t] using SMP.MP by auto qed blast+ qed lemma SMP_wt_subst_subset: assumes "t \ SMP (M \\<^sub>s\<^sub>e\<^sub>t \)" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "t \ SMP M" using assms wf_trm_subst_range_iff[of \] by (induct t rule: SMP.induct) blast+ lemma SMP_wt_instances_subset: assumes "\t \ M. \s \ N. \\. t = s \ \ \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" and "t \ SMP M" shows "t \ SMP N" proof - obtain m where m: "m \ M" "t \ SMP {m}" using SMP_singleton_ex(1)[OF assms(2)] by blast then obtain n \ where n: "n \ N" "m = n \ \" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using assms(1) by fast have "t \ SMP (N \\<^sub>s\<^sub>e\<^sub>t \)" using n(1,2) SMP_singleton_ex(2)[of m "N \\<^sub>s\<^sub>e\<^sub>t \", OF _ m(2)] by fast thus ?thesis using SMP_wt_subst_subset[OF _ n(3,4)] by blast qed lemma SMP_consts: assumes "\t \ M. \c. t = Fun c []" and "\t \ M. Ana t = ([], [])" shows "SMP M = M" proof show "SMP M \ M" proof fix t show "t \ SMP M \ t \ M" apply (induction t rule: SMP.induct) by (use assms in auto) qed qed auto lemma SMP_subterms_eq: "SMP (subterms\<^sub>s\<^sub>e\<^sub>t M) = SMP M" proof show "SMP M \ SMP (subterms\<^sub>s\<^sub>e\<^sub>t M)" using SMP_mono[of M "subterms\<^sub>s\<^sub>e\<^sub>t M"] by blast show "SMP (subterms\<^sub>s\<^sub>e\<^sub>t M) \ SMP M" proof fix t show "t \ SMP (subterms\<^sub>s\<^sub>e\<^sub>t M) \ t \ SMP M" by (induction t rule: SMP.induct) blast+ qed qed lemma SMP_funs_term: assumes t: "t \ SMP M" "f \ funs_term t \ (\x \ fv t. f \ funs_term (\ (Var x)))" and f: "arity f > 0" and M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M" and Ana_f: "\s K T. Ana s = (K,T) \ f \ \(funs_term ` set K) \ f \ funs_term s" shows "f \ \(funs_term ` M) \ (\x \ fv\<^sub>s\<^sub>e\<^sub>t M. f \ funs_term (\ (Var x)))" using t proof (induction t rule: SMP.induct) case (Subterm t t') thus ?case by (metis UN_I vars_iff_subtermeq funs_term_subterms_eq(1) term.order_trans) next case (Substitution t \) show ?case using M SMP_wf_trm[OF Substitution.hyps(1)] wf_trm_subst[of \ t, OF Substitution.hyps(3)] funs_term_type_iff[OF _ f] wt_subst_trm''[OF Substitution.hyps(2), of t] Substitution.prems Substitution.IH by metis next case (Ana t K T t') thus ?case using Ana_f[OF Ana.hyps(2)] Ana_keys_fv[OF Ana.hyps(2)] by fastforce qed auto lemma id_type_eq: assumes "\ (Fun f X) = \ (Fun g Y)" shows "f \ \ \ g \ \" "f \ \\<^sub>f \ g \ \\<^sub>f" using assms const_type' fun_type' id_union_univ(1) by (metis UNIV_I UnE "term.distinct"(1))+ lemma fun_type_arg_cong: assumes "f \ \\<^sub>f" "g \ \\<^sub>f" "\ (Fun f (x#X)) = \ (Fun g (y#Y))" shows "\ x = \ y" "\ (Fun f X) = \ (Fun g Y)" using assms fun_type' by auto lemma fun_type_arg_cong': assumes "f \ \\<^sub>f" "g \ \\<^sub>f" "\ (Fun f (X@x#X')) = \ (Fun g (Y@y#Y'))" "length X = length Y" shows "\ x = \ y" using assms proof (induction X arbitrary: Y) case Nil thus ?case using fun_type_arg_cong(1)[of f g x X' y Y'] by auto next case (Cons x' X Y'') then obtain y' Y where "Y'' = y'#Y" by (metis length_Suc_conv) hence "\ (Fun f (X@x#X')) = \ (Fun g (Y@y#Y'))" "length X = length Y" using Cons.prems(3,4) fun_type_arg_cong(2)[OF Cons.prems(1,2), of x' "X@x#X'"] by auto thus ?thesis using Cons.IH[OF Cons.prems(1,2)] by auto qed lemma fun_type_param_idx: "\ (Fun f T) = Fun g S \ i < length T \ \ (T ! i) = S ! i" by (metis fun_type fun_type_id_eq fun_type_inv(1) nth_map term.inject(2)) lemma fun_type_param_ex: assumes "\ (Fun f T) = Fun g (map \ S)" "t \ set S" shows "\s \ set T. \ s = \ t" using fun_type_length_eq[OF assms(1)] length_map[of \ S] assms(2) fun_type_param_idx[OF assms(1)] nth_map in_set_conv_nth by metis lemma tfr_stp_all_split: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (x#S) \ list_all tfr\<^sub>s\<^sub>t\<^sub>p [x]" "list_all tfr\<^sub>s\<^sub>t\<^sub>p (x#S) \ list_all tfr\<^sub>s\<^sub>t\<^sub>p S" "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S@S') \ list_all tfr\<^sub>s\<^sub>t\<^sub>p S" "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S@S') \ list_all tfr\<^sub>s\<^sub>t\<^sub>p S'" "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S@x#S') \ list_all tfr\<^sub>s\<^sub>t\<^sub>p (S@S')" by fastforce+ lemma tfr_stp_all_append: assumes "list_all tfr\<^sub>s\<^sub>t\<^sub>p S" "list_all tfr\<^sub>s\<^sub>t\<^sub>p S'" shows "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S@S')" using assms by fastforce lemma tfr_stp_all_wt_subst_apply: assumes "list_all tfr\<^sub>s\<^sub>t\<^sub>p S" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "bvars\<^sub>s\<^sub>t S \ range_vars \ = {}" shows "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S \\<^sub>s\<^sub>t \)" using assms(1,4) proof (induction S) case (Cons x S) hence IH: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S \\<^sub>s\<^sub>t \)" using tfr_stp_all_split(2)[of x S] unfolding range_vars_alt_def by fastforce thus ?case proof (cases x) case (Equality a t t') hence "(\\. Unifier \ t t') \ \ t = \ t'" using Cons.prems by auto hence "(\\. Unifier \ (t \ \) (t' \ \)) \ \ (t \ \) = \ (t' \ \)" by (metis Unifier_comp' wt_subst_trm'[OF assms(2)]) moreover have "(x#S) \\<^sub>s\<^sub>t \ = Equality a (t \ \) (t' \ \)#(S \\<^sub>s\<^sub>t \)" using \x = Equality a t t'\ by auto ultimately show ?thesis using IH by auto next case (Inequality X F) let ?\ = "rm_vars (set X) \" let ?G = "F \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ?\" let ?P = "\F X. \x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \a. \ (Var x) = TAtom a" let ?Q = "\F 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 0: "set X \ range_vars ?\ = {}" using Cons.prems(2) Inequality rm_vars_img_subset[of "set X"] by (auto simp add: subst_domain_def range_vars_alt_def) have 1: "?P F X \ ?Q F X" using Inequality Cons.prems by simp have 2: "fv\<^sub>s\<^sub>e\<^sub>t (?\ ` set X) = set X" by auto have "?P ?G X" when "?P F X" using that proof (induction F) case (Cons g G) obtain t t' where g: "g = (t,t')" by (metis surj_pair) have "\x \ (fv (t \ ?\) \ fv (t' \ ?\)) - set X. \a. \ (Var x) = Var a" proof - have *: "\x \ fv t - set X. \a. \ (Var x) = Var a" "\x \ fv t' - set X. \a. \ (Var x) = Var a" using g Cons.prems by simp_all have **: "\x. wf\<^sub>t\<^sub>r\<^sub>m (?\ x)" using \(2) wf_trm_subst_range_iff[of \] wf_trm_subst_rm_vars'[of \ _ "set X"] by simp show ?thesis using wt_subst_TAtom_fv[OF wt_subst_rm_vars[OF \(1)] ** *(1)] wt_subst_TAtom_fv[OF wt_subst_rm_vars[OF \(1)] ** *(2)] wt_subst_trm'[OF wt_subst_rm_vars[OF \(1), of "set X"]] 2 by blast qed moreover have "\x\fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (G \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ?\) - set X. \a. \ (Var x) = Var a" using Cons by auto ultimately show ?case using g by (auto simp add: subst_apply_pairs_def) qed (simp add: subst_apply_pairs_def) hence "?P ?G X \ ?Q ?G X" using 1 ineq_subterm_inj_cond_subst[OF 0, of "trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F"] trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s_subst[of F ?\] by presburger moreover have "(x#S) \\<^sub>s\<^sub>t \ = Inequality X (F \\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ?\)#(S \\<^sub>s\<^sub>t \)" using \x = Inequality X F\ by auto ultimately show ?thesis using IH by simp qed auto qed simp lemma tfr_stp_all_same_type: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (S@Equality a t t'#S') \ Unifier \ t t' \ \ t = \ t'" by force+ lemma tfr_subset: "\A B. tfr\<^sub>s\<^sub>e\<^sub>t (A \ B) \ tfr\<^sub>s\<^sub>e\<^sub>t A" "\A B. tfr\<^sub>s\<^sub>e\<^sub>t B \ A \ B \ tfr\<^sub>s\<^sub>e\<^sub>t A" "\A B. tfr\<^sub>s\<^sub>e\<^sub>t B \ SMP A \ SMP B \ tfr\<^sub>s\<^sub>e\<^sub>t A" proof - show 1: "tfr\<^sub>s\<^sub>e\<^sub>t (A \ B) \ tfr\<^sub>s\<^sub>e\<^sub>t A" for A B using SMP_union[of A B] unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by simp fix A B assume B: "tfr\<^sub>s\<^sub>e\<^sub>t B" show "A \ B \ tfr\<^sub>s\<^sub>e\<^sub>t A" proof - assume "A \ B" then obtain C where "B = A \ C" by moura thus ?thesis using B 1 by blast qed show "SMP A \ SMP B \ tfr\<^sub>s\<^sub>e\<^sub>t A" proof - assume "SMP A \ SMP B" then obtain C where "SMP B = SMP A \ C" by moura thus ?thesis using B unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by blast qed qed lemma tfr_empty[simp]: "tfr\<^sub>s\<^sub>e\<^sub>t {}" unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by simp lemma tfr_consts_mono: assumes "\t \ M. \c. t = Fun c []" and "\t \ M. Ana t = ([], [])" and "tfr\<^sub>s\<^sub>e\<^sub>t N" shows "tfr\<^sub>s\<^sub>e\<^sub>t (N \ M)" proof - { fix s t assume *: "s \ SMP (N \ M) - range Var" "t \ SMP (N \ M) - range Var" "\\. Unifier \ s t" hence **: "is_Fun s" "is_Fun t" "s \ SMP N \ s \ M" "t \ SMP N \ t \ M" using assms(3) SMP_consts[OF assms(1,2)] SMP_union[of N M] by auto moreover have "\ s = \ t" when "s \ SMP N" "t \ SMP N" using that assms(3) *(3) **(1,2) unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by blast moreover have "\ s = \ t" when st: "s \ M" "t \ M" proof - obtain c d where "s = Fun c []" "t = Fun d []" using st assms(1) by moura hence "s = t" using *(3) by fast thus ?thesis by metis qed moreover have "\ s = \ t" when st: "s \ SMP N" "t \ M" proof - obtain c where "t = Fun c []" using st assms(1) by moura hence "s = t" using *(3) **(1,2) by auto thus ?thesis by metis qed moreover have "\ s = \ t" when st: "s \ M" "t \ SMP N" proof - obtain c where "s = Fun c []" using st assms(1) by moura hence "s = t" using *(3) **(1,2) by auto thus ?thesis by metis qed ultimately have "\ s = \ t" by metis } thus ?thesis by (metis tfr\<^sub>s\<^sub>e\<^sub>t_def) qed lemma dual\<^sub>s\<^sub>t_tfr\<^sub>s\<^sub>t\<^sub>p: "list_all tfr\<^sub>s\<^sub>t\<^sub>p S \ list_all tfr\<^sub>s\<^sub>t\<^sub>p (dual\<^sub>s\<^sub>t S)" proof (induction S) case (Cons x S) have "list_all tfr\<^sub>s\<^sub>t\<^sub>p S" using Cons.prems by simp hence IH: "list_all tfr\<^sub>s\<^sub>t\<^sub>p (dual\<^sub>s\<^sub>t S)" using Cons.IH by metis from Cons show ?case proof (cases x) case (Equality a t t') hence "(\\. Unifier \ t t') \ \ t = \ t'" using Cons by auto thus ?thesis using Equality IH by fastforce next case (Inequality X F) have "set (dual\<^sub>s\<^sub>t (x#S)) = insert x (set (dual\<^sub>s\<^sub>t S))" using Inequality by auto moreover have "(\x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \a. \ (Var x) = Var a) \ (\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))" using Cons.prems Inequality by auto ultimately show ?thesis using Inequality IH by auto qed auto qed simp lemma subst_var_inv_wt: assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst_var_inv \ X)" using assms f_inv_into_f[of _ \ X] unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def subst_var_inv_def by presburger lemma subst_var_inv_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (subst_var_inv \ X))" using f_inv_into_f[of _ \ X] unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def subst_var_inv_def by auto lemma unify_list_wt_if_same_type: assumes "Unification.unify E B = Some U" "\(s,t) \ set E. wf\<^sub>t\<^sub>r\<^sub>m s \ wf\<^sub>t\<^sub>r\<^sub>m t \ \ s = \ t" and "\(v,t) \ set B. \ (Var v) = \ t" shows "\(v,t) \ set U. \ (Var v) = \ t" using assms proof (induction E B arbitrary: U rule: Unification.unify.induct) case (2 f X g Y E B U) hence "wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)" "wf\<^sub>t\<^sub>r\<^sub>m (Fun g Y)" "\ (Fun f X) = \ (Fun g Y)" by auto from "2.prems"(1) obtain E' where *: "decompose (Fun f X) (Fun g Y) = Some E'" and [simp]: "f = g" "length X = length Y" "E' = zip X Y" and **: "Unification.unify (E'@E) B = Some U" by (auto split: option.splits) have "\(s,t) \ set E'. wf\<^sub>t\<^sub>r\<^sub>m s \ wf\<^sub>t\<^sub>r\<^sub>m t \ \ s = \ t" proof - { fix s t assume "(s,t) \ set E'" then obtain X' X'' Y' Y'' where "X = X'@s#X''" "Y = Y'@t#Y''" "length X' = length Y'" using zip_arg_subterm_split[of s t X Y] \E' = zip X Y\ by metis hence "\ (Fun f (X'@s#X'')) = \ (Fun g (Y'@t#Y''))" by (metis \\ (Fun f X) = \ (Fun g Y)\) from \E' = zip X Y\ have "\(s,t) \ set E'. s \ Fun f X \ t \ Fun g Y" using zip_arg_subterm[of _ _ X Y] by blast with \(s,t) \ set E'\ have "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t" using wf_trm_subterm \wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)\ \wf\<^sub>t\<^sub>r\<^sub>m (Fun g Y)\ by (blast,blast) moreover have "f \ \\<^sub>f" proof (rule ccontr) assume "f \ \\<^sub>f" hence "f \ \" "arity f = 0" using const_arity_eq_zero[of f] by simp_all thus False using \wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)\ * \(s,t) \ set E'\ unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto qed hence "\ s = \ t" using fun_type_arg_cong' \f \ \\<^sub>f\ \\ (Fun f (X'@s#X'')) = \ (Fun g (Y'@t#Y''))\ \length X' = length Y'\ \f = g\ by metis ultimately have "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t" "\ s = \ t" by metis+ } thus ?thesis by blast qed moreover have "\(s,t) \ set E. wf\<^sub>t\<^sub>r\<^sub>m s \ wf\<^sub>t\<^sub>r\<^sub>m t \ \ s = \ t" using "2.prems"(2) by auto ultimately show ?case using "2.IH"[OF * ** _ "2.prems"(3)] by fastforce next case (3 v t E B U) hence "\ (Var v) = \ t" "wf\<^sub>t\<^sub>r\<^sub>m t" by auto hence "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst v t)" and *: "\(v, t) \ set ((v,t)#B). \ (Var v) = \ t" "\t t'. (t,t') \ set E \ \ t = \ t'" using "3.prems"(2,3) unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def subst_def by auto show ?case proof (cases "t = Var v") assume "t = Var v" thus ?case using 3 by auto next assume "t \ Var v" hence "v \ fv t" using "3.prems"(1) by auto hence **: "Unification.unify (subst_list (subst v t) E) ((v, t)#B) = Some U" using Unification.unify.simps(3)[of v t E B] "3.prems"(1) \t \ Var v\ by auto have "\(s, t) \ set (subst_list (subst v t) E). wf\<^sub>t\<^sub>r\<^sub>m s \ wf\<^sub>t\<^sub>r\<^sub>m t" using wf_trm_subst_singleton[OF _ \wf\<^sub>t\<^sub>r\<^sub>m t\] "3.prems"(2) unfolding subst_list_def subst_def by auto moreover have "\(s, t) \ set (subst_list (subst v t) E). \ s = \ t" using *(2)[THEN wt_subst_trm'[OF \wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst v t)\]] by (simp add: subst_list_def) ultimately show ?thesis using "3.IH"(2)[OF \t \ Var v\ \v \ fv t\ ** _ *(1)] by auto qed next case (4 f X v E B U) hence "\ (Var v) = \ (Fun f X)" "wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)" by auto hence "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst v (Fun f X))" and *: "\(v, t) \ set ((v,(Fun f X))#B). \ (Var v) = \ t" "\t t'. (t,t') \ set E \ \ t = \ t'" using "4.prems"(2,3) unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def subst_def by auto have "v \ fv (Fun f X)" using "4.prems"(1) by force hence **: "Unification.unify (subst_list (subst v (Fun f X)) E) ((v, (Fun f X))#B) = Some U" using Unification.unify.simps(3)[of v "Fun f X" E B] "4.prems"(1) by auto have "\(s, t) \ set (subst_list (subst v (Fun f X)) E). wf\<^sub>t\<^sub>r\<^sub>m s \ wf\<^sub>t\<^sub>r\<^sub>m t" using wf_trm_subst_singleton[OF _ \wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)\] "4.prems"(2) unfolding subst_list_def subst_def by auto moreover have "\(s, t) \ set (subst_list (subst v (Fun f X)) E). \ s = \ t" using *(2)[THEN wt_subst_trm'[OF \wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst v (Fun f X))\]] by (simp add: subst_list_def) ultimately show ?case using "4.IH"[OF \v \ fv (Fun f X)\ ** _ *(1)] by auto qed auto lemma mgu_wt_if_same_type: assumes "mgu s t = Some \" "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t" "\ s = \ t" shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" proof - let ?fv_disj = "\v t S. \(\(v',t') \ S - {(v,t)}. (insert v (fv t)) \ (insert v' (fv t')) \ {})" from assms(1) obtain \' where "Unification.unify [(s,t)] [] = Some \'" "subst_of \' = \" by (auto split: option.splits) hence "\(v,t) \ set \'. \ (Var v) = \ t" "distinct (map fst \')" using assms(2,3,4) unify_list_wt_if_same_type unify_list_distinct[of "[(s,t)]"] by auto thus "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" using \subst_of \' = \\ unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def proof (induction \' arbitrary: \ rule: List.rev_induct) case (snoc tt \' \) then obtain v t where tt: "tt = (v,t)" by (metis surj_pair) hence \: "\ = subst v t \\<^sub>s subst_of \'" using snoc.prems(3) by simp have "\(v,t) \ set \'. \ (Var v) = \ t" "distinct (map fst \')" using snoc.prems(1,2) by auto then obtain \'' where \'': "subst_of \' = \''" "\v. \ (Var v) = \ (\'' v)" by (metis snoc.IH) hence "\ t = \ (t \ \'')" for t using wt_subst_trm by blast hence "\ (Var v) = \ (\'' v)" "\ t = \ (t \ \'')" using \''(2) by auto moreover have "\ (Var v) = \ t" using snoc.prems(1) tt by simp moreover have \2: "\ = Var(v := t) \\<^sub>s \'' " using \ \''(1) unfolding subst_def by simp ultimately have "\ (Var v) = \ (\ v)" unfolding subst_compose_def by simp have "subst_domain (subst v t) \ {v}" unfolding subst_def by (auto simp add: subst_domain_def) hence *: "subst_domain \ \ insert v (subst_domain \'')" using tt \ \''(1) snoc.prems(2) subst_domain_compose[of _ \''] by (auto simp add: subst_domain_def) have "v \ set (map fst \')" using tt snoc.prems(2) by auto hence "v \ subst_domain \''" using \''(1) subst_of_dom_subset[of \'] by auto { fix w assume "w \ subst_domain \''" hence "\ w = \'' w" using \2 \''(1) \v \ subst_domain \''\ unfolding subst_compose_def by auto hence "\ (Var w) = \ (\ w)" using \''(2) by simp } thus ?case using \\ (Var v) = \ (\ v)\ * by force qed simp qed lemma wt_Unifier_if_Unifier: assumes s_t: "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t" "\ s = \ t" and \: "Unifier \ s t" shows "\\. Unifier \ s t \ wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using mgu_always_unifies[OF \] mgu_gives_MGU[THEN MGU_is_Unifier[of s _ t]] mgu_wt_if_same_type[OF _ s_t] mgu_wf_trm[OF _ s_t(1,2)] wf_trm_subst_range_iff by fast end subsection \Automatically Proving Type-Flaw Resistance\ subsubsection \Definitions: Variable Renaming\ abbreviation "max_var t \ Max (insert 0 (snd ` fv t))" abbreviation "max_var_set X \ Max (insert 0 (snd ` X))" definition "var_rename n v \ Var (fst v, snd v + Suc n)" definition "var_rename_inv n v \ Var (fst v, snd v - Suc n)" subsubsection \Definitions: Computing a Finite Representation of the Sub-Message Patterns\ text \A sufficient requirement for a term to be a well-typed instance of another term\ definition is_wt_instance_of_cond where "is_wt_instance_of_cond \ t s \ ( \ t = \ s \ (case mgu t s of None \ False | Some \ \ inj_on \ (fv t) \ (\x \ fv t. is_Var (\ x))))" definition has_all_wt_instances_of where "has_all_wt_instances_of \ N M \ \t \ N. \s \ M. is_wt_instance_of_cond \ t s" text \This function computes a finite representation of the set of sub-message patterns\ definition SMP0 where "SMP0 Ana \ M \ let f = \t. Fun (the_Fun (\ t)) (map Var (zip (args (\ t)) [0.. t))])); g = \M'. map f (filter (\t. is_Var t \ is_Fun (\ t)) M')@ concat (map (fst \ Ana) M')@concat (map subterms_list M'); h = remdups \ g in while (\A. set (h A) \ set A) h M" text \These definitions are useful to refine an SMP representation set\ fun generalize_term where "generalize_term _ _ n (Var x) = (Var x, n)" | "generalize_term \ p n (Fun f T) = (let \ = \ (Fun f T) in if p \ then (Var (\, n), Suc n) else let (T',n') = foldr (\t (S,m). let (t',m') = generalize_term \ p m t in (t'#S,m')) T ([],n) in (Fun f T', n'))" definition generalize_terms where "generalize_terms \ p \ map (fst \ generalize_term \ p 0)" definition remove_superfluous_terms where "remove_superfluous_terms \ T \ let f = \S t R. \s \ set S - R. s \ t \ is_wt_instance_of_cond \ t s; g = \S t (U,R). if f S t R then (U, insert t R) else (t#U, R); h = \S. remdups (fst (foldr (g S) S ([],{}))) in while (\S. h S \ S) h T" subsubsection \Definitions: Checking Type-Flaw Resistance\ definition is_TComp_var_instance_closed where "is_TComp_var_instance_closed \ M \ \x \ fv\<^sub>s\<^sub>e\<^sub>t (set M). is_Fun (\ (Var x)) \ list_ex (\t. is_Fun t \ \ t = \ (Var x) \ list_all is_Var (args t) \ distinct (args t)) M" definition finite_SMP_representation where "finite_SMP_representation arity Ana \ M \ list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) M \ has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M) \ has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M) \ is_TComp_var_instance_closed \ M" definition comp_tfr\<^sub>s\<^sub>e\<^sub>t where "comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \ M \ finite_SMP_representation arity Ana \ M \ (let \ = var_rename (max_var_set (fv\<^sub>s\<^sub>e\<^sub>t (set M))) in \s \ set M. \t \ set M. is_Fun s \ is_Fun t \ \ s \ \ t \ mgu s (t \ \) = None)" fun comp_tfr\<^sub>s\<^sub>t\<^sub>p where "comp_tfr\<^sub>s\<^sub>t\<^sub>p \ (\_: t \ t'\\<^sub>s\<^sub>t) = (mgu t t' \ None \ \ t = \ t')" | "comp_tfr\<^sub>s\<^sub>t\<^sub>p \ (\X\\\: F\\<^sub>s\<^sub>t) = ( (\x \ fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. is_Var (\ (Var x))) \ (\u \ subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F). is_Fun u \ (args u = [] \ (\s \ set (args u). s \ Var ` set X))))" | "comp_tfr\<^sub>s\<^sub>t\<^sub>p _ _ = True" definition comp_tfr\<^sub>s\<^sub>t where "comp_tfr\<^sub>s\<^sub>t arity Ana \ M S \ list_all (comp_tfr\<^sub>s\<^sub>t\<^sub>p \) S \ list_all (wf\<^sub>t\<^sub>r\<^sub>m' arity) (trms_list\<^sub>s\<^sub>t S) \ has_all_wt_instances_of \ (trms\<^sub>s\<^sub>t S) (set M) \ comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \ M" subsubsection \Small Lemmata\ lemma less_Suc_max_var_set: assumes z: "z \ X" and X: "finite X" shows "snd z < Suc (max_var_set X)" proof - have "snd z \ snd ` X" using z by simp hence "snd z \ Max (insert 0 (snd ` X))" using X by simp thus ?thesis using X by simp qed lemma (in typed_model) finite_SMP_representationD: assumes "finite_SMP_representation arity Ana \ M" shows "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" and "has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M)" and "is_TComp_var_instance_closed \ M" using assms unfolding finite_SMP_representation_def list_all_iff wf\<^sub>t\<^sub>r\<^sub>m_code by blast+ lemma (in typed_model) is_wt_instance_of_condD: assumes t_instance_s: "is_wt_instance_of_cond \ t s" obtains \ where "\ t = \ s" "mgu t s = Some \" "inj_on \ (fv t)" "\ ` (fv t) \ range Var" using t_instance_s unfolding is_wt_instance_of_cond_def Let_def by (cases "mgu t s") fastforce+ lemma (in typed_model) is_wt_instance_of_condD': assumes t_wf_trm: "wf\<^sub>t\<^sub>r\<^sub>m t" and s_wf_trm: "wf\<^sub>t\<^sub>r\<^sub>m s" and t_instance_s: "is_wt_instance_of_cond \ t s" shows "\\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = s \ \" proof - obtain \ where s: "\ t = \ s" "mgu t s = Some \" "inj_on \ (fv t)" "\ ` (fv t) \ range Var" by (metis is_wt_instance_of_condD[OF t_instance_s]) have 0: "wf\<^sub>t\<^sub>r\<^sub>m t" "wf\<^sub>t\<^sub>r\<^sub>m s" using s(1) t_wf_trm s_wf_trm by auto note 1 = mgu_wt_if_same_type[OF s(2) 0 s(1)] note 2 = conjunct1[OF mgu_gives_MGU[OF s(2)]] show ?thesis using s(1) inj_var_ran_unifiable_has_subst_match[OF 2 s(3,4)] wt_subst_compose[OF 1 subst_var_inv_wt[OF 1, of "fv t"]] wf_trms_subst_compose[OF mgu_wf_trms[OF s(2) 0] subst_var_inv_wf_trms[of \ "fv t"]] by auto qed lemma (in typed_model) is_wt_instance_of_condD'': assumes s_wf_trm: "wf\<^sub>t\<^sub>r\<^sub>m s" and t_instance_s: "is_wt_instance_of_cond \ t s" and t_var: "t = Var x" shows "\y. s = Var y \ \ (Var y) = \ (Var x)" proof - obtain \ where \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and s: "Var x = s \ \" using is_wt_instance_of_condD'[OF _ s_wf_trm t_instance_s] t_var by auto obtain y where y: "s = Var y" using s by (cases s) auto show ?thesis using wt_subst_trm''[OF \] s y by metis qed lemma (in typed_model) has_all_wt_instances_ofD: assumes N_instance_M: "has_all_wt_instances_of \ N M" and t_in_N: "t \ N" obtains s \ where "s \ M" "\ t = \ s" "mgu t s = Some \" "inj_on \ (fv t)" "\ ` (fv t) \ range Var" by (metis t_in_N N_instance_M is_wt_instance_of_condD has_all_wt_instances_of_def) lemma (in typed_model) has_all_wt_instances_ofD': assumes N_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N" and M_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M" and N_instance_M: "has_all_wt_instances_of \ N M" and t_in_N: "t \ N" shows "\\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t \ M \\<^sub>s\<^sub>e\<^sub>t \" using assms is_wt_instance_of_condD' unfolding has_all_wt_instances_of_def by fast lemma (in typed_model) has_all_wt_instances_ofD'': assumes N_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N" and M_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M" and N_instance_M: "has_all_wt_instances_of \ N M" and t_in_N: "Var x \ N" shows "\y. Var y \ M \ \ (Var y) = \ (Var x)" using assms is_wt_instance_of_condD'' unfolding has_all_wt_instances_of_def by fast lemma (in typed_model) has_all_instances_of_if_subset: assumes "N \ M" shows "has_all_wt_instances_of \ N M" using assms inj_onI mgu_same_empty unfolding has_all_wt_instances_of_def is_wt_instance_of_cond_def by (smt option.case_eq_if option.discI option.sel subsetD term.discI(1) term.inject(1)) lemma (in typed_model) SMP_I': assumes N_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s N" and M_wf_trms: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M" and N_instance_M: "has_all_wt_instances_of \ N M" and t_in_N: "t \ N" shows "t \ SMP M" using has_all_wt_instances_ofD'[OF N_wf_trms M_wf_trms N_instance_M t_in_N] SMP.Substitution[OF SMP.MP[of _ M]] by blast subsubsection \Lemma: Proving Type-Flaw Resistance\ locale typed_model' = typed_model arity public Ana \ 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" + assumes \_Var_fst: "\\ n m. \ (Var (\,n)) = \ (Var (\,m))" and Ana_const: "\c T. arity c = 0 \ Ana (Fun c T) = ([],[])" and Ana_subst'_or_Ana_keys_subterm: "(\f T \ K R. Ana (Fun f T) = (K,R) \ Ana (Fun f T \ \) = (K \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \,R \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \)) \ (\t K R k. Ana t = (K,R) \ k \ set K \ k \ t)" begin lemma var_rename_inv_comp: "t \ (var_rename n \\<^sub>s var_rename_inv n) = t" proof (induction t) case (Fun f T) hence "map (\t. t \ var_rename n \\<^sub>s var_rename_inv n) T = T" by (simp add: map_idI) thus ?case by (metis subst_apply_term.simps(2)) qed (simp add: var_rename_def var_rename_inv_def) lemma var_rename_fv_disjoint: "fv s \ fv (t \ var_rename (max_var s)) = {}" proof - have 1: "\v \ fv s. snd v \ max_var s" by simp have 2: "\v \ fv (t \ var_rename n). snd v > n" for n unfolding var_rename_def by (induct t) auto show ?thesis using 1 2 by force qed lemma var_rename_fv_set_disjoint: assumes "finite M" "s \ M" shows "fv s \ fv (t \ var_rename (max_var_set (fv\<^sub>s\<^sub>e\<^sub>t M))) = {}" proof - have 1: "\v \ fv s. snd v \ max_var_set (fv\<^sub>s\<^sub>e\<^sub>t M)" using assms proof (induction M rule: finite_induct) case (insert t M) thus ?case proof (cases "t = s") case False hence "\v \ fv s. snd v \ max_var_set (fv\<^sub>s\<^sub>e\<^sub>t M)" using insert by simp moreover have "max_var_set (fv\<^sub>s\<^sub>e\<^sub>t M) \ max_var_set (fv\<^sub>s\<^sub>e\<^sub>t (insert t M))" using insert.hyps(1) insert.prems by force ultimately show ?thesis by auto qed simp qed simp have 2: "\v \ fv (t \ var_rename n). snd v > n" for n unfolding var_rename_def by (induct t) auto show ?thesis using 1 2 by force qed lemma var_rename_fv_set_disjoint': assumes "finite M" shows "fv\<^sub>s\<^sub>e\<^sub>t M \ fv\<^sub>s\<^sub>e\<^sub>t (N \\<^sub>s\<^sub>e\<^sub>t var_rename (max_var_set (fv\<^sub>s\<^sub>e\<^sub>t M))) = {}" using var_rename_fv_set_disjoint[OF assms] by auto lemma var_rename_is_renaming[simp]: "subst_range (var_rename n) \ range Var" "subst_range (var_rename_inv n) \ range Var" unfolding var_rename_def var_rename_inv_def by auto lemma var_rename_wt[simp]: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (var_rename n)" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (var_rename_inv n)" by (auto simp add: var_rename_def var_rename_inv_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def \_Var_fst) lemma var_rename_wt': assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "s = m \ \" shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (var_rename_inv n \\<^sub>s \)" "s = m \ var_rename n \ var_rename_inv n \\<^sub>s \" using assms(2) wt_subst_compose[OF var_rename_wt(2)[of n] assms(1)] var_rename_inv_comp[of m n] by force+ lemma var_rename_wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_range[simp]: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (var_rename n))" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (var_rename_inv n))" using var_rename_is_renaming by fastforce+ lemma Fun_range_case: "(\f T. Fun f T \ M \ P f T) \ (\u \ M. case u of Fun f T \ P f T | _ \ True)" "(\f T. Fun f T \ M \ P f T) \ (\u \ M. is_Fun u \ P (the_Fun u) (args u))" by (auto split: "term.splits") lemma is_TComp_var_instance_closedD: assumes x: "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" "\ (Var x) = TComp f T" and closed: "is_TComp_var_instance_closed \ M" shows "\g U. Fun g U \ set M \ \ (Fun g U) = \ (Var x) \ (\u \ set U. is_Var u) \ distinct U" using assms unfolding is_TComp_var_instance_closed_def list_all_iff list_ex_iff by fastforce lemma is_TComp_var_instance_closedD': assumes "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" "TComp f T \ \ (Var x)" and closed: "is_TComp_var_instance_closed \ M" and wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" shows "\g U. Fun g U \ set M \ \ (Fun g U) = TComp f T \ (\u \ set U. is_Var u) \ distinct U" using assms(1,2) proof (induction "\ (Var x)" arbitrary: x) case (Fun g U) note IH = Fun.hyps(1) have g: "arity g > 0" "public g" using Fun.hyps(2) fun_type_inv[of "Var x"] \_Var_fst by simp_all then obtain V where V: "Fun g V \ set M" "\ (Fun g V) = \ (Var x)" "\v \ set V. \x. v = Var x" "distinct V" "length U = length V" using is_TComp_var_instance_closedD[OF Fun.prems(1) Fun.hyps(2)[symmetric] closed(1)] by (metis Fun.hyps(2) fun_type_id_eq fun_type_length_eq is_VarE) hence U: "U = map \ V" using fun_type[OF g(1), of V] Fun.hyps(2) by simp hence 1: "\ v \ set U" when v: "v \ set V" for v using v by simp have 2: "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var z) = \ (Var y)" when z: "Var z \ set V" for z using V(1) fv_subset_subterms Fun_param_in_subterms[OF z] by fastforce show ?case proof (cases "TComp f T = \ (Var x)") case False then obtain u where u: "u \ set U" "TComp f T \ u" using Fun.prems(2) Fun.hyps(2) by moura then obtain y where y: "Var y \ set V" "\ (Var y) = u" using U V(3) \_Var_fst by auto show ?thesis using IH[OF _ 2[OF y(1)]] u y(2) by metis qed (use V in fastforce) qed simp lemma TComp_var_instance_wt_subst_exists: assumes gT: "\ (Fun g T) = TComp g (map \ U)" "wf\<^sub>t\<^sub>r\<^sub>m (Fun g T)" and U: "\u \ set U. \y. u = Var y" "distinct U" shows "\\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ Fun g T = Fun g U \ \" proof - define the_i where "the_i \ \y. THE x. x < length U \ U ! x = Var y" define \ where \: "\ \ \y. if Var y \ set U then T ! the_i y else Var y" have g: "arity g > 0" using gT(1,2) fun_type_inv(1) by blast have UT: "length U = length T" using fun_type_length_eq gT(1) by fastforce have 1: "the_i y < length U \ U ! the_i y = Var y" when y: "Var y \ set U" for y using theI'[OF distinct_Ex1[OF U(2) y]] unfolding the_i_def by simp have 2: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" using \ 1 gT(1) fun_type[OF g] UT unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by (metis (no_types, lifting) nth_map term.inject(2)) have "\i \ = T ! i" using \ 1 U(1) UT distinct_Ex1[OF U(2)] in_set_conv_nth by (metis (no_types, lifting) subst_apply_term.simps(1)) hence "T = map (\t. t \ \) U" by (simp add: UT nth_equalityI) hence 3: "Fun g T = Fun g U \ \" by simp have "subst_range \ \ set T" using \ 1 U(1) UT by (auto simp add: subst_domain_def) hence 4: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using gT(2) wf_trm_param by auto show ?thesis by (metis 2 3 4) qed lemma TComp_var_instance_closed_has_Var: assumes closed: "is_TComp_var_instance_closed \ M" and wf_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and wf_\x: "wf\<^sub>t\<^sub>r\<^sub>m (\ x)" and y_ex: "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" and t: "t \ \ x" and \_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" shows "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var y) = \ t" proof (cases "\ (Var x)") case (Var a) hence "t = \ x" using t wf_\x \_wt by (metis (full_types) const_type_inv_wf fun_if_subterm subtermeq_Var_const(2) wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) thus ?thesis using y_ex wt_subst_trm''[OF \_wt, of "Var x"] by fastforce next case (Fun f T) hence \_\x: "\ (\ x) = TComp f T" using wt_subst_trm''[OF \_wt, of "Var x"] by auto show ?thesis proof (cases "t = \ x") case False hence t_subt_\x: "t \ \ x" using t(1) \_\x by fastforce obtain T' where T': "\ x = Fun f T'" using \_\x t_subt_\x fun_type_id_eq by (cases "\ x") auto obtain g S where gS: "Fun g S \ \ x" "t \ set S" using Fun_ex_if_subterm[OF t_subt_\x] by blast have gS_wf: "wf\<^sub>t\<^sub>r\<^sub>m (Fun g S)" by (rule wf_trm_subtermeq[OF wf_\x gS(1)]) hence "arity g > 0" using gS(2) by (metis length_pos_if_in_set wf_trm_arity) hence gS_\: "\ (Fun g S) = TComp g (map \ S)" using fun_type by blast obtain h U where hU: "Fun h U \ set M" "\ (Fun h U) = Fun g (map \ S)" "\u \ set U. is_Var u" using is_TComp_var_instance_closedD'[OF y_ex _ closed wf_M] subtermeq_imp_subtermtypeeq[OF wf_\x] gS \_\x Fun gS_\ by metis obtain y where y: "Var y \ set U" "\ (Var y) = \ t" using hU(3) fun_type_param_ex[OF hU(2) gS(2)] by fast have "y \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" using hU(1) y(1) by force thus ?thesis using y(2) closed by metis qed (metis y_ex Fun \_\x) qed lemma TComp_var_instance_closed_has_Fun: assumes closed: "is_TComp_var_instance_closed \ M" and wf_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and wf_\x: "wf\<^sub>t\<^sub>r\<^sub>m (\ x)" and y_ex: "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" and t: "t \ \ x" and \_wt: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" and t_\: "\ t = TComp g T" and t_fun: "is_Fun t" shows "\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \ \ is_Fun m" proof - obtain T'' where T'': "t = Fun g T''" using t_\ t_fun fun_type_id_eq by blast have g: "arity g > 0" using t_\ fun_type_inv[of t] by simp_all have "TComp g T \ \ (Var x)" using \_wt t t_\ by (metis wf_\x subtermeq_imp_subtermtypeeq wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) then obtain U where U: "Fun g U \ set M" "\ (Fun g U) = TComp g T" "\u \ set U. \y. u = Var y" "distinct U" "length T'' = length U" using is_TComp_var_instance_closedD'[OF y_ex _ closed wf_M] by (metis t_\ T'' fun_type_id_eq fun_type_length_eq is_VarE) hence UT': "T = map \ U" using fun_type[OF g, of U] by simp show ?thesis using TComp_var_instance_wt_subst_exists UT' T'' U(1,3,4) t t_\ wf_\x wf_trm_subtermeq by (metis term.disc(2)) qed lemma TComp_var_and_subterm_instance_closed_has_subterms_instances: assumes M_var_inst_cl: "is_TComp_var_instance_closed \ M" and M_subterms_cl: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" and M_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and t: "t \\<^sub>s\<^sub>e\<^sub>t set M" and s: "s \ t \ \" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" shows "\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ s = m \ \" using subterm_subst_unfold[OF s] proof assume "\s'. s' \ t \ s = s' \ \" then obtain s' where s': "s' \ t" "s = s' \ \" by blast then obtain \ where \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "s' \ set M \\<^sub>s\<^sub>e\<^sub>t \" using t has_all_wt_instances_ofD'[OF wf_trms_subterms[OF M_wf] M_wf M_subterms_cl] term.order_trans[of s' t] by blast then obtain m where m: "m \ set M" "s' = m \ \" by blast have "s = m \ (\ \\<^sub>s \)" using s'(2) m(2) by simp thus ?thesis using m(1) wt_subst_compose[OF \(1) \(1)] wf_trms_subst_compose[OF \(2) \(2)] by blast next assume "\x \ fv t. s \ \ x" then obtain x where x: "x \ fv t" "s \ \ x" "s \ \ x" by blast note 0 = TComp_var_instance_closed_has_Var[OF M_var_inst_cl M_wf] note 1 = has_all_wt_instances_ofD''[OF wf_trms_subterms[OF M_wf] M_wf M_subterms_cl] have \x_wf: "wf\<^sub>t\<^sub>r\<^sub>m (\ x)" and s_wf_trm: "wf\<^sub>t\<^sub>r\<^sub>m s" using \(2) wf_trm_subterm[OF _ x(2)] by fastforce+ have x_fv_ex: "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" using x(1) s fv_subset_subterms[OF t] by auto obtain y where y: "y \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\ (Var y) = \ s" using 0[of \ x s, OF \x_wf x_fv_ex x(3) \(1)] by metis then obtain z where z: "Var z \ set M" "\ (Var z) = \ s" using 1[of y] vars_iff_subtermeq_set[of y "set M"] by metis define \ where "\ \ Var(z := s)::('fun, ('fun, 'atom) term \ nat) subst" have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "s = Var z \ \" using z(2) s_wf_trm unfolding \_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by force+ thus ?thesis using z(1) by blast qed context begin private lemma SMP_D_aux1: assumes "t \ SMP (set M)" and closed: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" "is_TComp_var_instance_closed \ M" and wf_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" shows "\x \ fv t. \y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var y) = \ (Var x)" using assms(1) proof (induction t rule: SMP.induct) case (MP t) show ?case proof fix x assume x: "x \ fv t" hence "Var x \ subterms\<^sub>s\<^sub>e\<^sub>t (set M)" using MP.hyps vars_iff_subtermeq by fastforce then obtain \ s where \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" and s: "s \ set M" "Var x = s \ \" using has_all_wt_instances_ofD'[OF wf_trms_subterms[OF wf_M] wf_M closed(1)] by blast then obtain y where y: "s = Var y" by (cases s) auto thus "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var y) = \ (Var x)" using s wt_subst_trm''[OF \(1), of "Var y"] by force qed next case (Subterm t t') hence "fv t' \ fv t" using subtermeq_vars_subset by auto thus ?case using Subterm.IH by auto next case (Substitution t \) note IH = Substitution.IH show ?case proof fix x assume x: "x \ fv (t \ \)" then obtain y where y: "y \ fv t" "\ (Var x) \ \ (Var y)" using Substitution.hyps(2,3) by (metis subst_apply_img_var subtermeqI' subtermeq_imp_subtermtypeeq vars_iff_subtermeq wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def wf_trm_subst_rangeD) let ?P = "\x. \y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var y) = \ (Var x)" show "?P x" using y IH proof (induction "\ (Var y)" arbitrary: y t) case (Var a) hence "\ (Var x) = \ (Var y)" by auto thus ?case using Var(2,4) by auto next case (Fun f T) obtain z where z: "\w \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var z) = \ (Var w)" "\ (Var z) = \ (Var y)" using Fun.prems(1,3) by blast show ?case proof (cases "\ (Var x) = \ (Var y)") case True thus ?thesis using Fun.prems by auto next case False then obtain \ where \: "\ \ set T" "\ (Var x) \ \" using Fun.prems(2) Fun.hyps(2) by auto then obtain U where U: "Fun f U \ set M" "\ (Fun f U) = \ (Var z)" "\u \ set U. \v. u = Var v" "distinct U" using is_TComp_var_instance_closedD'[OF z(1) _ closed(2) wf_M] Fun.hyps(2) z(2) by (metis fun_type_id_eq subtermeqI' is_VarE) hence 1: "\x \ fv (Fun f U). \y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var y) = \ (Var x)" by force have "arity f > 0" using U(2) z(2) Fun.hyps(2) fun_type_inv(1) by metis hence "\ (Fun f U) = TComp f (map \ U)" using fun_type by auto then obtain u where u: "Var u \ set U" "\ (Var u) = \" using \(1) U(2,3) z(2) Fun.hyps(2) by auto show ?thesis using Fun.hyps(1)[of u "Fun f U"] u \ 1 by force qed qed qed next case (Ana t K T k) have "fv k \ fv t" using Ana_keys_fv[OF Ana.hyps(2)] Ana.hyps(3) by auto thus ?case using Ana.IH by auto qed private lemma SMP_D_aux2: fixes t::"('fun, ('fun, 'atom) term \ nat) term" assumes t_SMP: "t \ SMP (set M)" and t_Var: "\x. t = Var x" and M_SMP_repr: "finite_SMP_representation arity Ana \ M" shows "\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \" proof - have M_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and M_var_inst_cl: "is_TComp_var_instance_closed \ M" and M_subterms_cl: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" and M_Ana_cl: "has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M)" using finite_SMP_representationD[OF M_SMP_repr] by blast+ have M_Ana_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\ ((set \ fst \ Ana) ` set M))" proof fix k assume "k \ \((set \ fst \ Ana) ` set M)" then obtain m where m: "m \ set M" "k \ set (fst (Ana m))" by force thus "wf\<^sub>t\<^sub>r\<^sub>m k" using M_wf Ana_keys_wf'[of m "fst (Ana m)" _ k] surjective_pairing by blast qed note 0 = has_all_wt_instances_ofD'[OF wf_trms_subterms[OF M_wf] M_wf M_subterms_cl] note 1 = has_all_wt_instances_ofD'[OF M_Ana_wf M_wf M_Ana_cl] obtain x y where x: "t = Var x" and y: "y \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\ (Var y) = \ (Var x)" using t_Var SMP_D_aux1[OF t_SMP M_subterms_cl M_var_inst_cl M_wf] by fastforce then obtain m \ where m: "m \ set M" "m \ \ = Var y" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" using 0[of "Var y"] vars_iff_subtermeq_set[of y "set M"] by fastforce obtain z where z: "m = Var z" using m(2) by (cases m) auto define \ where "\ \ Var(z := Var x)::('fun, ('fun, 'atom) term \ nat) subst" have "\ (Var z) = \ (Var x)" using y(2) m(2) z wt_subst_trm''[OF \, of m] by argo hence "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" unfolding \_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by force+ moreover have "t = m \ \" using x z unfolding \_def by simp ultimately show ?thesis using m(1) by blast qed private lemma SMP_D_aux3: assumes hyps: "t' \ t" and wf_t: "wf\<^sub>t\<^sub>r\<^sub>m t" and prems: "is_Fun t'" and IH: "((\f. t = Fun f []) \ (\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \)) \ (\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \ \ is_Fun m)" and M_SMP_repr: "finite_SMP_representation arity Ana \ M" shows "((\f. t' = Fun f []) \ (\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t' = m \ \)) \ (\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t' = m \ \ \ is_Fun m)" proof (cases "\f. t = Fun f [] \ t' = Fun f []") case True have M_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and M_var_inst_cl: "is_TComp_var_instance_closed \ M" and M_subterms_cl: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" and M_Ana_cl: "has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M)" using finite_SMP_representationD[OF M_SMP_repr] by blast+ note 0 = has_all_wt_instances_ofD'[OF wf_trms_subterms[OF M_wf] M_wf M_subterms_cl] note 1 = TComp_var_instance_closed_has_Fun[OF M_var_inst_cl M_wf] note 2 = TComp_var_and_subterm_instance_closed_has_subterms_instances[ OF M_var_inst_cl M_subterms_cl M_wf] have wf_t': "wf\<^sub>t\<^sub>r\<^sub>m t'" using hyps wf_t wf_trm_subterm by blast obtain c where "t = Fun c [] \ t' = Fun c []" using True by moura thus ?thesis proof assume c: "t' = Fun c []" show ?thesis proof (cases "\f. t = Fun f []") case True hence "t = t'" using c hyps by force thus ?thesis using IH by fast next case False note F = this then obtain m \ where m: "m \ set M" "t = 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 IH by blast show ?thesis using subterm_subst_unfold[OF hyps[unfolded m(2)]] proof assume "\m'. m' \ m \ t' = m' \ \" then obtain m' where m': "m' \ m" "t' = m' \ \" by moura obtain n \ where n: "n \ set M" "m' = n \ \" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using 0[of m'] m(1) m'(1) by blast have "t' = n \ (\ \\<^sub>s \)" using m'(2) n(2) by auto thus ?thesis using c n(1) wt_subst_compose[OF \(1) \(1)] wf_trms_subst_compose[OF \(2) \(2)] by blast next assume "\x \ fv m. t' \ \ x" then obtain x where x: "x \ fv m" "t' \ \ x" "t' \ \ x" by moura have \x_wf: "wf\<^sub>t\<^sub>r\<^sub>m (\ x)" using \(2) by fastforce have x_fv_ex: "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" using x m by auto show ?thesis proof (cases "\ t'") case (Var a) show ?thesis using c m 2[OF _ hyps[unfolded m(2)] \] by fast next case (Fun g S) show ?thesis using c 1[of \ x t', OF \x_wf x_fv_ex x(3) \(1) Fun] by blast qed qed qed qed (use IH hyps in simp) next case False note F = False then obtain m \ where m: "m \ set M" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "t = m \ \" "is_Fun m" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using IH by moura obtain f T where fT: "t' = Fun f T" "arity f > 0" "\ t' = TComp f (map \ T)" using F prems fun_type wf_trm_subtermeq[OF wf_t hyps] by (metis is_FunE length_greater_0_conv subtermeqI' wf\<^sub>t\<^sub>r\<^sub>m_def) have closed: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" "is_TComp_var_instance_closed \ M" using M_SMP_repr unfolding finite_SMP_representation_def by metis+ have M_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" using finite_SMP_representationD[OF M_SMP_repr] by blast show ?thesis proof (cases "\x \ fv m. t' \ \ x") case True then obtain x where x: "x \ fv m" "t' \ \ x" by moura have 1: "x \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" using m(1) x(1) by auto have 2: "is_Fun (\ x)" using prems x(2) by auto have 3: "wf\<^sub>t\<^sub>r\<^sub>m (\ x)" using m(5) by (simp add: wf_trm_subst_rangeD) have "\(\f. \ x = Fun f [])" using F x(2) by auto hence "\f T. \ (Var x) = TComp f T" using 2 3 m(2) by (metis (no_types) fun_type is_FunE length_greater_0_conv subtermeqI' wf\<^sub>t\<^sub>r\<^sub>m_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def) moreover have "\f T. \ t' = Fun f T" using False prems wf_trm_subtermeq[OF wf_t hyps] by (metis (no_types) fun_type is_FunE length_greater_0_conv subtermeqI' wf\<^sub>t\<^sub>r\<^sub>m_def) ultimately show ?thesis using TComp_var_instance_closed_has_Fun 1 x(2) m(2) prems closed 3 M_wf by metis next case False then obtain m' where m': "m' \ m" "t' = m' \ \" "is_Fun m'" using hyps m(3) subterm_subst_not_img_subterm by blast then obtain \ m'' where \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "m'' \ set M" "m' = m'' \ \" using m(1) has_all_wt_instances_ofD'[OF wf_trms_subterms[OF M_wf] M_wf closed(1)] by blast hence t'_m'': "t' = m'' \ \ \\<^sub>s \" using m'(2) by fastforce note \\ = wt_subst_compose[OF \(1) m(2)] wf_trms_subst_compose[OF \(2) m(5)] show ?thesis proof (cases "is_Fun m''") case True thus ?thesis using \(3,4) m'(2,3) m(4) fT t'_m'' \\ by blast next case False then obtain x where x: "m'' = Var x" by moura hence "\y \ fv\<^sub>s\<^sub>e\<^sub>t (set M). \ (Var x) = \ (Var y)" "t' \ (\ \\<^sub>s \) x" "\ (Var x) = Fun f (map \ T)" "wf\<^sub>t\<^sub>r\<^sub>m ((\ \\<^sub>s \) x)" using \\ t'_m'' \(3) fv_subset[OF \(3)] fT(3) subst_apply_term.simps(1)[of x "\ \\<^sub>s \"] wt_subst_trm''[OF \\(1), of "Var x"] by (fastforce, blast, argo, fastforce) thus ?thesis using x TComp_var_instance_closed_has_Fun[ of M "\ \\<^sub>s \" x t' f "map \ T", OF closed(2) M_wf _ _ _ \\(1) fT(3) prems] by blast qed qed qed lemma SMP_D: assumes "t \ SMP (set M)" "is_Fun t" and M_SMP_repr: "finite_SMP_representation arity Ana \ M" shows "((\f. t = Fun f []) \ (\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \)) \ (\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \ \ is_Fun m)" proof - have wf_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and closed: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" "has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M)" "is_TComp_var_instance_closed \ M" using finite_SMP_representationD[OF M_SMP_repr] by blast+ show ?thesis using assms(1,2) proof (induction t rule: SMP.induct) case (MP t) moreover have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t Var" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range Var)" "t = t \ Var" by simp_all ultimately show ?case by blast next case (Subterm t t') hence t_fun: "is_Fun t" by auto note * = Subterm.hyps(2) SMP_wf_trm[OF Subterm.hyps(1) wf_M(1)] Subterm.prems Subterm.IH[OF t_fun] M_SMP_repr show ?case by (rule SMP_D_aux3[OF *]) next case (Substitution t \) have wf: "wf\<^sub>t\<^sub>r\<^sub>m t" by (metis Substitution.hyps(1) wf_M(1) SMP_wf_trm) hence wf': "wf\<^sub>t\<^sub>r\<^sub>m (t \ \)" using Substitution.hyps(3) wf_trm_subst by blast show ?case proof (cases "\ t") case (Var a) hence 1: "\ (t \ \) = TAtom a" using Substitution.hyps(2) by (metis wt_subst_trm'') then obtain c where c: "t \ \ = Fun c []" using TAtom_term_cases[OF wf' 1] Substitution.prems by fastforce hence "(\x. t = Var x) \ t = t \ \" by (cases t) auto thus ?thesis proof assume t_Var: "\x. t = Var x" then obtain x where x: "t = Var x" "\ x = Fun c []" "\ (Var x) = TAtom a" using c 1 wt_subst_trm''[OF Substitution.hyps(2), of t] by force obtain m \ where m: "m \ set M" "t = 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 SMP_D_aux2[OF Substitution.hyps(1) t_Var M_SMP_repr] by moura have "m \ (\ \\<^sub>s \) = Fun c []" using c m(2) by auto thus ?thesis using c m(1) wt_subst_compose[OF \(1) Substitution.hyps(2)] wf_trms_subst_compose[OF \(2) Substitution.hyps(3)] by metis qed (use c Substitution.IH in auto) next case (Fun f T) hence 1: "\ (t \ \) = TComp f T" using Substitution.hyps(2) by (metis wt_subst_trm'') have 2: "\(\f. t = Fun f [])" using Fun TComp_term_cases[OF wf] by auto obtain T'' where T'': "t \ \ = Fun f T''" using 1 2 fun_type_id_eq Fun Substitution.prems by fastforce have f: "arity f > 0" "public f" using fun_type_inv[OF 1] by metis+ show ?thesis proof (cases t) case (Fun g U) then obtain m \ where m: "m \ set M" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "t = m \ \" "is_Fun m" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using Substitution.IH Fun 2 by moura have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\ \\<^sub>s \)" "t \ \ = m \ (\ \\<^sub>s \)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\ \\<^sub>s \))" using wt_subst_compose[OF m(2) Substitution.hyps(2)] m(3) wf_trms_subst_compose[OF m(5) Substitution.hyps(3)] by auto thus ?thesis using m(1,4) by metis next case (Var x) then obtain y where y: "y \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\ (Var y) = \ (Var x)" using SMP_D_aux1[OF Substitution.hyps(1) closed(1,3) wf_M] Fun by moura hence 3: "\ (Var y) = TComp f T" using Var Fun \_Var_fst by simp obtain h V where V: "Fun h V \ set M" "\ (Fun h V) = \ (Var y)" "\u \ set V. \z. u = Var z" "distinct V" by (metis is_VarE is_TComp_var_instance_closedD[OF _ 3 closed(3)] y(1)) moreover have "length T'' = length V" using 3 V(2) fun_type_length_eq 1 T'' by metis ultimately have TV: "T = map \ V" by (metis fun_type[OF f(1)] 3 fun_type_id_eq term.inject(2)) obtain \ where \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "t \ \ = Fun h V \ \" using TComp_var_instance_wt_subst_exists 1 3 T'' TV V(2,3,4) wf' by (metis fun_type_id_eq) have 9: "\ (Fun h V) = \ (\ x)" using y(2) Substitution.hyps(2) V(2) 1 3 Var by auto show ?thesis using Var \ 9 V(1) by force qed qed next case (Ana t K T k) have 1: "is_Fun t" using Ana.hyps(2,3) by auto then obtain f U where U: "t = Fun f U" by moura have 2: "fv k \ fv t" using Ana_keys_fv[OF Ana.hyps(2)] Ana.hyps(3) by auto have wf_t: "wf\<^sub>t\<^sub>r\<^sub>m t" using SMP_wf_trm[OF Ana.hyps(1)] wf\<^sub>t\<^sub>r\<^sub>m_code wf_M by auto hence wf_k: "wf\<^sub>t\<^sub>r\<^sub>m k" using Ana_keys_wf'[OF Ana.hyps(2)] wf\<^sub>t\<^sub>r\<^sub>m_code Ana.hyps(3) by auto have wf_M_keys: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\((set \ fst \ Ana) ` set M))" proof fix t assume "t \ (\((set \ fst \ Ana) ` set M))" then obtain s where s: "s \ set M" "t \ (set \ fst \ Ana) s" by blast obtain K R where KR: "Ana s = (K,R)" by (metis surj_pair) hence "t \ set K" using s(2) by simp thus "wf\<^sub>t\<^sub>r\<^sub>m t" using Ana_keys_wf'[OF KR] wf_M s(1) by blast qed show ?case using Ana_subst'_or_Ana_keys_subterm proof assume "\t K T k. Ana t = (K, T) \ k \ set K \ k \ t" hence *: "k \ t" using Ana.hyps(2,3) by auto show ?thesis by (rule SMP_D_aux3[OF * wf_t Ana.prems Ana.IH[OF 1] M_SMP_repr]) next assume Ana_subst': "\f T \ K M. Ana (Fun f T) = (K, M) \ Ana (Fun f T \ \) = (K \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \, M \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \)" have "arity f > 0" using Ana_const[of f U] U Ana.hyps(2,3) by fastforce hence "U \ []" using wf_t U unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by force then obtain m \ where m: "m \ set M" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "t = m \ \" "is_Fun m" using Ana.IH[OF 1] U by auto hence "Ana (t \ \) = (K \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \,T \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \)" using Ana_subst' U Ana.hyps(2) by auto obtain Km Tm where Ana_m: "Ana m = (Km,Tm)" by moura hence "Ana (m \ \) = (Km \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \,Tm \\<^sub>l\<^sub>i\<^sub>s\<^sub>t \)" using Ana_subst' U m(4) is_FunE[OF m(5)] Ana.hyps(2) by metis then obtain km where km: "km \ set Km" "k = km \ \" using Ana.hyps(2,3) m(4) by auto then obtain \ km' where \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" and km': "km' \ set M" "km = km' \ \" using Ana_m m(1) has_all_wt_instances_ofD'[OF wf_M_keys wf_M closed(2), of km] by force have k\\: "k = km' \ \ \\<^sub>s \" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (\ \\<^sub>s \)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range (\ \\<^sub>s \))" using km(2) km' wt_subst_compose[OF \(1) m(2)] wf_trms_subst_compose[OF \(2) m(3)] by auto show ?case proof (cases "is_Fun km'") case True thus ?thesis using k\\ km'(1) by blast next case False note F = False then obtain x where x: "km' = Var x" by auto hence 3: "x \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" using fv_subset[OF km'(1)] by auto obtain kf kT where kf: "k = Fun kf kT" using Ana.prems by auto show ?thesis proof (cases "kT = []") case True thus ?thesis using k\\(1) k\\(2) k\\(3) kf km'(1) by blast next case False hence 4: "arity kf > 0" using wf_k kf TAtom_term_cases const_type by fastforce then obtain kT' where kT': "\ k = TComp kf kT'" by (simp add: fun_type kf) then obtain V where V: "Fun kf V \ set M" "\ (Fun kf V) = \ (Var x)" "\u \ set V. \v. u = Var v" "distinct V" "is_Fun (Fun kf V)" using is_TComp_var_instance_closedD[OF _ _ closed(3), of x] x m(2) k\\(1) 3 wt_subst_trm''[OF k\\(2)] by (metis fun_type_id_eq term.disc(2) is_VarE) have 5: "kT' = map \ V" using fun_type[OF 4] x kT' k\\ m(2) V(2) by (metis term.inject(2) wt_subst_trm'') thus ?thesis using TComp_var_instance_wt_subst_exists wf_k kf 4 V(3,4) kT' V(1,5) by metis qed qed qed qed qed lemma SMP_D': fixes M defines "\ \ var_rename (max_var_set (fv\<^sub>s\<^sub>e\<^sub>t (set M)))" assumes M_SMP_repr: "finite_SMP_representation arity Ana \ M" and s: "s \ SMP (set M)" "is_Fun s" "\f. s = Fun f []" and t: "t \ SMP (set M)" "is_Fun t" "\f. t = Fun f []" obtains \ s0 \ t0 where "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "s0 \ set M" "is_Fun s0" "s = s0 \ \" "\ s = \ s0" and "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "t0 \ set M" "is_Fun t0" "t = t0 \ \ \ \" "\ t = \ t0" proof - obtain \ s0 where s0: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "s0 \ set M" "s = s0 \ \" "is_Fun s0" using s(3) SMP_D[OF s(1,2) M_SMP_repr] unfolding \_def by metis obtain \ t0 where t0: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "t0 \ set M" "t = t0 \ \ \ \" "is_Fun t0" using t(3) SMP_D[OF t(1,2) M_SMP_repr] var_rename_wt'[of _ t] wf_trms_subst_compose_Var_range(1)[OF _ var_rename_is_renaming(2)] unfolding \_def by metis have "\ s = \ s0" "\ t = \ (t0 \ \)" "\ (t0 \ \) = \ t0" using s0 t0 wt_subst_trm'' by (metis, metis, metis \_def var_rename_wt(1)) thus ?thesis using s0 t0 that by simp qed lemma SMP_D'': fixes t::"('fun, ('fun, 'atom) term \ nat) term" assumes t_SMP: "t \ SMP (set M)" and M_SMP_repr: "finite_SMP_representation arity Ana \ M" shows "\m \ set M. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ t = m \ \" proof (cases "(\x. t = Var x) \ (\c. t = Fun c [])") case True have M_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and M_var_inst_cl: "is_TComp_var_instance_closed \ M" and M_subterms_cl: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" and M_Ana_cl: "has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M)" using finite_SMP_representationD[OF M_SMP_repr] by blast+ have M_Ana_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (\ ((set \ fst \ Ana) ` set M))" proof fix k assume "k \ \((set \ fst \ Ana) ` set M)" then obtain m where m: "m \ set M" "k \ set (fst (Ana m))" by force thus "wf\<^sub>t\<^sub>r\<^sub>m k" using M_wf Ana_keys_wf'[of m "fst (Ana m)" _ k] surjective_pairing by blast qed show ?thesis using True proof assume "\x. t = Var x" then obtain x y where x: "t = Var x" and y: "y \ fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\ (Var y) = \ (Var x)" using SMP_D_aux1[OF t_SMP M_subterms_cl M_var_inst_cl M_wf] by fastforce then obtain m \ where m: "m \ set M" "m \ \ = Var y" and \: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" using has_all_wt_instances_ofD'[OF wf_trms_subterms[OF M_wf] M_wf M_subterms_cl, of "Var y"] vars_iff_subtermeq_set[of y "set M"] by fastforce obtain z where z: "m = Var z" using m(2) by (cases m) auto define \ where "\ \ Var(z := Var x)::('fun, ('fun, 'atom) term \ nat) subst" have "\ (Var z) = \ (Var x)" using y(2) m(2) z wt_subst_trm''[OF \, of m] by argo hence "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" unfolding \_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by force+ moreover have "t = m \ \" using x z unfolding \_def by simp ultimately show ?thesis using m(1) by blast qed (use SMP_D[OF t_SMP _ M_SMP_repr] in blast) qed (use SMP_D[OF t_SMP _ M_SMP_repr] in blast) end lemma tfr\<^sub>s\<^sub>e\<^sub>t_if_comp_tfr\<^sub>s\<^sub>e\<^sub>t: assumes "comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \ M" shows "tfr\<^sub>s\<^sub>e\<^sub>t (set M)" proof - let ?\ = "var_rename (max_var_set (fv\<^sub>s\<^sub>e\<^sub>t (set M)))" have M_SMP_repr: "finite_SMP_representation arity Ana \ M" by (metis comp_tfr\<^sub>s\<^sub>e\<^sub>t_def assms) have M_finite: "finite (set M)" using assms card_gt_0_iff unfolding comp_tfr\<^sub>s\<^sub>e\<^sub>t_def by blast show ?thesis proof (unfold tfr\<^sub>s\<^sub>e\<^sub>t_def; intro ballI impI) fix s t assume "s \ SMP (set M) - Var`\" "t \ SMP (set M) - Var`\" hence st: "s \ SMP (set M)" "is_Fun s" "t \ SMP (set M)" "is_Fun t" by auto have "\(\\. Unifier \ s t)" when st_type_neq: "\ s \ \ t" proof (cases "\f. s = Fun f [] \ t = Fun f []") case False then obtain \ s0 \ t0 where s0: "s0 \ set M" "is_Fun s0" "s = s0 \ \" "\ s = \ s0" and t0: "t0 \ set M" "is_Fun t0" "t = t0 \ ?\ \ \" "\ t = \ t0" using SMP_D'[OF M_SMP_repr st(1,2) _ st(3,4)] by metis hence "\(\\. Unifier \ s0 (t0 \ ?\))" using assms mgu_None_is_subst_neq st_type_neq wt_subst_trm''[OF var_rename_wt(1)] unfolding comp_tfr\<^sub>s\<^sub>e\<^sub>t_def Let_def by metis thus ?thesis using vars_term_disjoint_imp_unifier[OF var_rename_fv_set_disjoint[OF M_finite]] s0(1) t0(1) unfolding s0(3) t0(3) by (metis (no_types, opaque_lifting) subst_subst_compose) qed (use st_type_neq st(2,4) in auto) thus "\ s = \ t" when "\\. Unifier \ s t" by (metis that) qed qed lemma tfr\<^sub>s\<^sub>e\<^sub>t_if_comp_tfr\<^sub>s\<^sub>e\<^sub>t': assumes "let N = SMP0 Ana \ M in set M \ set N \ comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \ N" shows "tfr\<^sub>s\<^sub>e\<^sub>t (set M)" by (rule tfr_subset(2)[ OF tfr\<^sub>s\<^sub>e\<^sub>t_if_comp_tfr\<^sub>s\<^sub>e\<^sub>t[OF conjunct2[OF assms[unfolded Let_def]]] conjunct1[OF assms[unfolded Let_def]]]) lemma tfr\<^sub>s\<^sub>t\<^sub>p_is_comp_tfr\<^sub>s\<^sub>t\<^sub>p: "tfr\<^sub>s\<^sub>t\<^sub>p a = comp_tfr\<^sub>s\<^sub>t\<^sub>p \ a" proof (cases a) case (Equality ac t t') thus ?thesis using mgu_always_unifies[of t _ t'] mgu_gives_MGU[of t t'] by auto next case (Inequality X F) thus ?thesis using tfr\<^sub>s\<^sub>t\<^sub>p.simps(2)[of X F] comp_tfr\<^sub>s\<^sub>t\<^sub>p.simps(2)[of \ X F] Fun_range_case(2)[of "subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F)"] unfolding is_Var_def by auto qed auto lemma tfr\<^sub>s\<^sub>t_if_comp_tfr\<^sub>s\<^sub>t: assumes "comp_tfr\<^sub>s\<^sub>t arity Ana \ M S" shows "tfr\<^sub>s\<^sub>t S" unfolding tfr\<^sub>s\<^sub>t_def proof have comp_tfr\<^sub>s\<^sub>e\<^sub>t_M: "comp_tfr\<^sub>s\<^sub>e\<^sub>t arity Ana \ M" using assms unfolding comp_tfr\<^sub>s\<^sub>t_def by blast have wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_S: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (trms\<^sub>s\<^sub>t S)" and S_trms_instance_M: "has_all_wt_instances_of \ (trms\<^sub>s\<^sub>t S) (set M)" using assms wf\<^sub>t\<^sub>r\<^sub>m_code trms_list\<^sub>s\<^sub>t_is_trms\<^sub>s\<^sub>t unfolding comp_tfr\<^sub>s\<^sub>t_def comp_tfr\<^sub>s\<^sub>e\<^sub>t_def finite_SMP_representation_def list_all_iff by blast+ show "tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>t S)" using tfr_subset(3)[OF tfr\<^sub>s\<^sub>e\<^sub>t_if_comp_tfr\<^sub>s\<^sub>e\<^sub>t[OF comp_tfr\<^sub>s\<^sub>e\<^sub>t_M] SMP_SMP_subset] SMP_I'[OF wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_S wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s_M S_trms_instance_M] by blast have "list_all (comp_tfr\<^sub>s\<^sub>t\<^sub>p \) S" by (metis assms comp_tfr\<^sub>s\<^sub>t_def) thus "list_all tfr\<^sub>s\<^sub>t\<^sub>p S" by (induct S) (simp_all add: tfr\<^sub>s\<^sub>t\<^sub>p_is_comp_tfr\<^sub>s\<^sub>t\<^sub>p) qed lemma tfr\<^sub>s\<^sub>t_if_comp_tfr\<^sub>s\<^sub>t': assumes "comp_tfr\<^sub>s\<^sub>t arity Ana \ (SMP0 Ana \ (trms_list\<^sub>s\<^sub>t S)) S" shows "tfr\<^sub>s\<^sub>t S" by (rule tfr\<^sub>s\<^sub>t_if_comp_tfr\<^sub>s\<^sub>t[OF assms]) subsubsection \Lemmata for Checking Ground SMP (GSMP) Disjointness\ context begin private lemma ground_SMP_disjointI_aux1: fixes M::"('fun, ('fun, 'atom) term \ nat) term set" assumes f_def: "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 \ \) = {}}" and g_def: "g \ \M. {t \ M. fv t = {}}" shows "f (SMP M) = g (SMP M)" proof have "t \ f (SMP M)" when t: "t \ SMP M" "fv t = {}" for t proof - define \ where "\ \ Var::('fun, ('fun, 'atom) term \ nat) subst" have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" "t = t \ \" using subst_apply_term_empty[of t] that(2) wt_subst_Var wf_trm_subst_range_Var unfolding \_def by auto thus ?thesis using SMP.Substitution[OF t(1), of \] t(2) unfolding f_def by fastforce qed thus "g (SMP M) \ f (SMP M)" unfolding g_def by blast qed (use f_def g_def in blast) private lemma ground_SMP_disjointI_aux2: fixes M::"('fun, ('fun, 'atom) term \ nat) term list" assumes f_def: "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 \ \) = {}}" and M_SMP_repr: "finite_SMP_representation arity Ana \ M" shows "f (set M) = f (SMP (set M))" proof have M_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)" and M_var_inst_cl: "is_TComp_var_instance_closed \ M" and M_subterms_cl: "has_all_wt_instances_of \ (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)" and M_Ana_cl: "has_all_wt_instances_of \ (\((set \ fst \ Ana) ` set M)) (set M)" using finite_SMP_representationD[OF M_SMP_repr] by blast+ show "f (SMP (set M)) \ f (set M)" proof fix t assume "t \ f (SMP (set M))" then obtain s \ where s: "t = s \ \" "s \ SMP (set M)" "fv (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 have t_wf: "wf\<^sub>t\<^sub>r\<^sub>m t" using SMP_wf_trm[OF s(2) M_wf] s(1) wf_trm_subst[OF \(2)] by blast obtain m \ where m: "m \ set M" "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 SMP_D''[OF s(2) M_SMP_repr] by blast have "t = m \ (\ \\<^sub>s \)" "fv (m \ (\ \\<^sub>s \)) = {}" using s(1,3) m(2) by simp_all thus "t \ f (set M)" using m(1) wt_subst_compose[OF \(1) \(1)] wf_trms_subst_compose[OF \(2) \(2)] unfolding f_def by blast qed qed (auto simp add: f_def) private lemma ground_SMP_disjointI_aux3: fixes A B C::"('fun, ('fun, 'atom) term \ nat) term set" defines "P \ \t s. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ Unifier \ t s" assumes f_def: "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 \ \) = {}}" and Q_def: "Q \ \t. intruder_synth' public arity {} t" and R_def: "R \ \t. \u \ C. is_wt_instance_of_cond \ t u" and AB: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s A" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s B" "fv\<^sub>s\<^sub>e\<^sub>t A \ fv\<^sub>s\<^sub>e\<^sub>t B = {}" and C: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s C" and ABC: "\t \ A. \s \ B. P t s \ (Q t \ Q s) \ (R t \ R s)" shows "f A \ f B \ f C \ {m. {} \\<^sub>c m}" proof fix t assume "t \ f A \ f B" then obtain ta tb \a \b where ta: "t = ta \ \a" "ta \ A" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \a" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \a)" "fv (ta \ \a) = {}" and tb: "t = tb \ \b" "tb \ B" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \b" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \b)" "fv (tb \ \b) = {}" unfolding f_def by blast have ta_tb_wf: "wf\<^sub>t\<^sub>r\<^sub>m ta" "wf\<^sub>t\<^sub>r\<^sub>m tb" "fv ta \ fv tb = {}" "\ ta = \ tb" using ta(1,2) tb(1,2) AB fv_subset_subterms wt_subst_trm''[OF ta(3), of ta] wt_subst_trm''[OF tb(3), of tb] by (fast, fast, blast, simp) obtain \ where \: "Unifier \ ta tb" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \)" using vars_term_disjoint_imp_unifier[OF ta_tb_wf(3), of \a \b] ta(1) tb(1) wt_Unifier_if_Unifier[OF ta_tb_wf(1,2,4)] by blast hence "(Q ta \ Q tb) \ (R ta \ R tb)" using ABC ta(2) tb(2) unfolding P_def by blast+ thus "t \ f C \ {m. {} \\<^sub>c m}" proof show "Q ta \ Q tb \ ?thesis" using ta(1) pgwt_ground[of ta] pgwt_is_empty_synth[of ta] subst_ground_ident[of ta \a] unfolding Q_def f_def intruder_synth_code[symmetric] by simp next assume "R ta \ R tb" then obtain ua \a where ua: "ta = ua \ \a" "ua \ C" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \a" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \a)" using \ ABC ta_tb_wf(1,2) ta(2) tb(2) C is_wt_instance_of_condD' unfolding P_def R_def by metis have "t = ua \ (\a \\<^sub>s \a)" "fv t = {}" using ua(1) ta(1,5) tb(1,5) by auto thus ?thesis using ua(2) wt_subst_compose[OF ua(3) ta(3)] wf_trms_subst_compose[OF ua(4) ta(4)] unfolding f_def by blast qed qed lemma ground_SMP_disjointI: fixes A B::"('fun, ('fun, 'atom) term \ nat) term list" and C 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 \ \) = {}}" and "g \ \M. {t \ M. fv t = {}}" and "Q \ \t. intruder_synth' public arity {} t" and "R \ \t. \u \ C. is_wt_instance_of_cond \ t u" assumes AB_fv_disj: "fv\<^sub>s\<^sub>e\<^sub>t (set A) \ fv\<^sub>s\<^sub>e\<^sub>t (set B) = {}" and A_SMP_repr: "finite_SMP_representation arity Ana \ A" and B_SMP_repr: "finite_SMP_representation arity Ana \ B" and C_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s C" and ABC: "\t \ set A. \s \ set B. \ t = \ s \ mgu t s \ None \ (Q t \ Q s) \ (R t \ R s)" shows "g (SMP (set A)) \ g (SMP (set B)) \ f C \ {m. {} \\<^sub>c m}" proof - have AB_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set A)" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set B)" using A_SMP_repr B_SMP_repr unfolding finite_SMP_representation_def wf\<^sub>t\<^sub>r\<^sub>m_code list_all_iff by blast+ let ?P = "\t s. \\. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \ \ wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \) \ Unifier \ t s" have ABC': "\t \ set A. \s \ set B. ?P t s \ (Q t \ Q s) \ (R t \ R s)" by (metis (no_types) ABC mgu_None_is_subst_neq wt_subst_trm'') show ?thesis using ground_SMP_disjointI_aux1[OF f_def g_def, of "set A"] ground_SMP_disjointI_aux1[OF f_def g_def, of "set B"] ground_SMP_disjointI_aux2[OF f_def A_SMP_repr] ground_SMP_disjointI_aux2[OF f_def B_SMP_repr] ground_SMP_disjointI_aux3[OF f_def Q_def R_def AB_wf AB_fv_disj C_wf ABC'] by argo qed end end end