src/Tools/Code/code_thingol.ML
changeset 56920 d651b944c67e
parent 56811 b66639331db5
child 56969 7491932da574
equal deleted inserted replaced
56919:6389a8c1268a 56920:d651b944c67e
    84       * ((Code_Symbol.T * stmt) list * (Code_Symbol.T * stmt) list)) list
    84       * ((Code_Symbol.T * stmt) list * (Code_Symbol.T * stmt) list)) list
    85 
    85 
    86   val read_const_exprs: Proof.context -> string list -> string list
    86   val read_const_exprs: Proof.context -> string list -> string list
    87   val consts_program: theory -> string list -> program
    87   val consts_program: theory -> string list -> program
    88   val dynamic_conv: Proof.context -> (program
    88   val dynamic_conv: Proof.context -> (program
    89     -> ((string * sort) list * typscheme) * iterm -> Code_Symbol.T list -> conv)
    89     -> (string -> (string * sort)) -> typscheme * iterm -> Code_Symbol.T list -> conv)
    90     -> conv
    90     -> conv
    91   val dynamic_value: Proof.context -> ((term -> term) -> 'a -> 'a) -> (program
    91   val dynamic_value: Proof.context -> ((term -> term) -> 'a -> 'a) -> (program
    92     -> ((string * sort) list * typscheme) * iterm -> Code_Symbol.T list -> 'a)
    92     -> (string -> (string * sort)) -> typscheme * iterm -> Code_Symbol.T list -> 'a)
    93     -> term -> 'a
    93     -> term -> 'a
    94   val static_conv: Proof.context -> string list -> (program -> string list
    94   val static_conv: Proof.context -> string list -> (program -> string list
    95     -> Proof.context -> ((string * sort) list * typscheme) * iterm -> Code_Symbol.T list -> conv)
    95     -> Proof.context -> (string -> (string * sort)) -> typscheme * iterm -> Code_Symbol.T list -> conv)
    96     -> Proof.context -> conv
    96     -> Proof.context -> conv
    97   val static_conv_simple: Proof.context -> string list
    97   val static_conv_simple: Proof.context -> string list
    98     -> (program -> Proof.context -> (string * sort) list -> term -> conv)
    98     -> (program -> Proof.context -> term -> conv)
    99     -> Proof.context -> conv
    99     -> Proof.context -> conv
   100   val static_value: Proof.context -> ((term -> term) -> 'a -> 'a) -> string list ->
   100   val static_value: Proof.context -> ((term -> term) -> 'a -> 'a) -> string list ->
   101     (program -> string list
   101     (program -> string list
   102       -> Proof.context -> ((string * sort) list * typscheme) * iterm -> Code_Symbol.T list -> 'a)
   102       -> Proof.context -> (string -> (string * sort)) -> typscheme * iterm -> Code_Symbol.T list -> 'a)
   103     -> Proof.context -> term -> 'a
   103     -> Proof.context -> term -> 'a
   104 end;
   104 end;
   105 
   105 
   106 structure Code_Thingol: CODE_THINGOL =
   106 structure Code_Thingol: CODE_THINGOL =
   107 struct
   107 struct
   386       |> pair x
   386       |> pair x
   387   end;
   387   end;
   388 
   388 
   389 exception PERMISSIVE of unit;
   389 exception PERMISSIVE of unit;
   390 
   390 
   391 fun translation_error ctxt program permissive some_thm deps msg sub_msg =
   391 fun translation_error ctxt permissive some_thm deps msg sub_msg =
   392   if permissive
   392   if permissive
   393   then raise PERMISSIVE ()
   393   then raise PERMISSIVE ()
   394   else
   394   else
   395     let
   395     let
   396       val thm_msg =
   396       val thm_msg =
   406     in error (msg ^ thm_dep_msg ^ ":\n" ^ sub_msg) end;
   406     in error (msg ^ thm_dep_msg ^ ":\n" ^ sub_msg) end;
   407 
   407 
   408 fun maybe_permissive f prgrm =
   408 fun maybe_permissive f prgrm =
   409   f prgrm |>> SOME handle PERMISSIVE () => (NONE, prgrm);
   409   f prgrm |>> SOME handle PERMISSIVE () => (NONE, prgrm);
   410 
   410 
   411 fun not_wellsorted ctxt program permissive some_thm deps ty sort e =
   411 fun not_wellsorted ctxt permissive some_thm deps ty sort e =
   412   let
   412   let
   413     val err_class = Sorts.class_error (Context.pretty ctxt) e;
   413     val err_class = Sorts.class_error (Context.pretty ctxt) e;
   414     val err_typ =
   414     val err_typ =
   415       "Type " ^ Syntax.string_of_typ ctxt ty ^ " not of sort " ^
   415       "Type " ^ Syntax.string_of_typ ctxt ty ^ " not of sort " ^
   416         Syntax.string_of_sort ctxt sort;
   416         Syntax.string_of_sort ctxt sort;
   417   in
   417   in
   418     translation_error ctxt program permissive some_thm deps
   418     translation_error ctxt permissive some_thm deps
   419       "Wellsortedness error" (err_typ ^ "\n" ^ err_class)
   419       "Wellsortedness error" (err_typ ^ "\n" ^ err_class)
   420   end;
   420   end;
   421 
   421 
   422 
   422 
   423 (* inference of type annotations for disambiguation with type classes *)
   423 (* inference of type annotations for disambiguation with type classes *)
   481       in map_index (fn (n, class) => (Weakening ([], Local (v, (n, sort'))), class)) sort' end;
   481       in map_index (fn (n, class) => (Weakening ([], Local (v, (n, sort'))), class)) sort' end;
   482     val typarg_witnesses = Sorts.of_sort_derivation algebra
   482     val typarg_witnesses = Sorts.of_sort_derivation algebra
   483       {class_relation = K (Sorts.classrel_derivation algebra class_relation),
   483       {class_relation = K (Sorts.classrel_derivation algebra class_relation),
   484        type_constructor = type_constructor,
   484        type_constructor = type_constructor,
   485        type_variable = type_variable} (ty, proj_sort sort)
   485        type_variable = type_variable} (ty, proj_sort sort)
   486       handle Sorts.CLASS_ERROR e => not_wellsorted ctxt program permissive some_thm deps ty sort e;
   486       handle Sorts.CLASS_ERROR e => not_wellsorted ctxt permissive some_thm deps ty sort e;
   487   in (typarg_witnesses, (deps, program)) end;
   487   in (typarg_witnesses, (deps, program)) end;
   488 
   488 
   489 
   489 
   490 (* translation *)
   490 (* translation *)
   491 
   491 
   628 and translate_const ctxt algbr eqngr permissive some_thm ((c, ty), some_abs) (deps, program) =
   628 and translate_const ctxt algbr eqngr permissive some_thm ((c, ty), some_abs) (deps, program) =
   629   let
   629   let
   630     val thy = Proof_Context.theory_of ctxt;
   630     val thy = Proof_Context.theory_of ctxt;
   631     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   631     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   632         andalso Code.is_abstr thy c
   632         andalso Code.is_abstr thy c
   633         then translation_error ctxt program permissive some_thm deps
   633         then translation_error ctxt permissive some_thm deps
   634           "Abstraction violation" ("constant " ^ Code.string_of_const thy c)
   634           "Abstraction violation" ("constant " ^ Code.string_of_const thy c)
   635       else ()
   635       else ()
   636   in translate_const_proper ctxt algbr eqngr permissive some_thm (c, ty) (deps, program) end
   636   in translate_const_proper ctxt algbr eqngr permissive some_thm (c, ty) (deps, program) end
   637 and translate_const_proper ctxt algbr eqngr permissive some_thm (c, ty) =
   637 and translate_const_proper ctxt algbr eqngr permissive some_thm (c, ty) =
   638   let
   638   let
   793   end;
   793   end;
   794 
   794 
   795 
   795 
   796 (* value evaluation *)
   796 (* value evaluation *)
   797 
   797 
   798 fun ensure_value ctxt algbr eqngr t =
   798 fun normalize_tvars t = 
   799   let
   799   let
   800     val ty = fastype_of t;
   800     val ty = fastype_of t;
   801     val vs = fold_term_types (K (fold_atyps (insert (eq_fst op =)
   801     val vs_original = fold_term_types (K (fold_atyps (insert (eq_fst op =)
   802       o dest_TFree))) t [];
   802       o dest_TFree))) t [];
       
   803     val vs_normalized = Name.invent_names Name.context Name.aT (map snd vs_original);
       
   804     val normalize = map_type_tfree (TFree o the o AList.lookup (op =) (vs_original ~~ vs_normalized));
       
   805   in ((vs_original, (vs_normalized, normalize ty)), map_types normalize t) end;
       
   806 
       
   807 fun ensure_value ctxt algbr eqngr t_original =
       
   808   let
       
   809     val ((vs_original, (vs, ty)), t) = normalize_tvars t_original;
   803     val t' = annotate ctxt algbr eqngr (@{const_name Pure.dummy_pattern}, ty) [] t;
   810     val t' = annotate ctxt algbr eqngr (@{const_name Pure.dummy_pattern}, ty) [] t;
   804     val dummy_constant = Constant @{const_name Pure.dummy_pattern};
   811     val dummy_constant = Constant @{const_name Pure.dummy_pattern};
   805     val stmt_value =
   812     val stmt_value =
   806       fold_map (translate_tyvar_sort ctxt algbr eqngr false) vs
   813       fold_map (translate_tyvar_sort ctxt algbr eqngr false) vs
   807       ##>> translate_typ ctxt algbr eqngr false ty
   814       ##>> translate_typ ctxt algbr eqngr false ty
   808       ##>> translate_term ctxt algbr eqngr false NONE (t', NONE)
   815       ##>> translate_term ctxt algbr eqngr false NONE (t', NONE)
   809       #>> (fn ((vs, ty), t) => Fun
   816       #>> (fn ((vs, ty), t) => Fun
   810         (((vs, ty), [(([], t), (NONE, true))]), NONE));
   817         (((vs, ty), [(([], t), (NONE, true))]), NONE));
   811     fun term_value (deps, program1) =
   818     fun term_value (_, program1) =
   812       let
   819       let
   813         val Fun ((vs_ty, [(([], t), _)]), _) =
   820         val Fun ((vs_ty as (vs, _), [(([], t), _)]), _) =
   814           Code_Symbol.Graph.get_node program1 dummy_constant;
   821           Code_Symbol.Graph.get_node program1 dummy_constant;
   815         val deps' = Code_Symbol.Graph.immediate_succs program1 dummy_constant;
   822         val deps' = Code_Symbol.Graph.immediate_succs program1 dummy_constant;
   816         val program2 = Code_Symbol.Graph.del_node dummy_constant program1;
   823         val program2 = Code_Symbol.Graph.del_node dummy_constant program1;
   817         val deps_all = Code_Symbol.Graph.all_succs program2 deps';
   824         val deps_all = Code_Symbol.Graph.all_succs program2 deps';
   818         val program3 = Code_Symbol.Graph.restrict (member (op =) deps_all) program2;
   825         val program3 = Code_Symbol.Graph.restrict (member (op =) deps_all) program2;
   819       in ((program3, ((vs_ty, t), deps')), (deps, program2)) end;
   826         val vs_mapping = map fst vs ~~ vs_original;
       
   827       in (((the o AList.lookup (op =) vs_mapping), (program3, ((vs_ty, t), deps'))), (deps', program2)) end;
   820   in
   828   in
   821     ensure_stmt Constant stmt_value @{const_name Pure.dummy_pattern}
   829     ensure_stmt Constant stmt_value @{const_name Pure.dummy_pattern}
   822     #> snd
   830     #> snd
   823     #> term_value
   831     #> term_value
   824   end;
   832   end;
   825 
   833 
   826 fun original_sorts vs =
   834 fun dynamic_evaluator ctxt evaluator algebra eqngr t =
   827   map (fn (v, _) => (v, (the o AList.lookup (op =) vs o prefix "'") v));
   835   let
   828 
   836     val ((resubst_tvar, (program, ((vs_ty', t'), deps))), _) =
   829 fun dynamic_evaluator ctxt evaluator algebra eqngr vs t =
       
   830   let
       
   831     val ((program, (((vs', ty'), t'), deps)), _) =
       
   832       invoke_generation false (Proof_Context.theory_of ctxt) (algebra, eqngr) ensure_value t;
   837       invoke_generation false (Proof_Context.theory_of ctxt) (algebra, eqngr) ensure_value t;
   833   in evaluator program ((original_sorts vs vs', (vs', ty')), t') deps end;
   838   in evaluator program resubst_tvar (vs_ty', t') deps end;
   834 
   839 
   835 fun dynamic_conv ctxt conv =
   840 fun dynamic_conv ctxt conv =
   836   Code_Preproc.dynamic_conv ctxt (dynamic_evaluator ctxt conv);
   841   Code_Preproc.dynamic_conv ctxt (dynamic_evaluator ctxt conv);
   837 
   842 
   838 fun dynamic_value ctxt postproc evaluator =
   843 fun dynamic_value ctxt postproc evaluator =
   839   Code_Preproc.dynamic_value ctxt postproc (dynamic_evaluator ctxt evaluator);
   844   Code_Preproc.dynamic_value ctxt postproc (dynamic_evaluator ctxt evaluator);
   840 
   845 
   841 fun lift_evaluation ctxt evaluation algebra eqngr program vs t =
   846 fun static_subevaluator ctxt subevaluator algebra eqngr program t =
   842   let
   847   let
   843     val ((_, (((vs', ty'), t'), deps)), _) =
   848     val ((resubst_tvar, (_, ((vs_ty', t'), deps))), _) =
   844       ensure_value ctxt algebra eqngr t ([], program);
   849       ensure_value ctxt algebra eqngr t ([], program);
   845   in evaluation ctxt ((original_sorts vs vs', (vs', ty')), t') deps end;
   850   in subevaluator ctxt resubst_tvar (vs_ty', t') deps end;
   846 
   851 
   847 fun lift_evaluator ctxt evaluator consts algebra eqngr =
   852 fun static_evaluator ctxt evaluator consts algebra eqngr =
   848   let
   853   let
   849     fun generate_consts ctxt algebra eqngr =
   854     fun generate_consts ctxt algebra eqngr =
   850       fold_map (ensure_const ctxt algebra eqngr false);
   855       fold_map (ensure_const ctxt algebra eqngr false);
   851     val (consts', program) =
   856     val (consts', program) =
   852       invoke_generation true (Proof_Context.theory_of ctxt) (algebra, eqngr) generate_consts consts;
   857       invoke_generation true (Proof_Context.theory_of ctxt) (algebra, eqngr) generate_consts consts;
   853     val evaluation = evaluator program consts';
   858     val subevaluator = evaluator program consts';
   854   in fn ctxt' => lift_evaluation ctxt' evaluation algebra eqngr program end;
   859   in fn ctxt' => static_subevaluator ctxt' subevaluator algebra eqngr program end;
   855 
   860 
   856 fun lift_evaluator_simple ctxt evaluator consts algebra eqngr =
   861 fun static_evaluator_simple ctxt evaluator consts algebra eqngr =
   857   let
   862   let
   858     fun generate_consts ctxt algebra eqngr =
   863     fun generate_consts ctxt algebra eqngr =
   859       fold_map (ensure_const ctxt algebra eqngr false);
   864       fold_map (ensure_const ctxt algebra eqngr false);
   860     val (_, program) =
   865     val (_, program) =
   861       invoke_generation true (Proof_Context.theory_of ctxt) (algebra, eqngr) generate_consts consts;
   866       invoke_generation true (Proof_Context.theory_of ctxt) (algebra, eqngr) generate_consts consts;
   862   in evaluator program end;
   867   in evaluator program end;
   863 
   868 
   864 fun static_conv ctxt consts conv =
   869 fun static_conv ctxt consts conv =
   865   Code_Preproc.static_conv ctxt consts (lift_evaluator ctxt conv consts);
   870   Code_Preproc.static_conv ctxt consts (static_evaluator ctxt conv consts);
   866 
   871 
   867 fun static_conv_simple ctxt consts conv =
   872 fun static_conv_simple ctxt consts conv =
   868   Code_Preproc.static_conv ctxt consts (lift_evaluator_simple ctxt conv consts);
   873   Code_Preproc.static_conv ctxt consts (static_evaluator_simple ctxt conv consts);
   869 
   874 
   870 fun static_value ctxt postproc consts evaluator =
   875 fun static_value ctxt postproc consts evaluator =
   871   Code_Preproc.static_value ctxt postproc consts (lift_evaluator ctxt evaluator consts);
   876   Code_Preproc.static_value ctxt postproc consts (static_evaluator ctxt evaluator consts);
   872 
   877 
   873 
   878 
   874 (** constant expressions **)
   879 (** constant expressions **)
   875 
   880 
   876 fun read_const_exprs_internal ctxt =
   881 fun read_const_exprs_internal ctxt =