482 Pretty.block [ |
485 Pretty.block [ |
483 Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
486 Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
484 Pretty.str " |=> ", |
487 Pretty.str " |=> ", |
485 pretty_itype ty |
488 pretty_itype ty |
486 ] |
489 ] |
487 | pretty_def (Datatype (vs, cs, clss)) = |
490 | pretty_def (Datatype (vs, cs, insts)) = |
488 Pretty.block [ |
491 Pretty.block [ |
489 Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
492 Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
490 Pretty.str " |=> ", |
493 Pretty.str " |=> ", |
491 Pretty.gen_list " |" "" "" (map Pretty.str cs), |
494 Pretty.gen_list " |" "" "" (map Pretty.str cs), |
492 Pretty.str ", instance of ", |
495 Pretty.str ", instances ", |
493 Pretty.gen_list "," "[" "]" (map Pretty.str clss) |
496 Pretty.gen_list "," "[" "]" (map Pretty.str insts) |
494 ] |
497 ] |
495 | pretty_def (Datatypecons (dtname, tys)) = |
498 | pretty_def (Datatypecons (dtname, tys)) = |
496 Pretty.block [ |
499 Pretty.block [ |
497 Pretty.str "cons ", |
500 Pretty.str "cons ", |
498 Pretty.gen_list " ->" "" "" (map pretty_itype tys @ [Pretty.str dtname]) |
501 Pretty.gen_list " ->" "" "" (map pretty_itype tys @ [Pretty.str dtname]) |
653 | join_module _ = |
656 | join_module _ = |
654 NONE |
657 NONE |
655 in Graph.join (K join_module) modl12 end; |
658 in Graph.join (K join_module) modl12 end; |
656 |
659 |
657 fun partof names modl = |
660 fun partof names modl = |
658 let |
661 let |
659 datatype pathnode = PN of (string list * (string * pathnode) list); |
662 datatype pathnode = PN of (string list * (string * pathnode) list); |
660 fun mk_ipath ([], base) (PN (defs, modls)) = |
663 fun mk_ipath ([], base) (PN (defs, modls)) = |
661 PN (base :: defs, modls) |
664 PN (base :: defs, modls) |
662 | mk_ipath (n::ns, base) (PN (defs, modls)) = |
665 | mk_ipath (n::ns, base) (PN (defs, modls)) = |
663 modls |
666 modls |
664 |> AList.default (op =) (n, PN ([], [])) |
667 |> AList.default (op =) (n, PN ([], [])) |
665 |> AList.map_entry (op =) n (mk_ipath (ns, base)) |
668 |> AList.map_entry (op =) n (mk_ipath (ns, base)) |
666 |> (pair defs #> PN); |
669 |> (pair defs #> PN); |
667 fun select (PN (defs, modls)) (Module module) = |
670 fun select (PN (defs, modls)) (Module module) = |
668 module |
671 module |
669 |> Graph.subgraph (Graph.all_succs module (defs @ map fst modls)) |
672 |> Graph.subgraph (Graph.all_succs module (defs @ map fst modls)) |
670 |> fold (fn (name, modls) => Graph.map_node name (select modls)) modls |
673 |> fold (fn (name, modls) => Graph.map_node name (select modls)) modls |
671 |> Module; |
674 |> Module; |
672 in |
675 in |
673 Module modl |
676 Module modl |
674 |> select (fold (mk_ipath o dest_name) (filter NameSpace.is_qualified names) (PN ([], []))) |
677 |> select (fold (mk_ipath o dest_name) (filter NameSpace.is_qualified names) (PN ([], []))) |
675 |> dest_modl |
678 |> dest_modl |
676 end; |
679 end; |
677 |
680 |
678 fun add_check_transform (name, (Datatypecons (dtname, _))) = |
681 fun add_check_transform (name, (Datatypecons (dtname, _))) = |
679 (debug 7 (fn _ => "transformation for datatype constructor " ^ quote name |
682 (debug 7 (fn _ => "transformation for datatype constructor " ^ quote name |
680 ^ " of datatype " ^ quote dtname) (); |
683 ^ " of datatype " ^ quote dtname) (); |
681 ([([dtname], |
684 ([([dtname], |
682 fn [Datatype (_, _, [])] => NONE |
685 fn [Datatype (_, _, [])] => NONE |
683 | _ => "attempted to add constructor to already instantiating datatype" |> SOME)], |
686 | _ => "attempted to add constructor to already instantiating datatype" |> SOME)], |
684 [(dtname, |
687 [(dtname, |
685 fn Datatype (vs, cs, clss) => Datatype (vs, name::cs, clss) |
688 fn Datatype (vs, cs, insts) => Datatype (vs, name::cs, insts) |
686 | def => "attempted to add datatype constructor to non-datatype: " |
689 | def => "attempted to add datatype constructor to non-datatype: " |
687 ^ (Pretty.output o pretty_def) def |> error)]) |
690 ^ (Pretty.output o pretty_def) def |> error)]) |
688 ) |
691 ) |
689 | add_check_transform (name, Classmember (clsname, v, ty)) = |
692 | add_check_transform (name, Classmember (clsname, v, ty)) = |
690 let |
693 let |
732 [(clsname, |
735 [(clsname, |
733 fn Class (supcs, v, mems, insts) => Class (supcs, v, mems, name::insts) |
736 fn Class (supcs, v, mems, insts) => Class (supcs, v, mems, name::insts) |
734 | def => "attempted to add class instance to non-class" |
737 | def => "attempted to add class instance to non-class" |
735 ^ (Pretty.output o pretty_def) def |> error), |
738 ^ (Pretty.output o pretty_def) def |> error), |
736 (tyco, |
739 (tyco, |
737 fn Datatype (vs, cs, clss) => Datatype (vs, cs, clsname::clss) |
740 fn Datatype (vs, cs, insts) => Datatype (vs, cs, name::insts) |
738 | Nop => Nop |
741 | Nop => Nop |
739 | def => "attempted to instantiate non-type to class instance" |
742 | def => "attempted to instantiate non-type to class instance" |
740 ^ (Pretty.output o pretty_def) def |> error)]) |
743 ^ (Pretty.output o pretty_def) def |> error)]) |
741 end |
744 end |
742 | add_check_transform _ = ([], []); |
745 | add_check_transform _ = ([], []); |
943 |
946 |
944 val prims = [class_eq, type_bool, type_integer, type_float, type_pair, type_list, |
947 val prims = [class_eq, type_bool, type_integer, type_float, type_pair, type_list, |
945 cons_true, cons_false, cons_pair, cons_nil, cons_cons, fun_primeq, fun_eq, fun_not, fun_and, |
948 cons_true, cons_false, cons_pair, cons_nil, cons_cons, fun_primeq, fun_eq, fun_not, fun_and, |
946 fun_or, fun_if, fun_fst, fun_snd, fun_add, fun_mult, fun_minus, fun_lt, fun_le, fun_wfrec]; |
949 fun_or, fun_if, fun_fst, fun_snd, fun_add, fun_mult, fun_minus, fun_lt, fun_le, fun_wfrec]; |
947 |
950 |
948 fun is_superclass_of modl class_sub class_sup = |
951 |
949 if class_sub = class_sup |
952 (** equality handling **) |
950 then true |
953 |
951 else |
954 fun get_eqpred modl tyco = |
952 if NameSpace.is_qualified class_sub |
955 if NameSpace.is_qualified tyco |
953 then |
956 then |
954 case get_def modl class_sub |
957 case get_def modl tyco |
955 of Class (supclsnames, _, _, _) |
958 of Datatype (_, _, insts) => |
956 => exists (fn class => is_superclass_of modl class class_sup) supclsnames |
959 get_first (fn inst => |
957 else |
960 case get_def modl inst |
958 false; |
961 of Classinst (cls, _, memdefs) => |
|
962 if cls = class_eq |
|
963 then (SOME o snd o hd) memdefs |
|
964 else NONE) insts |
|
965 else SOME fun_primeq; |
959 |
966 |
960 fun is_eqtype modl (IType (tyco, tys)) = |
967 fun is_eqtype modl (IType (tyco, tys)) = |
961 forall (is_eqtype modl) tys |
968 forall (is_eqtype modl) tys |
962 andalso |
969 andalso ( |
963 if NameSpace.is_qualified tyco |
970 NameSpace.is_qualified tyco |
964 then |
971 orelse |
965 case get_def modl tyco |
972 case get_def modl tyco |
966 of Typesyn (vs, ty) => is_eqtype modl ty |
973 of Typesyn (vs, ty) => is_eqtype modl ty |
967 | Datatype (_, _, classes) => exists (is_superclass_of modl class_eq) classes |
974 | Datatype (_, _, insts) => |
968 else |
975 exists (fn inst => case get_def modl inst of Classinst (cls, _, _) => cls = class_eq) insts |
969 true |
976 ) |
970 | is_eqtype modl (IFun _) = |
977 | is_eqtype modl (IFun _) = |
971 false |
978 false |
972 | is_eqtype modl (IVarT (_, sort)) = |
979 | is_eqtype modl (IVarT (_, sort)) = |
973 exists (is_superclass_of modl class_eq) sort |
980 member (op =) sort class_eq; |
|
981 |
|
982 fun build_eqpred modl dtname = |
|
983 let |
|
984 val cons = |
|
985 map ((fn Datatypecons c => c) o get_def modl) |
|
986 (case get_def modl dtname of Datatype (_, cs, _) => cs); |
|
987 val sortctxt = |
|
988 map (rpair [class_eq]) |
|
989 (case get_def modl dtname of Datatype (_, vs, _) => vs); |
|
990 val ty = IType (dtname, map IVarT sortctxt); |
|
991 fun mk_eq (c, []) = |
|
992 ([ICons ((c, []), ty), ICons ((c, []), ty)], Cons_true) |
|
993 | mk_eq (c, tys) = |
|
994 let |
|
995 val vars1 = Term.invent_names [] "a" (length tys); |
|
996 val vars2 = Term.invent_names vars1 "b" (length tys); |
|
997 fun mk_eq_cons ty' (v1, v2) = |
|
998 IConst (fun_eq, ty' `-> ty' `-> Type_bool) `$ IVarE (v1, ty) `$ IVarE (v2, ty) |
|
999 fun mk_conj (e1, e2) = |
|
1000 Fun_and `$ e1 `$ e2; |
|
1001 in |
|
1002 ([ICons ((c, map2 (curry IVarP) vars1 tys), ty), |
|
1003 ICons ((c, map2 (curry IVarP) vars2 tys), ty)], |
|
1004 foldr1 mk_conj (map2 mk_eq_cons tys (vars1 ~~ vars2))) |
|
1005 end; |
|
1006 val eqs = map mk_eq cons @ [([IVarP ("_", ty), IVarP ("_", ty)], Cons_false)]; |
|
1007 in |
|
1008 Fun (eqs, (sortctxt, ty `-> ty `-> Type_bool)) |
|
1009 end; |
|
1010 |
|
1011 |
|
1012 (** generic transformation **) |
974 |
1013 |
975 fun extract_defs e = |
1014 fun extract_defs e = |
976 let |
1015 let |
977 fun extr_itype (ty as IType (tyco, _)) = |
1016 fun extr_itype (ty as IType (tyco, _)) = |
978 cons tyco #> fold_itype extr_itype ty |
1017 cons tyco #> fold_itype extr_itype ty |