61 let |
59 let |
62 val descr' = flat descr; |
60 val descr' = flat descr; |
63 fun make_inj T (cname, cargs) = |
61 fun make_inj T (cname, cargs) = |
64 if null cargs then I else |
62 if null cargs then I else |
65 let |
63 let |
66 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
64 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
67 val constr_t = Const (cname, Ts ---> T); |
65 val constr_t = Const (cname, Ts ---> T); |
68 val tnames = make_tnames Ts; |
66 val tnames = make_tnames Ts; |
69 val frees = map Free (tnames ~~ Ts); |
67 val frees = map Free (tnames ~~ Ts); |
70 val frees' = map Free ((map ((op ^) o (rpair "'")) tnames) ~~ Ts); |
68 val frees' = map Free ((map ((op ^) o (rpair "'")) tnames) ~~ Ts); |
71 in cons (HOLogic.mk_Trueprop (HOLogic.mk_eq |
69 in cons (HOLogic.mk_Trueprop (HOLogic.mk_eq |
73 foldr1 (HOLogic.mk_binop @{const_name HOL.conj}) |
71 foldr1 (HOLogic.mk_binop @{const_name HOL.conj}) |
74 (map HOLogic.mk_eq (frees ~~ frees'))))) |
72 (map HOLogic.mk_eq (frees ~~ frees'))))) |
75 end; |
73 end; |
76 in |
74 in |
77 map2 (fn d => fn T => fold_rev (make_inj T) (#3 (snd d)) []) |
75 map2 (fn d => fn T => fold_rev (make_inj T) (#3 (snd d)) []) |
78 (hd descr) (take (length (hd descr)) (get_rec_types descr' sorts)) |
76 (hd descr) (take (length (hd descr)) (Datatype_Aux.get_rec_types descr' sorts)) |
79 end; |
77 end; |
80 |
78 |
81 |
79 |
82 (************************* distinctness of constructors ***********************) |
80 (************************* distinctness of constructors ***********************) |
83 |
81 |
84 fun make_distincts descr sorts = |
82 fun make_distincts descr sorts = |
85 let |
83 let |
86 val descr' = flat descr; |
84 val descr' = flat descr; |
87 val recTs = get_rec_types descr' sorts; |
85 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
88 val newTs = take (length (hd descr)) recTs; |
86 val newTs = take (length (hd descr)) recTs; |
89 |
87 |
90 fun prep_constr (cname, cargs) = (cname, map (typ_of_dtyp descr' sorts) cargs); |
88 fun prep_constr (cname, cargs) = (cname, map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs); |
91 |
89 |
92 fun make_distincts' _ [] = [] |
90 fun make_distincts' _ [] = [] |
93 | make_distincts' T ((cname, cargs)::constrs) = |
91 | make_distincts' T ((cname, cargs)::constrs) = |
94 let |
92 let |
95 val frees = map Free ((make_tnames cargs) ~~ cargs); |
93 val frees = map Free ((make_tnames cargs) ~~ cargs); |
115 (********************************* induction **********************************) |
113 (********************************* induction **********************************) |
116 |
114 |
117 fun make_ind descr sorts = |
115 fun make_ind descr sorts = |
118 let |
116 let |
119 val descr' = flat descr; |
117 val descr' = flat descr; |
120 val recTs = get_rec_types descr' sorts; |
118 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
121 val pnames = if length descr' = 1 then ["P"] |
119 val pnames = |
|
120 if length descr' = 1 then ["P"] |
122 else map (fn i => "P" ^ string_of_int i) (1 upto length descr'); |
121 else map (fn i => "P" ^ string_of_int i) (1 upto length descr'); |
123 |
122 |
124 fun make_pred i T = |
123 fun make_pred i T = |
125 let val T' = T --> HOLogic.boolT |
124 let val T' = T --> HOLogic.boolT |
126 in Free (List.nth (pnames, i), T') end; |
125 in Free (List.nth (pnames, i), T') end; |
127 |
126 |
128 fun make_ind_prem k T (cname, cargs) = |
127 fun make_ind_prem k T (cname, cargs) = |
129 let |
128 let |
130 fun mk_prem ((dt, s), T) = |
129 fun mk_prem ((dt, s), T) = |
131 let val (Us, U) = strip_type T |
130 let val (Us, U) = strip_type T |
132 in list_all (map (pair "x") Us, HOLogic.mk_Trueprop |
131 in |
133 (make_pred (body_index dt) U $ app_bnds (Free (s, T)) (length Us))) |
132 list_all (map (pair "x") Us, |
|
133 HOLogic.mk_Trueprop |
|
134 (make_pred (Datatype_Aux.body_index dt) U $ |
|
135 Datatype_Aux.app_bnds (Free (s, T)) (length Us))) |
134 end; |
136 end; |
135 |
137 |
136 val recs = filter is_rec_type cargs; |
138 val recs = filter Datatype_Aux.is_rec_type cargs; |
137 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
139 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
138 val recTs' = map (typ_of_dtyp descr' sorts) recs; |
140 val recTs' = map (Datatype_Aux.typ_of_dtyp descr' sorts) recs; |
139 val tnames = Name.variant_list pnames (make_tnames Ts); |
141 val tnames = Name.variant_list pnames (make_tnames Ts); |
140 val rec_tnames = map fst (filter (is_rec_type o snd) (tnames ~~ cargs)); |
142 val rec_tnames = map fst (filter (Datatype_Aux.is_rec_type o snd) (tnames ~~ cargs)); |
141 val frees = tnames ~~ Ts; |
143 val frees = tnames ~~ Ts; |
142 val prems = map mk_prem (recs ~~ rec_tnames ~~ recTs'); |
144 val prems = map mk_prem (recs ~~ rec_tnames ~~ recTs'); |
143 |
145 |
144 in list_all_free (frees, Logic.list_implies (prems, |
146 in list_all_free (frees, Logic.list_implies (prems, |
145 HOLogic.mk_Trueprop (make_pred k T $ |
147 HOLogic.mk_Trueprop (make_pred k T $ |
161 let |
163 let |
162 val descr' = flat descr; |
164 val descr' = flat descr; |
163 |
165 |
164 fun make_casedist_prem T (cname, cargs) = |
166 fun make_casedist_prem T (cname, cargs) = |
165 let |
167 let |
166 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
168 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
167 val frees = Name.variant_list ["P", "y"] (make_tnames Ts) ~~ Ts; |
169 val frees = Name.variant_list ["P", "y"] (make_tnames Ts) ~~ Ts; |
168 val free_ts = map Free frees |
170 val free_ts = map Free frees |
169 in list_all_free (frees, Logic.mk_implies (HOLogic.mk_Trueprop |
171 in list_all_free (frees, Logic.mk_implies (HOLogic.mk_Trueprop |
170 (HOLogic.mk_eq (Free ("y", T), list_comb (Const (cname, Ts ---> T), free_ts))), |
172 (HOLogic.mk_eq (Free ("y", T), list_comb (Const (cname, Ts ---> T), free_ts))), |
171 HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT)))) |
173 HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT)))) |
174 fun make_casedist ((_, (_, _, constrs))) T = |
176 fun make_casedist ((_, (_, _, constrs))) T = |
175 let val prems = map (make_casedist_prem T) constrs |
177 let val prems = map (make_casedist_prem T) constrs |
176 in Logic.list_implies (prems, HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT))) |
178 in Logic.list_implies (prems, HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT))) |
177 end |
179 end |
178 |
180 |
179 in map2 make_casedist (hd descr) (take (length (hd descr)) (get_rec_types descr' sorts)) end; |
181 in |
|
182 map2 make_casedist (hd descr) |
|
183 (take (length (hd descr)) (Datatype_Aux.get_rec_types descr' sorts)) |
|
184 end; |
180 |
185 |
181 (*************** characteristic equations for primrec combinator **************) |
186 (*************** characteristic equations for primrec combinator **************) |
182 |
187 |
183 fun make_primrec_Ts descr sorts used = |
188 fun make_primrec_Ts descr sorts used = |
184 let |
189 let |
188 replicate (length descr') HOLogic.typeS); |
193 replicate (length descr') HOLogic.typeS); |
189 |
194 |
190 val reccomb_fn_Ts = maps (fn (i, (_, _, constrs)) => |
195 val reccomb_fn_Ts = maps (fn (i, (_, _, constrs)) => |
191 map (fn (_, cargs) => |
196 map (fn (_, cargs) => |
192 let |
197 let |
193 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
198 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
194 val recs = filter (is_rec_type o fst) (cargs ~~ Ts); |
199 val recs = filter (Datatype_Aux.is_rec_type o fst) (cargs ~~ Ts); |
195 |
200 |
196 fun mk_argT (dt, T) = |
201 fun mk_argT (dt, T) = |
197 binder_types T ---> List.nth (rec_result_Ts, body_index dt); |
202 binder_types T ---> List.nth (rec_result_Ts, Datatype_Aux.body_index dt); |
198 |
203 |
199 val argTs = Ts @ map mk_argT recs |
204 val argTs = Ts @ map mk_argT recs |
200 in argTs ---> List.nth (rec_result_Ts, i) |
205 in argTs ---> List.nth (rec_result_Ts, i) |
201 end) constrs) descr'; |
206 end) constrs) descr'; |
202 |
207 |
203 in (rec_result_Ts, reccomb_fn_Ts) end; |
208 in (rec_result_Ts, reccomb_fn_Ts) end; |
204 |
209 |
205 fun make_primrecs new_type_names descr sorts thy = |
210 fun make_primrecs new_type_names descr sorts thy = |
206 let |
211 let |
207 val descr' = flat descr; |
212 val descr' = flat descr; |
208 val recTs = get_rec_types descr' sorts; |
213 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
209 val used = List.foldr OldTerm.add_typ_tfree_names [] recTs; |
214 val used = List.foldr OldTerm.add_typ_tfree_names [] recTs; |
210 |
215 |
211 val (rec_result_Ts, reccomb_fn_Ts) = make_primrec_Ts descr sorts used; |
216 val (rec_result_Ts, reccomb_fn_Ts) = make_primrec_Ts descr sorts used; |
212 |
217 |
213 val rec_fns = map (uncurry (mk_Free "f")) |
218 val rec_fns = map (uncurry (Datatype_Aux.mk_Free "f")) |
214 (reccomb_fn_Ts ~~ (1 upto (length reccomb_fn_Ts))); |
219 (reccomb_fn_Ts ~~ (1 upto (length reccomb_fn_Ts))); |
215 |
220 |
216 val big_reccomb_name = (space_implode "_" new_type_names) ^ "_rec"; |
221 val big_reccomb_name = (space_implode "_" new_type_names) ^ "_rec"; |
217 val reccomb_names = map (Sign.intern_const thy) |
222 val reccomb_names = map (Sign.intern_const thy) |
218 (if length descr' = 1 then [big_reccomb_name] else |
223 (if length descr' = 1 then [big_reccomb_name] else |
222 (Const (name, reccomb_fn_Ts @ [T] ---> T'), rec_fns)) |
227 (Const (name, reccomb_fn_Ts @ [T] ---> T'), rec_fns)) |
223 (reccomb_names ~~ recTs ~~ rec_result_Ts); |
228 (reccomb_names ~~ recTs ~~ rec_result_Ts); |
224 |
229 |
225 fun make_primrec T comb_t (cname, cargs) (ts, f::fs) = |
230 fun make_primrec T comb_t (cname, cargs) (ts, f::fs) = |
226 let |
231 let |
227 val recs = filter is_rec_type cargs; |
232 val recs = filter Datatype_Aux.is_rec_type cargs; |
228 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
233 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
229 val recTs' = map (typ_of_dtyp descr' sorts) recs; |
234 val recTs' = map (Datatype_Aux.typ_of_dtyp descr' sorts) recs; |
230 val tnames = make_tnames Ts; |
235 val tnames = make_tnames Ts; |
231 val rec_tnames = map fst (filter (is_rec_type o snd) (tnames ~~ cargs)); |
236 val rec_tnames = map fst (filter (Datatype_Aux.is_rec_type o snd) (tnames ~~ cargs)); |
232 val frees = map Free (tnames ~~ Ts); |
237 val frees = map Free (tnames ~~ Ts); |
233 val frees' = map Free (rec_tnames ~~ recTs'); |
238 val frees' = map Free (rec_tnames ~~ recTs'); |
234 |
239 |
235 fun mk_reccomb ((dt, T), t) = |
240 fun mk_reccomb ((dt, T), t) = |
236 let val (Us, U) = strip_type T |
241 let val (Us, U) = strip_type T |
237 in list_abs (map (pair "x") Us, |
242 in list_abs (map (pair "x") Us, |
238 List.nth (reccombs, body_index dt) $ app_bnds t (length Us)) |
243 List.nth (reccombs, Datatype_Aux.body_index dt) $ Datatype_Aux.app_bnds t (length Us)) |
239 end; |
244 end; |
240 |
245 |
241 val reccombs' = map mk_reccomb (recs ~~ recTs' ~~ frees') |
246 val reccombs' = map mk_reccomb (recs ~~ recTs' ~~ frees') |
242 |
247 |
243 in (ts @ [HOLogic.mk_Trueprop (HOLogic.mk_eq |
248 in (ts @ [HOLogic.mk_Trueprop (HOLogic.mk_eq |
254 (****************** make terms of form t_case f1 ... fn *********************) |
259 (****************** make terms of form t_case f1 ... fn *********************) |
255 |
260 |
256 fun make_case_combs new_type_names descr sorts thy fname = |
261 fun make_case_combs new_type_names descr sorts thy fname = |
257 let |
262 let |
258 val descr' = flat descr; |
263 val descr' = flat descr; |
259 val recTs = get_rec_types descr' sorts; |
264 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
260 val used = List.foldr OldTerm.add_typ_tfree_names [] recTs; |
265 val used = List.foldr OldTerm.add_typ_tfree_names [] recTs; |
261 val newTs = take (length (hd descr)) recTs; |
266 val newTs = take (length (hd descr)) recTs; |
262 val T' = TFree (Name.variant used "'t", HOLogic.typeS); |
267 val T' = TFree (Name.variant used "'t", HOLogic.typeS); |
263 |
268 |
264 val case_fn_Ts = map (fn (i, (_, _, constrs)) => |
269 val case_fn_Ts = map (fn (i, (_, _, constrs)) => |
265 map (fn (_, cargs) => |
270 map (fn (_, cargs) => |
266 let val Ts = map (typ_of_dtyp descr' sorts) cargs |
271 let val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs |
267 in Ts ---> T' end) constrs) (hd descr); |
272 in Ts ---> T' end) constrs) (hd descr); |
268 |
273 |
269 val case_names = map (fn s => |
274 val case_names = map (fn s => |
270 Sign.intern_const thy (s ^ "_case")) new_type_names |
275 Sign.intern_const thy (s ^ "_case")) new_type_names |
271 in |
276 in |
272 map (fn ((name, Ts), T) => list_comb |
277 map (fn ((name, Ts), T) => list_comb |
273 (Const (name, Ts @ [T] ---> T'), |
278 (Const (name, Ts @ [T] ---> T'), |
274 map (uncurry (mk_Free fname)) (Ts ~~ (1 upto length Ts)))) |
279 map (uncurry (Datatype_Aux.mk_Free fname)) (Ts ~~ (1 upto length Ts)))) |
275 (case_names ~~ case_fn_Ts ~~ newTs) |
280 (case_names ~~ case_fn_Ts ~~ newTs) |
276 end; |
281 end; |
277 |
282 |
278 (**************** characteristic equations for case combinator ****************) |
283 (**************** characteristic equations for case combinator ****************) |
279 |
284 |
280 fun make_cases new_type_names descr sorts thy = |
285 fun make_cases new_type_names descr sorts thy = |
281 let |
286 let |
282 val descr' = flat descr; |
287 val descr' = flat descr; |
283 val recTs = get_rec_types descr' sorts; |
288 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
284 val newTs = take (length (hd descr)) recTs; |
289 val newTs = take (length (hd descr)) recTs; |
285 |
290 |
286 fun make_case T comb_t ((cname, cargs), f) = |
291 fun make_case T comb_t ((cname, cargs), f) = |
287 let |
292 let |
288 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
293 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
289 val frees = map Free ((make_tnames Ts) ~~ Ts) |
294 val frees = map Free ((make_tnames Ts) ~~ Ts) |
290 in HOLogic.mk_Trueprop (HOLogic.mk_eq |
295 in HOLogic.mk_Trueprop (HOLogic.mk_eq |
291 (comb_t $ list_comb (Const (cname, Ts ---> T), frees), |
296 (comb_t $ list_comb (Const (cname, Ts ---> T), frees), |
292 list_comb (f, frees))) |
297 list_comb (f, frees))) |
293 end |
298 end |
301 (*************************** the "split" - equations **************************) |
306 (*************************** the "split" - equations **************************) |
302 |
307 |
303 fun make_splits new_type_names descr sorts thy = |
308 fun make_splits new_type_names descr sorts thy = |
304 let |
309 let |
305 val descr' = flat descr; |
310 val descr' = flat descr; |
306 val recTs = get_rec_types descr' sorts; |
311 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
307 val used' = List.foldr OldTerm.add_typ_tfree_names [] recTs; |
312 val used' = List.foldr OldTerm.add_typ_tfree_names [] recTs; |
308 val newTs = take (length (hd descr)) recTs; |
313 val newTs = take (length (hd descr)) recTs; |
309 val T' = TFree (Name.variant used' "'t", HOLogic.typeS); |
314 val T' = TFree (Name.variant used' "'t", HOLogic.typeS); |
310 val P = Free ("P", T' --> HOLogic.boolT); |
315 val P = Free ("P", T' --> HOLogic.boolT); |
311 |
316 |
314 val (_, fs) = strip_comb comb_t; |
319 val (_, fs) = strip_comb comb_t; |
315 val used = ["P", "x"] @ (map (fst o dest_Free) fs); |
320 val used = ["P", "x"] @ (map (fst o dest_Free) fs); |
316 |
321 |
317 fun process_constr ((cname, cargs), f) (t1s, t2s) = |
322 fun process_constr ((cname, cargs), f) (t1s, t2s) = |
318 let |
323 let |
319 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
324 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
320 val frees = map Free (Name.variant_list used (make_tnames Ts) ~~ Ts); |
325 val frees = map Free (Name.variant_list used (make_tnames Ts) ~~ Ts); |
321 val eqn = HOLogic.mk_eq (Free ("x", T), |
326 val eqn = HOLogic.mk_eq (Free ("x", T), |
322 list_comb (Const (cname, Ts ---> T), frees)); |
327 list_comb (Const (cname, Ts ---> T), frees)); |
323 val P' = P $ list_comb (f, frees) |
328 val P' = P $ list_comb (f, frees) |
324 in (fold_rev (fn Free (s, T) => fn t => HOLogic.mk_all (s, T, t)) frees |
329 in (fold_rev (fn Free (s, T) => fn t => HOLogic.mk_all (s, T, t)) frees |
328 end; |
333 end; |
329 |
334 |
330 val (t1s, t2s) = fold_rev process_constr (constrs ~~ fs) ([], []); |
335 val (t1s, t2s) = fold_rev process_constr (constrs ~~ fs) ([], []); |
331 val lhs = P $ (comb_t $ Free ("x", T)) |
336 val lhs = P $ (comb_t $ Free ("x", T)) |
332 in |
337 in |
333 (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, mk_conj t1s)), |
338 (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, Datatype_Aux.mk_conj t1s)), |
334 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, HOLogic.Not $ mk_disj t2s))) |
339 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, HOLogic.Not $ Datatype_Aux.mk_disj t2s))) |
335 end |
340 end |
336 |
341 |
337 in map make_split ((hd descr) ~~ newTs ~~ |
342 in map make_split ((hd descr) ~~ newTs ~~ |
338 (make_case_combs new_type_names descr sorts thy "f")) |
343 (make_case_combs new_type_names descr sorts thy "f")) |
339 end; |
344 end; |
413 *---------------------------------------------------------------------------*) |
418 *---------------------------------------------------------------------------*) |
414 |
419 |
415 fun make_nchotomys descr sorts = |
420 fun make_nchotomys descr sorts = |
416 let |
421 let |
417 val descr' = flat descr; |
422 val descr' = flat descr; |
418 val recTs = get_rec_types descr' sorts; |
423 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
419 val newTs = take (length (hd descr)) recTs; |
424 val newTs = take (length (hd descr)) recTs; |
420 |
425 |
421 fun mk_eqn T (cname, cargs) = |
426 fun mk_eqn T (cname, cargs) = |
422 let |
427 let |
423 val Ts = map (typ_of_dtyp descr' sorts) cargs; |
428 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
424 val tnames = Name.variant_list ["v"] (make_tnames Ts); |
429 val tnames = Name.variant_list ["v"] (make_tnames Ts); |
425 val frees = tnames ~~ Ts |
430 val frees = tnames ~~ Ts |
426 in |
431 in |
427 fold_rev (fn (s, T') => fn t => HOLogic.mk_exists (s, T', t)) frees |
432 fold_rev (fn (s, T') => fn t => HOLogic.mk_exists (s, T', t)) frees |
428 (HOLogic.mk_eq (Free ("v", T), |
433 (HOLogic.mk_eq (Free ("v", T), |
429 list_comb (Const (cname, Ts ---> T), map Free frees))) |
434 list_comb (Const (cname, Ts ---> T), map Free frees))) |
430 end |
435 end |
431 |
436 |
432 in map (fn ((_, (_, _, constrs)), T) => |
437 in map (fn ((_, (_, _, constrs)), T) => |
433 HOLogic.mk_Trueprop (HOLogic.mk_all ("v", T, mk_disj (map (mk_eqn T) constrs)))) |
438 HOLogic.mk_Trueprop (HOLogic.mk_all ("v", T, Datatype_Aux.mk_disj (map (mk_eqn T) constrs)))) |
434 (hd descr ~~ newTs) |
439 (hd descr ~~ newTs) |
435 end; |
440 end; |
436 |
441 |
|
442 |
|
443 open Datatype_Aux; |
|
444 |
437 end; |
445 end; |