319 val alpha_inj_loc = build_alpha_inj alpha_intros (inject @ distinct) alpha_cases_loc lthy4 |
334 val alpha_inj_loc = build_alpha_inj alpha_intros (inject @ distinct) alpha_cases_loc lthy4 |
320 val alpha_inj = ProofContext.export lthy4 lthy3 alpha_inj_loc |
335 val alpha_inj = ProofContext.export lthy4 lthy3 alpha_inj_loc |
321 fun alpha_eqvt_tac' _ = |
336 fun alpha_eqvt_tac' _ = |
322 if !cheat_alpha_eqvt then Skip_Proof.cheat_tac thy |
337 if !cheat_alpha_eqvt then Skip_Proof.cheat_tac thy |
323 else alpha_eqvt_tac alpha_induct_loc (raw_perm_def @ alpha_inj_loc) lthy4 1 |
338 else alpha_eqvt_tac alpha_induct_loc (raw_perm_def @ alpha_inj_loc) lthy4 1 |
324 val alpha_eqvt_loc = build_alpha_eqvts (List.take (alpha_ts_loc, length perms)) perms alpha_eqvt_tac' lthy4; |
339 val alpha_eqvt_loc = build_alpha_eqvts alpha_ts_loc_nobn perms alpha_eqvt_tac' lthy4; |
325 val alpha_eqvt = ProofContext.export lthy4 lthy2 alpha_eqvt_loc; |
340 val alpha_eqvt = ProofContext.export lthy4 lthy2 alpha_eqvt_loc; |
326 in |
341 val (bv_eqvts, lthy5) = fold_map (build_bv_eqvt (raw_bn_eqs @ raw_perm_def) inducts) bns lthy4; |
327 if !restricted_nominal = 0 then |
342 val fv_eqvt_tac = |
328 ((raw_dt_names, raw_bn_funs, raw_bn_eqs, raw_binds), lthy4) |
343 if !cheat_fv_eqvt then (fn _ => fn _ => Skip_Proof.cheat_tac thy) |
329 else |
344 else build_eqvts_tac induct ((flat (map snd bv_eqvts)) @ fv_def_loc @ raw_perm_def) lthy5 |
330 let |
345 val (fv_eqvts, lthy6) = build_eqvts Binding.empty fv_ts_loc fv_eqvt_tac lthy5; |
331 val (bv_eqvts, lthy5) = fold_map (build_bv_eqvt perms (raw_bn_eqs @ raw_perm_def) inducts) bns lthy4; |
|
332 val (fv_eqvts, lthy6) = build_eqvts Binding.empty fv_ts_loc perms |
|
333 ((flat (map snd bv_eqvts)) @ fv_def_loc @ raw_perm_def) induct lthy5; |
|
334 val raw_fv_bv_eqvt_loc = flat (map snd bv_eqvts) @ (snd fv_eqvts) |
346 val raw_fv_bv_eqvt_loc = flat (map snd bv_eqvts) @ (snd fv_eqvts) |
335 val raw_fv_bv_eqvt = ProofContext.export lthy6 lthy3 raw_fv_bv_eqvt_loc; |
347 val raw_fv_bv_eqvt = ProofContext.export lthy6 lthy3 raw_fv_bv_eqvt_loc; |
336 val alpha_equivp_loc = map (equivp_hack lthy6) alpha_ts_loc |
348 val alpha_equivp_loc = map (equivp_hack lthy6) alpha_ts_loc_nobn |
337 val alpha_equivp_loc = build_equivps alpha_ts_loc induct alpha_induct_loc |
349 (* val alpha_equivp_loc = build_equivps alpha_ts_loc induct alpha_induct_loc |
338 inject alpha_inj_loc distinct alpha_cases_loc alpha_eqvt_loc lthy6; |
350 inject alpha_inj_loc distinct alpha_cases_loc alpha_eqvt_loc lthy6;*) |
339 val alpha_equivp = ProofContext.export lthy6 lthy2 alpha_equivp_loc; |
351 val alpha_equivp = ProofContext.export lthy6 lthy2 alpha_equivp_loc; |
340 val qty_binds = map (fn (_, b, _, _) => b) dts; |
352 val qty_binds = map (fn (_, b, _, _) => b) dts; |
341 val qty_names = map Name.of_binding qty_binds; |
353 val qty_names = map Name.of_binding qty_binds; |
342 val qty_full_names = map (Long_Name.qualify thy_name) qty_names |
354 val qty_full_names = map (Long_Name.qualify thy_name) qty_names |
343 val lthy7 = define_quotient_type |
355 val lthy7 = define_quotient_type |
344 (map (fn ((b, t), alpha) => (([], b, NoSyn), (t, alpha))) ((qty_binds ~~ all_typs) ~~ alpha_ts)) |
356 (map (fn ((b, t), alpha) => (([], b, NoSyn), (t, alpha))) ((qty_binds ~~ all_typs) ~~ alpha_ts_nobn)) |
345 (ALLGOALS (resolve_tac alpha_equivp)) lthy6; |
357 (ALLGOALS (resolve_tac alpha_equivp)) lthy6; |
346 val const_names = map Name.of_binding (flat (map (fn (_, _, _, t) => map (fn (b, _, _) => b) t) dts)); |
358 val const_names = map Name.of_binding (flat (map (fn (_, _, _, t) => map (fn (b, _, _) => b) t) dts)); |
347 val raw_consts = |
359 val raw_consts = |
348 flat (map (fn (i, (_, _, l)) => |
360 flat (map (fn (i, (_, _, l)) => |
349 map (fn (cname, dts) => |
361 map (fn (cname, dts) => |
350 Const (cname, map (typ_of_dtyp descr sorts) dts ---> |
362 Const (cname, map (typ_of_dtyp descr sorts) dts ---> |
351 typ_of_dtyp descr sorts (DtRec i))) l) descr); |
363 typ_of_dtyp descr sorts (DtRec i))) l) descr); |
352 val (consts_defs, lthy8) = fold_map Quotient_Def.quotient_lift_const (const_names ~~ raw_consts) lthy7; |
364 val (consts_defs, lthy8) = fold_map Quotient_Def.quotient_lift_const (const_names ~~ raw_consts) lthy7; |
353 val (consts, const_defs) = split_list consts_defs; |
365 val (consts, const_defs) = split_list consts_defs; |
354 in |
|
355 if !restricted_nominal = 1 then |
|
356 ((raw_dt_names, raw_bn_funs, raw_bn_eqs, raw_binds), lthy8) |
|
357 else |
|
358 let |
|
359 val (bns_rsp_pre, lthy9) = fold_map ( |
366 val (bns_rsp_pre, lthy9) = fold_map ( |
360 fn (bn_t, i) => prove_const_rsp Binding.empty [bn_t] |
367 fn (bn_t, i) => prove_const_rsp Binding.empty [bn_t] |
361 (fn _ => fvbv_rsp_tac (nth alpha_inducts i) raw_bn_eqs 1)) bns lthy8; |
368 (fn _ => fvbv_rsp_tac (nth alpha_inducts i) raw_bn_eqs 1)) bns lthy8; |
362 val bns_rsp = flat (map snd bns_rsp_pre); |
369 val bns_rsp = flat (map snd bns_rsp_pre); |
363 val ((_, fv_rsp), lthy10) = prove_const_rsp Binding.empty fv_ts |
370 fun fv_rsp_tac _ = if !cheat_fv_rsp then Skip_Proof.cheat_tac thy |
364 (fn _ => fvbv_rsp_tac alpha_induct fv_def 1) lthy9; |
371 else fvbv_rsp_tac alpha_induct fv_def 1; |
365 val (const_rsps, lthy11) = fold_map (fn cnst => prove_const_rsp Binding.empty [cnst] |
372 val ((_, fv_rsp), lthy10) = prove_const_rsp Binding.empty fv_ts fv_rsp_tac lthy9 |
366 (fn _ => constr_rsp_tac alpha_inj (fv_rsp @ bns_rsp) alpha_equivp 1)) raw_consts lthy10 |
373 val (perms_rsp, lthy11) = prove_const_rsp Binding.empty perms |
367 val (perms_rsp, lthy12) = prove_const_rsp Binding.empty perms |
374 (fn _ => asm_simp_tac (HOL_ss addsimps alpha_eqvt) 1) lthy10; |
368 (fn _ => asm_simp_tac (HOL_ss addsimps alpha_eqvt) 1) lthy11; |
375 fun const_rsp_tac _ = if !cheat_const_rsp then Skip_Proof.cheat_tac thy |
369 val qfv_names = map (fn x => "fv_" ^ x) qty_names |
376 else constr_rsp_tac alpha_inj (fv_rsp @ bns_rsp) alpha_equivp 1 |
|
377 val (const_rsps, lthy12) = fold_map (fn cnst => prove_const_rsp Binding.empty [cnst] |
|
378 const_rsp_tac) (raw_consts @ alpha_ts_bn) lthy11 |
|
379 val qfv_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) fv_ts |
370 val (qfv_defs, lthy12a) = fold_map Quotient_Def.quotient_lift_const (qfv_names ~~ fv_ts) lthy12; |
380 val (qfv_defs, lthy12a) = fold_map Quotient_Def.quotient_lift_const (qfv_names ~~ fv_ts) lthy12; |
371 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
381 val qbn_names = map (fn (b, _ , _) => Name.of_binding b) bn_funs |
372 val (qbn_defs, lthy12b) = fold_map Quotient_Def.quotient_lift_const (qbn_names ~~ raw_bn_funs) lthy12a; |
382 val (qbn_defs, lthy12b) = fold_map Quotient_Def.quotient_lift_const (qbn_names ~~ raw_bn_funs) lthy12a; |
373 val thy = Local_Theory.exit_global lthy12b; |
383 val qalpha_bn_names = map (unsuffix "_raw" o Long_Name.base_name o fst o dest_Const) alpha_ts_bn |
|
384 val (qbn_defs, lthy12c) = fold_map Quotient_Def.quotient_lift_const (qalpha_bn_names ~~ alpha_ts_bn) lthy12b; |
|
385 val thy = Local_Theory.exit_global lthy12c; |
374 val perm_names = map (fn x => "permute_" ^ x) qty_names |
386 val perm_names = map (fn x => "permute_" ^ x) qty_names |
375 val thy' = define_lifted_perms qty_full_names (perm_names ~~ perms) raw_perm_simps thy; |
387 val thy' = define_lifted_perms qty_full_names (perm_names ~~ perms) raw_perm_simps thy; |
376 val lthy13 = Theory_Target.init NONE thy'; |
388 val lthy13 = Theory_Target.init NONE thy'; |
377 val q_name = space_implode "_" qty_names; |
389 val q_name = space_implode "_" qty_names; |
378 val q_induct = snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy13, induct)); |
390 val q_induct = lift_thm lthy13 induct; |
379 val (_, lthy14) = Local_Theory.note ((Binding.name (q_name ^ "_induct"), []), [q_induct]) lthy13; |
391 val (_, lthy14) = Local_Theory.note ((Binding.name (q_name ^ "_induct"), []), [q_induct]) lthy13; |
380 val q_perm = map (fn th => snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy14, th))) raw_perm_def; |
392 val q_perm = map (lift_thm lthy14) raw_perm_def; |
381 val (_, lthy15) = Local_Theory.note ((Binding.name (q_name ^ "_perm"), []), q_perm) lthy14; |
393 val (_, lthy15) = Local_Theory.note ((Binding.name (q_name ^ "_perm"), []), q_perm) lthy14; |
382 val q_fv = map (fn th => snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy15, th))) fv_def; |
394 val q_fv = map (lift_thm lthy15) fv_def; |
383 val (_, lthy16) = Local_Theory.note ((Binding.name (q_name ^ "_fv"), []), q_fv) lthy15; |
395 val (_, lthy16) = Local_Theory.note ((Binding.name (q_name ^ "_fv"), []), q_fv) lthy15; |
384 val q_bn = map (fn th => snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy16, th))) raw_bn_eqs; |
396 val q_bn = map (lift_thm lthy16) raw_bn_eqs; |
385 val (_, lthy17) = Local_Theory.note ((Binding.name (q_name ^ "_bn"), []), q_bn) lthy16; |
397 val (_, lthy17) = Local_Theory.note ((Binding.name (q_name ^ "_bn"), []), q_bn) lthy16; |
386 val inj_unfolded = map (Local_Defs.unfold lthy17 @{thms alpha_gen}) alpha_inj |
398 val inj_unfolded = map (Local_Defs.unfold lthy17 @{thms alpha_gen}) alpha_inj |
387 val q_inj_pre = map (fn th => snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy17, th))) inj_unfolded; |
399 val q_inj_pre = map (lift_thm lthy17) inj_unfolded; |
388 val q_inj = map (Local_Defs.fold lthy17 @{thms alpha_gen}) q_inj_pre |
400 val q_inj = map (Local_Defs.fold lthy17 @{thms alpha_gen}) q_inj_pre |
389 val (_, lthy18) = Local_Theory.note ((Binding.name (q_name ^ "_inject"), []), q_inj) lthy17; |
401 val (_, lthy18) = Local_Theory.note ((Binding.name (q_name ^ "_inject"), []), q_inj) lthy17; |
390 val rel_dists = flat (map (distinct_rel lthy18 alpha_cases) |
402 val rel_dists = flat (map (distinct_rel lthy18 alpha_cases) |
391 (rel_distinct ~~ (List.take (alpha_ts, (length dts))))) |
403 (rel_distinct ~~ (List.take (alpha_ts, (length dts))))) |
392 val q_dis = map (fn th => snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy18, th))) rel_dists; |
404 val q_dis = map (lift_thm lthy18) rel_dists; |
393 val (_, lthy19) = Local_Theory.note ((Binding.name (q_name ^ "_distinct"), []), q_dis) lthy18; |
405 val (_, lthy19) = Local_Theory.note ((Binding.name (q_name ^ "_distinct"), []), q_dis) lthy18; |
394 val q_eqvt = map (fn th => snd (Quotient_Tacs.lifted_attrib (Context.Proof lthy19, th))) raw_fv_bv_eqvt; |
406 val q_eqvt = map (lift_thm lthy19) raw_fv_bv_eqvt; |
395 val (_, lthy20) = Local_Theory.note ((Binding.empty, |
407 val (_, lthy20) = Local_Theory.note ((Binding.empty, |
396 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19; |
408 [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19; |
397 in |
409 in |
398 ((raw_dt_names, raw_bn_funs, raw_bn_eqs, raw_binds), lthy20) |
410 ((raw_dt_names, raw_bn_funs, raw_bn_eqs, raw_binds), lthy20) |
399 end |
411 end |
400 end |
412 *} |
401 end |
413 |
402 *} |
|
403 |
414 |
404 ML {* |
415 ML {* |
405 (* parsing the datatypes and declaring *) |
416 (* parsing the datatypes and declaring *) |
406 (* constructors in the local theory *) |
417 (* constructors in the local theory *) |
407 fun prepare_dts dt_strs lthy = |
418 fun prepare_dts dt_strs lthy = |