709 |
709 |
710 (* parse translations *) |
710 (* parse translations *) |
711 |
711 |
712 local |
712 local |
713 |
713 |
714 fun field_update_tr (Const (@{syntax_const "_field_update"}, _) $ Const (name, _) $ arg) = |
714 fun field_type_tr ((Const (@{syntax_const "_field_type"}, _) $ Const (name, _) $ arg)) = |
715 Syntax.const (suffix updateN name) $ Abs ("_", dummyT, arg) |
715 (name, arg) |
716 | field_update_tr t = raise TERM ("field_update_tr", [t]); |
716 | field_type_tr t = raise TERM ("field_type_tr", [t]); |
717 |
717 |
718 fun field_updates_tr (Const (@{syntax_const "_field_updates"}, _) $ t $ u) = |
718 fun field_types_tr (Const (@{syntax_const "_field_types"}, _) $ t $ u) = |
719 field_update_tr t :: field_updates_tr u |
719 field_type_tr t :: field_types_tr u |
720 | field_updates_tr t = [field_update_tr t]; |
720 | field_types_tr t = [field_type_tr t]; |
721 |
721 |
722 fun record_update_tr [t, u] = fold (curry op $) (field_updates_tr u) t |
722 fun record_field_types_tr more ctxt t = |
723 | record_update_tr ts = raise TERM ("record_update_tr", ts); |
723 let |
|
724 val thy = ProofContext.theory_of ctxt; |
|
725 fun err msg = raise TERM ("Error in record-type input: " ^ msg, [t]); |
|
726 |
|
727 fun split_args (field :: fields) ((name, arg) :: fargs) = |
|
728 if can (unsuffix name) field then |
|
729 let val (args, rest) = split_args fields fargs |
|
730 in (arg :: args, rest) end |
|
731 else err ("expecting field " ^ field ^ " but got " ^ name) |
|
732 | split_args [] (fargs as (_ :: _)) = ([], fargs) |
|
733 | split_args (_ :: _) [] = err "expecting more fields" |
|
734 | split_args _ _ = ([], []); |
|
735 |
|
736 fun mk_ext (fargs as (name, _) :: _) = |
|
737 (case get_fieldext thy (Sign.intern_const thy name) of |
|
738 SOME (ext, alphas) => |
|
739 (case get_extfields thy ext of |
|
740 SOME fields => |
|
741 let |
|
742 val fields' = but_last fields; |
|
743 val types = map snd fields'; |
|
744 val (args, rest) = split_args (map fst fields') fargs; |
|
745 val argtypes = map (Sign.certify_typ thy o decode_type thy) args; |
|
746 val midx = fold Term.maxidx_typ argtypes 0; |
|
747 val varifyT = varifyT midx; |
|
748 val vartypes = map varifyT types; |
|
749 |
|
750 val subst = fold (Sign.typ_match thy) (vartypes ~~ argtypes) Vartab.empty |
|
751 handle Type.TYPE_MATCH => err "type is no proper record (extension)"; |
|
752 val alphas' = |
|
753 map (Syntax.term_of_typ (! Syntax.show_sorts) o Envir.norm_type subst o varifyT) |
|
754 (but_last alphas); |
|
755 |
|
756 val more' = mk_ext rest; |
|
757 in |
|
758 (* FIXME authentic syntax *) |
|
759 list_comb (Syntax.const (suffix ext_typeN ext), alphas' @ [more']) |
|
760 end |
|
761 | NONE => err ("no fields defined for " ^ ext)) |
|
762 | NONE => err (name ^ " is no proper field")) |
|
763 | mk_ext [] = more; |
|
764 in |
|
765 mk_ext (field_types_tr t) |
|
766 end; |
|
767 |
|
768 (* FIXME @{type_syntax} *) |
|
769 fun record_type_tr ctxt [t] = record_field_types_tr (Syntax.const "Product_Type.unit") ctxt t |
|
770 | record_type_tr _ ts = raise TERM ("record_type_tr", ts); |
|
771 |
|
772 fun record_type_scheme_tr ctxt [t, more] = record_field_types_tr more ctxt t |
|
773 | record_type_scheme_tr _ ts = raise TERM ("record_type_scheme_tr", ts); |
724 |
774 |
725 |
775 |
726 fun field_tr ((Const (@{syntax_const "_field"}, _) $ Const (name, _) $ arg)) = (name, arg) |
776 fun field_tr ((Const (@{syntax_const "_field"}, _) $ Const (name, _) $ arg)) = (name, arg) |
727 | field_tr t = raise TERM ("field_tr", [t]); |
777 | field_tr t = raise TERM ("field_tr", [t]); |
728 |
778 |
766 |
816 |
767 fun record_scheme_tr ctxt [t, more] = record_fields_tr more ctxt t |
817 fun record_scheme_tr ctxt [t, more] = record_fields_tr more ctxt t |
768 | record_scheme_tr _ ts = raise TERM ("record_scheme_tr", ts); |
818 | record_scheme_tr _ ts = raise TERM ("record_scheme_tr", ts); |
769 |
819 |
770 |
820 |
771 fun field_type_tr ((Const (@{syntax_const "_field_type"}, _) $ Const (name, _) $ arg)) = |
821 fun field_update_tr (Const (@{syntax_const "_field_update"}, _) $ Const (name, _) $ arg) = |
772 (name, arg) |
822 Syntax.const (suffix updateN name) $ Abs ("_", dummyT, arg) |
773 | field_type_tr t = raise TERM ("field_type_tr", [t]); |
823 | field_update_tr t = raise TERM ("field_update_tr", [t]); |
774 |
824 |
775 fun field_types_tr (Const (@{syntax_const "_field_types"}, _) $ t $ u) = |
825 fun field_updates_tr (Const (@{syntax_const "_field_updates"}, _) $ t $ u) = |
776 field_type_tr t :: field_types_tr u |
826 field_update_tr t :: field_updates_tr u |
777 | field_types_tr t = [field_type_tr t]; |
827 | field_updates_tr t = [field_update_tr t]; |
778 |
828 |
779 fun record_field_types_tr more ctxt t = |
829 fun record_update_tr [t, u] = fold (curry op $) (field_updates_tr u) t |
780 let |
830 | record_update_tr ts = raise TERM ("record_update_tr", ts); |
781 val thy = ProofContext.theory_of ctxt; |
|
782 fun err msg = raise TERM ("Error in record-type input: " ^ msg, [t]); |
|
783 |
|
784 fun split_args (field :: fields) ((name, arg) :: fargs) = |
|
785 if can (unsuffix name) field then |
|
786 let val (args, rest) = split_args fields fargs |
|
787 in (arg :: args, rest) end |
|
788 else err ("expecting field " ^ field ^ " but got " ^ name) |
|
789 | split_args [] (fargs as (_ :: _)) = ([], fargs) |
|
790 | split_args (_ :: _) [] = err "expecting more fields" |
|
791 | split_args _ _ = ([], []); |
|
792 |
|
793 fun mk_ext (fargs as (name, _) :: _) = |
|
794 (case get_fieldext thy (Sign.intern_const thy name) of |
|
795 SOME (ext, alphas) => |
|
796 (case get_extfields thy ext of |
|
797 SOME fields => |
|
798 let |
|
799 val fields' = but_last fields; |
|
800 val types = map snd fields'; |
|
801 val (args, rest) = split_args (map fst fields') fargs; |
|
802 val argtypes = map (Sign.certify_typ thy o decode_type thy) args; |
|
803 val midx = fold Term.maxidx_typ argtypes 0; |
|
804 val varifyT = varifyT midx; |
|
805 val vartypes = map varifyT types; |
|
806 |
|
807 val subst = fold (Sign.typ_match thy) (vartypes ~~ argtypes) Vartab.empty |
|
808 handle Type.TYPE_MATCH => err "type is no proper record (extension)"; |
|
809 val alphas' = |
|
810 map (Syntax.term_of_typ (! Syntax.show_sorts) o Envir.norm_type subst o varifyT) |
|
811 (but_last alphas); |
|
812 |
|
813 val more' = mk_ext rest; |
|
814 in |
|
815 (* FIXME authentic syntax *) |
|
816 list_comb (Syntax.const (suffix ext_typeN ext), alphas' @ [more']) |
|
817 end |
|
818 | NONE => err ("no fields defined for " ^ ext)) |
|
819 | NONE => err (name ^ " is no proper field")) |
|
820 | mk_ext [] = more; |
|
821 in |
|
822 mk_ext (field_types_tr t) |
|
823 end; |
|
824 |
|
825 (* FIXME @{type_syntax} *) |
|
826 fun record_type_tr ctxt [t] = record_field_types_tr (Syntax.const "Product_Type.unit") ctxt t |
|
827 | record_type_tr _ ts = raise TERM ("record_type_tr", ts); |
|
828 |
|
829 fun record_type_scheme_tr ctxt [t, more] = record_field_types_tr more ctxt t |
|
830 | record_type_scheme_tr _ ts = raise TERM ("record_type_scheme_tr", ts); |
|
831 |
831 |
832 in |
832 in |
833 |
833 |
834 val parse_translation = |
834 val parse_translation = |
835 [(@{syntax_const "_record_update"}, record_update_tr)]; |
835 [(@{syntax_const "_record_update"}, record_update_tr)]; |
1427 fun record_split_simproc P = |
1427 fun record_split_simproc P = |
1428 Simplifier.simproc @{theory HOL} "record_split_simp" ["x"] |
1428 Simplifier.simproc @{theory HOL} "record_split_simp" ["x"] |
1429 (fn thy => fn _ => fn t => |
1429 (fn thy => fn _ => fn t => |
1430 (case t of |
1430 (case t of |
1431 Const (quantifier, Type (_, [Type (_, [T, _]), _])) $ _ => |
1431 Const (quantifier, Type (_, [Type (_, [T, _]), _])) $ _ => |
1432 if quantifier = @{const_name All} orelse |
1432 if quantifier = @{const_name all} orelse |
1433 quantifier = @{const_name all} orelse |
1433 quantifier = @{const_name All} orelse |
1434 quantifier = @{const_name Ex} |
1434 quantifier = @{const_name Ex} |
1435 then |
1435 then |
1436 (case rec_id ~1 T of |
1436 (case rec_id ~1 T of |
1437 "" => NONE |
1437 "" => NONE |
1438 | _ => |
1438 | _ => |
1552 end); |
1552 end); |
1553 |
1553 |
1554 |
1554 |
1555 (* record_split_tac *) |
1555 (* record_split_tac *) |
1556 |
1556 |
1557 (*Split all records in the goal, which are quantified by ALL or !!.*) |
1557 (*Split all records in the goal, which are quantified by !! or ALL.*) |
1558 val record_split_tac = CSUBGOAL (fn (cgoal, i) => |
1558 val record_split_tac = CSUBGOAL (fn (cgoal, i) => |
1559 let |
1559 let |
1560 val goal = term_of cgoal; |
1560 val goal = term_of cgoal; |
1561 |
1561 |
1562 val has_rec = exists_Const |
1562 val has_rec = exists_Const |
1563 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1563 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1564 (s = @{const_name All} orelse s = @{const_name all}) andalso is_recT T |
1564 (s = @{const_name all} orelse s = @{const_name All}) andalso is_recT T |
1565 | _ => false); |
1565 | _ => false); |
1566 |
1566 |
1567 fun is_all t = |
1567 fun is_all t = |
1568 (case t of |
1568 (case t of |
1569 Const (quantifier, _) $ _ => |
1569 Const (quantifier, _) $ _ => |
1570 if quantifier = @{const_name All} orelse quantifier = @{const_name all} then ~1 else 0 |
1570 if quantifier = @{const_name all} orelse quantifier = @{const_name All} then ~1 else 0 |
1571 | _ => 0); |
1571 | _ => 0); |
1572 in |
1572 in |
1573 if has_rec goal then |
1573 if has_rec goal then |
1574 Simplifier.full_simp_tac (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i |
1574 Simplifier.full_simp_tac (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i |
1575 else no_tac |
1575 else no_tac |