134 Otherwise we return: argl = argr |
134 Otherwise we return: argl = argr |
135 |
135 |
136 *) |
136 *) |
137 |
137 |
138 ML {* |
138 ML {* |
|
139 datatype alpha_type = AlphaGen | AlphaRes | AlphaLst; |
|
140 *} |
|
141 |
|
142 ML {* |
139 fun is_atom thy typ = |
143 fun is_atom thy typ = |
140 Sign.of_sort thy (typ, @{sort at}) |
144 Sign.of_sort thy (typ, @{sort at}) |
141 |
145 |
142 fun is_atom_set thy (Type ("fun", [t, @{typ bool}])) = is_atom thy t |
146 fun is_atom_set thy (Type ("fun", [t, @{typ bool}])) = is_atom thy t |
143 | is_atom_set thy _ = false; |
147 | is_atom_set _ _ = false; |
144 |
148 |
145 fun is_atom_fset thy (Type ("FSet.fset", [t])) = is_atom thy t |
149 fun is_atom_fset thy (Type ("FSet.fset", [t])) = is_atom thy t |
146 | is_atom_fset thy _ = false; |
150 | is_atom_fset _ _ = false; |
147 *} |
151 *} |
148 |
152 |
149 |
153 |
150 (* Like map2, only if the second list is empty passes empty lists insted of error *) |
154 (* Like map2, only if the second list is empty passes empty lists insted of error *) |
151 ML {* |
155 ML {* |
324 end |
328 end |
325 *} |
329 *} |
326 |
330 |
327 |
331 |
328 ML {* |
332 ML {* |
329 fun alpha_bn thy (dt_info : Datatype_Aux.info) alpha_frees bn_alphabn ((bn, ith_dtyp, args_in_bns), (alpha_bn_free, is_rec)) = |
333 fun alpha_bn (dt_info : Datatype_Aux.info) alpha_frees bn_alphabn ((bn, ith_dtyp, args_in_bns), (alpha_bn_free, _ (*is_rec*) )) = |
330 let |
334 let |
331 val {descr, sorts, ...} = dt_info; |
335 val {descr, sorts, ...} = dt_info; |
332 fun nth_dtyp i = typ_of_dtyp descr sorts (DtRec i); |
336 fun nth_dtyp i = typ_of_dtyp descr sorts (DtRec i); |
333 val pi = Free("pi", @{typ perm}) |
|
334 fun alpha_bn_constr (cname, dts) args_in_bn = |
337 fun alpha_bn_constr (cname, dts) args_in_bn = |
335 let |
338 let |
336 val Ts = map (typ_of_dtyp descr sorts) dts; |
339 val Ts = map (typ_of_dtyp descr sorts) dts; |
337 val names = Name.variant_list ["pi"] (Datatype_Prop.make_tnames Ts); |
340 val names = Name.variant_list ["pi"] (Datatype_Prop.make_tnames Ts); |
338 val names2 = Name.variant_list ("pi" :: names) (Datatype_Prop.make_tnames Ts); |
341 val names2 = Name.variant_list ("pi" :: names) (Datatype_Prop.make_tnames Ts); |
340 val args2 = map Free (names2 ~~ Ts); |
343 val args2 = map Free (names2 ~~ Ts); |
341 val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp)); |
344 val c = Const (cname, Ts ---> (nth_dtyp ith_dtyp)); |
342 val rhs = HOLogic.mk_Trueprop |
345 val rhs = HOLogic.mk_Trueprop |
343 (alpha_bn_free $ (list_comb (c, args)) $ (list_comb (c, args2))); |
346 (alpha_bn_free $ (list_comb (c, args)) $ (list_comb (c, args2))); |
344 fun lhs_arg ((dt, arg_no), (arg, arg2)) = |
347 fun lhs_arg ((dt, arg_no), (arg, arg2)) = |
345 let |
348 case AList.lookup (op=) args_in_bn arg_no of |
346 val argty = fastype_of arg; |
349 SOME NONE => @{term True} |
347 val permute = Const (@{const_name permute}, @{typ perm} --> argty --> argty); |
350 | SOME (SOME f) => (the (AList.lookup (op=) bn_alphabn f)) $ arg $ arg2 |
348 in |
351 | NONE => |
349 case AList.lookup (op=) args_in_bn arg_no of |
352 if is_rec_type dt then (nth alpha_frees (body_index dt)) $ arg $ arg2 |
350 SOME NONE => @{term True} |
353 else HOLogic.mk_eq (arg, arg2) |
351 | SOME (SOME f) => (the (AList.lookup (op=) bn_alphabn f)) $ arg $ arg2 |
|
352 | NONE => |
|
353 if is_rec_type dt then (nth alpha_frees (body_index dt)) $ arg $ arg2 |
|
354 else HOLogic.mk_eq (arg, arg2) |
|
355 end |
|
356 val arg_nos = 0 upto (length dts - 1) |
354 val arg_nos = 0 upto (length dts - 1) |
357 val lhss = mk_conjl (map lhs_arg (dts ~~ arg_nos ~~ (args ~~ args2))) |
355 val lhss = mk_conjl (map lhs_arg (dts ~~ arg_nos ~~ (args ~~ args2))) |
358 val eq = Logic.mk_implies (HOLogic.mk_Trueprop lhss, rhs) |
356 val eq = Logic.mk_implies (HOLogic.mk_Trueprop lhss, rhs) |
359 in |
357 in |
360 eq |
358 eq |
365 ((bn, alpha_bn_free), eqs) |
363 ((bn, alpha_bn_free), eqs) |
366 end |
364 end |
367 *} |
365 *} |
368 |
366 |
369 ML {* |
367 ML {* |
370 fun alpha_bns thy dt_info alpha_frees rel_bns bns_rec = |
368 fun alpha_bns dt_info alpha_frees rel_bns bns_rec = |
371 let |
369 let |
372 val {descr, sorts, ...} = dt_info; |
370 val {descr, sorts, ...} = dt_info; |
373 fun nth_dtyp i = typ_of_dtyp descr sorts (DtRec i); |
371 fun nth_dtyp i = typ_of_dtyp descr sorts (DtRec i); |
374 fun mk_alphabn_free (bn, ith, _) = |
372 fun mk_alphabn_free (bn, ith, _) = |
375 let |
373 let |
379 in |
377 in |
380 (alphabn_name, alphabn_free) |
378 (alphabn_name, alphabn_free) |
381 end; |
379 end; |
382 val (alphabn_names, alphabn_frees) = split_list (map mk_alphabn_free rel_bns); |
380 val (alphabn_names, alphabn_frees) = split_list (map mk_alphabn_free rel_bns); |
383 val bn_alphabn = (map (fn (bn, _, _) => bn) rel_bns) ~~ alphabn_frees; |
381 val bn_alphabn = (map (fn (bn, _, _) => bn) rel_bns) ~~ alphabn_frees; |
384 val pair = split_list (map (alpha_bn thy dt_info alpha_frees bn_alphabn) |
382 val pair = split_list (map (alpha_bn dt_info alpha_frees bn_alphabn) |
385 (rel_bns ~~ (alphabn_frees ~~ bns_rec))) |
383 (rel_bns ~~ (alphabn_frees ~~ bns_rec))) |
386 in |
384 in |
387 (alphabn_names, pair) |
385 (alphabn_names, pair) |
388 end |
386 end |
389 *} |
387 *} |
420 val alpha_types = map (fn (i, _) => nth_dtyp i --> nth_dtyp i --> @{typ bool}) descr; |
418 val alpha_types = map (fn (i, _) => nth_dtyp i --> nth_dtyp i --> @{typ bool}) descr; |
421 val alpha_frees = map Free (alpha_names ~~ alpha_types); |
419 val alpha_frees = map Free (alpha_names ~~ alpha_types); |
422 (* We assume that a bn is either recursive or not *) |
420 (* We assume that a bn is either recursive or not *) |
423 val bns_rec = map (fn (bn, _, _) => not (bn mem nr_bns)) bns; |
421 val bns_rec = map (fn (bn, _, _) => not (bn mem nr_bns)) bns; |
424 val (alpha_bn_names, (bn_alpha_bns, alpha_bn_eqs)) = |
422 val (alpha_bn_names, (bn_alpha_bns, alpha_bn_eqs)) = |
425 alpha_bns thy dt_info alpha_frees bns bns_rec |
423 alpha_bns dt_info alpha_frees bns bns_rec |
426 val alpha_bn_frees = map snd bn_alpha_bns; |
424 val alpha_bn_frees = map snd bn_alpha_bns; |
427 val alpha_bn_types = map fastype_of alpha_bn_frees; |
425 val alpha_bn_types = map fastype_of alpha_bn_frees; |
428 fun fv_alpha_constr ith_dtyp (cname, dts) bindcs = |
426 fun fv_alpha_constr ith_dtyp (cname, dts) bindcs = |
429 let |
427 let |
430 val Ts = map (typ_of_dtyp descr sorts) dts; |
428 val Ts = map (typ_of_dtyp descr sorts) dts; |
493 ([], [], [], []) => |
491 ([], [], [], []) => |
494 if is_rec_type dt then (nth alpha_frees (body_index dt) $ arg $ arg2) |
492 if is_rec_type dt then (nth alpha_frees (body_index dt) $ arg $ arg2) |
495 else (HOLogic.mk_eq (arg, arg2)) |
493 else (HOLogic.mk_eq (arg, arg2)) |
496 | (_, [], [], []) => @{term True} |
494 | (_, [], [], []) => @{term True} |
497 | ([], [], [], _) => @{term True} |
495 | ([], [], [], _) => @{term True} |
498 | ([], ((((SOME (bn, is_rec)), _, _), pi) :: _), [], []) => |
496 | ([], ((((SOME (bn, is_rec)), _, _), _) :: _), [], []) => |
499 if not (bns_same rel_in_comp_binds) then error "incompatible bindings for an argument" else |
497 if not (bns_same rel_in_comp_binds) then error "incompatible bindings for an argument" else |
500 if is_rec then |
498 if is_rec then |
501 let |
499 let |
502 val (rbinds, rpis) = split_list rel_in_comp_binds |
500 val (rbinds, rpis) = split_list rel_in_comp_binds |
503 val bound_in_nos = map (fn (_, _, i) => i) rbinds |
501 val bound_in_nos = map (fn (_, _, i) => i) rbinds |
504 val bound_in_ty_nos = map (fn i => body_index (nth dts i)) bound_in_nos; |
502 val bound_in_ty_nos = map (fn i => body_index (nth dts i)) bound_in_nos; |
505 val bound_args = arg :: map (nth args) bound_in_nos; |
503 val bound_args = arg :: map (nth args) bound_in_nos; |
506 val bound_args2 = arg2 :: map (nth args2) bound_in_nos; |
504 val bound_args2 = arg2 :: map (nth args2) bound_in_nos; |
507 fun bound_in args (_, _, i) = nth args i; |
|
508 val lhs_binds = fv_binds args rbinds |
505 val lhs_binds = fv_binds args rbinds |
509 val lhs_arg = foldr1 HOLogic.mk_prod bound_args |
506 val lhs_arg = foldr1 HOLogic.mk_prod bound_args |
510 val lhs = mk_pair (lhs_binds, lhs_arg); |
507 val lhs = mk_pair (lhs_binds, lhs_arg); |
511 val rhs_binds = fv_binds args2 rbinds; |
508 val rhs_binds = fv_binds args2 rbinds; |
512 val rhs_arg = foldr1 HOLogic.mk_prod bound_args2; |
509 val rhs_arg = foldr1 HOLogic.mk_prod bound_args2; |
576 coind = false, no_elim = false, no_ind = false, skip_mono = true, fork_mono = false} |
573 coind = false, no_elim = false, no_ind = false, skip_mono = true, fork_mono = false} |
577 (map2 (fn x => fn y => ((Binding.name x, y), NoSyn)) (alpha_names @ alpha_bn_names) |
574 (map2 (fn x => fn y => ((Binding.name x, y), NoSyn)) (alpha_names @ alpha_bn_names) |
578 (alpha_types @ alpha_bn_types)) [] |
575 (alpha_types @ alpha_bn_types)) [] |
579 (add_binds (alpha_eqs @ flat alpha_bn_eqs)) [] lthy'') |
576 (add_binds (alpha_eqs @ flat alpha_bn_eqs)) [] lthy'') |
580 val ordered_fvs = fv_frees @ fvbns; |
577 val ordered_fvs = fv_frees @ fvbns; |
581 val exported_fvs = map (Morphism.term (ProofContext.export_morphism lthy''' lthy)) ordered_fvs; |
|
582 val all_fvs = (fst fvs @ fst fvs2, snd fvs @ snd fvs2) |
578 val all_fvs = (fst fvs @ fst fvs2, snd fvs @ snd fvs2) |
583 in |
579 in |
584 (((all_fvs, ordered_fvs), alphas), lthy''') |
580 (((all_fvs, ordered_fvs), alphas), lthy''') |
585 end |
581 end |
586 *} |
582 *} |
619 val tys = map (domain_type o fastype_of) alpha_ts; |
615 val tys = map (domain_type o fastype_of) alpha_ts; |
620 val names = Datatype_Prop.make_tnames tys; |
616 val names = Datatype_Prop.make_tnames tys; |
621 val args = map Free (names ~~ tys); |
617 val args = map Free (names ~~ tys); |
622 fun find_alphas ty x = |
618 fun find_alphas ty x = |
623 domain_type (fastype_of x) = ty; |
619 domain_type (fastype_of x) = ty; |
624 fun mk_alpha_refl arg (_, alpha) = alpha $ arg $ arg; |
|
625 fun refl_eq_arg (ty, arg) = |
620 fun refl_eq_arg (ty, arg) = |
626 let |
621 let |
627 val rel_alphas = filter (find_alphas ty) alphas; |
622 val rel_alphas = filter (find_alphas ty) alphas; |
628 in |
623 in |
629 map (fn x => x $ arg $ arg) rel_alphas |
624 map (fn x => x $ arg $ arg) rel_alphas |
634 (names, HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj eqs)) |
629 (names, HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj eqs)) |
635 end |
630 end |
636 *} |
631 *} |
637 |
632 |
638 ML {* |
633 ML {* |
639 fun reflp_tac induct eq_iff ctxt = |
634 fun reflp_tac induct eq_iff = |
640 rtac induct THEN_ALL_NEW |
635 rtac induct THEN_ALL_NEW |
641 simp_tac (HOL_basic_ss addsimps eq_iff) THEN_ALL_NEW |
636 simp_tac (HOL_basic_ss addsimps eq_iff) THEN_ALL_NEW |
642 split_conj_tac THEN_ALL_NEW REPEAT o rtac @{thm exI[of _ "0 :: perm"]} |
637 split_conj_tac THEN_ALL_NEW REPEAT o rtac @{thm exI[of _ "0 :: perm"]} |
643 THEN_ALL_NEW split_conj_tac THEN_ALL_NEW asm_full_simp_tac (HOL_ss addsimps |
638 THEN_ALL_NEW split_conj_tac THEN_ALL_NEW asm_full_simp_tac (HOL_ss addsimps |
644 @{thms alpha_gen fresh_star_def fresh_zero_perm permute_zero ball_triv |
639 @{thms alpha_gen fresh_star_def fresh_zero_perm permute_zero ball_triv |