398 val distinct = |
398 val distinct = |
399 mk_distinct cos |
399 mk_distinct cos |
400 |> map (fn t => Goal.prove_global thy [] [] t (K tac)) |
400 |> map (fn t => Goal.prove_global thy [] [] t (K tac)) |
401 |> map (fn thm => not_eq_quodlibet OF [thm]) |
401 |> map (fn thm => not_eq_quodlibet OF [thm]) |
402 in inject @ distinct end |
402 in inject @ distinct end |
403 and get_cert_typecopy thy dtco = |
|
404 let |
|
405 val SOME { inject, ... } = TypecopyPackage.get_typecopy_info thy dtco; |
|
406 val thm = Tactic.rewrite_rule [rew_eq] (bool_eq_implies OF [inject]); |
|
407 in |
|
408 [thm] |
|
409 end; |
|
410 end (*local*); |
403 end (*local*); |
411 |
404 |
412 fun get_cert thy (true, dtco) = get_cert_datatype thy dtco |
405 local |
413 | get_cert thy (false, dtco) = get_cert_typecopy thy dtco; |
406 val not_sym = thm "HOL.not_sym"; |
|
407 val not_false_true = iffD2 OF [nth (thms "HOL.simp_thms") 7, TrueI]; |
|
408 in fun get_eq_datatype thy dtco = |
|
409 let |
|
410 val SOME (vs, cs) = DatatypePackage.get_datatype_spec thy dtco; |
|
411 fun mk_triv_inject co = |
|
412 let |
|
413 val ct' = Thm.cterm_of thy |
|
414 (Const (co, Type (dtco, map (fn (v, sort) => TVar ((v, 0), sort)) vs))) |
|
415 val cty' = Thm.ctyp_of_term ct'; |
|
416 val refl = Thm.prop_of HOL.refl; |
|
417 val SOME (ct, cty) = fold_aterms (fn Var (v, ty) => |
|
418 (K o SOME) (Thm.cterm_of thy (Var (v, Thm.typ_of cty')), Thm.ctyp_of thy ty) | _ => I) |
|
419 refl NONE; |
|
420 in eqTrueI OF [Thm.instantiate ([(cty, cty')], [(ct, ct')]) HOL.refl] end; |
|
421 val inject1 = map_filter (fn (co, []) => SOME (mk_triv_inject co) | _ => NONE) cs |
|
422 val inject2 = (#inject o DatatypePackage.the_datatype thy) dtco; |
|
423 val ctxt = Context.init_proof thy; |
|
424 val simpset = Simplifier.context ctxt |
|
425 (MetaSimplifier.empty_ss addsimprocs [distinct_simproc]); |
|
426 val cos = map (fn (co, tys) => |
|
427 (Const (co, tys ---> Type (dtco, map TFree vs)), tys)) cs; |
|
428 val tac = ALLGOALS (simp_tac simpset) |
|
429 THEN ALLGOALS (ProofContext.fact_tac [not_false_true, TrueI]); |
|
430 val distinct = |
|
431 mk_distinct cos |
|
432 |> map (fn t => Goal.prove_global thy [] [] t (K tac)) |
|
433 |> (fn thms => thms @ map (fn thm => not_sym OF [thm]) thms) |
|
434 in inject1 @ inject2 @ distinct end; |
|
435 end (*local*); |
414 |
436 |
415 fun add_datatype_case_const dtco thy = |
437 fun add_datatype_case_const dtco thy = |
416 let |
438 let |
417 val {case_name, index, descr, ...} = DatatypePackage.the_datatype thy dtco; |
439 val {case_name, index, descr, ...} = DatatypePackage.the_datatype thy dtco; |
418 in |
440 in |
459 |> fold add_node names |
480 |> fold add_node names |
460 |> Graph.strong_conn |
481 |> Graph.strong_conn |
461 |> map (AList.make (the o AList.lookup (op =) names)) |
482 |> map (AList.make (the o AList.lookup (op =) names)) |
462 end; |
483 end; |
463 |
484 |
464 fun mk_typecopy_spec ({ vs, constr, typ, ... } : TypecopyPackage.info) = |
|
465 (vs, [(constr, [typ])]); |
|
466 |
|
467 fun get_spec thy (dtco, true) = |
485 fun get_spec thy (dtco, true) = |
468 (the o DatatypePackage.get_datatype_spec thy) dtco |
486 (the o DatatypePackage.get_datatype_spec thy) dtco |
469 | get_spec thy (tyco, false) = |
487 | get_spec thy (tyco, false) = |
470 (mk_typecopy_spec o the o TypecopyPackage.get_typecopy_info thy) tyco; |
488 TypecopyPackage.get_spec thy tyco; |
471 |
489 |
472 fun add_spec thy (tyco, is_dt) = |
490 fun get_cert thy (true, dtco) = get_cert_datatype thy dtco |
473 (tyco, (is_dt, get_spec thy (tyco, is_dt))); |
491 | get_cert thy (false, dtco) = [TypecopyPackage.get_cert thy dtco]; |
|
492 |
|
493 local |
|
494 val eq_def_sym = thm "eq_def" |> Thm.symmetric; |
|
495 val class_eq = "OperationalEquality.eq"; |
|
496 fun get_eq_thms thy tyco = case DatatypePackage.get_datatype thy tyco |
|
497 of SOME _ => get_eq_datatype thy tyco |
|
498 | NONE => [TypecopyPackage.get_eq thy tyco]; |
|
499 fun constrain_op_eq_thms thy thms = |
|
500 let |
|
501 fun add_eq (Const ("op =", ty)) = |
|
502 fold (insert (eq_fst (op =))) |
|
503 (Term.add_tvarsT ty []) |
|
504 | add_eq _ = |
|
505 I |
|
506 val eqs = fold (fold_aterms add_eq o Thm.prop_of) thms []; |
|
507 val instT = map (fn (v_i, sort) => |
|
508 (Thm.ctyp_of thy (TVar (v_i, sort)), |
|
509 Thm.ctyp_of thy (TVar (v_i, Sorts.inter_sort (Sign.classes_of thy) (sort, [class_eq]))))) eqs; |
|
510 in |
|
511 thms |
|
512 |> map (Thm.instantiate (instT, [])) |
|
513 end; |
|
514 in |
|
515 fun get_eq thy tyco = |
|
516 get_eq_thms thy tyco |
|
517 |> maps ((#mk o #mk_rews o snd o MetaSimplifier.rep_ss o Simplifier.simpset_of) thy) |
|
518 |> constrain_op_eq_thms thy |
|
519 |> map (Tactic.rewrite_rule [eq_def_sym]) |
|
520 end; |
|
521 |
|
522 type hook = (string * (bool * ((string * sort) list * (string * typ list) list))) list |
|
523 -> theory -> theory; |
474 |
524 |
475 fun add_codetypes_hook_bootstrap hook thy = |
525 fun add_codetypes_hook_bootstrap hook thy = |
476 let |
526 let |
|
527 fun add_spec thy (tyco, is_dt) = |
|
528 (tyco, (is_dt, get_spec thy (tyco, is_dt))); |
477 fun datatype_hook dtcos thy = |
529 fun datatype_hook dtcos thy = |
478 hook (map (add_spec thy) (map (rpair true) dtcos)) thy; |
530 hook (map (add_spec thy) (map (rpair true) dtcos)) thy; |
479 fun typecopy_hook ((tyco, info )) thy = |
531 fun typecopy_hook ((tyco, _)) thy = |
480 hook ([(tyco, (false, mk_typecopy_spec info))]) thy; |
532 hook ([(tyco, (false, TypecopyPackage.get_spec thy tyco))]) thy; |
481 in |
533 in |
482 thy |
534 thy |
483 |> fold hook ((map o map) (add_spec thy) (codetypes_dependency thy)) |
535 |> fold hook ((map o map) (add_spec thy) (codetypes_dependency thy)) |
484 |> DatatypeHooks.add datatype_hook |
536 |> DatatypeHooks.add datatype_hook |
485 |> TypecopyPackage.add_hook typecopy_hook |
537 |> TypecopyPackage.add_hook typecopy_hook |
495 val tycos'' = (map (#1 o snd) o #descr o DatatypePackage.the_datatype thy) tyco; |
547 val tycos'' = (map (#1 o snd) o #descr o DatatypePackage.the_datatype thy) tyco; |
496 val _ = if gen_subset (op =) (tycos, tycos'') then () else |
548 val _ = if gen_subset (op =) (tycos, tycos'') then () else |
497 error ("datatype constructors are not mutually recursive: " ^ (commas o map quote) tycos); |
549 error ("datatype constructors are not mutually recursive: " ^ (commas o map quote) tycos); |
498 val (vs::_, css) = split_list (map (the o DatatypePackage.get_datatype_spec thy) tycos); |
550 val (vs::_, css) = split_list (map (the o DatatypePackage.get_datatype_spec thy) tycos); |
499 in (vs, map2 (fn (tyco, is_dt) => fn cs => (tyco, (is_dt, cs))) tycos' css) end; |
551 in (vs, map2 (fn (tyco, is_dt) => fn cs => (tyco, (is_dt, cs))) tycos' css) end; |
|
552 |
|
553 |
|
554 (* registering code types in code generator *) |
|
555 |
|
556 fun codetype_hook specs = |
|
557 let |
|
558 fun add (dtco, (flag, spec)) thy = |
|
559 let |
|
560 fun cert thy_ref = (fn () => get_cert (Theory.deref thy_ref) (flag, dtco)); |
|
561 in |
|
562 CodegenData.add_datatype |
|
563 (dtco, (spec, CodegenData.lazy (cert (Theory.self_ref thy)))) thy |
|
564 end; |
|
565 in fold add specs end; |
|
566 |
|
567 |
|
568 (* instrumentalizing the sort algebra *) |
500 |
569 |
501 fun get_codetypes_arities thy tycos sort = |
570 fun get_codetypes_arities thy tycos sort = |
502 let |
571 let |
503 val algebra = Sign.classes_of thy; |
572 val algebra = Sign.classes_of thy; |
504 val (vs_proto, css_proto) = the_codetypes_mut_specs thy tycos; |
573 val (vs_proto, css_proto) = the_codetypes_mut_specs thy tycos; |
536 val (arities, css) = (split_list o map_filter |
605 val (arities, css) = (split_list o map_filter |
537 (fn (tyco, (arity, cs)) => if proven arity |
606 (fn (tyco, (arity, cs)) => if proven arity |
538 then NONE else SOME (arity, (tyco, cs)))) insts; |
607 then NONE else SOME (arity, (tyco, cs)))) insts; |
539 in |
608 in |
540 thy |
609 thy |
541 |> K ((not o null) arities) ? (ClassPackage.prove_instance_arity tac |
610 |> K ((not o null) arities) ? ( |
542 arities ("", []) (f thy arities css) #> after_qed) |
611 f arities css |
|
612 #-> (fn defs => |
|
613 ClassPackage.prove_instance_arity tac arities ("", []) defs |
|
614 #> after_qed arities css)) |
543 end; |
615 end; |
|
616 |
|
617 |
|
618 (* operational equality *) |
544 |
619 |
545 local |
620 local |
546 val class_eq = "OperationalEquality.eq"; |
621 val class_eq = "OperationalEquality.eq"; |
547 in fun add_eq_instance specs = |
622 in fun eq_hook specs = |
548 prove_codetypes_arities |
623 let |
549 (K (ClassPackage.intro_classes_tac [])) |
624 fun add_eq_thms (dtco, (_, (vs, cs))) thy = |
550 (map (fn (tyco, (is_dt, _)) => (tyco, is_dt)) specs) |
625 let |
551 [class_eq] ((K o K o K) []) |
626 val thy_ref = Theory.self_ref thy; |
552 end; (*local*) |
627 val ty = Type (dtco, map TFree vs) |> Logic.varifyT; |
553 |
628 val c = CodegenConsts.norm thy ("OperationalEquality.eq", [ty]); |
554 local |
629 val get_thms = (fn () => get_eq (Theory.deref thy_ref) dtco |> rev); |
555 val not_sym = thm "HOL.not_sym"; |
|
556 val not_false_true = iffD2 OF [nth (thms "HOL.simp_thms") 7, TrueI]; |
|
557 in fun get_eq_datatype thy dtco = |
|
558 let |
|
559 (* val _ = writeln "01"; *) |
|
560 val SOME (vs, cs) = DatatypePackage.get_datatype_spec (Context.check_thy thy) dtco; |
|
561 (* val _ = writeln "02"; *) |
|
562 fun mk_triv_inject co = |
|
563 let |
|
564 val ct' = Thm.cterm_of (Context.check_thy thy) |
|
565 (Const (co, Type (dtco, map (fn (v, sort) => TVar ((v, 0), sort)) vs))) |
|
566 val cty' = Thm.ctyp_of_term ct'; |
|
567 val refl = Thm.prop_of HOL.refl; |
|
568 val SOME (ct, cty) = fold_aterms (fn Var (v, ty) => |
|
569 (K o SOME) (Thm.cterm_of (Context.check_thy thy) (Var (v, Thm.typ_of cty')), Thm.ctyp_of (Context.check_thy thy) ty) | _ => I) |
|
570 refl NONE; |
|
571 in eqTrueI OF [Thm.instantiate ([(cty, cty')], [(ct, ct')]) HOL.refl] end; |
|
572 (* val _ = writeln "03"; *) |
|
573 val inject1 = map_filter (fn (co, []) => SOME (mk_triv_inject co) | _ => NONE) cs |
|
574 (* val _ = writeln "04"; *) |
|
575 val inject2 = (#inject o DatatypePackage.the_datatype (Context.check_thy thy)) dtco; |
|
576 (* val _ = writeln "05"; *) |
|
577 val ctxt = Context.init_proof (Context.check_thy thy); |
|
578 (* val _ = writeln "06"; *) |
|
579 val simpset = Simplifier.context ctxt |
|
580 (MetaSimplifier.empty_ss addsimprocs [distinct_simproc]); |
|
581 (* val _ = writeln "07"; *) |
|
582 val cos = map (fn (co, tys) => |
|
583 (Const (co, tys ---> Type (dtco, map TFree vs)), tys)) cs; |
|
584 val tac = ALLGOALS (simp_tac simpset) |
|
585 THEN ALLGOALS (ProofContext.fact_tac [not_false_true, TrueI]); |
|
586 (* val _ = writeln "08"; *) |
|
587 val distinct = |
|
588 mk_distinct cos |
|
589 |> map (fn t => Goal.prove_global (Context.check_thy thy) [] [] t (K tac)) |
|
590 |> (fn thms => thms @ map (fn thm => not_sym OF [thm]) thms) |
|
591 (* val _ = writeln "09"; *) |
|
592 in inject1 @ inject2 @ distinct end; |
|
593 |
|
594 fun get_eq_typecopy thy tyco = |
|
595 case TypecopyPackage.get_typecopy_info thy tyco |
|
596 of SOME { inject, ... } => [inject] |
|
597 | NONE => []; |
|
598 |
|
599 local |
|
600 val lift_not_thm = thm "HOL.Eq_FalseI"; |
|
601 val lift_thm = thm "HOL.eq_reflection"; |
|
602 val eq_def_sym = thm "eq_def" |> Thm.symmetric; |
|
603 fun get_eq_thms thy tyco = case DatatypePackage.get_datatype (Context.check_thy thy) tyco |
|
604 of SOME _ => get_eq_datatype (Context.check_thy thy) tyco |
|
605 | NONE => case TypecopyPackage.get_typecopy_info thy tyco |
|
606 of SOME _ => get_eq_typecopy thy tyco |
|
607 | NONE => []; |
|
608 in |
|
609 fun get_eq thy tyco = |
|
610 get_eq_thms (Context.check_thy thy) tyco |
|
611 (* |> tap (fn _ => writeln "10") *) |
|
612 |> maps ((#mk o #mk_rews o snd o MetaSimplifier.rep_ss o Simplifier.simpset_of) (Context.check_thy thy)) |
|
613 (* |> tap (fn _ => writeln "11") *) |
|
614 |> constrain_op_eq (Context.check_thy thy) |
|
615 (* |> tap (fn _ => writeln "12") *) |
|
616 |> map (Tactic.rewrite_rule [eq_def_sym]) |
|
617 (* |> tap (fn _ => writeln "13") *) |
|
618 end; |
|
619 |
|
620 end; |
|
621 |
|
622 fun add_eq_thms (dtco, (_, (vs, cs))) thy = |
|
623 let |
|
624 val thy_ref = Theory.self_ref thy; |
|
625 val ty = Type (dtco, map TFree vs) |> Logic.varifyT; |
|
626 val c = CodegenConsts.norm thy ("OperationalEquality.eq", [ty]); |
|
627 val get_thms = (fn () => get_eq (Theory.deref thy_ref) dtco |> rev); |
|
628 in |
|
629 CodegenData.add_funcl |
|
630 (c, CodegenData.lazy get_thms) thy |
|
631 end; |
|
632 |
|
633 fun codetype_hook dtcos theory = |
|
634 let |
|
635 fun add (dtco, (flag, spec)) thy = |
|
636 let |
|
637 fun cert thy_ref = (fn () => get_cert (Theory.deref thy_ref) (flag, dtco)); |
|
638 in |
630 in |
639 CodegenData.add_datatype |
631 CodegenData.add_funcl (c, CodegenData.lazy get_thms) thy |
640 (dtco, (spec, CodegenData.lazy (cert (Theory.self_ref thy)))) thy |
|
641 end; |
632 end; |
642 in |
633 in |
643 theory |
634 prove_codetypes_arities (K (ClassPackage.intro_classes_tac [])) |
644 |> fold add dtcos |
635 (map (fn (tyco, (is_dt, _)) => (tyco, is_dt)) specs) |
645 end; |
636 [class_eq] ((K o K o pair) []) ((K o K) (fold add_eq_thms specs)) |
646 |
637 end; |
647 fun eq_hook dtcos = |
638 end; (*local*) |
648 add_eq_instance dtcos (fold add_eq_thms dtcos); |
|
649 |
639 |
650 |
640 |
651 |
641 |
652 (** theory setup **) |
642 (** theory setup **) |
653 |
643 |