529 fun logical_typscheme thy (c, ty) = |
524 fun logical_typscheme thy (c, ty) = |
530 (map dest_TFree (Sign.const_typargs thy (c, ty)), Type.strip_sorts ty); |
525 (map dest_TFree (Sign.const_typargs thy (c, ty)), Type.strip_sorts ty); |
531 |
526 |
532 fun typscheme thy (c, ty) = logical_typscheme thy (c, subst_signature thy c ty); |
527 fun typscheme thy (c, ty) = logical_typscheme thy (c, subst_signature thy c ty); |
533 |
528 |
534 fun typscheme_eqn thy = typscheme thy o apsnd Logic.unvarifyT o const_typ_eqn thy; |
|
535 |
|
536 fun typscheme_eqns thy c [] = |
|
537 let |
|
538 val raw_ty = const_typ thy c; |
|
539 val tvars = Term.add_tvar_namesT raw_ty []; |
|
540 val tvars' = case AxClass.class_of_param thy c |
|
541 of SOME class => [TFree (Name.aT, [class])] |
|
542 | NONE => Name.invent_list [] Name.aT (length tvars) |
|
543 |> map (fn v => TFree (v, [])); |
|
544 val ty = typ_subst_TVars (tvars ~~ tvars') raw_ty; |
|
545 in logical_typscheme thy (c, ty) end |
|
546 | typscheme_eqns thy c (thm :: _) = typscheme_eqn thy thm; |
|
547 |
|
548 fun assert_eqns_const thy c eqns = |
529 fun assert_eqns_const thy c eqns = |
549 let |
530 let |
550 fun cert (eqn as (thm, _)) = if c = const_eqn thy thm |
531 fun cert (eqn as (thm, _)) = if c = const_eqn thy thm |
551 then eqn else error ("Wrong head of code equation,\nexpected constant " |
532 then eqn else error ("Wrong head of code equation,\nexpected constant " |
552 ^ string_of_const thy c ^ "\n" ^ Display.string_of_thm_global thy thm) |
533 ^ string_of_const thy c ^ "\n" ^ Display.string_of_thm_global thy thm) |
553 in map (cert o assert_eqn thy) eqns end; |
534 in map (cert o assert_eqn thy) eqns end; |
554 |
535 |
555 |
536 |
556 (* code equation certificates *) |
537 (* code equation certificates *) |
557 |
538 |
558 fun standard_typscheme thy thms = |
|
559 let |
|
560 fun tvars_of T = rev (Term.add_tvarsT T []); |
|
561 val vss = map (tvars_of o snd o head_eqn) thms; |
|
562 fun inter_sorts vs = |
|
563 fold (curry (Sorts.inter_sort (Sign.classes_of thy)) o snd) vs []; |
|
564 val sorts = map_transpose inter_sorts vss; |
|
565 val vts = Name.names Name.context Name.aT sorts |
|
566 |> map (fn (v, sort) => TVar ((v, 0), sort)); |
|
567 in map2 (fn vs => Thm.certify_instantiate (vs ~~ vts, [])) vss thms end; |
|
568 |
|
569 type cert = thm * bool list; |
539 type cert = thm * bool list; |
570 |
540 |
571 fun cert_of_eqns thy [] = (Drule.dummy_thm, []) |
541 fun mk_head_cterm thy (c, ty) = |
572 | cert_of_eqns thy eqns = |
542 Thm.cterm_of thy (Logic.mk_equals (Free ("HEAD", ty), Const (c, ty))); |
573 let |
543 |
574 val propers = map snd eqns; |
544 fun empty_cert thy c = |
575 val thms as thm :: _ = (map Thm.freezeT o standard_typscheme thy o map fst) eqns; (*FIXME*) |
545 let |
576 val (c, ty) = head_eqn thm; |
546 val raw_ty = const_typ thy c; |
577 val head_thm = Thm.assume (Thm.cterm_of thy (Logic.mk_equals |
547 val tvars = Term.add_tvar_namesT raw_ty []; |
578 (Free ("HEAD", ty), Const (c, ty)))) |> Thm.symmetric; |
548 val tvars' = case AxClass.class_of_param thy c |
|
549 of SOME class => [TFree (Name.aT, [class])] |
|
550 | NONE => Name.invent_list [] Name.aT (length tvars) |
|
551 |> map (fn v => TFree (v, [])); |
|
552 val ty = typ_subst_TVars (tvars ~~ tvars') raw_ty; |
|
553 val chead = mk_head_cterm thy (c, ty); |
|
554 in (Thm.weaken chead Drule.dummy_thm, []) end; |
|
555 |
|
556 fun cert_of_eqns thy c [] = empty_cert thy c |
|
557 | cert_of_eqns thy c eqns = |
|
558 let |
|
559 val _ = assert_eqns_const thy c eqns; |
|
560 val (thms, propers) = split_list eqns; |
|
561 fun tvars_of T = rev (Term.add_tvarsT T []); |
|
562 val vss = map (tvars_of o snd o head_eqn) thms; |
|
563 fun inter_sorts vs = |
|
564 fold (curry (Sorts.inter_sort (Sign.classes_of thy)) o snd) vs []; |
|
565 val sorts = map_transpose inter_sorts vss; |
|
566 val vts = Name.names Name.context Name.aT sorts; |
|
567 val thms as thm :: _ = |
|
568 map2 (fn vs => Thm.certify_instantiate (vs ~~ map TFree vts, [])) vss thms; |
|
569 val head_thm = Thm.symmetric (Thm.assume (mk_head_cterm thy (head_eqn (hd thms)))); |
579 fun head_conv ct = if can Thm.dest_comb ct |
570 fun head_conv ct = if can Thm.dest_comb ct |
580 then Conv.fun_conv head_conv ct |
571 then Conv.fun_conv head_conv ct |
581 else Conv.rewr_conv head_thm ct; |
572 else Conv.rewr_conv head_thm ct; |
582 val rewrite_head = Conv.fconv_rule (Conv.arg1_conv head_conv); |
573 val rewrite_head = Conv.fconv_rule (Conv.arg1_conv head_conv); |
583 val cert = Conjunction.intr_balanced (map rewrite_head thms); |
574 val cert_thm = Conjunction.intr_balanced (map rewrite_head thms); |
584 in (cert, propers) end; |
575 in (cert_thm, propers) end; |
585 |
576 |
586 fun head_cert thy cert = |
577 fun head_cert thy cert_thm = |
587 let |
578 let |
588 val [head] = Thm.hyps_of cert; |
579 val [head] = Thm.hyps_of cert_thm; |
589 val (Free (h, _), Const (c, ty)) = (Logic.dest_equals o the_single o Thm.hyps_of) cert; |
580 val (Free (h, _), Const (c, ty)) = Logic.dest_equals head; |
590 in ((c, typscheme thy (AxClass.unoverload_const thy (c, ty), ty)), (head, h)) end; |
581 in ((c, typscheme thy (c, ty)), (head, h)) end; |
591 |
582 |
592 fun constrain_cert thy sorts (cert, []) = (cert, []) |
583 fun constrain_cert thy sorts (cert_thm, propers) = |
593 | constrain_cert thy sorts (cert, propers) = |
584 let |
594 let |
585 val ((c, (vs, _)), (head, _)) = head_cert thy cert_thm; |
595 val ((c, (vs, _)), (head, _)) = head_cert thy cert; |
586 val subst = map2 (fn (v, _) => fn sort => (v, sort)) vs sorts; |
596 val subst = map2 (fn (v, _) => fn sort => (v, sort)) vs sorts; |
587 val head' = (map_types o map_atyps) |
597 val head' = (map_types o map_atyps) |
588 (fn TFree (v, _) => TFree (v, the (AList.lookup (op =) subst v))) head; |
598 (fn TFree (v, _) => TFree (v, the (AList.lookup (op =) subst v))) head; |
589 val inst = (map2 (fn (v, sort) => fn sort' => |
599 val inst = (map2 (fn (v, sort) => fn sort' => |
590 pairself (Thm.ctyp_of thy) (TVar ((v, 0), sort), TFree (v, sort'))) vs sorts, []); |
600 pairself (Thm.ctyp_of thy) (TVar ((v, 0), sort), TFree (v, sort'))) vs sorts ,[]); |
591 val cert_thm' = cert_thm |
601 val cert' = cert |
592 |> Thm.implies_intr (Thm.cterm_of thy head) |
602 |> Thm.implies_intr (Thm.cterm_of thy head) |
593 |> Thm.varifyT |
603 |> Thm.varifyT |
594 |> Thm.instantiate inst |
604 |> Thm.instantiate inst |
595 |> Thm.elim_implies (Thm.assume (Thm.cterm_of thy head')); |
605 |> Thm.elim_implies (Thm.assume (Thm.cterm_of thy head')) |
596 in (cert_thm', propers) end; |
606 in (cert', propers) end; |
597 |
607 |
598 fun eqns_of_cert thy (cert_thm, []) = [] |
608 fun dest_cert thy (cert, propers) = |
599 | eqns_of_cert thy (cert_thm, propers) = |
609 let |
600 let |
610 val (c_vs_ty, (head, h)) = head_cert thy cert; |
601 val (_, (head, _)) = head_cert thy cert_thm; |
611 val equations = cert |
602 val thms = cert_thm |
612 |> Thm.prop_of |
|
613 |> Logic.dest_conjunction_balanced (length propers) |
|
614 |> map Logic.dest_equals |
|
615 |> (map o apfst) strip_comb |
|
616 |> (map o apfst) (fn (Free (h', _), ts) => case h = h' of True => ts) |
|
617 in (c_vs_ty, equations ~~ propers) end; |
|
618 |
|
619 fun eqns_of_cert thy (cert, []) = [] |
|
620 | eqns_of_cert thy (cert, propers) = |
|
621 let |
|
622 val (_, (head, _)) = head_cert thy cert; |
|
623 val thms = cert |
|
624 |> LocalDefs.expand [Thm.cterm_of thy head] |
603 |> LocalDefs.expand [Thm.cterm_of thy head] |
625 |> Thm.varifyT |
604 |> Thm.varifyT |
626 |> Conjunction.elim_balanced (length propers) |
605 |> Conjunction.elim_balanced (length propers) |
627 in thms ~~ propers end; |
606 in thms ~~ propers end; |
628 |
607 |
|
608 fun dest_cert thy (cert as (cert_thm, propers)) = |
|
609 let |
|
610 val eqns = eqns_of_cert thy cert; |
|
611 val ((_, vs_ty), _) = head_cert thy cert_thm; |
|
612 val equations = if null propers then [] else cert_thm |
|
613 |> Thm.prop_of |
|
614 |> Logic.dest_conjunction_balanced (length propers) |
|
615 |> map Logic.dest_equals |
|
616 |> (map o apfst) (snd o strip_comb) |
|
617 in (vs_ty, equations ~~ eqns) end; |
|
618 |
629 |
619 |
630 (* code equation access *) |
620 (* code equation access *) |
631 |
621 |
632 fun these_eqns thy c = |
622 fun get_cert thy f c = |
633 Symtab.lookup ((the_eqns o the_exec) thy) c |
623 Symtab.lookup ((the_eqns o the_exec) thy) c |
634 |> Option.map (snd o snd o fst) |
624 |> Option.map (snd o snd o fst) |
635 |> these |
625 |> these |
636 |> (map o apfst) (Thm.transfer thy) |
626 |> (map o apfst) (Thm.transfer thy) |
637 |> burrow_fst (standard_typscheme thy); |
627 |> f |
638 |
628 |> (map o apfst) (AxClass.unoverload thy) |
639 fun eqn_cert thy c = |
629 |> cert_of_eqns thy c; |
640 Symtab.lookup ((the_eqns o the_exec) thy) c |
|
641 |> Option.map (snd o snd o fst) |
|
642 |> these |
|
643 |> (map o apfst) (Thm.transfer thy) |
|
644 |> cert_of_eqns thy; |
|
645 |
630 |
646 |
631 |
647 (* cases *) |
632 (* cases *) |
648 |
633 |
649 fun case_certificate thm = |
634 fun case_certificate thm = |