| Ana[intro]: "\<lbrakk>t \<in> SMP M; Ana t = (K,T); k \<in> set K\<rbrakk> \<Longrightarrow> k \<in> SMP M"
text \<open>
Type-flaw resistance for sets:
Unifiable sub-message patterns must have the same type (unless they are variables)
\<close>
definition tfr\<^sub>s\<^sub>e\<^sub>t where
"tfr\<^sub>s\<^sub>e\<^sub>t M \<equiv> (\<forall>s \<in> SMP M - (Var`\<V>). \<forall>t \<in> SMP M - (Var`\<V>). (\<exists>\<delta>. Unifier \<delta> s t) \<longrightarrow> \<Gamma> s = \<Gamma> t)"
text \<open>
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"\<close>
fun tfr\<^sub>s\<^sub>t\<^sub>p where
"tfr\<^sub>s\<^sub>t\<^sub>p (Equality a t t') = ((\<exists>\<delta>. Unifier \<delta> t t') \<longrightarrow> \<Gamma> t = \<Gamma> t')"
| "tfr\<^sub>s\<^sub>t\<^sub>p (Inequality X F) = (
(\<forall>x \<in> fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \<exists>a. \<Gamma> (Var x) = TAtom a) \<or>
(\<forall>f T. Fun f T \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) \<longrightarrow> T = [] \<or> (\<exists>s \<in> set T. s \<notin> Var ` set X)))"
| "tfr\<^sub>s\<^sub>t\<^sub>p _ = True"
text \<open>
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
\<close>
definition tfr\<^sub>s\<^sub>t where
"tfr\<^sub>s\<^sub>t S \<equiv> tfr\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>s\<^sub>t S) \<and> list_all tfr\<^sub>s\<^sub>t\<^sub>p S"
"list_all tfr\<^sub>s\<^sub>t\<^sub>p S \<longleftrightarrow>
((\<forall>a t t'. Equality a t t' \<in> set S \<and> (\<exists>\<delta>. Unifier \<delta> t t') \<longrightarrow> \<Gamma> t = \<Gamma> t') \<and>
(\<forall>X F. Inequality X F \<in> set S \<longrightarrow>
(\<forall>x \<in> fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \<exists>a. \<Gamma> (Var x) = TAtom a)
\<or> (\<forall>f T. Fun f T \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) \<longrightarrow> T = [] \<or> (\<exists>s \<in> set T. s \<notin> Var ` set X))))"
(is "?P S \<longleftrightarrow> ?Q S")
proof
show "?P S \<Longrightarrow> ?Q S"
proof (induction S)
case (Cons x S) thus ?case by (cases x) auto
qed simp
show "?Q S \<Longrightarrow> ?P S"
proof (induction S)
case (Cons x S) thus ?case by (cases x) auto
qed simp
qed
lemma \<Gamma>_wf': "wf\<^sub>t\<^sub>r\<^sub>m t \<Longrightarrow> wf\<^sub>t\<^sub>r\<^sub>m (\<Gamma> t)"
proof (induction t)
case (Fun f T)
hence *: "arity f = length T" "\<And>t. t \<in> set T \<Longrightarrow> wf\<^sub>t\<^sub>r\<^sub>m (\<Gamma> 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 \<Gamma>_wf(2))
lemma fun_type_inv: assumes "\<Gamma> t = TComp f T" shows "arity f > 0" "public f"
using \<Gamma>_wf(1)[of f T t] assms by simp_all
lemma fun_type_inv_wf: assumes "\<Gamma> t = TComp f T" "wf\<^sub>t\<^sub>r\<^sub>m t" shows "arity f = length T"
using \<Gamma>_wf'[OF assms(2)] assms(1) unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto
lemma const_type_inv: "\<Gamma> (Fun c X) = TAtom a \<Longrightarrow> arity c = 0"
by (rule ccontr, simp add: fun_type)
lemma const_type_inv_wf: assumes "\<Gamma> (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': "\<forall>c \<in> \<C>. \<exists>a \<in> \<TT>\<^sub>a. \<forall>X. \<Gamma> (Fun c X) = TAtom a" using const_type by simp
lemma fun_type': "\<forall>f \<in> \<Sigma>\<^sub>f. \<forall>X. \<Gamma> (Fun f X) = TComp f (map \<Gamma> X)" using fun_type by simp
lemma infinite_public_consts[simp]: "infinite {c. public c \<and> arity c = 0}"
proof -
fix a::'atom
define A where "A \<equiv> {c. \<Gamma> (Fun c []) = TAtom a \<and> public c}"
define B where "B \<equiv> {c. public c \<and> arity c = 0}"
have "arity c = 0" when c: "c \<in> A" for c
using c const_type_inv unfolding A_def by blast
hence "A \<subseteq> 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 \<and> arity c > 0} \<Longrightarrow> infinite \<Sigma>\<^sub>f"
from Fun.IH Fun.prems(1) have "\<exists>Y. map \<Gamma> Y = T \<and> (\<forall>x \<in> set Y. fv x = {})"
proof (induction T)
case (Cons x X)
hence "\<And>g Y. Fun g Y \<sqsubseteq> Fun f X \<Longrightarrow> 0 < arity g" by auto
hence "\<exists>Y. map \<Gamma> Y = X \<and> (\<forall>x\<in>set Y. fv x = {})" using Cons by auto
moreover have "\<exists>t'. fv t' = {} \<and> x = \<Gamma> t'" using Cons by auto
ultimately obtain y Y where
"fv y = {}" "\<Gamma> y = x" "map \<Gamma> Y = X" "\<forall>x\<in>set Y. fv x = {}"
using Cons by moura
hence "map \<Gamma> (y#Y) = x#X \<and> (\<forall>x\<in>set (y#Y). fv x = {})" by auto
thus ?case by meson
qed simp
then obtain Y where "map \<Gamma> Y = T" "\<forall>x \<in> set Y. fv x = {}" by metis
hence "fv (Fun f Y) = {}" "\<Gamma> (Fun f Y) = TComp f T" using fun_type[OF \<open>arity f > 0\<close>] by auto
thus ?case by (metis exI[of "\<lambda>t. fv t = {} \<and> \<Gamma> t = TComp f T" "Fun f Y"])
qed (metis atype_ground_term_ex)
}
thus ?thesis by (metis \<Gamma>_wf(1))
qed
lemma type_wfttype_inhabited:
assumes "\<And>f T. Fun f T \<sqsubseteq> \<tau> \<Longrightarrow> 0 < arity f" "wf\<^sub>t\<^sub>r\<^sub>m \<tau>"
shows "\<exists>t. \<Gamma> t = \<tau> \<and> wf\<^sub>t\<^sub>r\<^sub>m t"
using assms
proof (induction \<tau>)
case (Fun f Y)
have IH: "\<exists>t. \<Gamma> t = y \<and> wf\<^sub>t\<^sub>r\<^sub>m t" when y: "y \<in> 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 \<sqsubseteq> y \<Longrightarrow> 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 "\<exists>X. map \<Gamma> X = Y \<and> (\<forall>x \<in> 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 \<Longrightarrow> \<exists>t'. \<Gamma> t = \<Gamma> t' \<and> public_ground_wf_term t'"
proof -
assume "wf\<^sub>t\<^sub>r\<^sub>m t"
{ fix \<tau> assume "\<Gamma> t = \<tau>"
hence "\<exists>t'. \<Gamma> t = \<Gamma> t' \<and> public_ground_wf_term t'" using \<open>wf\<^sub>t\<^sub>r\<^sub>m t\<close>
proof (induction \<tau> arbitrary: t)
case (Var a t)
then obtain c where "\<Gamma> t = \<Gamma> (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 \<open>public c\<close>, of "[]"] by auto
next
case (Fun f Y t)
have *: "arity f > 0" "public f" "arity f = length Y"
using fun_type_inv[OF \<open>\<Gamma> t = TComp f Y\<close>] fun_type_inv_wf[OF \<open>\<Gamma> t = TComp f Y\<close> \<open>wf\<^sub>t\<^sub>r\<^sub>m t\<close>]
by auto
have "\<And>y. y \<in> set Y \<Longrightarrow> \<exists>t'. y = \<Gamma> t' \<and> public_ground_wf_term t'"
by (metis Fun_param_is_subterm term.order_trans wf_trm_subtermeq)
hence "\<exists>X. map \<Gamma> X = Y \<and> (\<forall>x \<in> set X. public_ground_wf_term x)"
by (induct Y, simp_all, metis list.simps(9) set_ConsD)
then obtain X where X: "map \<Gamma> X = Y" "\<And>x. x \<in> set X \<Longrightarrow> public_ground_wf_term x" by moura
hence "arity f = length X" using *(3) by auto
have "\<Gamma> t = \<Gamma> (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) \<open>arity f = length X\<close> X(2)] by metis
thus ?case by metis
qed
}
thus ?thesis using \<open>wf\<^sub>t\<^sub>r\<^sub>m t\<close> by auto
qed
lemma pgwt_type_map:
assumes "public_ground_wf_term t"
shows "\<Gamma> t = TAtom a \<Longrightarrow> \<exists>f. t = Fun f []" "\<Gamma> t = TComp g Y \<Longrightarrow> \<exists>X. t = Fun g X \<and> map \<Gamma> X = Y"
proof -
let ?A = "\<Gamma> t = TAtom a \<longrightarrow> (\<exists>f. t = Fun f [])"
let ?B = "\<Gamma> t = TComp g Y \<longrightarrow> (\<exists>X. t = Fun g X \<and> map \<Gamma> X = Y)"
have "?A \<and> ?B"
proof (cases "\<Gamma> 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 \<open>\<Gamma> t = TAtom a\<close> 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 \<Gamma> X = Y"
using fun_type_id_eq \<open>\<Gamma> t = TComp g Y\<close> fun_type[OF fun_type_inv(1)[OF \<open>\<Gamma> t = TComp g Y\<close>]]
by fastforce+
thus ?thesis using *(1) \<open>\<Gamma> t = TComp g Y\<close> by auto
qed
thus "\<Gamma> t = TAtom a \<Longrightarrow> \<exists>f. t = Fun f []" "\<Gamma> t = TComp g Y \<Longrightarrow> \<exists>X. t = Fun g X \<and> map \<Gamma> 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: "(\<And>v. v \<in> fv t \<Longrightarrow> \<Gamma> (Var v) = \<Gamma> (\<theta> v)) \<Longrightarrow> \<Gamma> t = \<Gamma> (t \<cdot> \<theta>)"
proof (induction t)
case (Fun f X)
hence *: "\<And>x. x \<in> set X \<Longrightarrow> \<Gamma> x = \<Gamma> (x \<cdot> \<theta>)" by auto
show ?case
proof (cases "f \<in> \<Sigma>\<^sub>f")
case True
hence "\<forall>X. \<Gamma> (Fun f X) = TComp f (map \<Gamma> X)" using fun_type' by auto
thus ?thesis using * by auto
next
case False
hence "\<exists>a \<in> \<TT>\<^sub>a. \<forall>X. \<Gamma> (Fun f X) = TAtom a" using const_type' by auto
thus ?thesis by auto
qed
qed auto
lemma wt_subst_trm': "\<lbrakk>wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<sigma>; \<Gamma> s = \<Gamma> t\<rbrakk> \<Longrightarrow> \<Gamma> (s \<cdot> \<sigma>) = \<Gamma> (t \<cdot> \<sigma>)"
by (metis wt_subst_trm wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def)
have "\<And>v. \<Gamma> (\<theta> v) = \<Gamma> (\<theta> v \<cdot> \<delta>)" using wt_subst_trm \<open>wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>\<close> unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by metis
moreover have "\<And>v. \<Gamma> (Var v) = \<Gamma> (\<theta> v)" using \<open>wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>\<close> unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def by metis
ultimately have "\<And>v. \<Gamma> (Var v) = \<Gamma> (\<theta> v \<cdot> \<delta>)" by metis
thus ?thesis unfolding wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def subst_compose_def by metis
shows "subterms\<^sub>s\<^sub>e\<^sub>t (M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>) = subterms\<^sub>s\<^sub>e\<^sub>t M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>"
proof
show "subterms\<^sub>s\<^sub>e\<^sub>t (M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>) \<subseteq> subterms\<^sub>s\<^sub>e\<^sub>t M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>"
proof
fix t assume "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t (M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>)"
then obtain s where s: "s \<in> M" "t \<in> subterms (s \<cdot> \<theta>)" by auto
thus "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>"
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 \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta> \<subseteq> subterms\<^sub>s\<^sub>e\<^sub>t (M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>)"
proof
fix t assume "t \<in> subterms\<^sub>s\<^sub>e\<^sub>t M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>"
then obtain s where s: "s \<in> M" "t \<in> subterms s \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>" by auto
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 \<in> funs_term (\<Gamma> t) \<longleftrightarrow> (f \<in> funs_term t \<or> (\<exists>x \<in> fv t. f \<in> funs_term (\<Gamma> (Var x))))"
(is "?P t \<longleftrightarrow> ?Q t")
using t
proof (induction t)
case (Fun g T)
hence IH: "?P s \<longleftrightarrow> ?Q s" when "s \<in> 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) \<longleftrightarrow> (\<exists>s \<in> set T. ?P s)"
proof
assume *: "?P (Fun g T)"
hence "\<Gamma> (Fun g T) = TComp g (map \<Gamma> T)"
using const_type[of g] fun_type[of g] by force
thus "\<exists>s \<in> set T. ?P s" using False * by force
next
assume *: "\<exists>s \<in> set T. ?P s"
hence "\<Gamma> (Fun g T) = TComp g (map \<Gamma> 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 \<in> \<Union>(funs_term ` \<Gamma> ` M) \<longleftrightarrow>
(f \<in> \<Union>(funs_term ` M) \<or> (\<exists>x \<in> fv\<^sub>s\<^sub>e\<^sub>t M. f \<in> funs_term (\<Gamma> (Var x))))" (is "?A \<longleftrightarrow> ?B")
proof
assume ?A
then obtain t where "t \<in> M" "wf\<^sub>t\<^sub>r\<^sub>m t" "f \<in> funs_term (\<Gamma> 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 \<in> M" "wf\<^sub>t\<^sub>r\<^sub>m t" "f \<in> funs_term t \<or> (\<exists>x \<in> fv t. f \<in> funs_term (\<Gamma> (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 \<in> set M"
shows "\<Gamma> m \<sqsubseteq> \<Gamma> t"
proof -
have "m \<sqsubseteq> 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" "\<Gamma> t = TAtom \<tau>"
shows "subterms t = {t}"
using assms const_type_inv unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by (cases t) force+
lemma SMP_ikI[intro]: "t \<in> ik\<^sub>s\<^sub>t S \<Longrightarrow> t \<in> SMP (trms\<^sub>s\<^sub>t S)" by force
lemma MP_setI[intro]: "x \<in> set S \<Longrightarrow> trms\<^sub>s\<^sub>t\<^sub>p x \<subseteq> trms\<^sub>s\<^sub>t S" by force
lemma SMP_setI[intro]: "x \<in> set S \<Longrightarrow> trms\<^sub>s\<^sub>t\<^sub>p x \<subseteq> SMP (trms\<^sub>s\<^sub>t S)" by force
lemma SMP_subset_I:
assumes M: "\<forall>t \<in> M. \<exists>s \<delta>. s \<in> N \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = s \<cdot> \<delta>"
shows "SMP M \<subseteq> SMP N"
proof
fix t show "t \<in> SMP M \<Longrightarrow> t \<in> SMP N"
proof (induction t rule: SMP.induct)
case (MP t)
then obtain s \<delta> where s: "s \<in> N" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)" "t = s \<cdot> \<delta>"
using M by moura
show ?case using SMP_I[OF s(1,2), of "s \<cdot> \<delta>"] s(3,4) wf_trm_subst_range_iff by fast
qed (auto intro!: SMP.Substitution[of _ N])
qed
lemma SMP_union: "SMP (A \<union> B) = SMP A \<union> SMP B"
proof
show "SMP (A \<union> B) \<subseteq> SMP A \<union> SMP B"
proof
fix t assume "t \<in> SMP (A \<union> B)"
thus "t \<in> SMP A \<union> SMP B" by (induct rule: SMP.induct) blast+
qed
{ fix t assume "t \<in> SMP A" hence "t \<in> SMP (A \<union> B)" by (induct rule: SMP.induct) blast+ }
moreover { fix t assume "t \<in> SMP B" hence "t \<in> SMP (A \<union> B)" by (induct rule: SMP.induct) blast+ }
ultimately show "SMP A \<union> SMP B \<subseteq> SMP (A \<union> B)" by blast
thus "t \<in> SMP S'" using assms SMP.Substitution by auto
next
assume "\<exists>X F. Inequality X F \<in> set S \<and> (\<exists>t'\<in>trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F. t = t' \<cdot> rm_vars (set X) \<delta>)"
then obtain X F t' where **:
"Inequality X F \<in> set S" "t'\<in>trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F" "t = t' \<cdot> rm_vars (set X) \<delta>"
by force
then obtain s where s: "s \<in> trms\<^sub>s\<^sub>t\<^sub>p (Inequality X F)" "t = s \<cdot> rm_vars (set X) \<delta>" by moura
hence "s \<in> SMP (trms\<^sub>s\<^sub>t S)" using **(1) by force
hence "t \<in> 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)]]
using assms wf_trm_subst_range_iff[of \<I>] by (induct t rule: SMP.induct) blast+
lemma SMP_wt_instances_subset:
assumes "\<forall>t \<in> M. \<exists>s \<in> N. \<exists>\<delta>. t = s \<cdot> \<delta> \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
and "t \<in> SMP M"
shows "t \<in> SMP N"
proof -
obtain m where m: "m \<in> M" "t \<in> SMP {m}" using SMP_singleton_ex(1)[OF assms(2)] by blast
then obtain n \<delta> where n: "n \<in> N" "m = n \<cdot> \<delta>" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
using assms(1) by fast
have "t \<in> SMP (N \<cdot>\<^sub>s\<^sub>e\<^sub>t \<delta>)" using n(1,2) SMP_singleton_ex(2)[of m "N \<cdot>\<^sub>s\<^sub>e\<^sub>t \<delta>", OF _ m(2)] by fast
thus ?thesis using SMP_wt_subst_subset[OF _ n(3,4)] by blast
qed
lemma SMP_consts:
assumes "\<forall>t \<in> M. \<exists>c. t = Fun c []"
and "\<forall>t \<in> M. Ana t = ([], [])"
shows "SMP M = M"
proof
show "SMP M \<subseteq> M"
proof
fix t show "t \<in> SMP M \<Longrightarrow> t \<in> 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 \<subseteq> 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) \<subseteq> SMP M"
proof
fix t show "t \<in> SMP (subterms\<^sub>s\<^sub>e\<^sub>t M) \<Longrightarrow> t \<in> SMP M" by (induction t rule: SMP.induct) blast+
qed
qed
lemma SMP_funs_term:
assumes t: "t \<in> SMP M" "f \<in> funs_term t \<or> (\<exists>x \<in> fv t. f \<in> funs_term (\<Gamma> (Var x)))"
and f: "arity f > 0"
and M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s M"
and Ana_f: "\<And>s K T. Ana s = (K,T) \<Longrightarrow> f \<in> \<Union>(funs_term ` set K) \<Longrightarrow> f \<in> funs_term s"
shows "f \<in> \<Union>(funs_term ` M) \<or> (\<exists>x \<in> fv\<^sub>s\<^sub>e\<^sub>t M. f \<in> funs_term (\<Gamma> (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 \<delta>)
show ?case
using M SMP_wf_trm[OF Substitution.hyps(1)] wf_trm_subst[of \<delta> 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 "\<Gamma> (Fun f X) = \<Gamma> (Fun g Y)"
shows "f \<in> \<C> \<Longrightarrow> g \<in> \<C>" "f \<in> \<Sigma>\<^sub>f \<Longrightarrow> g \<in> \<Sigma>\<^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 \<in> \<Sigma>\<^sub>f" "g \<in> \<Sigma>\<^sub>f" "\<Gamma> (Fun f (x#X)) = \<Gamma> (Fun g (y#Y))"
shows "\<Gamma> x = \<Gamma> y" "\<Gamma> (Fun f X) = \<Gamma> (Fun g Y)"
using assms fun_type' by auto
lemma fun_type_arg_cong':
assumes "f \<in> \<Sigma>\<^sub>f" "g \<in> \<Sigma>\<^sub>f" "\<Gamma> (Fun f (X@x#X')) = \<Gamma> (Fun g (Y@y#Y'))" "length X = length Y"
shows "\<Gamma> x = \<Gamma> 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 "\<Gamma> (Fun f (X@x#X')) = \<Gamma> (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: "\<Gamma> (Fun f T) = Fun g S \<Longrightarrow> i < length T \<Longrightarrow> \<Gamma> (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 "\<Gamma> (Fun f T) = Fun g (map \<Gamma> S)" "t \<in> set S"
shows "\<exists>s \<in> set T. \<Gamma> s = \<Gamma> t"
using fun_type_length_eq[OF assms(1)] length_map[of \<Gamma> S] assms(2)
by (metis Unifier_comp' wt_subst_trm'[OF assms(2)])
moreover have "(x#S) \<cdot>\<^sub>s\<^sub>t \<theta> = Equality a (t \<cdot> \<theta>) (t' \<cdot> \<theta>)#(S \<cdot>\<^sub>s\<^sub>t \<theta>)"
using \<open>x = Equality a t t'\<close> by auto
ultimately show ?thesis using IH by auto
next
case (Inequality X F)
let ?\<sigma> = "rm_vars (set X) \<theta>"
let ?G = "F \<cdot>\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ?\<sigma>"
let ?P = "\<lambda>F X. \<forall>x \<in> fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \<exists>a. \<Gamma> (Var x) = TAtom a"
let ?Q = "\<lambda>F X.
\<forall>f T. Fun f T \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) \<longrightarrow> T = [] \<or> (\<exists>s \<in> set T. s \<notin> Var ` set X)"
have 0: "set X \<inter> range_vars ?\<sigma> = {}"
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 \<or> ?Q F X" using Inequality Cons.prems by simp
have 2: "fv\<^sub>s\<^sub>e\<^sub>t (?\<sigma> ` 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 "\<forall>x \<in> (fv (t \<cdot> ?\<sigma>) \<union> fv (t' \<cdot> ?\<sigma>)) - set X. \<exists>a. \<Gamma> (Var x) = Var a"
proof -
have *: "\<forall>x \<in> fv t - set X. \<exists>a. \<Gamma> (Var x) = Var a"
"\<forall>x \<in> fv t' - set X. \<exists>a. \<Gamma> (Var x) = Var a"
using g Cons.prems by simp_all
have **: "\<forall>x. wf\<^sub>t\<^sub>r\<^sub>m (?\<sigma> x)"
using \<theta>(2) wf_trm_subst_range_iff[of \<theta>] wf_trm_subst_rm_vars'[of \<theta> _ "set X"] by simp
show ?thesis
using wt_subst_TAtom_fv[OF wt_subst_rm_vars[OF \<theta>(1)] ** *(1)]
wt_subst_trm'[OF wt_subst_rm_vars[OF \<theta>(1), of "set X"]] 2
by blast
qed
moreover have "\<forall>x\<in>fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s (G \<cdot>\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ?\<sigma>) - set X. \<exists>a. \<Gamma> (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 \<or> ?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 ?\<sigma>]
by presburger
moreover have "(x#S) \<cdot>\<^sub>s\<^sub>t \<theta> = Inequality X (F \<cdot>\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s ?\<sigma>)#(S \<cdot>\<^sub>s\<^sub>t \<theta>)"
using \<open>x = Inequality X F\<close> 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') \<Longrightarrow> Unifier \<delta> t t' \<Longrightarrow> \<Gamma> t = \<Gamma> t'"
by force+
lemma tfr_subset:
"\<And>A B. tfr\<^sub>s\<^sub>e\<^sub>t (A \<union> B) \<Longrightarrow> tfr\<^sub>s\<^sub>e\<^sub>t A"
"\<And>A B. tfr\<^sub>s\<^sub>e\<^sub>t B \<Longrightarrow> A \<subseteq> B \<Longrightarrow> tfr\<^sub>s\<^sub>e\<^sub>t A"
"\<And>A B. tfr\<^sub>s\<^sub>e\<^sub>t B \<Longrightarrow> SMP A \<subseteq> SMP B \<Longrightarrow> tfr\<^sub>s\<^sub>e\<^sub>t A"
proof -
show 1: "tfr\<^sub>s\<^sub>e\<^sub>t (A \<union> B) \<Longrightarrow> 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 \<subseteq> B \<Longrightarrow> tfr\<^sub>s\<^sub>e\<^sub>t A"
proof -
assume "A \<subseteq> B"
then obtain C where "B = A \<union> C" by moura
thus ?thesis using B 1 by blast
qed
show "SMP A \<subseteq> SMP B \<Longrightarrow> tfr\<^sub>s\<^sub>e\<^sub>t A"
proof -
assume "SMP A \<subseteq> SMP B"
then obtain C where "SMP B = SMP A \<union> C" by moura
thus ?thesis using B unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by blast
assume *: "s \<in> SMP (N \<union> M) - range Var" "t \<in> SMP (N \<union> M) - range Var" "\<exists>\<delta>. Unifier \<delta> s t"
hence **: "is_Fun s" "is_Fun t" "s \<in> SMP N \<or> s \<in> M" "t \<in> SMP N \<or> t \<in> M"
using assms(3) SMP_consts[OF assms(1,2)] SMP_union[of N M] by auto
moreover have "\<Gamma> s = \<Gamma> t" when "s \<in> SMP N" "t \<in> SMP N"
using that assms(3) *(3) **(1,2) unfolding tfr\<^sub>s\<^sub>e\<^sub>t_def by blast
moreover have "\<Gamma> s = \<Gamma> t" when st: "s \<in> M" "t \<in> 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 "\<Gamma> s = \<Gamma> t" when st: "s \<in> SMP N" "t \<in> 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 "\<Gamma> s = \<Gamma> t" when st: "s \<in> M" "t \<in> 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 "\<Gamma> s = \<Gamma> 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 \<Longrightarrow> 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 "(\<exists>\<delta>. Unifier \<delta> t t') \<Longrightarrow> \<Gamma> t = \<Gamma> 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 "(\<forall>x \<in> fv\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F - set X. \<exists>a. \<Gamma> (Var x) = Var a) \<or>
(\<forall>f T. Fun f T \<in> subterms\<^sub>s\<^sub>e\<^sub>t (trms\<^sub>p\<^sub>a\<^sub>i\<^sub>r\<^sub>s F) \<longrightarrow> T = [] \<or> (\<exists>s \<in> set T. s \<notin> Var ` set X))"
using Cons.prems Inequality by auto
ultimately show ?thesis using Inequality IH by auto
assumes "Unification.unify E B = Some U" "\<forall>(s,t) \<in> set E. wf\<^sub>t\<^sub>r\<^sub>m s \<and> wf\<^sub>t\<^sub>r\<^sub>m t \<and> \<Gamma> s = \<Gamma> t"
and "\<forall>(v,t) \<in> set B. \<Gamma> (Var v) = \<Gamma> t"
shows "\<forall>(v,t) \<in> set U. \<Gamma> (Var v) = \<Gamma> 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)" "\<Gamma> (Fun f X) = \<Gamma> (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 "\<forall>(s,t) \<in> set E'. wf\<^sub>t\<^sub>r\<^sub>m s \<and> wf\<^sub>t\<^sub>r\<^sub>m t \<and> \<Gamma> s = \<Gamma> t"
proof -
{ fix s t assume "(s,t) \<in> 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] \<open>E' = zip X Y\<close> by metis
hence "\<Gamma> (Fun f (X'@s#X'')) = \<Gamma> (Fun g (Y'@t#Y''))" by (metis \<open>\<Gamma> (Fun f X) = \<Gamma> (Fun g Y)\<close>)
from \<open>E' = zip X Y\<close> have "\<forall>(s,t) \<in> set E'. s \<sqsubset> Fun f X \<and> t \<sqsubset> Fun g Y"
using zip_arg_subterm[of _ _ X Y] by blast
with \<open>(s,t) \<in> set E'\<close> have "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t"
using wf_trm_subterm \<open>wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)\<close> \<open>wf\<^sub>t\<^sub>r\<^sub>m (Fun g Y)\<close> by (blast,blast)
moreover have "f \<in> \<Sigma>\<^sub>f"
proof (rule ccontr)
assume "f \<notin> \<Sigma>\<^sub>f"
hence "f \<in> \<C>" "arity f = 0" using const_arity_eq_zero[of f] by simp_all
thus False using \<open>wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)\<close> * \<open>(s,t) \<in> set E'\<close> unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by auto
qed
hence "\<Gamma> s = \<Gamma> t"
using fun_type_arg_cong' \<open>f \<in> \<Sigma>\<^sub>f\<close> \<open>\<Gamma> (Fun f (X'@s#X'')) = \<Gamma> (Fun g (Y'@t#Y''))\<close>
ultimately have "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t" "\<Gamma> s = \<Gamma> t" by metis+
}
thus ?thesis by blast
qed
moreover have "\<forall>(s,t) \<in> set E. wf\<^sub>t\<^sub>r\<^sub>m s \<and> wf\<^sub>t\<^sub>r\<^sub>m t \<and> \<Gamma> s = \<Gamma> 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 "\<Gamma> (Var v) = \<Gamma> 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 *: "\<forall>(v, t) \<in> set ((v,t)#B). \<Gamma> (Var v) = \<Gamma> t"
"\<And>t t'. (t,t') \<in> set E \<Longrightarrow> \<Gamma> t = \<Gamma> 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 \<noteq> Var v"
hence "v \<notin> 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) \<open>t \<noteq> Var v\<close> by auto
have "\<forall>(s, t) \<in> set (subst_list (subst v t) E). wf\<^sub>t\<^sub>r\<^sub>m s \<and> wf\<^sub>t\<^sub>r\<^sub>m t"
using wf_trm_subst_singleton[OF _ \<open>wf\<^sub>t\<^sub>r\<^sub>m t\<close>] "3.prems"(2)
unfolding subst_list_def subst_def by auto
moreover have "\<forall>(s, t) \<in> set (subst_list (subst v t) E). \<Gamma> s = \<Gamma> t"
using *(2)[THEN wt_subst_trm'[OF \<open>wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst v t)\<close>]] by (simp add: subst_list_def)
ultimately show ?thesis using "3.IH"(2)[OF \<open>t \<noteq> Var v\<close> \<open>v \<notin> fv t\<close> ** _ *(1)] by auto
qed
next
case (4 f X v E B U)
hence "\<Gamma> (Var v) = \<Gamma> (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 *: "\<forall>(v, t) \<in> set ((v,(Fun f X))#B). \<Gamma> (Var v) = \<Gamma> t"
"\<And>t t'. (t,t') \<in> set E \<Longrightarrow> \<Gamma> t = \<Gamma> 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 \<notin> 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 "\<forall>(s, t) \<in> set (subst_list (subst v (Fun f X)) E). wf\<^sub>t\<^sub>r\<^sub>m s \<and> wf\<^sub>t\<^sub>r\<^sub>m t"
using wf_trm_subst_singleton[OF _ \<open>wf\<^sub>t\<^sub>r\<^sub>m (Fun f X)\<close>] "4.prems"(2)
unfolding subst_list_def subst_def by auto
moreover have "\<forall>(s, t) \<in> set (subst_list (subst v (Fun f X)) E). \<Gamma> s = \<Gamma> t"
using *(2)[THEN wt_subst_trm'[OF \<open>wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (subst v (Fun f X))\<close>]] by (simp add: subst_list_def)
ultimately show ?case using "4.IH"[OF \<open>v \<notin> fv (Fun f X)\<close> ** _ *(1)] by auto
qed auto
lemma mgu_wt_if_same_type:
assumes "mgu s t = Some \<sigma>" "wf\<^sub>t\<^sub>r\<^sub>m s" "wf\<^sub>t\<^sub>r\<^sub>m t" "\<Gamma> s = \<Gamma> t"
in \<forall>s \<in> set M. \<forall>t \<in> set M. is_Fun s \<and> is_Fun t \<and> \<Gamma> s \<noteq> \<Gamma> t \<longrightarrow> mgu s (t \<cdot> \<delta>) = None)"
fun comp_tfr\<^sub>s\<^sub>t\<^sub>p where
"comp_tfr\<^sub>s\<^sub>t\<^sub>p \<Gamma> (\<langle>_: t \<doteq> t'\<rangle>\<^sub>s\<^sub>t) = (mgu t t' \<noteq> None \<longrightarrow> \<Gamma> t = \<Gamma> t')"
locale typed_model' = typed_model arity public Ana \<Gamma>
for arity::"'fun \<Rightarrow> nat"
and public::"'fun \<Rightarrow> bool"
and Ana::"('fun,(('fun,'atom::finite) term_type \<times> nat)) term
\<Rightarrow> (('fun,(('fun,'atom) term_type \<times> nat)) term list
\<times> ('fun,(('fun,'atom) term_type \<times> nat)) term list)"
and \<Gamma>::"('fun,(('fun,'atom) term_type \<times> nat)) term \<Rightarrow> ('fun,'atom) term_type"
+
assumes \<Gamma>_Var_fst: "\<And>\<tau> n m. \<Gamma> (Var (\<tau>,n)) = \<Gamma> (Var (\<tau>,m))"
and Ana_const: "\<And>c T. arity c = 0 \<Longrightarrow> Ana (Fun c T) = ([],[])"
and Ana_subst'_or_Ana_keys_subterm:
"(\<forall>f T \<delta> K R. Ana (Fun f T) = (K,R) \<longrightarrow> Ana (Fun f T \<cdot> \<delta>) = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>,R \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>)) \<or>
(\<forall>t K R k. Ana t = (K,R) \<longrightarrow> k \<in> set K \<longrightarrow> k \<sqsubset> t)"
by (auto simp add: var_rename_def var_rename_inv_def wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t_def \<Gamma>_Var_fst)
lemma var_rename_wt':
assumes "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "s = m \<cdot> \<delta>"
shows "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t (var_rename_inv n \<circ>\<^sub>s \<delta>)" "s = m \<cdot> var_rename n \<cdot> var_rename_inv n \<circ>\<^sub>s \<delta>"
using assms(2) wt_subst_compose[OF var_rename_wt(2)[of n] assms(1)] var_rename_inv_comp[of m n]
"(\<forall>f T. Fun f T \<in> M \<longrightarrow> P f T) \<longleftrightarrow> (\<forall>u \<in> M. case u of Fun f T \<Rightarrow> P f T | _ \<Rightarrow> True)"
"(\<forall>f T. Fun f T \<in> M \<longrightarrow> P f T) \<longleftrightarrow> (\<forall>u \<in> M. is_Fun u \<longrightarrow> P (the_Fun u) (args u))"
and closed: "is_TComp_var_instance_closed \<Gamma> M"
shows "\<exists>g U. Fun g U \<in> set M \<and> \<Gamma> (Fun g U) = \<Gamma> (Var x) \<and> (\<forall>u \<in> set U. is_Var u) \<and> 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 "\<exists>y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M). \<Gamma> (Var x) = \<Gamma> (Var y)" "TComp f T \<sqsubseteq> \<Gamma> (Var x)"
and closed: "is_TComp_var_instance_closed \<Gamma> M"
and wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)"
shows "\<exists>g U. Fun g U \<in> set M \<and> \<Gamma> (Fun g U) = TComp f T \<and> (\<forall>u \<in> set U. is_Var u) \<and> distinct U"
using assms(1,2)
proof (induction "\<Gamma> (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"] \<Gamma>_Var_fst by simp_all
then obtain V where V:
"Fun g V \<in> set M" "\<Gamma> (Fun g V) = \<Gamma> (Var x)" "\<forall>v \<in> set V. \<exists>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 \<Gamma> V" using fun_type[OF g(1), of V] Fun.hyps(2) by simp
hence 1: "\<Gamma> v \<in> set U" when v: "v \<in> set V" for v using v by simp
have 2: "\<exists>y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M). \<Gamma> (Var z) = \<Gamma> (Var y)" when z: "Var z \<in> 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 = \<Gamma> (Var x)")
case False
then obtain u where u: "u \<in> set U" "TComp f T \<sqsubseteq> u"
using Fun.prems(2) Fun.hyps(2) by moura
then obtain y where y: "Var y \<in> set V" "\<Gamma> (Var y) = u" using U V(3) \<Gamma>_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: "\<Gamma> (Fun g T) = TComp g (map \<Gamma> U)" "wf\<^sub>t\<^sub>r\<^sub>m (Fun g T)"
and U: "\<forall>u \<in> set U. \<exists>y. u = Var y" "distinct U"
shows "\<exists>\<theta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>) \<and> Fun g T = Fun g U \<cdot> \<theta>"
proof -
define the_i where "the_i \<equiv> \<lambda>y. THE x. x < length U \<and> U ! x = Var y"
define \<theta> where \<theta>: "\<theta> \<equiv> \<lambda>y. if Var y \<in> 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 \<and> U ! the_i y = Var y" when y: "Var y \<in> 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 \<theta>"
and M_subterms_cl: "has_all_wt_instances_of \<Gamma> (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 \<sqsubseteq>\<^sub>s\<^sub>e\<^sub>t set M"
and s: "s \<sqsubseteq> t \<cdot> \<delta>"
and \<delta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
shows "\<exists>m \<in> set M. \<exists>\<theta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>) \<and> s = m \<cdot> \<theta>"
using subterm_subst_unfold[OF s]
proof
assume "\<exists>s'. s' \<sqsubseteq> t \<and> s = s' \<cdot> \<delta>"
then obtain s' where s': "s' \<sqsubseteq> t" "s = s' \<cdot> \<delta>" by blast
then obtain \<theta> where \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)" "s' \<in> set M \<cdot>\<^sub>s\<^sub>e\<^sub>t \<theta>"
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 \<in> set M" "s' = m \<cdot> \<theta>" by blast
have "s = m \<cdot> (\<theta> \<circ>\<^sub>s \<delta>)" using s'(2) m(2) by simp
thus ?thesis
using m(1) wt_subst_compose[OF \<theta>(1) \<delta>(1)] wf_trms_subst_compose[OF \<theta>(2) \<delta>(2)] by blast
next
assume "\<exists>x \<in> fv t. s \<sqsubset> \<delta> x"
then obtain x where x: "x \<in> fv t" "s \<sqsubset> \<delta> x" "s \<sqsubseteq> \<delta> x" by blast
have \<delta>x_wf: "wf\<^sub>t\<^sub>r\<^sub>m (\<delta> x)" and s_wf_trm: "wf\<^sub>t\<^sub>r\<^sub>m s"
using \<delta>(2) wf_trm_subterm[OF _ x(2)] by fastforce+
have x_fv_ex: "\<exists>y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M). \<Gamma> (Var x) = \<Gamma> (Var y)"
using x(1) s fv_subset_subterms[OF t] by auto
obtain y where y: "y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\<Gamma> (Var y) = \<Gamma> s"
using 0[of \<delta> x s, OF \<delta>x_wf x_fv_ex x(3) \<delta>(1)] by metis
then obtain z where z: "Var z \<in> set M" "\<Gamma> (Var z) = \<Gamma> s"
using 1[of y] vars_iff_subtermeq_set[of y "set M"] by metis
define \<theta> where "\<theta> \<equiv> Var(z := s)::('fun, ('fun, 'atom) term \<times> nat) subst"
have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)" "s = Var z \<cdot> \<theta>"
using z(2) s_wf_trm unfolding \<theta>_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 \<in> SMP (set M)"
and closed: "has_all_wt_instances_of \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
"is_TComp_var_instance_closed \<Gamma> M"
and wf_M: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (set M)"
shows "\<forall>x \<in> fv t. \<exists>y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M). \<Gamma> (Var y) = \<Gamma> (Var x)"
using assms(1)
proof (induction t rule: SMP.induct)
case (MP t) show ?case
proof
fix x assume x: "x \<in> fv t"
hence "Var x \<in> subterms\<^sub>s\<^sub>e\<^sub>t (set M)" using MP.hyps vars_iff_subtermeq by fastforce
then obtain \<delta> s where \<delta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
and s: "s \<in> set M" "Var x = s \<cdot> \<delta>"
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
then obtain \<tau> where \<tau>: "\<tau> \<in> set T" "\<Gamma> (Var x) \<sqsubseteq> \<tau>" using Fun.prems(2) Fun.hyps(2) by auto
then obtain U where U:
"Fun f U \<in> set M" "\<Gamma> (Fun f U) = \<Gamma> (Var z)" "\<forall>u \<in> set U. \<exists>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: "\<forall>x \<in> fv (Fun f U). \<exists>y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M). \<Gamma> (Var y) = \<Gamma> (Var x)" by force
have "arity f > 0" using U(2) z(2) Fun.hyps(2) fun_type_inv(1) by metis
hence "\<Gamma> (Fun f U) = TComp f (map \<Gamma> U)" using fun_type by auto
then obtain u where u: "Var u \<in> set U" "\<Gamma> (Var u) = \<tau>"
using \<tau>(1) U(2,3) z(2) Fun.hyps(2) by auto
show ?thesis
using Fun.hyps(1)[of u "Fun f U"] u \<tau> 1
by force
qed
qed
qed
next
case (Ana t K T k)
have "fv k \<subseteq> 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 \<times> nat) term"
assumes t_SMP: "t \<in> SMP (set M)"
and t_Var: "\<exists>x. t = Var x"
and M_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> M"
shows "\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = m \<cdot> \<delta>"
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 \<Gamma> M"
and M_subterms_cl: "has_all_wt_instances_of \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
and M_Ana_cl: "has_all_wt_instances_of \<Gamma> (\<Union>((set \<circ> fst \<circ> 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 (\<Union> ((set \<circ> fst \<circ> Ana) ` set M))"
proof
fix k assume "k \<in> \<Union>((set \<circ> fst \<circ> Ana) ` set M)"
then obtain m where m: "m \<in> set M" "k \<in> 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
moreover have "t = m \<cdot> \<theta>" using x z unfolding \<theta>_def by simp
ultimately show ?thesis using m(1) by blast
qed
private lemma SMP_D_aux3:
assumes hyps: "t' \<sqsubseteq> t" and wf_t: "wf\<^sub>t\<^sub>r\<^sub>m t" and prems: "is_Fun t'"
and IH:
"((\<exists>f. t = Fun f []) \<and> (\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = m \<cdot> \<delta>)) \<or>
(\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = m \<cdot> \<delta> \<and> is_Fun m)"
and M_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> M"
shows "((\<exists>f. t' = Fun f []) \<and> (\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t' = m \<cdot> \<delta>)) \<or>
(\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t' = m \<cdot> \<delta> \<and> is_Fun m)"
proof (cases "\<exists>f. t = Fun f [] \<or> 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 \<Gamma> M"
and M_subterms_cl: "has_all_wt_instances_of \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
and M_Ana_cl: "has_all_wt_instances_of \<Gamma> (\<Union>((set \<circ> fst \<circ> Ana) ` set M)) (set M)"
using finite_SMP_representationD[OF M_SMP_repr] by blast+
then obtain m' where m': "m' \<sqsubseteq> m" "t' = m' \<cdot> \<delta>" by moura
obtain n \<theta> where n: "n \<in> set M" "m' = n \<cdot> \<theta>" and \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)"
using 0[of m'] m(1) m'(1) by blast
have "t' = n \<cdot> (\<theta> \<circ>\<^sub>s \<delta>)" using m'(2) n(2) by auto
thus ?thesis
using c n(1) wt_subst_compose[OF \<theta>(1) \<delta>(1)] wf_trms_subst_compose[OF \<theta>(2) \<delta>(2)] by blast
next
assume "\<exists>x \<in> fv m. t' \<sqsubset> \<delta> x"
then obtain x where x: "x \<in> fv m" "t' \<sqsubset> \<delta> x" "t' \<sqsubseteq> \<delta> x" by moura
have \<delta>x_wf: "wf\<^sub>t\<^sub>r\<^sub>m (\<delta> x)" using \<delta>(2) by fastforce
have x_fv_ex: "\<exists>y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M). \<Gamma> (Var x) = \<Gamma> (Var y)" using x m by auto
show ?thesis
proof (cases "\<Gamma> t'")
case (Var a)
show ?thesis
using c m 2[OF _ hyps[unfolded m(2)] \<delta>]
by fast
next
case (Fun g S)
show ?thesis
using c 1[of \<delta> x t', OF \<delta>x_wf x_fv_ex x(3) \<delta>(1) Fun]
by blast
qed
qed
qed
qed (use IH hyps in simp)
next
case False
note F = False
then obtain m \<delta> where m:
"m \<in> set M" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "t = m \<cdot> \<delta>" "is_Fun m" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
using IH by moura
obtain f T where fT: "t' = Fun f T" "arity f > 0" "\<Gamma> t' = TComp f (map \<Gamma> 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 \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
"is_TComp_var_instance_closed \<Gamma> 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 "\<exists>x \<in> fv m. t' \<sqsubseteq> \<delta> x")
case True
then obtain x where x: "x \<in> fv m" "t' \<sqsubseteq> \<delta> x" by moura
have 1: "x \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M)" using m(1) x(1) by auto
have 2: "is_Fun (\<delta> x)" using prems x(2) by auto
have 3: "wf\<^sub>t\<^sub>r\<^sub>m (\<delta> x)" using m(5) by (simp add: wf_trm_subst_rangeD)
have "\<not>(\<exists>f. \<delta> x = Fun f [])" using F x(2) by auto
hence "\<exists>f T. \<Gamma> (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 "\<exists>f T. \<Gamma> 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' \<sqsubseteq> m" "t' = m' \<cdot> \<delta>" "is_Fun m'"
using hyps m(3) subterm_subst_not_img_subterm
by blast
then obtain \<theta> m'' where \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)" "m'' \<in> set M" "m' = m'' \<cdot> \<theta>"
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'' \<cdot> \<theta> \<circ>\<^sub>s \<delta>" using m'(2) by fastforce
"\<Gamma> (Var x) = Fun f (map \<Gamma> T)" "wf\<^sub>t\<^sub>r\<^sub>m ((\<theta> \<circ>\<^sub>s \<delta>) x)"
using \<theta>\<delta> t'_m'' \<theta>(3) fv_subset[OF \<theta>(3)] fT(3) subst_apply_term.simps(1)[of x "\<theta> \<circ>\<^sub>s \<delta>"]
wt_subst_trm''[OF \<theta>\<delta>(1), of "Var x"]
by (fastforce, blast, argo, fastforce)
thus ?thesis
using x TComp_var_instance_closed_has_Fun[
of M "\<theta> \<circ>\<^sub>s \<delta>" x t' f "map \<Gamma> T", OF closed(2) M_wf _ _ _ \<theta>\<delta>(1) fT(3) prems]
by blast
qed
qed
qed
lemma SMP_D:
assumes "t \<in> SMP (set M)" "is_Fun t"
and M_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> M"
shows "((\<exists>f. t = Fun f []) \<and> (\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = m \<cdot> \<delta>)) \<or>
(\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = m \<cdot> \<delta> \<and> 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 \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
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 \<cdot> \<delta>)" using Substitution.hyps(3) wf_trm_subst by blast
show ?case
proof (cases "\<Gamma> t")
case (Var a)
hence 1: "\<Gamma> (t \<cdot> \<delta>) = TAtom a" using Substitution.hyps(2) by (metis wt_subst_trm'')
then obtain c where c: "t \<cdot> \<delta> = Fun c []"
using TAtom_term_cases[OF wf' 1] Substitution.prems by fastforce
hence "(\<exists>x. t = Var x) \<or> t = t \<cdot> \<delta>" by (cases t) auto
thus ?thesis
proof
assume t_Var: "\<exists>x. t = Var x"
then obtain x where x: "t = Var x" "\<delta> x = Fun c []" "\<Gamma> (Var x) = TAtom a"
using c 1 wt_subst_trm''[OF Substitution.hyps(2), of t] by force
obtain m \<theta> where m: "m \<in> set M" "t = m \<cdot> \<theta>" and \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)"
using SMP_D_aux2[OF Substitution.hyps(1) t_Var M_SMP_repr] by moura
have "m \<cdot> (\<theta> \<circ>\<^sub>s \<delta>) = Fun c []" using c m(2) by auto
thus ?thesis
using c m(1) wt_subst_compose[OF \<theta>(1) Substitution.hyps(2)]
then obtain y where y: "y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\<Gamma> (Var y) = \<Gamma> (Var x)"
using SMP_D_aux1[OF Substitution.hyps(1) closed(1,3) wf_M] Fun
by moura
hence 3: "\<Gamma> (Var y) = TComp f T" using Var Fun \<Gamma>_Var_fst by simp
obtain h V where V:
"Fun h V \<in> set M" "\<Gamma> (Fun h V) = \<Gamma> (Var y)" "\<forall>u \<in> set V. \<exists>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 \<Gamma> V"
by (metis fun_type[OF f(1)] 3 fun_type_id_eq term.inject(2))
obtain \<theta> where \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)" "t \<cdot> \<delta> = Fun h V \<cdot> \<theta>"
using TComp_var_instance_wt_subst_exists 1 3 T'' TV V(2,3,4) wf'
by (metis fun_type_id_eq)
have 9: "\<Gamma> (Fun h V) = \<Gamma> (\<delta> x)" using y(2) Substitution.hyps(2) V(2) 1 3 Var by auto
show ?thesis using Var \<theta> 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 \<subseteq> 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 (\<Union>((set \<circ> fst \<circ> Ana) ` set M))"
proof
fix t assume "t \<in> (\<Union>((set \<circ> fst \<circ> Ana) ` set M))"
then obtain s where s: "s \<in> set M" "t \<in> (set \<circ> fst \<circ> Ana) s" by blast
obtain K R where KR: "Ana s = (K,R)" by (metis surj_pair)
hence "t \<in> 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 "\<forall>t K T k. Ana t = (K, T) \<longrightarrow> k \<in> set K \<longrightarrow> k \<sqsubset> t"
hence *: "k \<sqsubseteq> 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':
"\<forall>f T \<delta> K M. Ana (Fun f T) = (K, M) \<longrightarrow> Ana (Fun f T \<cdot> \<delta>) = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>, M \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>)"
have "arity f > 0" using Ana_const[of f U] U Ana.hyps(2,3) by fastforce
hence "U \<noteq> []" using wf_t U unfolding wf\<^sub>t\<^sub>r\<^sub>m_def by force
then obtain m \<delta> where m: "m \<in> set M" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)" "t = m \<cdot> \<delta>" "is_Fun m"
using Ana.IH[OF 1] U by auto
hence "Ana (t \<cdot> \<delta>) = (K \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>,T \<cdot>\<^sub>l\<^sub>i\<^sub>s\<^sub>t \<delta>)" using Ana_subst' U Ana.hyps(2) by auto
obtain Km Tm where Ana_m: "Ana m = (Km,Tm)" by moura
have "\<Gamma> s = \<Gamma> s0" "\<Gamma> t = \<Gamma> (t0 \<cdot> \<delta>)" "\<Gamma> (t0 \<cdot> \<delta>) = \<Gamma> t0"
using s0 t0 wt_subst_trm'' by (metis, metis, metis \<delta>_def var_rename_wt(1))
thus ?thesis using s0 t0 that by simp
qed
lemma SMP_D'':
fixes t::"('fun, ('fun, 'atom) term \<times> nat) term"
assumes t_SMP: "t \<in> SMP (set M)"
and M_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> M"
shows "\<exists>m \<in> set M. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> t = m \<cdot> \<delta>"
proof (cases "(\<exists>x. t = Var x) \<or> (\<exists>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 \<Gamma> M"
and M_subterms_cl: "has_all_wt_instances_of \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
and M_Ana_cl: "has_all_wt_instances_of \<Gamma> (\<Union>((set \<circ> fst \<circ> 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 (\<Union> ((set \<circ> fst \<circ> Ana) ` set M))"
proof
fix k assume "k \<in> \<Union>((set \<circ> fst \<circ> Ana) ` set M)"
then obtain m where m: "m \<in> set M" "k \<in> 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 "\<exists>x. t = Var x"
then obtain x y where x: "t = Var x" and y: "y \<in> fv\<^sub>s\<^sub>e\<^sub>t (set M)" "\<Gamma> (Var y) = \<Gamma> (Var x)"
using SMP_D_aux1[OF t_SMP M_subterms_cl M_var_inst_cl M_wf] by fastforce
then obtain m \<delta> where m: "m \<in> set M" "m \<cdot> \<delta> = Var y" and \<delta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>"
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 \<theta> where "\<theta> \<equiv> Var(z := Var x)::('fun, ('fun, 'atom) term \<times> nat) subst"
have "\<Gamma> (Var z) = \<Gamma> (Var x)" using y(2) m(2) z wt_subst_trm''[OF \<delta>, of m] by argo
assumes "comp_tfr\<^sub>s\<^sub>t arity Ana \<Gamma> (SMP0 Ana \<Gamma> (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 \<open>Lemmata for Checking Ground SMP (GSMP) Disjointness\<close>
context
begin
private lemma ground_SMP_disjointI_aux1:
fixes M::"('fun, ('fun, 'atom) term \<times> nat) term set"
assumes f_def: "f \<equiv> \<lambda>M. {t \<cdot> \<delta> | t \<delta>. t \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> fv (t \<cdot> \<delta>) = {}}"
and g_def: "g \<equiv> \<lambda>M. {t \<in> M. fv t = {}}"
shows "f (SMP M) = g (SMP M)"
proof
have "t \<in> f (SMP M)" when t: "t \<in> SMP M" "fv t = {}" for t
proof -
define \<delta> where "\<delta> \<equiv> Var::('fun, ('fun, 'atom) term \<times> nat) subst"
have "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)" "t = t \<cdot> \<delta>"
using subst_apply_term_empty[of t] that(2) wt_subst_Var wf_trm_subst_range_Var
unfolding \<delta>_def by auto
thus ?thesis using SMP.Substitution[OF t(1), of \<delta>] t(2) unfolding f_def by fastforce
qed
thus "g (SMP M) \<subseteq> 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 \<times> nat) term list"
assumes f_def: "f \<equiv> \<lambda>M. {t \<cdot> \<delta> | t \<delta>. t \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> fv (t \<cdot> \<delta>) = {}}"
and M_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> 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 \<Gamma> M"
and M_subterms_cl: "has_all_wt_instances_of \<Gamma> (subterms\<^sub>s\<^sub>e\<^sub>t (set M)) (set M)"
and M_Ana_cl: "has_all_wt_instances_of \<Gamma> (\<Union>((set \<circ> fst \<circ> Ana) ` set M)) (set M)"
using finite_SMP_representationD[OF M_SMP_repr] by blast+
show "f (SMP (set M)) \<subseteq> f (set M)"
proof
fix t assume "t \<in> f (SMP (set M))"
then obtain s \<delta> where s: "t = s \<cdot> \<delta>" "s \<in> SMP (set M)" "fv (s \<cdot> \<delta>) = {}"
and \<delta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>)"
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 \<delta>(2)] by blast
obtain m \<theta> where m: "m \<in> set M" "s = m \<cdot> \<theta>" and \<theta>: "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<theta>" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<theta>)"
using SMP_D''[OF s(2) M_SMP_repr] by blast
have "t = m \<cdot> (\<theta> \<circ>\<^sub>s \<delta>)" "fv (m \<cdot> (\<theta> \<circ>\<^sub>s \<delta>)) = {}" using s(1,3) m(2) by simp_all
thus "t \<in> f (set M)"
using m(1) wt_subst_compose[OF \<theta>(1) \<delta>(1)] wf_trms_subst_compose[OF \<theta>(2) \<delta>(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 \<times> nat) term set"
defines "P \<equiv> \<lambda>t s. \<exists>\<delta>. wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> Unifier \<delta> t s"
assumes f_def: "f \<equiv> \<lambda>M. {t \<cdot> \<delta> | t \<delta>. t \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> fv (t \<cdot> \<delta>) = {}}"
and Q_def: "Q \<equiv> \<lambda>t. intruder_synth' public arity {} t"
and R_def: "R \<equiv> \<lambda>t. \<exists>u \<in> C. is_wt_instance_of_cond \<Gamma> 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 \<inter> fv\<^sub>s\<^sub>e\<^sub>t B = {}"
and C: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s C"
and ABC: "\<forall>t \<in> A. \<forall>s \<in> B. P t s \<longrightarrow> (Q t \<and> Q s) \<or> (R t \<and> R s)"
shows "f A \<inter> f B \<subseteq> f C \<union> {m. {} \<turnstile>\<^sub>c m}"
hence "(Q ta \<and> Q tb) \<or> (R ta \<and> R tb)" using ABC ta(2) tb(2) unfolding P_def by blast+
thus "t \<in> f C \<union> {m. {} \<turnstile>\<^sub>c m}"
proof
show "Q ta \<and> Q tb \<Longrightarrow> ?thesis"
using ta(1) pgwt_ground[of ta] pgwt_is_empty_synth[of ta] subst_ground_ident[of ta \<delta>a]
unfolding Q_def f_def intruder_synth_code[symmetric] by simp
next
assume "R ta \<and> R tb"
then obtain ua \<sigma>a where ua: "ta = ua \<cdot> \<sigma>a" "ua \<in> C" "wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<sigma>a" "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<sigma>a)"
using \<theta> 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 \<cdot> (\<sigma>a \<circ>\<^sub>s \<delta>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 \<times> nat) term list" and C
defines "f \<equiv> \<lambda>M. {t \<cdot> \<delta> | t \<delta>. t \<in> M \<and> wt\<^sub>s\<^sub>u\<^sub>b\<^sub>s\<^sub>t \<delta> \<and> wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s (subst_range \<delta>) \<and> fv (t \<cdot> \<delta>) = {}}"
and "g \<equiv> \<lambda>M. {t \<in> M. fv t = {}}"
and "Q \<equiv> \<lambda>t. intruder_synth' public arity {} t"
and "R \<equiv> \<lambda>t. \<exists>u \<in> C. is_wt_instance_of_cond \<Gamma> t u"
assumes AB_fv_disj: "fv\<^sub>s\<^sub>e\<^sub>t (set A) \<inter> fv\<^sub>s\<^sub>e\<^sub>t (set B) = {}"
and A_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> A"
and B_SMP_repr: "finite_SMP_representation arity Ana \<Gamma> B"
and C_wf: "wf\<^sub>t\<^sub>r\<^sub>m\<^sub>s C"
and ABC: "\<forall>t \<in> set A. \<forall>s \<in> set B. \<Gamma> t = \<Gamma> s \<and> mgu t s \<noteq> None \<longrightarrow> (Q t \<and> Q s) \<or> (R t \<and> R s)"
shows "g (SMP (set A)) \<inter> g (SMP (set B)) \<subseteq> f C \<union> {m. {} \<turnstile>\<^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)"