138 ML {* |
138 ML {* |
139 datatype alpha_type = AlphaGen | AlphaRes | AlphaLst; |
139 datatype alpha_type = AlphaGen | AlphaRes | AlphaLst; |
140 *} |
140 *} |
141 |
141 |
142 ML {* |
142 ML {* |
|
143 fun atyp_const AlphaGen = @{const_name alpha_gen} |
|
144 | atyp_const AlphaRes = @{const_name alpha_res} |
|
145 | atyp_const AlphaLst = @{const_name alpha_lst} |
|
146 *} |
|
147 |
|
148 (* TODO: make sure that parser checks that bindings are compatible *) |
|
149 ML {* |
|
150 fun alpha_const_for_binds [] = atyp_const AlphaGen |
|
151 | alpha_const_for_binds ((NONE, _, _, at) :: t) = atyp_const at |
|
152 | alpha_const_for_binds ((SOME (_, _), _, _, at) :: _) = atyp_const at |
|
153 *} |
|
154 |
|
155 ML {* |
143 fun is_atom thy typ = |
156 fun is_atom thy typ = |
144 Sign.of_sort thy (typ, @{sort at}) |
157 Sign.of_sort thy (typ, @{sort at}) |
145 |
158 |
146 fun is_atom_set thy (Type ("fun", [t, @{typ bool}])) = is_atom thy t |
159 fun is_atom_set thy (Type ("fun", [t, @{typ bool}])) = is_atom thy t |
147 | is_atom_set _ _ = false; |
160 | is_atom_set _ _ = false; |
165 ML {* |
178 ML {* |
166 fun gather_binds binds = |
179 fun gather_binds binds = |
167 let |
180 let |
168 fun gather_binds_cons binds = |
181 fun gather_binds_cons binds = |
169 let |
182 let |
170 val common = map (fn (f, bi, _) => (f, bi)) binds |
183 val common = map (fn (f, bi, _, aty) => (f, bi, aty)) binds |
171 val nodups = distinct (op =) common |
184 val nodups = distinct (op =) common |
172 fun find_bodys (sf, sbi) = |
185 fun find_bodys (sf, sbi, sty) = |
173 filter (fn (f, bi, _) => f = sf andalso bi = sbi) binds |
186 filter (fn (f, bi, _, aty) => f = sf andalso bi = sbi andalso aty = sty) binds |
174 val bodys = map ((map (fn (_, _, bo) => bo)) o find_bodys) nodups |
187 val bodys = map ((map (fn (_, _, bo, _) => bo)) o find_bodys) nodups |
175 in |
188 in |
176 nodups ~~ bodys |
189 nodups ~~ bodys |
177 end |
190 end |
178 in |
191 in |
179 map (map gather_binds_cons) binds |
192 map (map gather_binds_cons) binds |
180 end |
193 end |
181 *} |
194 *} |
182 |
195 |
183 ML {* |
196 ML {* |
184 fun un_gather_binds_cons binds = |
197 fun un_gather_binds_cons binds = |
185 flat (map (fn (((f, bi), bos), pi) => map (fn bo => ((f, bi, bo), pi)) bos) binds) |
198 flat (map (fn (((f, bi, aty), bos), pi) => map (fn bo => ((f, bi, bo, aty), pi)) bos) binds) |
186 *} |
199 *} |
187 |
200 |
188 ML {* |
201 ML {* |
189 open Datatype_Aux; (* typ_of_dtyp, DtRec, ... *); |
202 open Datatype_Aux; (* typ_of_dtyp, DtRec, ... *); |
|
203 *} |
|
204 ML {* |
190 (* TODO: It is the same as one in 'nominal_atoms' *) |
205 (* TODO: It is the same as one in 'nominal_atoms' *) |
191 fun mk_atom ty = Const (@{const_name atom}, ty --> @{typ atom}); |
206 fun mk_atom ty = Const (@{const_name atom}, ty --> @{typ atom}); |
192 val noatoms = @{term "{} :: atom set"}; |
207 val noatoms = @{term "{} :: atom set"}; |
193 fun mk_single_atom x = HOLogic.mk_set @{typ atom} [mk_atom (type_of x) $ x]; |
208 fun mk_single_atom x = HOLogic.mk_set @{typ atom} [mk_atom (type_of x) $ x]; |
194 fun mk_union sets = |
209 fun mk_union sets = |
439 val args2 = map Free (names2 ~~ Ts); |
455 val args2 = map Free (names2 ~~ Ts); |
440 val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp)); |
456 val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp)); |
441 val fv_c = nth fv_frees ith_dtyp; |
457 val fv_c = nth fv_frees ith_dtyp; |
442 val alpha = nth alpha_frees ith_dtyp; |
458 val alpha = nth alpha_frees ith_dtyp; |
443 val arg_nos = 0 upto (length dts - 1) |
459 val arg_nos = 0 upto (length dts - 1) |
444 fun fv_bind args (NONE, i, _) = |
460 fun fv_bind args (NONE, i, _, _) = |
445 if is_rec_type (nth dts i) then (nth fv_frees (body_index (nth dts i))) $ (nth args i) else |
461 if is_rec_type (nth dts i) then (nth fv_frees (body_index (nth dts i))) $ (nth args i) else |
446 if ((is_atom thy) o fastype_of) (nth args i) then mk_single_atom (nth args i) else |
462 if ((is_atom thy) o fastype_of) (nth args i) then mk_single_atom (nth args i) else |
447 if ((is_atom_set thy) o fastype_of) (nth args i) then mk_atom_set (nth args i) else |
463 if ((is_atom_set thy) o fastype_of) (nth args i) then mk_atom_set (nth args i) else |
448 if ((is_atom_fset thy) o fastype_of) (nth args i) then mk_atom_fset (nth args i) else |
464 if ((is_atom_fset thy) o fastype_of) (nth args i) then mk_atom_fset (nth args i) else |
449 (* TODO we do not know what to do with non-atomizable things *) |
465 (* TODO we do not know what to do with non-atomizable things *) |
450 @{term "{} :: atom set"} |
466 @{term "{} :: atom set"} |
451 | fv_bind args (SOME (f, _), i, _) = f $ (nth args i); |
467 | fv_bind args (SOME (f, _), i, _, _) = f $ (nth args i); |
452 fun fv_binds args relevant = mk_union (map (fv_bind args) relevant) |
468 fun fv_binds args relevant = mk_union (map (fv_bind args) relevant) |
453 fun find_nonrec_binder j (SOME (f, false), i, _) = if i = j then SOME f else NONE |
469 fun find_nonrec_binder j (SOME (f, false), i, _, _) = if i = j then SOME f else NONE |
454 | find_nonrec_binder _ _ = NONE |
470 | find_nonrec_binder _ _ = NONE |
455 fun fv_arg ((dt, x), arg_no) = |
471 fun fv_arg ((dt, x), arg_no) = |
456 case get_first (find_nonrec_binder arg_no) bindcs of |
472 case get_first (find_nonrec_binder arg_no) bindcs of |
457 SOME f => |
473 SOME f => |
458 (case get_first (fn (x, y) => if x = f then SOME y else NONE) bn_fv_bns of |
474 (case get_first (fn (x, y) => if x = f then SOME y else NONE) bn_fv_bns of |
466 if ((is_atom_set thy) o fastype_of) x then mk_atom_set x else |
482 if ((is_atom_set thy) o fastype_of) x then mk_atom_set x else |
467 if ((is_atom_fset thy) o fastype_of) x then mk_atom_fset x else |
483 if ((is_atom_fset thy) o fastype_of) x then mk_atom_fset x else |
468 (* TODO we do not know what to do with non-atomizable things *) |
484 (* TODO we do not know what to do with non-atomizable things *) |
469 @{term "{} :: atom set"}; |
485 @{term "{} :: atom set"}; |
470 (* If i = j then we generate it only once *) |
486 (* If i = j then we generate it only once *) |
471 val relevant = filter (fn (_, i, j) => ((i = arg_no) orelse (j = arg_no))) bindcs; |
487 val relevant = filter (fn (_, i, j, _) => ((i = arg_no) orelse (j = arg_no))) bindcs; |
472 val sub = fv_binds args relevant |
488 val sub = fv_binds args relevant |
473 in |
489 in |
474 mk_diff arg sub |
490 mk_diff arg sub |
475 end; |
491 end; |
476 val fv_eq = HOLogic.mk_Trueprop (HOLogic.mk_eq |
492 val fv_eq = HOLogic.mk_Trueprop (HOLogic.mk_eq |
477 (fv_c $ list_comb (c, args), mk_union (map fv_arg (dts ~~ args ~~ arg_nos)))) |
493 (fv_c $ list_comb (c, args), mk_union (map fv_arg (dts ~~ args ~~ arg_nos)))) |
478 val alpha_rhs = |
494 val alpha_rhs = |
479 HOLogic.mk_Trueprop (alpha $ (list_comb (c, args)) $ (list_comb (c, args2))); |
495 HOLogic.mk_Trueprop (alpha $ (list_comb (c, args)) $ (list_comb (c, args2))); |
480 fun alpha_arg ((dt, arg_no), (arg, arg2)) = |
496 fun alpha_arg ((dt, arg_no), (arg, arg2)) = |
481 let |
497 let |
482 val rel_in_simp_binds = filter (fn ((NONE, i, _), _) => i = arg_no | _ => false) bind_pis; |
498 val rel_in_simp_binds = filter (fn ((NONE, i, _, _), _) => i = arg_no | _ => false) bind_pis; |
483 val rel_in_comp_binds = filter (fn ((SOME _, i, _), _) => i = arg_no | _ => false) bind_pis; |
499 val rel_in_comp_binds = filter (fn ((SOME _, i, _, _), _) => i = arg_no | _ => false) bind_pis; |
484 val rel_has_binds = filter (fn ((NONE, _, j), _) => j = arg_no |
500 val rel_has_binds = filter (fn ((NONE, _, j, _), _) => j = arg_no |
485 | ((SOME (_, false), _, j), _) => j = arg_no |
501 | ((SOME (_, false), _, j, _), _) => j = arg_no |
486 | _ => false) bind_pis; |
502 | _ => false) bind_pis; |
487 val rel_has_rec_binds = filter |
503 val rel_has_rec_binds = filter |
488 (fn ((SOME (_, true), _, j), _) => j = arg_no | _ => false) bind_pis; |
504 (fn ((SOME (_, true), _, j, _), _) => j = arg_no | _ => false) bind_pis; |
489 in |
505 in |
490 case (rel_in_simp_binds, rel_in_comp_binds, rel_has_binds, rel_has_rec_binds) of |
506 case (rel_in_simp_binds, rel_in_comp_binds, rel_has_binds, rel_has_rec_binds) of |
491 ([], [], [], []) => |
507 ([], [], [], []) => |
492 if is_rec_type dt then (nth alpha_frees (body_index dt) $ arg $ arg2) |
508 if is_rec_type dt then (nth alpha_frees (body_index dt) $ arg $ arg2) |
493 else (HOLogic.mk_eq (arg, arg2)) |
509 else (HOLogic.mk_eq (arg, arg2)) |
494 | (_, [], [], []) => @{term True} |
510 | (_, [], [], []) => @{term True} |
495 | ([], [], [], _) => @{term True} |
511 | ([], [], [], _) => @{term True} |
496 | ([], ((((SOME (bn, is_rec)), _, _), _) :: _), [], []) => |
512 | ([], ((((SOME (bn, is_rec)), _, _, atyp), _) :: _), [], []) => |
497 if not (bns_same rel_in_comp_binds) then error "incompatible bindings for an argument" else |
513 if not (bns_same rel_in_comp_binds) then error "incompatible bindings for an argument" else |
498 if is_rec then |
514 if is_rec then |
499 let |
515 let |
500 val (rbinds, rpis) = split_list rel_in_comp_binds |
516 val (rbinds, rpis) = split_list rel_in_comp_binds |
501 val bound_in_nos = map (fn (_, _, i) => i) rbinds |
517 val bound_in_nos = map (fn (_, _, i, _) => i) rbinds |
502 val bound_in_ty_nos = map (fn i => body_index (nth dts i)) bound_in_nos; |
518 val bound_in_ty_nos = map (fn i => body_index (nth dts i)) bound_in_nos; |
503 val bound_args = arg :: map (nth args) bound_in_nos; |
519 val bound_args = arg :: map (nth args) bound_in_nos; |
504 val bound_args2 = arg2 :: map (nth args2) bound_in_nos; |
520 val bound_args2 = arg2 :: map (nth args2) bound_in_nos; |
505 val lhs_binds = fv_binds args rbinds |
521 val lhs_binds = fv_binds args rbinds |
506 val lhs_arg = foldr1 HOLogic.mk_prod bound_args |
522 val lhs_arg = foldr1 HOLogic.mk_prod bound_args |