src/HOL/ex/Unification.thy
changeset 44368 91e8062605d5
parent 44367 74c08021ab2e
child 44369 02e13192a053
equal deleted inserted replaced
44367:74c08021ab2e 44368:91e8062605d5
    22   some partial correctness properties are intertwined, we can prove
    22   some partial correctness properties are intertwined, we can prove
    23   partial correctness and termination separately.
    23   partial correctness and termination separately.
    24 *}
    24 *}
    25 
    25 
    26 
    26 
    27 subsection {* Basic definitions *}
    27 subsection {* Terms *}
       
    28 
       
    29 text {* Binary trees with leaves that are constants or variables. *}
    28 
    30 
    29 datatype 'a trm = 
    31 datatype 'a trm = 
    30   Var 'a 
    32   Var 'a 
    31   | Const 'a
    33   | Const 'a
    32   | Comb "'a trm" "'a trm" (infix "\<cdot>" 60)
    34   | Comb "'a trm" "'a trm" (infix "\<cdot>" 60)
    33 
    35 
       
    36 primrec vars_of :: "'a trm \<Rightarrow> 'a set"
       
    37 where
       
    38   "vars_of (Var v) = {v}"
       
    39 | "vars_of (Const c) = {}"
       
    40 | "vars_of (M \<cdot> N) = vars_of M \<union> vars_of N"
       
    41 
       
    42 fun occs :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> bool" (infixl "\<prec>" 54) 
       
    43 where
       
    44   "occs u (Var v) = False"
       
    45 | "occs u (Const c) = False"
       
    46 | "occs u (M \<cdot> N) = (u = M \<or> u = N \<or> occs u M \<or> occs u N)"
       
    47 
       
    48 
       
    49 lemma finite_vars_of[intro]: "finite (vars_of t)"
       
    50   by (induct t) simp_all
       
    51 
       
    52 lemma vars_var_iff: "v \<in> vars_of (Var w) \<longleftrightarrow> w = v"
       
    53   by auto
       
    54 
       
    55 lemma vars_iff_occseq: "x \<in> vars_of t \<longleftrightarrow> Var x \<prec> t \<or> Var x = t"
       
    56   by (induct t) auto
       
    57 
       
    58 lemma occs_vars_subset: "M \<prec> N \<Longrightarrow> vars_of M \<subseteq> vars_of N"
       
    59   by (induct N) auto
       
    60 
       
    61 
       
    62 subsection {* Substitutions *}
       
    63 
    34 type_synonym 'a subst = "('a \<times> 'a trm) list"
    64 type_synonym 'a subst = "('a \<times> 'a trm) list"
    35 
    65 
    36 text {* Applying a substitution to a variable: *}
    66 text {* Applying a substitution to a variable: *}
    37 
    67 
    38 fun assoc :: "'a \<Rightarrow> 'b \<Rightarrow> ('a \<times> 'b) list \<Rightarrow> 'b"
    68 fun assoc :: "'a \<Rightarrow> 'b \<Rightarrow> ('a \<times> 'b) list \<Rightarrow> 'b"
    46 where
    76 where
    47   "(Var v) \<lhd> s = assoc v (Var v) s"
    77   "(Var v) \<lhd> s = assoc v (Var v) s"
    48 | "(Const c) \<lhd> s = (Const c)"
    78 | "(Const c) \<lhd> s = (Const c)"
    49 | "(M \<cdot> N) \<lhd> s = (M \<lhd> s) \<cdot> (N \<lhd> s)"
    79 | "(M \<cdot> N) \<lhd> s = (M \<lhd> s) \<cdot> (N \<lhd> s)"
    50 
    80 
    51 text {* Composition of substitutions: *}
    81 definition subst_eq (infixr "\<doteq>" 52)
    52 
    82 where
    53 fun
    83   "s1 \<doteq> s2 \<longleftrightarrow> (\<forall>t. t \<lhd> s1 = t \<lhd> s2)" 
    54   comp :: "'a subst \<Rightarrow> 'a subst \<Rightarrow> 'a subst" (infixl "\<lozenge>" 56)
    84 
       
    85 fun comp :: "'a subst \<Rightarrow> 'a subst \<Rightarrow> 'a subst" (infixl "\<lozenge>" 56)
    55 where
    86 where
    56   "[] \<lozenge> bl = bl"
    87   "[] \<lozenge> bl = bl"
    57 | "((a,b) # al) \<lozenge> bl = (a, b \<lhd> bl) # (al \<lozenge> bl)"
    88 | "((a,b) # al) \<lozenge> bl = (a, b \<lhd> bl) # (al \<lozenge> bl)"
    58 
    89 
    59 text {* Equivalence of substitutions: *}
    90 
    60 
    91 subsection {* Basic Laws *}
    61 definition subst_eq (infixr "\<doteq>" 52)
    92 
    62 where
    93 lemma subst_Nil[simp]: "t \<lhd> [] = t"
    63   "s1 \<doteq> s2 \<equiv> \<forall>t. t \<lhd> s1 = t \<lhd> s2" 
       
    64 
       
    65 
       
    66 subsection {* Basic lemmas *}
       
    67 
       
    68 lemma apply_empty[simp]: "t \<lhd> [] = t"
       
    69 by (induct t) auto
    94 by (induct t) auto
    70 
    95 
    71 lemma compose_empty[simp]: "\<sigma> \<lozenge> [] = \<sigma>"
    96 lemma subst_mono: "t \<prec> u \<Longrightarrow> t \<lhd> s \<prec> u \<lhd> s"
       
    97 by (induct u) auto
       
    98 
       
    99 lemma agreement: "(t \<lhd> r = t \<lhd> s) \<longleftrightarrow> (\<forall>v \<in> vars_of t. Var v \<lhd> r = Var v \<lhd> s)"
       
   100 by (induct t) auto
       
   101 
       
   102 lemma repl_invariance: "v \<notin> vars_of t \<Longrightarrow> t \<lhd> (v,u) # s = t \<lhd> s"
       
   103 by (simp add: agreement)
       
   104 
       
   105 lemma Var_in_subst:
       
   106   "v \<in> vars_of t \<Longrightarrow> w \<in> vars_of (t \<lhd> (v, Var(w)) # s)"
       
   107 by (induct t) auto
       
   108 
       
   109 lemma subst_refl[iff]: "s \<doteq> s"
       
   110   by (auto simp:subst_eq_def)
       
   111 
       
   112 lemma subst_sym[sym]: "\<lbrakk>s1 \<doteq> s2\<rbrakk> \<Longrightarrow> s2 \<doteq> s1"
       
   113   by (auto simp:subst_eq_def)
       
   114 
       
   115 lemma subst_trans[trans]: "\<lbrakk>s1 \<doteq> s2; s2 \<doteq> s3\<rbrakk> \<Longrightarrow> s1 \<doteq> s3"
       
   116   by (auto simp:subst_eq_def)
       
   117 
       
   118 text {* Composition of Substitutions *}
       
   119 
       
   120 
       
   121 lemma comp_Nil[simp]: "\<sigma> \<lozenge> [] = \<sigma>"
    72 by (induct \<sigma>) auto
   122 by (induct \<sigma>) auto
    73 
   123 
    74 lemma apply_compose[simp]: "t \<lhd> (s1 \<lozenge> s2) = t \<lhd> s1 \<lhd> s2"
   124 lemma subst_comp[simp]: "t \<lhd> (r \<lozenge> s) = t \<lhd> r \<lhd> s"
    75 proof (induct t)
   125 proof (induct t)
    76   case Comb thus ?case by simp
       
    77 next 
       
    78   case Const thus ?case by simp
       
    79 next
       
    80   case (Var v) thus ?case
   126   case (Var v) thus ?case
    81   proof (induct s1)
   127     by (induct r) auto
    82     case Nil show ?case by simp
   128 qed auto
    83   next
   129 
    84     case (Cons p s1s) thus ?case by (cases p, simp)
   130 lemma subst_eq_intro[intro]: "(\<And>t. t \<lhd> \<sigma> = t \<lhd> \<theta>) \<Longrightarrow> \<sigma> \<doteq> \<theta>"
    85   qed
       
    86 qed
       
    87 
       
    88 lemma eqv_refl[intro]: "s \<doteq> s"
       
    89   by (auto simp:subst_eq_def)
   131   by (auto simp:subst_eq_def)
    90 
   132 
    91 lemma eqv_trans[trans]: "\<lbrakk>s1 \<doteq> s2; s2 \<doteq> s3\<rbrakk> \<Longrightarrow> s1 \<doteq> s3"
   133 lemma subst_eq_dest[dest]: "s1 \<doteq> s2 \<Longrightarrow> t \<lhd> s1 = t \<lhd> s2"
    92   by (auto simp:subst_eq_def)
   134   by (auto simp:subst_eq_def)
    93 
   135 
    94 lemma eqv_sym[sym]: "\<lbrakk>s1 \<doteq> s2\<rbrakk> \<Longrightarrow> s2 \<doteq> s1"
   136 lemma comp_assoc: "(a \<lozenge> b) \<lozenge> c \<doteq> a \<lozenge> (b \<lozenge> c)"
    95   by (auto simp:subst_eq_def)
       
    96 
       
    97 lemma eqv_intro[intro]: "(\<And>t. t \<lhd> \<sigma> = t \<lhd> \<theta>) \<Longrightarrow> \<sigma> \<doteq> \<theta>"
       
    98   by (auto simp:subst_eq_def)
       
    99 
       
   100 lemma eqv_dest[dest]: "s1 \<doteq> s2 \<Longrightarrow> t \<lhd> s1 = t \<lhd> s2"
       
   101   by (auto simp:subst_eq_def)
       
   102 
       
   103 lemma compose_eqv: "\<lbrakk>\<sigma> \<doteq> \<sigma>'; \<theta> \<doteq> \<theta>'\<rbrakk> \<Longrightarrow> (\<sigma> \<lozenge> \<theta>) \<doteq> (\<sigma>' \<lozenge> \<theta>')"
       
   104   by (auto simp:subst_eq_def)
       
   105 
       
   106 lemma compose_assoc: "(a \<lozenge> b) \<lozenge> c \<doteq> a \<lozenge> (b \<lozenge> c)"
       
   107   by auto
   137   by auto
   108 
   138 
       
   139 lemma subst_cong: "\<lbrakk>\<sigma> \<doteq> \<sigma>'; \<theta> \<doteq> \<theta>'\<rbrakk> \<Longrightarrow> (\<sigma> \<lozenge> \<theta>) \<doteq> (\<sigma>' \<lozenge> \<theta>')"
       
   140   by (auto simp: subst_eq_def)
       
   141 
       
   142 
   109 
   143 
   110 subsection {* Specification: Most general unifiers *}
   144 subsection {* Specification: Most general unifiers *}
   111 
   145 
   112 definition
   146 definition Unifier :: "'a subst \<Rightarrow> 'a trm \<Rightarrow> 'a trm \<Rightarrow> bool"
   113   "Unifier \<sigma> t u \<equiv> (t\<lhd>\<sigma> = u\<lhd>\<sigma>)"
   147 where "Unifier \<sigma> t u \<longleftrightarrow> (t \<lhd> \<sigma> = u \<lhd> \<sigma>)"
   114 
   148 
   115 definition
   149 definition MGU :: "'a subst \<Rightarrow> 'a trm \<Rightarrow> 'a trm \<Rightarrow> bool" where
   116   "MGU \<sigma> t u \<equiv> Unifier \<sigma> t u \<and> (\<forall>\<theta>. Unifier \<theta> t u 
   150   "MGU \<sigma> t u \<longleftrightarrow> 
   117   \<longrightarrow> (\<exists>\<gamma>. \<theta> \<doteq> \<sigma> \<lozenge> \<gamma>))"
   151    Unifier \<sigma> t u \<and> (\<forall>\<theta>. Unifier \<theta> t u \<longrightarrow> (\<exists>\<gamma>. \<theta> \<doteq> \<sigma> \<lozenge> \<gamma>))"
   118 
   152 
   119 lemma MGUI[intro]:
   153 lemma MGUI[intro]:
   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>
   154   "\<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"
   155   \<Longrightarrow> MGU \<sigma> t u"
   122   by (simp only:Unifier_def MGU_def, auto)
   156   by (simp only:Unifier_def MGU_def, auto)
   124 lemma MGU_sym[sym]:
   158 lemma MGU_sym[sym]:
   125   "MGU \<sigma> s t \<Longrightarrow> MGU \<sigma> t s"
   159   "MGU \<sigma> s t \<Longrightarrow> MGU \<sigma> t s"
   126   by (auto simp:MGU_def Unifier_def)
   160   by (auto simp:MGU_def Unifier_def)
   127 
   161 
   128 
   162 
       
   163 definition Idem :: "'a subst \<Rightarrow> bool"
       
   164 where "Idem s \<longleftrightarrow> (s \<lozenge> s) \<doteq> s"
       
   165 
       
   166 
       
   167 
   129 subsection {* The unification algorithm *}
   168 subsection {* The unification algorithm *}
   130 
   169 
   131 text {* Occurs check: Proper subterm relation *}
       
   132 
       
   133 fun occs :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> bool" (infixl "<:" 54) 
       
   134 where
       
   135   "occs u (Var v) = False"
       
   136 | "occs u (Const c) = False"
       
   137 | "occs u (M \<cdot> N) = (u = M \<or> u = N \<or> occs u M \<or> occs u N)"
       
   138 
   170 
   139 text {* The unification algorithm: *}
   171 text {* The unification algorithm: *}
   140 
   172 
   141 function unify :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> 'a subst option"
   173 function unify :: "'a trm \<Rightarrow> 'a trm \<Rightarrow> 'a subst option"
   142 where
   174 where
   224       where eqv: "\<sigma>' \<doteq> \<theta>1 \<lozenge> \<delta>"
   256       where eqv: "\<sigma>' \<doteq> \<theta>1 \<lozenge> \<delta>"
   225       unfolding MGU_def Unifier_def
   257       unfolding MGU_def Unifier_def
   226       by auto
   258       by auto
   227 
   259 
   228     from Ns have "N \<lhd> \<theta>1 \<lhd> \<delta> = N' \<lhd> \<theta>1 \<lhd> \<delta>"
   260     from Ns have "N \<lhd> \<theta>1 \<lhd> \<delta> = N' \<lhd> \<theta>1 \<lhd> \<delta>"
   229       by (simp add:eqv_dest[OF eqv])
   261       by (simp add:subst_eq_dest[OF eqv])
   230 
   262 
   231     with MGU_outer obtain \<rho>
   263     with MGU_outer obtain \<rho>
   232       where eqv2: "\<delta> \<doteq> \<theta>2 \<lozenge> \<rho>"
   264       where eqv2: "\<delta> \<doteq> \<theta>2 \<lozenge> \<rho>"
   233       unfolding MGU_def Unifier_def
   265       unfolding MGU_def Unifier_def
   234       by auto
   266       by auto
   235     
   267     
   236     have "\<sigma>' \<doteq> \<sigma> \<lozenge> \<rho>" unfolding \<sigma>
   268     have "\<sigma>' \<doteq> \<sigma> \<lozenge> \<rho>" unfolding \<sigma>
   237       by (rule eqv_intro, auto simp:eqv_dest[OF eqv] eqv_dest[OF eqv2])
   269       by (rule subst_eq_intro, auto simp:subst_eq_dest[OF eqv] subst_eq_dest[OF eqv2])
   238     thus "\<exists>\<gamma>. \<sigma>' \<doteq> \<sigma> \<lozenge> \<gamma>" ..
   270     thus "\<exists>\<gamma>. \<sigma>' \<doteq> \<sigma> \<lozenge> \<gamma>" ..
   239   qed
   271   qed
   240 qed (auto split:split_if_asm) -- "Solve the remaining cases automatically"
   272 qed (auto split:split_if_asm) -- "Solve the remaining cases automatically"
   241 
   273 
   242 
   274 
   243 subsection {* Properties used in termination proof *}
   275 subsection {* Properties used in termination proof *}
   244 
   276 
   245 text {* The variables of a term: *}
       
   246 
       
   247 fun vars_of:: "'a trm \<Rightarrow> 'a set"
       
   248 where
       
   249   "vars_of (Var v) = { v }"
       
   250 | "vars_of (Const c) = {}"
       
   251 | "vars_of (M \<cdot> N) = vars_of M \<union> vars_of N"
       
   252 
       
   253 lemma vars_of_finite[intro]: "finite (vars_of t)"
       
   254   by (induct t) simp_all
       
   255 
   277 
   256 text {* Elimination of variables by a substitution: *}
   278 text {* Elimination of variables by a substitution: *}
   257 
   279 
   258 definition
   280 definition
   259   "elim \<sigma> v \<equiv> \<forall>t. v \<notin> vars_of (t \<lhd> \<sigma>)"
   281   "elim \<sigma> v \<equiv> \<forall>t. v \<notin> vars_of (t \<lhd> \<sigma>)"
   472       by (auto simp:elim_def)
   494       by (auto simp:elim_def)
   473   next
   495   next
   474     assume empty[simp]: "\<theta>2 \<doteq> []"
   496     assume empty[simp]: "\<theta>2 \<doteq> []"
   475 
   497 
   476     have "\<sigma> \<doteq> (\<theta>1 \<lozenge> [])" unfolding \<sigma>
   498     have "\<sigma> \<doteq> (\<theta>1 \<lozenge> [])" unfolding \<sigma>
   477       by (rule compose_eqv) auto
   499       by (rule subst_cong) auto
   478     also have "\<dots> \<doteq> \<theta>1" by auto
   500     also have "\<dots> \<doteq> \<theta>1" by auto
   479     finally have "\<sigma> \<doteq> \<theta>1" .
   501     finally have "\<sigma> \<doteq> \<theta>1" .
   480 
   502 
   481     from ih1 show ?thesis
   503     from ih1 show ?thesis
   482     proof
   504     proof