63 val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option) |
63 val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option) |
64 -> (theory -> string * string -> typ list option) |
64 -> (theory -> string * string -> typ list option) |
65 -> defgen; |
65 -> defgen; |
66 val defgen_datacons: (theory -> string * string -> typ list option) |
66 val defgen_datacons: (theory -> string * string -> typ list option) |
67 -> defgen; |
67 -> defgen; |
68 val defgen_datatype_eq: (theory -> string -> ((string * sort) list * string list) option) |
|
69 -> defgen; |
|
70 val defgen_datatype_eqinst: (theory -> string -> ((string * sort) list * string list) option) |
|
71 -> defgen; |
|
72 val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ) |
68 val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ) |
73 -> defgen; |
69 -> defgen; |
74 |
70 |
75 val print_codegen_generated: theory -> unit; |
71 val print_codegen_generated: theory -> unit; |
76 val mk_deftab: theory -> deftab; |
72 val mk_deftab: theory -> deftab; |
123 val nsp_type = "type"; |
126 val nsp_type = "type"; |
124 val nsp_const = "const"; |
127 val nsp_const = "const"; |
125 val nsp_dtcon = "dtcon"; (*NOT OPERATIONAL YET*) |
128 val nsp_dtcon = "dtcon"; (*NOT OPERATIONAL YET*) |
126 val nsp_mem = "mem"; |
129 val nsp_mem = "mem"; |
127 val nsp_inst = "inst"; |
130 val nsp_inst = "inst"; |
128 val nsp_eq_class = "eq_class"; |
131 val nsp_eq_inst = "eq_inst"; |
129 val nsp_eq = "eq"; |
132 val nsp_eq_pred = "eq"; |
130 |
133 |
131 |
134 |
132 (* serializer *) |
135 (* serializer *) |
133 |
136 |
134 val serializer_ml = |
137 val serializer_ml = |
135 let |
138 let |
136 val name_root = "Generated"; |
139 val name_root = "Generated"; |
137 val nsp_conn = [ |
140 val nsp_conn = [ |
138 [nsp_class, nsp_type, nsp_eq_class], [nsp_const, nsp_dtcon, nsp_inst, nsp_mem, nsp_eq] |
141 [nsp_class, nsp_type], [nsp_const, nsp_dtcon, nsp_inst, nsp_mem, nsp_eq_inst, nsp_eq_pred] |
139 ]; |
142 ]; |
140 in CodegenSerializer.ml_from_thingol nsp_conn name_root end; |
143 in CodegenSerializer.ml_from_thingol nsp_conn name_root end; |
141 |
144 |
142 val serializer_hs = |
145 val serializer_hs = |
143 let |
146 let |
144 val name_root = "Generated"; |
147 val name_root = "Generated"; |
145 val nsp_conn = [ |
148 val nsp_conn = [ |
146 [nsp_class, nsp_eq_class], [nsp_type], [nsp_const, nsp_mem, nsp_eq], [nsp_dtcon], [nsp_inst] |
149 [nsp_class], [nsp_type], [nsp_const, nsp_mem, nsp_eq_pred], [nsp_dtcon], [nsp_inst, nsp_eq_inst] |
147 ]; |
150 ]; |
148 in CodegenSerializer.haskell_from_thingol nsp_conn name_root end; |
151 in CodegenSerializer.haskell_from_thingol nsp_conn name_root end; |
149 |
152 |
150 |
153 |
151 (* theory data for codegen *) |
154 (* theory data for codegen *) |
270 Symtab.empty |
273 Symtab.empty |
271 |> Symtab.update ("ml", |
274 |> Symtab.update ("ml", |
272 { serializer = serializer_ml : CodegenSerializer.serializer, |
275 { serializer = serializer_ml : CodegenSerializer.serializer, |
273 primitives = |
276 primitives = |
274 CodegenSerializer.empty_prims |
277 CodegenSerializer.empty_prims |
|
278 |> CodegenSerializer.add_prim ("Eq", ("type 'a Eq = {eq: 'a -> 'a -> bool};", [])) |
275 |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", [])) |
279 |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", [])) |
276 |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", [])) |
280 |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", [])) |
277 |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])), |
281 |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])), |
278 syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
282 syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
279 |> Symtab.update ("haskell", |
283 |> Symtab.update ("haskell", |
569 |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty)))) |
573 |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty)))) |
570 end; |
574 end; |
571 |
575 |
572 fun fix_nargs thy defs gen (imin, imax) (t, ts) trns = |
576 fun fix_nargs thy defs gen (imin, imax) (t, ts) trns = |
573 if length ts < imin then |
577 if length ts < imin then |
574 trns |
578 let |
575 |> debug 10 (fn _ => "eta-expanding") |
579 val d = imin - length ts; |
576 |> gen (strip_comb (Codegen.eta_expand t ts imin)) |
580 val vs = Term.invent_names (add_term_names (t, [])) "x" d; |
577 |-> succeed |
581 val tys = Library.take (d, ((fst o strip_type o fastype_of) t)); |
|
582 in |
|
583 trns |
|
584 |> debug 10 (fn _ => "eta-expanding") |
|
585 |> fold_map (invoke_cg_type thy defs) tys |
|
586 ||>> gen (t, ts @ map2 (curry Free) vs tys) |
|
587 |-> (fn (tys, e) => succeed ((vs ~~ tys) `|--> e)) |
|
588 end |
578 else if length ts > imax then |
589 else if length ts > imax then |
579 trns |
590 trns |
580 |> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")") |
591 |> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")") |
581 |> gen (t, Library.take (imax, ts)) |
592 |> gen (t, Library.take (imax, ts)) |
582 ||>> fold_map (invoke_cg_expr thy defs) (Library.drop (imax, ts)) |
593 ||>> fold_map (invoke_cg_expr thy defs) (Library.drop (imax, ts)) |
699 end |
700 end |
700 | appgen_neg thy defs ((f, _), _) trns = |
701 | appgen_neg thy defs ((f, _), _) trns = |
701 trns |
702 trns |
702 |> fail ("not a negation: " ^ quote f); |
703 |> fail ("not a negation: " ^ quote f); |
703 |
704 |
704 fun exprgen_term_eq thy defs (Const ("op =", Type ("fun", [ty, _]))) trns = |
705 fun appgen_eq thy defs (f as ("op =", Type ("fun", [ty, _])), ts) trns = |
705 trns |
706 let |
706 |
707 fun mk_eq_pred_inst (dtco, (eqpred, arity)) trns = |
707 (*fun codegen_eq thy defs t trns = |
708 let |
708 let |
709 val name_dtco = (the oo tname_of_idf) thy dtco; |
709 fun cg_eq (Const ("op =", _), [t, u]) = |
710 val idf_eqinst = idf_of_name thy nsp_eq_inst name_dtco; |
710 trns |
711 val idf_eqpred = idf_of_name thy nsp_eq_pred name_dtco; |
711 |> invoke_cg_type thy defs (type_of t) |
712 fun mk_eq_pred _ trns = |
712 |-> (fn ty => invoke_ensure_eqinst nsp_eq_class nsp_eq ty #> pair ty) |
713 trns |
713 ||>> invoke_cg_expr thy defs t |
714 |> succeed (eqpred, []) |
714 ||>> invoke_cg_expr thy defs u |
715 fun mk_eq_inst _ trns = |
715 |-> (fn ((ty, t'), u') => succeed ( |
716 trns |
716 IConst (fun_eq, ty `-> ty `-> Type_bool) |
717 |> gen_ensure_def [("eqpred", mk_eq_pred)] ("generating equality predicate for " ^ quote dtco) idf_eqpred |
717 `$ t' `$ u')) |
718 |> succeed (Classinst (class_eq, (dtco, arity), [(fun_eq, idf_eqpred)]), []) |
718 | cg_eq _ = |
719 in |
719 trns |
720 trns |
720 |> fail ("no equality: " ^ Sign.string_of_term thy t) |
721 |> gen_ensure_def [("eqinst", mk_eq_inst)] ("generating equality instance for " ^ quote dtco) idf_eqinst |
721 in cg_eq (strip_comb t) end;*) |
722 end; |
722 |
723 fun mk_eq_expr (_, [t1, t2]) trns = |
|
724 trns |
|
725 |> invoke_eq (invoke_cg_type thy defs) mk_eq_pred_inst ty |
|
726 |-> (fn false => error ("could not derive equality for " ^ Sign.string_of_typ thy ty) |
|
727 | true => fn trns => trns |
|
728 |> invoke_cg_expr thy defs t1 |
|
729 ||>> invoke_cg_expr thy defs t2 |
|
730 |-> (fn (e1, e2) => pair (Fun_eq `$ e1 `$ e2))) |
|
731 in |
|
732 trns |
|
733 |> fix_nargs thy defs mk_eq_expr (2, 2) (Const f, ts) |
|
734 end |
|
735 | appgen_eq thy defs ((f, _), _) trns = |
|
736 trns |
|
737 |> fail ("not an equality: " ^ quote f); |
|
738 |
|
739 |
|
740 (* invoke_eq: ((string * def) -> transact -> transact) -> itype -> transact -> bool * transact; *) |
723 |
741 |
724 (* definition generators *) |
742 (* definition generators *) |
725 |
743 |
726 fun defgen_tyco_fallback thy defs tyco trns = |
744 fun defgen_tyco_fallback thy defs tyco trns = |
727 if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco) |
745 if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco) |
944 |> fix_nargs thy defs (cg_case dty (cs ~~ tys)) |
962 |> fix_nargs thy defs (cg_case dty (cs ~~ tys)) |
945 (length cs + 1, length cs + 1) (Const (f, ty), ts) |
963 (length cs + 1, length cs + 1) (Const (f, ty), ts) |
946 end |
964 end |
947 end; |
965 end; |
948 |
966 |
949 local |
|
950 |
|
951 fun add_eqinst get_datacons thy modl dtname cnames = |
|
952 if forall (is_eqtype modl) |
|
953 (Library.flat (map (fn cname => get_datacons thy (cname, dtname)) cnames)) |
|
954 then append [idf_of_name thy nsp_eq_class dtname] |
|
955 else I |
|
956 |
|
957 in |
|
958 |
|
959 fun defgen_datatype get_datatype get_datacons thy defs idf trns = |
967 fun defgen_datatype get_datatype get_datacons thy defs idf trns = |
960 case tname_of_idf thy idf |
968 case tname_of_idf thy idf |
961 of SOME dtco => |
969 of SOME dtco => |
962 (case get_datatype thy dtco |
970 (case get_datatype thy dtco |
963 of SOME (vars, cos) => |
971 of SOME (vars, cos) => |
1013 |> fail ("no datatype constructor found for " ^ quote f)) |
1018 |> fail ("no datatype constructor found for " ^ quote f)) |
1014 | _ => |
1019 | _ => |
1015 trns |
1020 trns |
1016 |> fail ("not a constant: " ^ quote f) |
1021 |> fail ("not a constant: " ^ quote f) |
1017 end; |
1022 end; |
1018 |
|
1019 fun defgen_datatype_eq get_datatype thy defs f trns = |
|
1020 case name_of_idf thy nsp_eq f |
|
1021 of SOME dtname => |
|
1022 (case get_datatype thy dtname |
|
1023 of SOME (_, cnames) => |
|
1024 trns |
|
1025 |> debug 5 (fn _ => "trying defgen datatype_eq for " ^ quote dtname) |
|
1026 |> ensure_def_tyco thy defs (idf_of_tname thy dtname) |
|
1027 ||>> fold_map (ensure_def_const thy defs) (cnames |
|
1028 |> map (idf_of_name thy nsp_const) |
|
1029 |> map (fn "0" => "const.Zero" | c => c)) |
|
1030 ||>> `(fn (_, modl) => build_eqpred modl dtname) |
|
1031 |-> (fn (_, eqpred) => succeed (eqpred, [])) |
|
1032 | NONE => |
|
1033 trns |
|
1034 |> fail ("no datatype found for " ^ quote dtname)) |
|
1035 | NONE => |
|
1036 trns |
|
1037 |> fail ("not an equality predicate: " ^ quote f) |
|
1038 |
|
1039 fun defgen_datatype_eqinst get_datatype thy defs f trns = |
|
1040 case name_of_idf thy nsp_eq_class f |
|
1041 of SOME dtname => |
|
1042 (case get_datatype thy dtname |
|
1043 of SOME (vars, _) => |
|
1044 trns |
|
1045 |> debug 5 (fn _ => "trying defgen datatype_eqinst for " ^ quote dtname) |
|
1046 |> ensure_def_const thy defs (idf_of_name thy nsp_eq dtname) |
|
1047 |-> (fn pred_eq => succeed (Classinst (class_eq, (dtname, |
|
1048 map (fn (v, _) => (v, [class_eq])) vars), [(fun_eq, pred_eq)]), [])) |
|
1049 | NONE => |
|
1050 trns |
|
1051 |> fail ("no datatype found for " ^ quote dtname)) |
|
1052 | NONE => |
|
1053 trns |
|
1054 |> fail ("not an equality instance: " ^ quote f) |
|
1055 |
1023 |
1056 fun defgen_recfun get_equations thy defs f trns = |
1024 fun defgen_recfun get_equations thy defs f trns = |
1057 case cname_of_idf thy defs f |
1025 case cname_of_idf thy defs f |
1058 of SOME (f, ty) => |
1026 of SOME (f, ty) => |
1059 let |
1027 let |
1453 CodegenData.init, |
1421 CodegenData.init, |
1454 add_codegen_sort ("default", exprgen_sort_default), |
1422 add_codegen_sort ("default", exprgen_sort_default), |
1455 add_codegen_type ("default", exprgen_type_default), |
1423 add_codegen_type ("default", exprgen_type_default), |
1456 add_codegen_expr ("default", exprgen_term_default), |
1424 add_codegen_expr ("default", exprgen_term_default), |
1457 add_appgen ("default", appgen_default), |
1425 add_appgen ("default", appgen_default), |
1458 (* add_codegen_expr ("eq", codegen_eq), *) |
1426 add_appgen ("eq", appgen_eq), |
1459 add_appgen ("neg", appgen_neg), |
1427 add_appgen ("neg", appgen_neg), |
1460 add_defgen ("clsdecl", defgen_clsdecl), |
1428 add_defgen ("clsdecl", defgen_clsdecl), |
1461 add_defgen ("tyco_fallback", defgen_tyco_fallback), |
1429 add_defgen ("tyco_fallback", defgen_tyco_fallback), |
1462 add_defgen ("const_fallback", defgen_const_fallback), |
1430 add_defgen ("const_fallback", defgen_const_fallback), |
1463 add_defgen ("defs", defgen_defs), |
1431 add_defgen ("defs", defgen_defs), |