123 |
123 |
124 val raw_bn_induct = (the inducts) |
124 val raw_bn_induct = (the inducts) |
125 val raw_bn_eqs = the simps |
125 val raw_bn_eqs = the simps |
126 |
126 |
127 val raw_bn_info = |
127 val raw_bn_info = |
128 prep_bn_info lthy raw_dt_names raw_dts fs (map prop_of raw_bn_eqs) |
128 prep_bn_info lthy raw_dt_names raw_dts fs (map Thm.prop_of raw_bn_eqs) |
129 in |
129 in |
130 (fs, raw_bn_eqs, raw_bn_info, raw_bn_induct, lthy2) |
130 (fs, raw_bn_eqs, raw_bn_info, raw_bn_induct, lthy2) |
131 end |
131 end |
132 |
132 |
133 |
133 |
197 | _ => mk_fv_rhs lthy fv_map fv_bn_map args bclause |
197 | _ => mk_fv_rhs lthy fv_map fv_bn_map args bclause |
198 end |
198 end |
199 |
199 |
200 fun mk_fv_eq lthy fv_map fv_bn_map (constr, ty, arg_tys, _) bclauses = |
200 fun mk_fv_eq lthy fv_map fv_bn_map (constr, ty, arg_tys, _) bclauses = |
201 let |
201 let |
202 val arg_names = Datatype_Prop.make_tnames arg_tys |
202 val arg_names = Old_Datatype_Prop.make_tnames arg_tys |
203 val args = map Free (arg_names ~~ arg_tys) |
203 val args = map Free (arg_names ~~ arg_tys) |
204 val fv = lookup fv_map ty |
204 val fv = lookup fv_map ty |
205 val lhs = fv $ list_comb (constr, args) |
205 val lhs = fv $ list_comb (constr, args) |
206 val rhs_trms = map (mk_fv_rhs lthy fv_map fv_bn_map args) bclauses |
206 val rhs_trms = map (mk_fv_rhs lthy fv_map fv_bn_map args) bclauses |
207 val rhs = fold_union rhs_trms |
207 val rhs = fold_union rhs_trms |
209 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs)) |
209 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs)) |
210 end |
210 end |
211 |
211 |
212 fun mk_fv_bn_eq lthy bn_trm fv_map fv_bn_map (bn_args, (constr, _, arg_tys, _)) bclauses = |
212 fun mk_fv_bn_eq lthy bn_trm fv_map fv_bn_map (bn_args, (constr, _, arg_tys, _)) bclauses = |
213 let |
213 let |
214 val arg_names = Datatype_Prop.make_tnames arg_tys |
214 val arg_names = Old_Datatype_Prop.make_tnames arg_tys |
215 val args = map Free (arg_names ~~ arg_tys) |
215 val args = map Free (arg_names ~~ arg_tys) |
216 val fv_bn = lookup fv_bn_map bn_trm |
216 val fv_bn = lookup fv_bn_map bn_trm |
217 val lhs = fv_bn $ list_comb (constr, args) |
217 val lhs = fv_bn $ list_comb (constr, args) |
218 val rhs_trms = map (mk_fv_bn_rhs lthy fv_map fv_bn_map bn_args args) bclauses |
218 val rhs_trms = map (mk_fv_bn_rhs lthy fv_map fv_bn_map bn_args args) bclauses |
219 val rhs = fold_union rhs_trms |
219 val rhs = fold_union rhs_trms |
285 |
285 |
286 |
286 |
287 fun mk_perm_bn_eq lthy bn_trm perm_bn_map bn_args (constr, _, arg_tys, _) = |
287 fun mk_perm_bn_eq lthy bn_trm perm_bn_map bn_args (constr, _, arg_tys, _) = |
288 let |
288 let |
289 val p = Free ("p", @{typ perm}) |
289 val p = Free ("p", @{typ perm}) |
290 val arg_names = Datatype_Prop.make_tnames arg_tys |
290 val arg_names = Old_Datatype_Prop.make_tnames arg_tys |
291 val args = map Free (arg_names ~~ arg_tys) |
291 val args = map Free (arg_names ~~ arg_tys) |
292 val perm_bn = lookup perm_bn_map bn_trm |
292 val perm_bn = lookup perm_bn_map bn_trm |
293 val lhs = perm_bn $ p $ list_comb (constr, args) |
293 val lhs = perm_bn $ p $ list_comb (constr, args) |
294 val rhs = list_comb (constr, map_index (mk_perm_bn_eq_rhs p perm_bn_map bn_args) args) |
294 val rhs = list_comb (constr, map_index (mk_perm_bn_eq_rhs p perm_bn_map bn_args) args) |
295 in |
295 in |
345 (** proves the two pt-type class properties **) |
345 (** proves the two pt-type class properties **) |
346 |
346 |
347 fun prove_permute_zero induct perm_defs perm_fns ctxt = |
347 fun prove_permute_zero induct perm_defs perm_fns ctxt = |
348 let |
348 let |
349 val perm_types = map (body_type o fastype_of) perm_fns |
349 val perm_types = map (body_type o fastype_of) perm_fns |
350 val perm_indnames = Datatype_Prop.make_tnames perm_types |
350 val perm_indnames = Old_Datatype_Prop.make_tnames perm_types |
351 |
351 |
352 fun single_goal ((perm_fn, T), x) = |
352 fun single_goal ((perm_fn, T), x) = |
353 HOLogic.mk_eq (perm_fn $ @{term "0::perm"} $ Free (x, T), Free (x, T)) |
353 HOLogic.mk_eq (perm_fn $ @{term "0::perm"} $ Free (x, T), Free (x, T)) |
354 |
354 |
355 val goals = |
355 val goals = |
356 HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj |
356 HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj |
357 (map single_goal (perm_fns ~~ perm_types ~~ perm_indnames))) |
357 (map single_goal (perm_fns ~~ perm_types ~~ perm_indnames))) |
358 |
358 |
359 val simpset = put_simpset HOL_basic_ss ctxt addsimps (@{thm permute_zero} :: perm_defs) |
359 val simpset = put_simpset HOL_basic_ss ctxt addsimps (@{thm permute_zero} :: perm_defs) |
360 |
360 |
361 val tac = (Datatype_Aux.ind_tac induct perm_indnames |
361 val tac = (Old_Datatype_Aux.ind_tac induct perm_indnames |
362 THEN_ALL_NEW asm_simp_tac simpset) 1 |
362 THEN_ALL_NEW asm_simp_tac simpset) 1 |
363 in |
363 in |
364 Goal.prove ctxt perm_indnames [] goals (K tac) |
364 Goal.prove ctxt perm_indnames [] goals (K tac) |
365 |> Datatype_Aux.split_conj_thm |
365 |> Old_Datatype_Aux.split_conj_thm |
366 end |
366 end |
367 |
367 |
368 |
368 |
369 fun prove_permute_plus induct perm_defs perm_fns ctxt = |
369 fun prove_permute_plus induct perm_defs perm_fns ctxt = |
370 let |
370 let |
371 val p = Free ("p", @{typ perm}) |
371 val p = Free ("p", @{typ perm}) |
372 val q = Free ("q", @{typ perm}) |
372 val q = Free ("q", @{typ perm}) |
373 val perm_types = map (body_type o fastype_of) perm_fns |
373 val perm_types = map (body_type o fastype_of) perm_fns |
374 val perm_indnames = Datatype_Prop.make_tnames perm_types |
374 val perm_indnames = Old_Datatype_Prop.make_tnames perm_types |
375 |
375 |
376 fun single_goal ((perm_fn, T), x) = HOLogic.mk_eq |
376 fun single_goal ((perm_fn, T), x) = HOLogic.mk_eq |
377 (perm_fn $ (mk_plus p q) $ Free (x, T), perm_fn $ p $ (perm_fn $ q $ Free (x, T))) |
377 (perm_fn $ (mk_plus p q) $ Free (x, T), perm_fn $ p $ (perm_fn $ q $ Free (x, T))) |
378 |
378 |
379 val goals = |
379 val goals = |
381 (map single_goal (perm_fns ~~ perm_types ~~ perm_indnames))) |
381 (map single_goal (perm_fns ~~ perm_types ~~ perm_indnames))) |
382 |
382 |
383 (* FIXME proper goal context *) |
383 (* FIXME proper goal context *) |
384 val simpset = put_simpset HOL_basic_ss ctxt addsimps (@{thm permute_plus} :: perm_defs) |
384 val simpset = put_simpset HOL_basic_ss ctxt addsimps (@{thm permute_plus} :: perm_defs) |
385 |
385 |
386 val tac = (Datatype_Aux.ind_tac induct perm_indnames |
386 val tac = (Old_Datatype_Aux.ind_tac induct perm_indnames |
387 THEN_ALL_NEW asm_simp_tac simpset) 1 |
387 THEN_ALL_NEW asm_simp_tac simpset) 1 |
388 in |
388 in |
389 Goal.prove ctxt ("p" :: "q" :: perm_indnames) [] goals (K tac) |
389 Goal.prove ctxt ("p" :: "q" :: perm_indnames) [] goals (K tac) |
390 |> Datatype_Aux.split_conj_thm |
390 |> Old_Datatype_Aux.split_conj_thm |
391 end |
391 end |
392 |
392 |
393 |
393 |
394 fun mk_perm_eq ty_perm_assoc cnstr = |
394 fun mk_perm_eq ty_perm_assoc cnstr = |
395 let |
395 let |
401 val p = Free ("p", @{typ perm}) |
401 val p = Free ("p", @{typ perm}) |
402 val (arg_tys, ty) = |
402 val (arg_tys, ty) = |
403 fastype_of cnstr |
403 fastype_of cnstr |
404 |> strip_type |
404 |> strip_type |
405 |
405 |
406 val arg_names = Name.variant_list ["p"] (Datatype_Prop.make_tnames arg_tys) |
406 val arg_names = Name.variant_list ["p"] (Old_Datatype_Prop.make_tnames arg_tys) |
407 val args = map Free (arg_names ~~ arg_tys) |
407 val args = map Free (arg_names ~~ arg_tys) |
408 |
408 |
409 val lhs = lookup_perm p (ty, list_comb (cnstr, args)) |
409 val lhs = lookup_perm p (ty, list_comb (cnstr, args)) |
410 val rhs = list_comb (cnstr, map (lookup_perm p) (arg_tys ~~ args)) |
410 val rhs = list_comb (cnstr, map (lookup_perm p) (arg_tys ~~ args)) |
411 |
411 |
428 val perm_fn_frees = map Free (perm_fn_names ~~ perm_fn_types) |
428 val perm_fn_frees = map Free (perm_fn_names ~~ perm_fn_types) |
429 val perm_fn_binds = map (fn s => (Binding.name s, NONE, NoSyn)) perm_fn_names |
429 val perm_fn_binds = map (fn s => (Binding.name s, NONE, NoSyn)) perm_fn_names |
430 |
430 |
431 val perm_eqs = map (mk_perm_eq (raw_tys ~~ perm_fn_frees)) (flat raw_all_cns) |
431 val perm_eqs = map (mk_perm_eq (raw_tys ~~ perm_fn_frees)) (flat raw_all_cns) |
432 |
432 |
433 fun tac _ (_, _, simps) = |
433 fun tac ctxt (_, _, simps) = |
434 Class.intro_classes_tac [] THEN ALLGOALS (resolve_tac simps) |
434 Class.intro_classes_tac ctxt [] THEN ALLGOALS (resolve_tac ctxt simps) |
435 |
435 |
436 fun morphism phi (fvs, dfs, simps) = |
436 fun morphism phi (fvs, dfs, simps) = |
437 (map (Morphism.term phi) fvs, |
437 (map (Morphism.term phi) fvs, |
438 map (Morphism.thm phi) dfs, |
438 map (Morphism.thm phi) dfs, |
439 map (Morphism.thm phi) simps); |
439 map (Morphism.thm phi) simps); |
440 |
440 |
441 val ((perm_funs, perm_eq_thms), lthy') = |
441 val ((perm_funs, perm_eq_thms), lthy') = |
442 lthy |
442 lthy |
443 |> Local_Theory.exit_global |
443 |> Local_Theory.exit_global |
444 |> Class.instantiation (raw_dt_names, raw_ty_args, @{sort pt}) |
444 |> Class.instantiation (raw_dt_names, raw_ty_args, @{sort pt}) |
445 |> Primrec.add_primrec perm_fn_binds perm_eqs |
445 |> BNF_LFP_Compat.primrec perm_fn_binds perm_eqs |
446 |
446 |
447 val perm_zero_thms = prove_permute_zero raw_induct_thm perm_eq_thms perm_funs lthy' |
447 val perm_zero_thms = prove_permute_zero raw_induct_thm perm_eq_thms perm_funs lthy' |
448 val perm_plus_thms = prove_permute_plus raw_induct_thm perm_eq_thms perm_funs lthy' |
448 val perm_plus_thms = prove_permute_plus raw_induct_thm perm_eq_thms perm_funs lthy' |
449 in |
449 in |
450 lthy' |
450 lthy' |
466 THEN' simp_tac (put_simpset HOL_basic_ss ctxt addsimps (prems @ [eqvt_apply_sym])))) |
466 THEN' simp_tac (put_simpset HOL_basic_ss ctxt addsimps (prems @ [eqvt_apply_sym])))) |
467 |
467 |
468 fun prove_eqvt_tac insts ind_thms const_names simps ctxt = |
468 fun prove_eqvt_tac insts ind_thms const_names simps ctxt = |
469 HEADGOAL |
469 HEADGOAL |
470 (Object_Logic.full_atomize_tac ctxt |
470 (Object_Logic.full_atomize_tac ctxt |
471 THEN' (DETERM o (Induct_Tacs.induct_rules_tac ctxt insts ind_thms)) |
471 THEN' (DETERM o (Induct_Tacs.induct_tac ctxt insts (SOME ind_thms))) |
472 THEN_ALL_NEW subproof_tac const_names simps ctxt) |
472 THEN_ALL_NEW subproof_tac const_names simps ctxt) |
473 |
473 |
474 fun mk_eqvt_goal pi const arg = |
474 fun mk_eqvt_goal pi const arg = |
475 let |
475 let |
476 val lhs = mk_perm pi (const $ arg) |
476 val lhs = mk_perm pi (const $ arg) |
489 val arg_tys = |
489 val arg_tys = |
490 consts |
490 consts |
491 |> map fastype_of |
491 |> map fastype_of |
492 |> map domain_type |
492 |> map domain_type |
493 val (arg_names, ctxt'') = |
493 val (arg_names, ctxt'') = |
494 Variable.variant_fixes (Datatype_Prop.make_tnames arg_tys) ctxt' |
494 Variable.variant_fixes (Old_Datatype_Prop.make_tnames arg_tys) ctxt' |
495 val args = map Free (arg_names ~~ arg_tys) |
495 val args = map Free (arg_names ~~ arg_tys) |
496 val goals = map2 (mk_eqvt_goal p) consts args |
496 val goals = map2 (mk_eqvt_goal p) consts args |
497 val insts = map (single o SOME) arg_names |
497 val insts = map (single o SOME) arg_names |
498 val const_names = map (fst o dest_Const) consts |
498 val const_names = map (fst o dest_Const) consts |
499 in |
499 in |
500 Goal.prove_multi ctxt'' [] [] goals (fn {context, ...} => |
500 Goal.prove_common ctxt'' NONE [] [] goals (fn {context, ...} => |
501 prove_eqvt_tac insts ind_thms const_names simps context) |
501 prove_eqvt_tac insts ind_thms const_names simps context) |
502 |> Proof_Context.export ctxt'' ctxt |
502 |> Proof_Context.export ctxt'' ctxt |
503 end |
503 end |
504 |
504 |
505 |
505 |