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) |
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>)" |