33 val operational_algebra: theory -> (sort -> sort) * Sorts.algebra |
33 val operational_algebra: theory -> (sort -> sort) * Sorts.algebra |
34 val these_eqns: theory -> string -> (thm * bool) list |
34 val these_eqns: theory -> string -> (thm * bool) list |
35 val these_raw_eqns: theory -> string -> (thm * bool) list |
35 val these_raw_eqns: theory -> string -> (thm * bool) list |
36 val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list) |
36 val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list) |
37 val get_datatype_of_constr: theory -> string -> string option |
37 val get_datatype_of_constr: theory -> string -> string option |
38 val get_case_scheme: theory -> string -> (int * string list) option |
38 val get_case_scheme: theory -> string -> (int * (int * string list)) option |
39 val is_undefined: theory -> string -> bool |
39 val is_undefined: theory -> string -> bool |
40 val default_typscheme: theory -> string -> (string * sort) list * typ |
40 val default_typscheme: theory -> string -> (string * sort) list * typ |
41 |
41 |
42 val preprocess_conv: theory -> cterm -> thm |
42 val preprocess_conv: theory -> cterm -> thm |
43 val preprocess_term: theory -> term -> term |
43 val preprocess_term: theory -> term -> term |
109 end; |
109 end; |
110 |
110 |
111 |
111 |
112 (** logical and syntactical specification of executable code **) |
112 (** logical and syntactical specification of executable code **) |
113 |
113 |
114 (* defining equations *) |
114 (* code equations *) |
115 |
115 |
116 type eqns = bool * (thm * bool) list lazy; |
116 type eqns = bool * (thm * bool) list lazy; |
117 (*default flag, theorems with linear flag (perhaps lazy)*) |
117 (*default flag, theorems with linear flag (perhaps lazy)*) |
118 |
118 |
119 fun pretty_lthms ctxt r = case Lazy.peek r |
119 fun pretty_lthms ctxt r = case Lazy.peek r |
134 val incr_idx = Logic.incr_indexes ([], Thm.maxidx_of thm + 1); |
134 val incr_idx = Logic.incr_indexes ([], Thm.maxidx_of thm + 1); |
135 fun matches_args args' = length args <= length args' andalso |
135 fun matches_args args' = length args <= length args' andalso |
136 Pattern.matchess thy (args, (map incr_idx o curry Library.take (length args)) args'); |
136 Pattern.matchess thy (args, (map incr_idx o curry Library.take (length args)) args'); |
137 fun drop (thm', linear') = if (linear orelse not linear') |
137 fun drop (thm', linear') = if (linear orelse not linear') |
138 andalso matches_args (args_of thm') then |
138 andalso matches_args (args_of thm') then |
139 (warning ("Code generator: dropping redundant defining equation\n" ^ Display.string_of_thm thm'); true) |
139 (warning ("Code generator: dropping redundant code equation\n" ^ Display.string_of_thm thm'); true) |
140 else false; |
140 else false; |
141 in (thm, linear) :: filter_out drop thms end; |
141 in (thm, linear) :: filter_out drop thms end; |
142 |
142 |
143 fun add_thm thy _ thm (false, thms) = (false, Lazy.map_force (add_drop_redundant thy thm) thms) |
143 fun add_thm thy _ thm (false, thms) = (false, Lazy.map_force (add_drop_redundant thy thm) thms) |
144 | add_thm thy true thm (true, thms) = (true, Lazy.map_force (fn thms => thms @ [thm]) thms) |
144 | add_thm thy true thm (true, thms) = (true, Lazy.map_force (fn thms => thms @ [thm]) thms) |
407 (Syntax.string_of_typ_global thy (Type (dtco, map TFree vs)), cos)) |
407 (Syntax.string_of_typ_global thy (Type (dtco, map TFree vs)), cos)) |
408 |> sort (string_ord o pairself fst) |
408 |> sort (string_ord o pairself fst) |
409 in |
409 in |
410 (Pretty.writeln o Pretty.chunks) [ |
410 (Pretty.writeln o Pretty.chunks) [ |
411 Pretty.block ( |
411 Pretty.block ( |
412 Pretty.str "defining equations:" |
412 Pretty.str "code equations:" |
413 :: Pretty.fbrk |
413 :: Pretty.fbrk |
414 :: (Pretty.fbreaks o map pretty_eqn) eqns |
414 :: (Pretty.fbreaks o map pretty_eqn) eqns |
415 ), |
415 ), |
416 Pretty.block [ |
416 Pretty.block [ |
417 Pretty.str "preprocessing simpset:", |
417 Pretty.str "preprocessing simpset:", |
450 in (thm', max') end; |
450 in (thm', max') end; |
451 val (thms', maxidx) = fold_map incr_thm thms 0; |
451 val (thms', maxidx) = fold_map incr_thm thms 0; |
452 val ty1 :: tys = map (snd o Code_Unit.const_typ_eqn) thms'; |
452 val ty1 :: tys = map (snd o Code_Unit.const_typ_eqn) thms'; |
453 fun unify ty env = Sign.typ_unify thy (ty1, ty) env |
453 fun unify ty env = Sign.typ_unify thy (ty1, ty) env |
454 handle Type.TUNIFY => |
454 handle Type.TUNIFY => |
455 error ("Type unificaton failed, while unifying defining equations\n" |
455 error ("Type unificaton failed, while unifying code equations\n" |
456 ^ (cat_lines o map Display.string_of_thm) thms |
456 ^ (cat_lines o map Display.string_of_thm) thms |
457 ^ "\nwith types\n" |
457 ^ "\nwith types\n" |
458 ^ (cat_lines o map (Code_Unit.string_of_typ thy)) (ty1 :: tys)); |
458 ^ (cat_lines o map (Code_Unit.string_of_typ thy)) (ty1 :: tys)); |
459 val (env, _) = fold unify tys (Vartab.empty, maxidx) |
459 val (env, _) = fold unify tys (Vartab.empty, maxidx) |
460 val instT = Vartab.fold (fn (x_i, (sort, ty)) => |
460 val instT = Vartab.fold (fn (x_i, (sort, ty)) => |
461 cons (Thm.ctyp_of thy (TVar (x_i, sort)), Thm.ctyp_of thy ty)) env []; |
461 cons (Thm.ctyp_of thy (TVar (x_i, sort)), Thm.ctyp_of thy ty)) env []; |
462 in map (Thm.instantiate (instT, [])) thms' end; |
462 in map (Thm.instantiate (instT, [])) thms' end; |
463 |
463 |
464 fun check_linear (eqn as (thm, linear)) = |
464 fun check_linear (eqn as (thm, linear)) = |
465 if linear then eqn else Code_Unit.bad_thm |
465 if linear then eqn else Code_Unit.bad_thm |
466 ("Duplicate variables on left hand side of defining equation:\n" |
466 ("Duplicate variables on left hand side of code equation:\n" |
467 ^ Display.string_of_thm thm); |
467 ^ Display.string_of_thm thm); |
468 |
468 |
469 fun mk_eqn thy linear = |
469 fun mk_eqn thy linear = |
470 Code_Unit.error_thm ((if linear then check_linear else I) o Code_Unit.mk_eqn thy); |
470 Code_Unit.error_thm ((if linear then check_linear else I) o Code_Unit.mk_eqn thy); |
471 fun mk_syntactic_eqn thy = Code_Unit.warning_thm (Code_Unit.mk_eqn thy); |
471 fun mk_syntactic_eqn thy = Code_Unit.warning_thm (Code_Unit.mk_eqn thy); |
523 case (snd o strip_type o Sign.the_const_type thy) c |
523 case (snd o strip_type o Sign.the_const_type thy) c |
524 of Type (tyco, _) => if member (op =) ((map fst o snd o get_datatype thy) tyco) c |
524 of Type (tyco, _) => if member (op =) ((map fst o snd o get_datatype thy) tyco) c |
525 then SOME tyco else NONE |
525 then SOME tyco else NONE |
526 | _ => NONE; |
526 | _ => NONE; |
527 |
527 |
528 fun get_constr_typ thy c = |
|
529 case get_datatype_of_constr thy c |
|
530 of SOME tyco => let |
|
531 val (vs, cos) = get_datatype thy tyco; |
|
532 val SOME tys = AList.lookup (op =) cos c; |
|
533 val ty = tys ---> Type (tyco, map TFree vs); |
|
534 in SOME (Logic.varifyT ty) end |
|
535 | NONE => NONE; |
|
536 |
|
537 fun recheck_eqn thy = Code_Unit.error_thm |
528 fun recheck_eqn thy = Code_Unit.error_thm |
538 (Code_Unit.assert_linear (is_some o get_datatype_of_constr thy) o apfst (Code_Unit.assert_eqn thy)); |
529 (Code_Unit.assert_linear (is_some o get_datatype_of_constr thy) o apfst (Code_Unit.assert_eqn thy)); |
539 |
530 |
540 fun recheck_eqns_const thy c eqns = |
531 fun recheck_eqns_const thy c eqns = |
541 let |
532 let |
542 fun cert (eqn as (thm, _)) = if c = Code_Unit.const_eqn thm |
533 fun cert (eqn as (thm, _)) = if c = Code_Unit.const_eqn thm |
543 then eqn else error ("Wrong head of defining equation,\nexpected constant " |
534 then eqn else error ("Wrong head of code equation,\nexpected constant " |
544 ^ Code_Unit.string_of_const thy c ^ "\n" ^ Display.string_of_thm thm) |
535 ^ Code_Unit.string_of_const thy c ^ "\n" ^ Display.string_of_thm thm) |
545 in map (cert o recheck_eqn thy) eqns end; |
536 in map (cert o recheck_eqn thy) eqns end; |
546 |
537 |
547 fun change_eqns delete c f = (map_exec_purge (SOME [c]) o map_eqns |
538 fun change_eqns delete c f = (map_exec_purge (SOME [c]) o map_eqns |
548 o (if delete then Symtab.map_entry c else Symtab.map_default (c, ((false, (true, Lazy.value [])), []))) |
539 o (if delete then Symtab.map_entry c else Symtab.map_default (c, ((false, (true, Lazy.value [])), []))) |
552 case (if default then mk_default_eqn thy else SOME o mk_eqn thy linear) thm |
543 case (if default then mk_default_eqn thy else SOME o mk_eqn thy linear) thm |
553 of SOME (thm, _) => |
544 of SOME (thm, _) => |
554 let |
545 let |
555 val c = Code_Unit.const_eqn thm; |
546 val c = Code_Unit.const_eqn thm; |
556 val _ = if not default andalso (is_some o AxClass.class_of_param thy) c |
547 val _ = if not default andalso (is_some o AxClass.class_of_param thy) c |
557 then error ("Rejected polymorphic equation for overloaded constant:\n" |
548 then error ("Rejected polymorphic code equation for overloaded constant:\n" |
558 ^ Display.string_of_thm thm) |
549 ^ Display.string_of_thm thm) |
559 else (); |
550 else (); |
560 val _ = if not default andalso (is_some o get_datatype_of_constr thy) c |
551 val _ = if not default andalso (is_some o get_datatype_of_constr thy) c |
561 then error ("Rejected equation for datatype constructor:\n" |
552 then error ("Rejected code equation for datatype constructor:\n" |
562 ^ Display.string_of_thm thm) |
553 ^ Display.string_of_thm thm) |
563 else (); |
554 else (); |
564 in change_eqns false c (add_thm thy default (thm, linear)) thy end |
555 in change_eqns false c (add_thm thy default (thm, linear)) thy end |
565 | NONE => thy; |
556 | NONE => thy; |
566 |
557 |
581 of SOME (thm, _) => change_eqns true (Code_Unit.const_eqn thm) (del_thm thm) thy |
572 of SOME (thm, _) => change_eqns true (Code_Unit.const_eqn thm) (del_thm thm) thy |
582 | NONE => thy; |
573 | NONE => thy; |
583 |
574 |
584 fun del_eqns c = change_eqns true c (K (false, Lazy.value [])); |
575 fun del_eqns c = change_eqns true c (K (false, Lazy.value [])); |
585 |
576 |
586 fun get_case_scheme thy = Symtab.lookup ((fst o the_cases o the_exec) thy); |
577 fun get_case_scheme thy c = case Symtab.lookup ((fst o the_cases o the_exec) thy) c |
|
578 of SOME (base_case_scheme as (_, case_pats)) => |
|
579 if forall (is_some o get_datatype_of_constr thy) case_pats |
|
580 then SOME (1 + Int.max (1, length case_pats), base_case_scheme) |
|
581 else NONE |
|
582 | NONE => NONE; |
587 |
583 |
588 val is_undefined = Symtab.defined o snd o the_cases o the_exec; |
584 val is_undefined = Symtab.defined o snd o the_cases o the_exec; |
589 |
585 |
590 structure TypeInterpretation = InterpretationFun(type T = string * serial val eq = eq_snd (op =) : T * T -> bool); |
586 structure TypeInterpretation = InterpretationFun(type T = string * serial val eq = eq_snd (op =) : T * T -> bool); |
591 |
587 |
725 |> preprocess thy functrans c |
721 |> preprocess thy functrans c |
726 end; |
722 end; |
727 |
723 |
728 fun default_typscheme thy c = |
724 fun default_typscheme thy c = |
729 let |
725 let |
730 val typscheme = curry (Code_Unit.typscheme thy) c |
726 fun the_const_typscheme c = (curry (Code_Unit.typscheme thy) c o snd o dest_Const |
731 val the_const_type = snd o dest_Const o TermSubst.zero_var_indexes |
727 o TermSubst.zero_var_indexes o curry Const "" o Sign.the_const_type thy) c; |
732 o curry Const "" o Sign.the_const_type thy; |
728 fun strip_sorts (vs, ty) = (map (fn (v, _) => (v, [])) vs, ty); |
733 in case AxClass.class_of_param thy c |
729 in case AxClass.class_of_param thy c |
734 of SOME class => the_const_type c |
730 of SOME class => ([(Name.aT, [class])], snd (the_const_typscheme c)) |
735 |> Term.map_type_tvar (K (TVar ((Name.aT, 0), [class]))) |
731 | NONE => if is_some (get_datatype_of_constr thy c) |
736 |> typscheme |
732 then strip_sorts (the_const_typscheme c) |
737 | NONE => (case get_constr_typ thy c |
733 else case get_eqns thy c |
738 of SOME ty => typscheme ty |
734 of (thm, _) :: _ => snd (Code_Unit.head_eqn thy (Drule.zero_var_indexes thm)) |
739 | NONE => (case get_eqns thy c |
735 | [] => strip_sorts (the_const_typscheme c) end; |
740 of (thm, _) :: _ => snd (Code_Unit.head_eqn thy (Drule.zero_var_indexes thm)) |
|
741 | [] => typscheme (the_const_type c))) end; |
|
742 |
736 |
743 end; (*local*) |
737 end; (*local*) |
744 |
738 |
745 end; (*struct*) |
739 end; (*struct*) |
746 |
740 |