src/HOL/ex/Unification.thy
changeset 44367 74c08021ab2e
parent 42463 f270e3e18be5
child 44368 91e8062605d5
equal deleted inserted replaced
44361:75ec83d45303 44367:74c08021ab2e
    27 subsection {* Basic definitions *}
    27 subsection {* Basic definitions *}
    28 
    28 
    29 datatype 'a trm = 
    29 datatype 'a trm = 
    30   Var 'a 
    30   Var 'a 
    31   | Const 'a
    31   | Const 'a
    32   | App "'a trm" "'a trm" (infix "\<cdot>" 60)
    32   | Comb "'a trm" "'a trm" (infix "\<cdot>" 60)
    33 
    33 
    34 type_synonym 'a subst = "('a \<times> 'a trm) list"
    34 type_synonym 'a subst = "('a \<times> 'a trm) list"
    35 
    35 
    36 text {* Applying a substitution to a variable: *}
    36 text {* Applying a substitution to a variable: *}
    37 
    37 
    40   "assoc x d [] = d"
    40   "assoc x d [] = d"
    41 | "assoc x d ((p,q)#t) = (if x = p then q else assoc x d t)"
    41 | "assoc x d ((p,q)#t) = (if x = p then q else assoc x d t)"
    42 
    42 
    43 text {* Applying a substitution to a term: *}
    43 text {* Applying a substitution to a term: *}
    44 
    44 
    45 fun apply_subst :: "'a trm \<Rightarrow> 'a subst \<Rightarrow> 'a trm" (infixl "\<triangleleft>" 60)
    45 primrec subst :: "'a trm \<Rightarrow> 'a subst \<Rightarrow> 'a trm" (infixl "\<lhd>" 55)
    46 where
    46 where
    47   "(Var v) \<triangleleft> s = assoc v (Var v) s"
    47   "(Var v) \<lhd> s = assoc v (Var v) s"
    48 | "(Const c) \<triangleleft> s = (Const c)"
    48 | "(Const c) \<lhd> s = (Const c)"
    49 | "(M \<cdot> N) \<triangleleft> s = (M \<triangleleft> s) \<cdot> (N \<triangleleft> s)"
    49 | "(M \<cdot> N) \<lhd> s = (M \<lhd> s) \<cdot> (N \<lhd> s)"
    50 
    50 
    51 text {* Composition of substitutions: *}
    51 text {* Composition of substitutions: *}
    52 
    52 
    53 fun
    53 fun
    54   "compose" :: "'a subst \<Rightarrow> 'a subst \<Rightarrow> 'a subst" (infixl "\<bullet>" 80)
    54   comp :: "'a subst \<Rightarrow> 'a subst \<Rightarrow> 'a subst" (infixl "\<lozenge>" 56)
    55 where
    55 where
    56   "[] \<bullet> bl = bl"
    56   "[] \<lozenge> bl = bl"
    57 | "((a,b) # al) \<bullet> bl = (a, b \<triangleleft> bl) # (al \<bullet> bl)"
    57 | "((a,b) # al) \<lozenge> bl = (a, b \<lhd> bl) # (al \<lozenge> bl)"
    58 
    58 
    59 text {* Equivalence of substitutions: *}
    59 text {* Equivalence of substitutions: *}
    60 
    60 
    61 definition eqv (infix "=\<^sub>s" 50)
    61 definition subst_eq (infixr "\<doteq>" 52)
    62 where
    62 where
    63   "s1 =\<^sub>s s2 \<equiv> \<forall>t. t \<triangleleft> s1 = t \<triangleleft> s2" 
    63   "s1 \<doteq> s2 \<equiv> \<forall>t. t \<lhd> s1 = t \<lhd> s2" 
    64 
    64 
    65 
    65 
    66 subsection {* Basic lemmas *}
    66 subsection {* Basic lemmas *}
    67 
    67 
    68 lemma apply_empty[simp]: "t \<triangleleft> [] = t"
    68 lemma apply_empty[simp]: "t \<lhd> [] = t"
    69 by (induct t) auto
    69 by (induct t) auto
    70 
    70 
    71 lemma compose_empty[simp]: "\<sigma> \<bullet> [] = \<sigma>"
    71 lemma compose_empty[simp]: "\<sigma> \<lozenge> [] = \<sigma>"
    72 by (induct \<sigma>) auto
    72 by (induct \<sigma>) auto
    73 
    73 
    74 lemma apply_compose[simp]: "t \<triangleleft> (s1 \<bullet> s2) = t \<triangleleft> s1 \<triangleleft> s2"
    74 lemma apply_compose[simp]: "t \<lhd> (s1 \<lozenge> s2) = t \<lhd> s1 \<lhd> s2"
    75 proof (induct t)
    75 proof (induct t)
    76   case App thus ?case by simp
    76   case Comb thus ?case by simp
    77 next 
    77 next 
    78   case Const thus ?case by simp
    78   case Const thus ?case by simp
    79 next
    79 next
    80   case (Var v) thus ?case
    80   case (Var v) thus ?case
    81   proof (induct s1)
    81   proof (induct s1)
    83   next
    83   next
    84     case (Cons p s1s) thus ?case by (cases p, simp)
    84     case (Cons p s1s) thus ?case by (cases p, simp)
    85   qed
    85   qed
    86 qed
    86 qed
    87 
    87 
    88 lemma eqv_refl[intro]: "s =\<^sub>s s"
    88 lemma eqv_refl[intro]: "s \<doteq> s"
    89   by (auto simp:eqv_def)
    89   by (auto simp:subst_eq_def)
    90 
    90 
    91 lemma eqv_trans[trans]: "\<lbrakk>s1 =\<^sub>s s2; s2 =\<^sub>s s3\<rbrakk> \<Longrightarrow> s1 =\<^sub>s s3"
    91 lemma eqv_trans[trans]: "\<lbrakk>s1 \<doteq> s2; s2 \<doteq> s3\<rbrakk> \<Longrightarrow> s1 \<doteq> s3"
    92   by (auto simp:eqv_def)
    92   by (auto simp:subst_eq_def)
    93 
    93 
    94 lemma eqv_sym[sym]: "\<lbrakk>s1 =\<^sub>s s2\<rbrakk> \<Longrightarrow> s2 =\<^sub>s s1"
    94 lemma eqv_sym[sym]: "\<lbrakk>s1 \<doteq> s2\<rbrakk> \<Longrightarrow> s2 \<doteq> s1"
    95   by (auto simp:eqv_def)
    95   by (auto simp:subst_eq_def)
    96 
    96 
    97 lemma eqv_intro[intro]: "(\<And>t. t \<triangleleft> \<sigma> = t \<triangleleft> \<theta>) \<Longrightarrow> \<sigma> =\<^sub>s \<theta>"
    97 lemma eqv_intro[intro]: "(\<And>t. t \<lhd> \<sigma> = t \<lhd> \<theta>) \<Longrightarrow> \<sigma> \<doteq> \<theta>"
    98   by (auto simp:eqv_def)
    98   by (auto simp:subst_eq_def)
    99 
    99 
   100 lemma eqv_dest[dest]: "s1 =\<^sub>s s2 \<Longrightarrow> t \<triangleleft> s1 = t \<triangleleft> s2"
   100 lemma eqv_dest[dest]: "s1 \<doteq> s2 \<Longrightarrow> t \<lhd> s1 = t \<lhd> s2"
   101   by (auto simp:eqv_def)
   101   by (auto simp:subst_eq_def)
   102 
   102 
   103 lemma compose_eqv: "\<lbrakk>\<sigma> =\<^sub>s \<sigma>'; \<theta> =\<^sub>s \<theta>'\<rbrakk> \<Longrightarrow> (\<sigma> \<bullet> \<theta>) =\<^sub>s (\<sigma>' \<bullet> \<theta>')"
   103 lemma compose_eqv: "\<lbrakk>\<sigma> \<doteq> \<sigma>'; \<theta> \<doteq> \<theta>'\<rbrakk> \<Longrightarrow> (\<sigma> \<lozenge> \<theta>) \<doteq> (\<sigma>' \<lozenge> \<theta>')"
   104   by (auto simp:eqv_def)
   104   by (auto simp:subst_eq_def)
   105 
   105 
   106 lemma compose_assoc: "(a \<bullet> b) \<bullet> c =\<^sub>s a \<bullet> (b \<bullet> c)"
   106 lemma compose_assoc: "(a \<lozenge> b) \<lozenge> c \<doteq> a \<lozenge> (b \<lozenge> c)"
   107   by auto
   107   by auto
   108 
   108 
   109 
   109 
   110 subsection {* Specification: Most general unifiers *}
   110 subsection {* Specification: Most general unifiers *}
   111 
   111 
   112 definition
   112 definition
   113   "Unifier \<sigma> t u \<equiv> (t\<triangleleft>\<sigma> = u\<triangleleft>\<sigma>)"
   113   "Unifier \<sigma> t u \<equiv> (t\<lhd>\<sigma> = u\<lhd>\<sigma>)"
   114 
   114 
   115 definition
   115 definition
   116   "MGU \<sigma> t u \<equiv> Unifier \<sigma> t u \<and> (\<forall>\<theta>. Unifier \<theta> t u 
   116   "MGU \<sigma> t u \<equiv> Unifier \<sigma> t u \<and> (\<forall>\<theta>. Unifier \<theta> t u 
   117   \<longrightarrow> (\<exists>\<gamma>. \<theta> =\<^sub>s \<sigma> \<bullet> \<gamma>))"
   117   \<longrightarrow> (\<exists>\<gamma>. \<theta> \<doteq> \<sigma> \<lozenge> \<gamma>))"
   118 
   118 
   119 lemma MGUI[intro]:
   119 lemma MGUI[intro]:
   120   "\<lbrakk>t \<triangleleft> \<sigma> = u \<triangleleft> \<sigma>; \<And>\<theta>. t \<triangleleft> \<theta> = u \<triangleleft> \<theta> \<Longrightarrow> \<exists>\<gamma>. \<theta> =\<^sub>s \<sigma> \<bullet> \<gamma>\<rbrakk>
   120   "\<lbrakk>t \<lhd> \<sigma> = u \<lhd> \<sigma>; \<And>\<theta>. t \<lhd> \<theta> = u \<lhd> \<theta> \<Longrightarrow> \<exists>\<gamma>. \<theta> \<doteq> \<sigma> \<lozenge> \<gamma>\<rbrakk>
   121   \<Longrightarrow> MGU \<sigma> t u"
   121   \<Longrightarrow> MGU \<sigma> t u"
   122   by (simp only:Unifier_def MGU_def, auto)
   122   by (simp only:Unifier_def MGU_def, auto)
   123 
   123 
   124 lemma MGU_sym[sym]:
   124 lemma MGU_sym[sym]:
   125   "MGU \<sigma> s t \<Longrightarrow> MGU \<sigma> t s"
   125   "MGU \<sigma> s t \<Longrightarrow> MGU \<sigma> t s"
   128 
   128 
   129 subsection {* The unification algorithm *}
   129 subsection {* The unification algorithm *}
   130 
   130 
   131 text {* Occurs check: Proper subterm relation *}
   131 text {* Occurs check: Proper subterm relation *}
   132 
   132 
   133 fun occ :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> bool"
   133 fun occs :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> bool" (infixl "<:" 54) 
   134 where
   134 where
   135   "occ u (Var v) = False"
   135   "occs u (Var v) = False"
   136 | "occ u (Const c) = False"
   136 | "occs u (Const c) = False"
   137 | "occ u (M \<cdot> N) = (u = M \<or> u = N \<or> occ u M \<or> occ u N)"
   137 | "occs u (M \<cdot> N) = (u = M \<or> u = N \<or> occs u M \<or> occs u N)"
   138 
   138 
   139 text {* The unification algorithm: *}
   139 text {* The unification algorithm: *}
   140 
   140 
   141 function unify :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> 'a subst option"
   141 function unify :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> 'a subst option"
   142 where
   142 where
   143   "unify (Const c) (M \<cdot> N)   = None"
   143   "unify (Const c) (M \<cdot> N)   = None"
   144 | "unify (M \<cdot> N)   (Const c) = None"
   144 | "unify (M \<cdot> N)   (Const c) = None"
   145 | "unify (Const c) (Var v)   = Some [(v, Const c)]"
   145 | "unify (Const c) (Var v)   = Some [(v, Const c)]"
   146 | "unify (M \<cdot> N)   (Var v)   = (if (occ (Var v) (M \<cdot> N)) 
   146 | "unify (M \<cdot> N)   (Var v)   = (if (occs (Var v) (M \<cdot> N)) 
   147                                         then None
   147                                         then None
   148                                         else Some [(v, M \<cdot> N)])"
   148                                         else Some [(v, M \<cdot> N)])"
   149 | "unify (Var v)   M         = (if (occ (Var v) M) 
   149 | "unify (Var v)   M         = (if (occs (Var v) M) 
   150                                         then None
   150                                         then None
   151                                         else Some [(v, M)])"
   151                                         else Some [(v, M)])"
   152 | "unify (Const c) (Const d) = (if c=d then Some [] else None)"
   152 | "unify (Const c) (Const d) = (if c=d then Some [] else None)"
   153 | "unify (M \<cdot> N) (M' \<cdot> N') = (case unify M M' of
   153 | "unify (M \<cdot> N) (M' \<cdot> N') = (case unify M M' of
   154                                     None \<Rightarrow> None |
   154                                     None \<Rightarrow> None |
   155                                     Some \<theta> \<Rightarrow> (case unify (N \<triangleleft> \<theta>) (N' \<triangleleft> \<theta>)
   155                                     Some \<theta> \<Rightarrow> (case unify (N \<lhd> \<theta>) (N' \<lhd> \<theta>)
   156                                       of None \<Rightarrow> None |
   156                                       of None \<Rightarrow> None |
   157                                          Some \<sigma> \<Rightarrow> Some (\<theta> \<bullet> \<sigma>)))"
   157                                          Some \<sigma> \<Rightarrow> Some (\<theta> \<lozenge> \<sigma>)))"
   158   by pat_completeness auto
   158   by pat_completeness auto
   159 
   159 
   160 declare unify.psimps[simp]
   160 declare unify.psimps[simp]
   161 
   161 
   162 subsection {* Partial correctness *}
   162 subsection {* Partial correctness *}
   163 
   163 
   164 text {* Some lemmas about occ and MGU: *}
   164 text {* Some lemmas about occs and MGU: *}
   165 
   165 
   166 lemma subst_no_occ: "\<not>occ (Var v) t \<Longrightarrow> Var v \<noteq> t
   166 lemma subst_no_occs: "\<not>occs (Var v) t \<Longrightarrow> Var v \<noteq> t
   167   \<Longrightarrow> t \<triangleleft> [(v,s)] = t"
   167   \<Longrightarrow> t \<lhd> [(v,s)] = t"
   168 by (induct t) auto
   168 by (induct t) auto
   169 
   169 
   170 lemma MGU_Var[intro]: 
   170 lemma MGU_Var[intro]: 
   171   assumes no_occ: "\<not>occ (Var v) t"
   171   assumes no_occs: "\<not>occs (Var v) t"
   172   shows "MGU [(v,t)] (Var v) t"
   172   shows "MGU [(v,t)] (Var v) t"
   173 proof (intro MGUI exI)
   173 proof (intro MGUI exI)
   174   show "Var v \<triangleleft> [(v,t)] = t \<triangleleft> [(v,t)]" using no_occ
   174   show "Var v \<lhd> [(v,t)] = t \<lhd> [(v,t)]" using no_occs
   175     by (cases "Var v = t", auto simp:subst_no_occ)
   175     by (cases "Var v = t", auto simp:subst_no_occs)
   176 next
   176 next
   177   fix \<theta> assume th: "Var v \<triangleleft> \<theta> = t \<triangleleft> \<theta>" 
   177   fix \<theta> assume th: "Var v \<lhd> \<theta> = t \<lhd> \<theta>" 
   178   show "\<theta> =\<^sub>s [(v,t)] \<bullet> \<theta>" 
   178   show "\<theta> \<doteq> [(v,t)] \<lozenge> \<theta>" 
   179   proof
   179   proof
   180     fix s show "s \<triangleleft> \<theta> = s \<triangleleft> [(v,t)] \<bullet> \<theta>" using th 
   180     fix s show "s \<lhd> \<theta> = s \<lhd> [(v,t)] \<lozenge> \<theta>" using th 
   181       by (induct s) auto
   181       by (induct s) auto
   182   qed
   182   qed
   183 qed
   183 qed
   184 
   184 
   185 declare MGU_Var[symmetric, intro]
   185 declare MGU_Var[symmetric, intro]
   198 proof (induct M N arbitrary: \<sigma>)
   198 proof (induct M N arbitrary: \<sigma>)
   199   case (7 M N M' N' \<sigma>) -- "The interesting case"
   199   case (7 M N M' N' \<sigma>) -- "The interesting case"
   200 
   200 
   201   then obtain \<theta>1 \<theta>2 
   201   then obtain \<theta>1 \<theta>2 
   202     where "unify M M' = Some \<theta>1"
   202     where "unify M M' = Some \<theta>1"
   203     and "unify (N \<triangleleft> \<theta>1) (N' \<triangleleft> \<theta>1) = Some \<theta>2"
   203     and "unify (N \<lhd> \<theta>1) (N' \<lhd> \<theta>1) = Some \<theta>2"
   204     and \<sigma>: "\<sigma> = \<theta>1 \<bullet> \<theta>2"
   204     and \<sigma>: "\<sigma> = \<theta>1 \<lozenge> \<theta>2"
   205     and MGU_inner: "MGU \<theta>1 M M'" 
   205     and MGU_inner: "MGU \<theta>1 M M'" 
   206     and MGU_outer: "MGU \<theta>2 (N \<triangleleft> \<theta>1) (N' \<triangleleft> \<theta>1)"
   206     and MGU_outer: "MGU \<theta>2 (N \<lhd> \<theta>1) (N' \<lhd> \<theta>1)"
   207     by (auto split:option.split_asm)
   207     by (auto split:option.split_asm)
   208 
   208 
   209   show ?case
   209   show ?case
   210   proof
   210   proof
   211     from MGU_inner and MGU_outer
   211     from MGU_inner and MGU_outer
   212     have "M \<triangleleft> \<theta>1 = M' \<triangleleft> \<theta>1" 
   212     have "M \<lhd> \<theta>1 = M' \<lhd> \<theta>1" 
   213       and "N \<triangleleft> \<theta>1 \<triangleleft> \<theta>2 = N' \<triangleleft> \<theta>1 \<triangleleft> \<theta>2"
   213       and "N \<lhd> \<theta>1 \<lhd> \<theta>2 = N' \<lhd> \<theta>1 \<lhd> \<theta>2"
   214       unfolding MGU_def Unifier_def
   214       unfolding MGU_def Unifier_def
   215       by auto
   215       by auto
   216     thus "M \<cdot> N \<triangleleft> \<sigma> = M' \<cdot> N' \<triangleleft> \<sigma>" unfolding \<sigma>
   216     thus "M \<cdot> N \<lhd> \<sigma> = M' \<cdot> N' \<lhd> \<sigma>" unfolding \<sigma>
   217       by simp
   217       by simp
   218   next
   218   next
   219     fix \<sigma>' assume "M \<cdot> N \<triangleleft> \<sigma>' = M' \<cdot> N' \<triangleleft> \<sigma>'"
   219     fix \<sigma>' assume "M \<cdot> N \<lhd> \<sigma>' = M' \<cdot> N' \<lhd> \<sigma>'"
   220     hence "M \<triangleleft> \<sigma>' = M' \<triangleleft> \<sigma>'"
   220     hence "M \<lhd> \<sigma>' = M' \<lhd> \<sigma>'"
   221       and Ns: "N \<triangleleft> \<sigma>' = N' \<triangleleft> \<sigma>'" by auto
   221       and Ns: "N \<lhd> \<sigma>' = N' \<lhd> \<sigma>'" by auto
   222 
   222 
   223     with MGU_inner obtain \<delta>
   223     with MGU_inner obtain \<delta>
   224       where eqv: "\<sigma>' =\<^sub>s \<theta>1 \<bullet> \<delta>"
   224       where eqv: "\<sigma>' \<doteq> \<theta>1 \<lozenge> \<delta>"
   225       unfolding MGU_def Unifier_def
   225       unfolding MGU_def Unifier_def
   226       by auto
   226       by auto
   227 
   227 
   228     from Ns have "N \<triangleleft> \<theta>1 \<triangleleft> \<delta> = N' \<triangleleft> \<theta>1 \<triangleleft> \<delta>"
   228     from Ns have "N \<lhd> \<theta>1 \<lhd> \<delta> = N' \<lhd> \<theta>1 \<lhd> \<delta>"
   229       by (simp add:eqv_dest[OF eqv])
   229       by (simp add:eqv_dest[OF eqv])
   230 
   230 
   231     with MGU_outer obtain \<rho>
   231     with MGU_outer obtain \<rho>
   232       where eqv2: "\<delta> =\<^sub>s \<theta>2 \<bullet> \<rho>"
   232       where eqv2: "\<delta> \<doteq> \<theta>2 \<lozenge> \<rho>"
   233       unfolding MGU_def Unifier_def
   233       unfolding MGU_def Unifier_def
   234       by auto
   234       by auto
   235     
   235     
   236     have "\<sigma>' =\<^sub>s \<sigma> \<bullet> \<rho>" unfolding \<sigma>
   236     have "\<sigma>' \<doteq> \<sigma> \<lozenge> \<rho>" unfolding \<sigma>
   237       by (rule eqv_intro, auto simp:eqv_dest[OF eqv] eqv_dest[OF eqv2])
   237       by (rule eqv_intro, auto simp:eqv_dest[OF eqv] eqv_dest[OF eqv2])
   238     thus "\<exists>\<gamma>. \<sigma>' =\<^sub>s \<sigma> \<bullet> \<gamma>" ..
   238     thus "\<exists>\<gamma>. \<sigma>' \<doteq> \<sigma> \<lozenge> \<gamma>" ..
   239   qed
   239   qed
   240 qed (auto split:split_if_asm) -- "Solve the remaining cases automatically"
   240 qed (auto split:split_if_asm) -- "Solve the remaining cases automatically"
   241 
   241 
   242 
   242 
   243 subsection {* Properties used in termination proof *}
   243 subsection {* Properties used in termination proof *}
   254   by (induct t) simp_all
   254   by (induct t) simp_all
   255 
   255 
   256 text {* Elimination of variables by a substitution: *}
   256 text {* Elimination of variables by a substitution: *}
   257 
   257 
   258 definition
   258 definition
   259   "elim \<sigma> v \<equiv> \<forall>t. v \<notin> vars_of (t \<triangleleft> \<sigma>)"
   259   "elim \<sigma> v \<equiv> \<forall>t. v \<notin> vars_of (t \<lhd> \<sigma>)"
   260 
   260 
   261 lemma elim_intro[intro]: "(\<And>t. v \<notin> vars_of (t \<triangleleft> \<sigma>)) \<Longrightarrow> elim \<sigma> v"
   261 lemma elim_intro[intro]: "(\<And>t. v \<notin> vars_of (t \<lhd> \<sigma>)) \<Longrightarrow> elim \<sigma> v"
   262   by (auto simp:elim_def)
   262   by (auto simp:elim_def)
   263 
   263 
   264 lemma elim_dest[dest]: "elim \<sigma> v \<Longrightarrow> v \<notin> vars_of (t \<triangleleft> \<sigma>)"
   264 lemma elim_dest[dest]: "elim \<sigma> v \<Longrightarrow> v \<notin> vars_of (t \<lhd> \<sigma>)"
   265   by (auto simp:elim_def)
   265   by (auto simp:elim_def)
   266 
   266 
   267 lemma elim_eqv: "\<sigma> =\<^sub>s \<theta> \<Longrightarrow> elim \<sigma> x = elim \<theta> x"
   267 lemma elim_eqv: "\<sigma> \<doteq> \<theta> \<Longrightarrow> elim \<sigma> x = elim \<theta> x"
   268   by (auto simp:elim_def eqv_def)
   268   by (auto simp:elim_def subst_eq_def)
   269 
   269 
   270 
   270 
   271 text {* Replacing a variable by itself yields an identity subtitution: *}
   271 text {* Replacing a variable by itself yields an identity subtitution: *}
   272 
   272 
   273 lemma var_self[intro]: "[(v, Var v)] =\<^sub>s []"
   273 lemma var_self[intro]: "[(v, Var v)] \<doteq> []"
   274 proof
   274 proof
   275   fix t show "t \<triangleleft> [(v, Var v)] = t \<triangleleft> []"
   275   fix t show "t \<lhd> [(v, Var v)] = t \<lhd> []"
   276     by (induct t) simp_all
   276     by (induct t) simp_all
   277 qed
   277 qed
   278 
   278 
   279 lemma var_same: "([(v, t)] =\<^sub>s []) = (t = Var v)"
   279 lemma var_same: "([(v, t)] \<doteq> []) = (t = Var v)"
   280 proof
   280 proof
   281   assume t_v: "t = Var v"
   281   assume t_v: "t = Var v"
   282   thus "[(v, t)] =\<^sub>s []"
   282   thus "[(v, t)] \<doteq> []"
   283     by auto
   283     by auto
   284 next
   284 next
   285   assume id: "[(v, t)] =\<^sub>s []"
   285   assume id: "[(v, t)] \<doteq> []"
   286   show "t = Var v"
   286   show "t = Var v"
   287   proof -
   287   proof -
   288     have "t = Var v \<triangleleft> [(v, t)]" by simp
   288     have "t = Var v \<lhd> [(v, t)]" by simp
   289     also from id have "\<dots> = Var v \<triangleleft> []" ..
   289     also from id have "\<dots> = Var v \<lhd> []" ..
   290     finally show ?thesis by simp
   290     finally show ?thesis by simp
   291   qed
   291   qed
   292 qed
   292 qed
   293 
   293 
   294 text {* A lemma about occ and elim *}
   294 text {* A lemma about occs and elim *}
   295 
   295 
   296 lemma remove_var:
   296 lemma remove_var:
   297   assumes [simp]: "v \<notin> vars_of s"
   297   assumes [simp]: "v \<notin> vars_of s"
   298   shows "v \<notin> vars_of (t \<triangleleft> [(v, s)])"
   298   shows "v \<notin> vars_of (t \<lhd> [(v, s)])"
   299   by (induct t) simp_all
   299   by (induct t) simp_all
   300 
   300 
   301 lemma occ_elim: "\<not>occ (Var v) t 
   301 lemma occs_elim: "\<not>occs (Var v) t 
   302   \<Longrightarrow> elim [(v,t)] v \<or> [(v,t)] =\<^sub>s []"
   302   \<Longrightarrow> elim [(v,t)] v \<or> [(v,t)] \<doteq> []"
   303 proof (induct t)
   303 proof (induct t)
   304   case (Var x)
   304   case (Var x)
   305   show ?case
   305   show ?case
   306   proof cases
   306   proof cases
   307     assume "v = x"
   307     assume "v = x"
   317   case (Const c)
   317   case (Const c)
   318   have "elim [(v, Const c)] v"
   318   have "elim [(v, Const c)] v"
   319     by (auto intro!:remove_var)
   319     by (auto intro!:remove_var)
   320   thus ?case ..
   320   thus ?case ..
   321 next
   321 next
   322   case (App M N)
   322   case (Comb M N)
   323   
   323   
   324   hence ih1: "elim [(v, M)] v \<or> [(v, M)] =\<^sub>s []"
   324   hence ih1: "elim [(v, M)] v \<or> [(v, M)] \<doteq> []"
   325     and ih2: "elim [(v, N)] v \<or> [(v, N)] =\<^sub>s []"
   325     and ih2: "elim [(v, N)] v \<or> [(v, N)] \<doteq> []"
   326     and nonocc: "Var v \<noteq> M" "Var v \<noteq> N"
   326     and nonoccs: "Var v \<noteq> M" "Var v \<noteq> N"
   327     by auto
   327     by auto
   328 
   328 
   329   from nonocc have "\<not> [(v,M)] =\<^sub>s []"
   329   from nonoccs have "\<not> [(v,M)] \<doteq> []"
   330     by (simp add:var_same)
   330     by (simp add:var_same)
   331   with ih1 have "elim [(v, M)] v" by blast
   331   with ih1 have "elim [(v, M)] v" by blast
   332   hence "v \<notin> vars_of (Var v \<triangleleft> [(v,M)])" ..
   332   hence "v \<notin> vars_of (Var v \<lhd> [(v,M)])" ..
   333   hence not_in_M: "v \<notin> vars_of M" by simp
   333   hence not_in_M: "v \<notin> vars_of M" by simp
   334 
   334 
   335   from nonocc have "\<not> [(v,N)] =\<^sub>s []"
   335   from nonoccs have "\<not> [(v,N)] \<doteq> []"
   336     by (simp add:var_same)
   336     by (simp add:var_same)
   337   with ih2 have "elim [(v, N)] v" by blast
   337   with ih2 have "elim [(v, N)] v" by blast
   338   hence "v \<notin> vars_of (Var v \<triangleleft> [(v,N)])" ..
   338   hence "v \<notin> vars_of (Var v \<lhd> [(v,N)])" ..
   339   hence not_in_N: "v \<notin> vars_of N" by simp
   339   hence not_in_N: "v \<notin> vars_of N" by simp
   340 
   340 
   341   have "elim [(v, M \<cdot> N)] v"
   341   have "elim [(v, M \<cdot> N)] v"
   342   proof 
   342   proof 
   343     fix t 
   343     fix t 
   344     show "v \<notin> vars_of (t \<triangleleft> [(v, M \<cdot> N)])"
   344     show "v \<notin> vars_of (t \<lhd> [(v, M \<cdot> N)])"
   345     proof (induct t)
   345     proof (induct t)
   346       case (Var x) thus ?case by (simp add: not_in_M not_in_N)
   346       case (Var x) thus ?case by (simp add: not_in_M not_in_N)
   347     qed auto
   347     qed auto
   348   qed
   348   qed
   349   thus ?case ..
   349   thus ?case ..
   352 text {* The result of a unification never introduces new variables: *}
   352 text {* The result of a unification never introduces new variables: *}
   353 
   353 
   354 lemma unify_vars: 
   354 lemma unify_vars: 
   355   assumes "unify_dom (M, N)"
   355   assumes "unify_dom (M, N)"
   356   assumes "unify M N = Some \<sigma>"
   356   assumes "unify M N = Some \<sigma>"
   357   shows "vars_of (t \<triangleleft> \<sigma>) \<subseteq> vars_of M \<union> vars_of N \<union> vars_of t"
   357   shows "vars_of (t \<lhd> \<sigma>) \<subseteq> vars_of M \<union> vars_of N \<union> vars_of t"
   358   (is "?P M N \<sigma> t")
   358   (is "?P M N \<sigma> t")
   359 using assms
   359 using assms
   360 proof (induct M N arbitrary:\<sigma> t)
   360 proof (induct M N arbitrary:\<sigma> t)
   361   case (3 c v) 
   361   case (3 c v) 
   362   hence "\<sigma> = [(v, Const c)]" by simp
   362   hence "\<sigma> = [(v, Const c)]" by simp
   363   thus ?case by (induct t) auto
   363   thus ?case by (induct t) auto
   364 next
   364 next
   365   case (4 M N v) 
   365   case (4 M N v) 
   366   hence "\<not>occ (Var v) (M\<cdot>N)" by (cases "occ (Var v) (M\<cdot>N)", auto)
   366   hence "\<not>occs (Var v) (M\<cdot>N)" by (cases "occs (Var v) (M\<cdot>N)", auto)
   367   with 4 have "\<sigma> = [(v, M\<cdot>N)]" by simp
   367   with 4 have "\<sigma> = [(v, M\<cdot>N)]" by simp
   368   thus ?case by (induct t) auto
   368   thus ?case by (induct t) auto
   369 next
   369 next
   370   case (5 v M)
   370   case (5 v M)
   371   hence "\<not>occ (Var v) M" by (cases "occ (Var v) M", auto)
   371   hence "\<not>occs (Var v) M" by (cases "occs (Var v) M", auto)
   372   with 5 have "\<sigma> = [(v, M)]" by simp
   372   with 5 have "\<sigma> = [(v, M)]" by simp
   373   thus ?case by (induct t) auto
   373   thus ?case by (induct t) auto
   374 next
   374 next
   375   case (7 M N M' N' \<sigma>)
   375   case (7 M N M' N' \<sigma>)
   376   then obtain \<theta>1 \<theta>2 
   376   then obtain \<theta>1 \<theta>2 
   377     where "unify M M' = Some \<theta>1"
   377     where "unify M M' = Some \<theta>1"
   378     and "unify (N \<triangleleft> \<theta>1) (N' \<triangleleft> \<theta>1) = Some \<theta>2"
   378     and "unify (N \<lhd> \<theta>1) (N' \<lhd> \<theta>1) = Some \<theta>2"
   379     and \<sigma>: "\<sigma> = \<theta>1 \<bullet> \<theta>2"
   379     and \<sigma>: "\<sigma> = \<theta>1 \<lozenge> \<theta>2"
   380     and ih1: "\<And>t. ?P M M' \<theta>1 t"
   380     and ih1: "\<And>t. ?P M M' \<theta>1 t"
   381     and ih2: "\<And>t. ?P (N\<triangleleft>\<theta>1) (N'\<triangleleft>\<theta>1) \<theta>2 t"
   381     and ih2: "\<And>t. ?P (N\<lhd>\<theta>1) (N'\<lhd>\<theta>1) \<theta>2 t"
   382     by (auto split:option.split_asm)
   382     by (auto split:option.split_asm)
   383 
   383 
   384   show ?case
   384   show ?case
   385   proof
   385   proof
   386     fix v assume a: "v \<in> vars_of (t \<triangleleft> \<sigma>)"
   386     fix v assume a: "v \<in> vars_of (t \<lhd> \<sigma>)"
   387     
   387     
   388     show "v \<in> vars_of (M \<cdot> N) \<union> vars_of (M' \<cdot> N') \<union> vars_of t"
   388     show "v \<in> vars_of (M \<cdot> N) \<union> vars_of (M' \<cdot> N') \<union> vars_of t"
   389     proof (cases "v \<notin> vars_of M \<and> v \<notin> vars_of M'
   389     proof (cases "v \<notin> vars_of M \<and> v \<notin> vars_of M'
   390         \<and> v \<notin> vars_of N \<and> v \<notin> vars_of N'")
   390         \<and> v \<notin> vars_of N \<and> v \<notin> vars_of N'")
   391       case True
   391       case True
   392       with ih1 have l:"\<And>t. v \<in> vars_of (t \<triangleleft> \<theta>1) \<Longrightarrow> v \<in> vars_of t"
   392       with ih1 have l:"\<And>t. v \<in> vars_of (t \<lhd> \<theta>1) \<Longrightarrow> v \<in> vars_of t"
   393         by auto
   393         by auto
   394       
   394       
   395       from a and ih2[where t="t \<triangleleft> \<theta>1"]
   395       from a and ih2[where t="t \<lhd> \<theta>1"]
   396       have "v \<in> vars_of (N \<triangleleft> \<theta>1) \<union> vars_of (N' \<triangleleft> \<theta>1) 
   396       have "v \<in> vars_of (N \<lhd> \<theta>1) \<union> vars_of (N' \<lhd> \<theta>1) 
   397         \<or> v \<in> vars_of (t \<triangleleft> \<theta>1)" unfolding \<sigma>
   397         \<or> v \<in> vars_of (t \<lhd> \<theta>1)" unfolding \<sigma>
   398         by auto
   398         by auto
   399       hence "v \<in> vars_of t"
   399       hence "v \<in> vars_of t"
   400       proof
   400       proof
   401         assume "v \<in> vars_of (N \<triangleleft> \<theta>1) \<union> vars_of (N' \<triangleleft> \<theta>1)"
   401         assume "v \<in> vars_of (N \<lhd> \<theta>1) \<union> vars_of (N' \<lhd> \<theta>1)"
   402         with True show ?thesis by (auto dest:l)
   402         with True show ?thesis by (auto dest:l)
   403       next
   403       next
   404         assume "v \<in> vars_of (t \<triangleleft> \<theta>1)" 
   404         assume "v \<in> vars_of (t \<lhd> \<theta>1)" 
   405         thus ?thesis by (rule l)
   405         thus ?thesis by (rule l)
   406       qed
   406       qed
   407       
   407       
   408       thus ?thesis by auto
   408       thus ?thesis by auto
   409     qed auto
   409     qed auto
   415 substitution or it eliminates a variable from one of the terms: *}
   415 substitution or it eliminates a variable from one of the terms: *}
   416 
   416 
   417 lemma unify_eliminates: 
   417 lemma unify_eliminates: 
   418   assumes "unify_dom (M, N)"
   418   assumes "unify_dom (M, N)"
   419   assumes "unify M N = Some \<sigma>"
   419   assumes "unify M N = Some \<sigma>"
   420   shows "(\<exists>v\<in>vars_of M \<union> vars_of N. elim \<sigma> v) \<or> \<sigma> =\<^sub>s []"
   420   shows "(\<exists>v\<in>vars_of M \<union> vars_of N. elim \<sigma> v) \<or> \<sigma> \<doteq> []"
   421   (is "?P M N \<sigma>")
   421   (is "?P M N \<sigma>")
   422 using assms
   422 using assms
   423 proof (induct M N arbitrary:\<sigma>)
   423 proof (induct M N arbitrary:\<sigma>)
   424   case 1 thus ?case by simp
   424   case 1 thus ?case by simp
   425 next
   425 next
   426   case 2 thus ?case by simp
   426   case 2 thus ?case by simp
   427 next
   427 next
   428   case (3 c v)
   428   case (3 c v)
   429   have no_occ: "\<not> occ (Var v) (Const c)" by simp
   429   have no_occs: "\<not> occs (Var v) (Const c)" by simp
   430   with 3 have "\<sigma> = [(v, Const c)]" by simp
   430   with 3 have "\<sigma> = [(v, Const c)]" by simp
   431   with occ_elim[OF no_occ]
   431   with occs_elim[OF no_occs]
   432   show ?case by auto
   432   show ?case by auto
   433 next
   433 next
   434   case (4 M N v)
   434   case (4 M N v)
   435   hence no_occ: "\<not>occ (Var v) (M\<cdot>N)" by (cases "occ (Var v) (M\<cdot>N)", auto)
   435   hence no_occs: "\<not>occs (Var v) (M\<cdot>N)" by (cases "occs (Var v) (M\<cdot>N)", auto)
   436   with 4 have "\<sigma> = [(v, M\<cdot>N)]" by simp
   436   with 4 have "\<sigma> = [(v, M\<cdot>N)]" by simp
   437   with occ_elim[OF no_occ]
   437   with occs_elim[OF no_occs]
   438   show ?case by auto 
   438   show ?case by auto 
   439 next
   439 next
   440   case (5 v M) 
   440   case (5 v M) 
   441   hence no_occ: "\<not>occ (Var v) M" by (cases "occ (Var v) M", auto)
   441   hence no_occs: "\<not>occs (Var v) M" by (cases "occs (Var v) M", auto)
   442   with 5 have "\<sigma> = [(v, M)]" by simp
   442   with 5 have "\<sigma> = [(v, M)]" by simp
   443   with occ_elim[OF no_occ]
   443   with occs_elim[OF no_occs]
   444   show ?case by auto 
   444   show ?case by auto 
   445 next 
   445 next 
   446   case (6 c d) thus ?case
   446   case (6 c d) thus ?case
   447     by (cases "c = d") auto
   447     by (cases "c = d") auto
   448 next
   448 next
   449   case (7 M N M' N' \<sigma>)
   449   case (7 M N M' N' \<sigma>)
   450   then obtain \<theta>1 \<theta>2 
   450   then obtain \<theta>1 \<theta>2 
   451     where "unify M M' = Some \<theta>1"
   451     where "unify M M' = Some \<theta>1"
   452     and "unify (N \<triangleleft> \<theta>1) (N' \<triangleleft> \<theta>1) = Some \<theta>2"
   452     and "unify (N \<lhd> \<theta>1) (N' \<lhd> \<theta>1) = Some \<theta>2"
   453     and \<sigma>: "\<sigma> = \<theta>1 \<bullet> \<theta>2"
   453     and \<sigma>: "\<sigma> = \<theta>1 \<lozenge> \<theta>2"
   454     and ih1: "?P M M' \<theta>1"
   454     and ih1: "?P M M' \<theta>1"
   455     and ih2: "?P (N\<triangleleft>\<theta>1) (N'\<triangleleft>\<theta>1) \<theta>2"
   455     and ih2: "?P (N\<lhd>\<theta>1) (N'\<lhd>\<theta>1) \<theta>2"
   456     by (auto split:option.split_asm)
   456     by (auto split:option.split_asm)
   457 
   457 
   458   from `unify_dom (M \<cdot> N, M' \<cdot> N')`
   458   from `unify_dom (M \<cdot> N, M' \<cdot> N')`
   459   have "unify_dom (M, M')"
   459   have "unify_dom (M, M')"
   460     by (rule accp_downward) (rule unify_rel.intros)
   460     by (rule accp_downward) (rule unify_rel.intros)
   461   hence no_new_vars: 
   461   hence no_new_vars: 
   462     "\<And>t. vars_of (t \<triangleleft> \<theta>1) \<subseteq> vars_of M \<union> vars_of M' \<union> vars_of t"
   462     "\<And>t. vars_of (t \<lhd> \<theta>1) \<subseteq> vars_of M \<union> vars_of M' \<union> vars_of t"
   463     by (rule unify_vars) (rule `unify M M' = Some \<theta>1`)
   463     by (rule unify_vars) (rule `unify M M' = Some \<theta>1`)
   464 
   464 
   465   from ih2 show ?case 
   465   from ih2 show ?case 
   466   proof 
   466   proof 
   467     assume "\<exists>v\<in>vars_of (N \<triangleleft> \<theta>1) \<union> vars_of (N' \<triangleleft> \<theta>1). elim \<theta>2 v"
   467     assume "\<exists>v\<in>vars_of (N \<lhd> \<theta>1) \<union> vars_of (N' \<lhd> \<theta>1). elim \<theta>2 v"
   468     then obtain v 
   468     then obtain v 
   469       where "v\<in>vars_of (N \<triangleleft> \<theta>1) \<union> vars_of (N' \<triangleleft> \<theta>1)"
   469       where "v\<in>vars_of (N \<lhd> \<theta>1) \<union> vars_of (N' \<lhd> \<theta>1)"
   470       and el: "elim \<theta>2 v" by auto
   470       and el: "elim \<theta>2 v" by auto
   471     with no_new_vars show ?thesis unfolding \<sigma> 
   471     with no_new_vars show ?thesis unfolding \<sigma> 
   472       by (auto simp:elim_def)
   472       by (auto simp:elim_def)
   473   next
   473   next
   474     assume empty[simp]: "\<theta>2 =\<^sub>s []"
   474     assume empty[simp]: "\<theta>2 \<doteq> []"
   475 
   475 
   476     have "\<sigma> =\<^sub>s (\<theta>1 \<bullet> [])" unfolding \<sigma>
   476     have "\<sigma> \<doteq> (\<theta>1 \<lozenge> [])" unfolding \<sigma>
   477       by (rule compose_eqv) auto
   477       by (rule compose_eqv) auto
   478     also have "\<dots> =\<^sub>s \<theta>1" by auto
   478     also have "\<dots> \<doteq> \<theta>1" by auto
   479     finally have "\<sigma> =\<^sub>s \<theta>1" .
   479     finally have "\<sigma> \<doteq> \<theta>1" .
   480 
   480 
   481     from ih1 show ?thesis
   481     from ih1 show ?thesis
   482     proof
   482     proof
   483       assume "\<exists>v\<in>vars_of M \<union> vars_of M'. elim \<theta>1 v"
   483       assume "\<exists>v\<in>vars_of M \<union> vars_of M'. elim \<theta>1 v"
   484       with elim_eqv[OF `\<sigma> =\<^sub>s \<theta>1`]
   484       with elim_eqv[OF `\<sigma> \<doteq> \<theta>1`]
   485       show ?thesis by auto
   485       show ?thesis by auto
   486     next
   486     next
   487       note `\<sigma> =\<^sub>s \<theta>1`
   487       note `\<sigma> \<doteq> \<theta>1`
   488       also assume "\<theta>1 =\<^sub>s []"
   488       also assume "\<theta>1 \<doteq> []"
   489       finally show ?thesis ..
   489       finally show ?thesis ..
   490     qed
   490     qed
   491   qed
   491   qed
   492 qed
   492 qed
   493 
   493 
   507   fix \<theta>                                   -- "Outer call"
   507   fix \<theta>                                   -- "Outer call"
   508   assume inner: "unify_dom (M, M')"
   508   assume inner: "unify_dom (M, M')"
   509     "unify M M' = Some \<theta>"
   509     "unify M M' = Some \<theta>"
   510 
   510 
   511   from unify_eliminates[OF inner]
   511   from unify_eliminates[OF inner]
   512   show "((N \<triangleleft> \<theta>, N' \<triangleleft> \<theta>), (M \<cdot> N, M' \<cdot> N')) \<in>?R"
   512   show "((N \<lhd> \<theta>, N' \<lhd> \<theta>), (M \<cdot> N, M' \<cdot> N')) \<in>?R"
   513   proof
   513   proof
   514     -- {* Either a variable is eliminated \ldots *}
   514     -- {* Either a variable is eliminated \ldots *}
   515     assume "(\<exists>v\<in>vars_of M \<union> vars_of M'. elim \<theta> v)"
   515     assume "(\<exists>v\<in>vars_of M \<union> vars_of M'. elim \<theta> v)"
   516     then obtain v 
   516     then obtain v 
   517       where "elim \<theta> v" 
   517       where "elim \<theta> v" 
   518       and "v\<in>vars_of M \<union> vars_of M'" by auto
   518       and "v\<in>vars_of M \<union> vars_of M'" by auto
   519     with unify_vars[OF inner]
   519     with unify_vars[OF inner]
   520     have "vars_of (N\<triangleleft>\<theta>) \<union> vars_of (N'\<triangleleft>\<theta>)
   520     have "vars_of (N\<lhd>\<theta>) \<union> vars_of (N'\<lhd>\<theta>)
   521       \<subset> vars_of (M\<cdot>N) \<union> vars_of (M'\<cdot>N')"
   521       \<subset> vars_of (M\<cdot>N) \<union> vars_of (M'\<cdot>N')"
   522       by auto
   522       by auto
   523     
   523     
   524     thus ?thesis
   524     thus ?thesis
   525       by (auto intro!: measures_less intro: psubset_card_mono)
   525       by (auto intro!: measures_less intro: psubset_card_mono)
   526   next
   526   next
   527     -- {* Or the substitution is empty *}
   527     -- {* Or the substitution is empty *}
   528     assume "\<theta> =\<^sub>s []"
   528     assume "\<theta> \<doteq> []"
   529     hence "N \<triangleleft> \<theta> = N" 
   529     hence "N \<lhd> \<theta> = N" 
   530       and "N' \<triangleleft> \<theta> = N'" by auto
   530       and "N' \<lhd> \<theta> = N'" by auto
   531     thus ?thesis 
   531     thus ?thesis 
   532        by (auto intro!: measures_less intro: psubset_card_mono)
   532        by (auto intro!: measures_less intro: psubset_card_mono)
   533   qed
   533   qed
   534 qed
   534 qed
   535 
   535