src/Tools/Code/code_runtime.ML
changeset 64989 40c36a4aee1f
parent 64988 93aaff2b0ae0
child 64990 c6a7de505796
equal deleted inserted replaced
64988:93aaff2b0ae0 64989:40c36a4aee1f
    32     -> string option -> theory -> theory
    32     -> string option -> theory -> theory
    33   datatype truth = Holds
    33   datatype truth = Holds
    34   val put_truth: (unit -> truth) -> Proof.context -> Proof.context
    34   val put_truth: (unit -> truth) -> Proof.context -> Proof.context
    35   val mount_computation: Proof.context -> (string * typ) list -> typ
    35   val mount_computation: Proof.context -> (string * typ) list -> typ
    36     -> (term -> 'ml) -> ((term -> term) -> 'ml option -> 'a) -> Proof.context -> term -> 'a
    36     -> (term -> 'ml) -> ((term -> term) -> 'ml option -> 'a) -> Proof.context -> term -> 'a
       
    37   val mount_computation_conv: Proof.context -> (string * typ) list -> typ
       
    38     -> (term -> 'ml) -> ('ml -> conv) -> Proof.context -> conv
       
    39   val mount_computation_check: Proof.context -> (string * typ) list
       
    40     -> (term -> truth) -> Proof.context -> conv
    37   val polyml_as_definition: (binding * typ) list -> Path.T list -> theory -> theory
    41   val polyml_as_definition: (binding * typ) list -> Path.T list -> theory -> theory
    38   val trace: bool Config.T
    42   val trace: bool Config.T
    39 end;
    43 end;
    40 
    44 
    41 structure Code_Runtime : CODE_RUNTIME =
    45 structure Code_Runtime : CODE_RUNTIME =
   359 
   363 
   360 fun mount_computation ctxt cTs T raw_computation lift_postproc =
   364 fun mount_computation ctxt cTs T raw_computation lift_postproc =
   361   Code_Preproc.static_value { ctxt = ctxt, lift_postproc = lift_postproc, consts = [] }
   365   Code_Preproc.static_value { ctxt = ctxt, lift_postproc = lift_postproc, consts = [] }
   362     (K (checked_computation cTs T raw_computation));
   366     (K (checked_computation cTs T raw_computation));
   363 
   367 
       
   368 fun mount_computation_conv ctxt cTs T raw_computation conv =
       
   369   Code_Preproc.static_conv { ctxt = ctxt, consts = [] }
       
   370     (K (fn ctxt' => fn t =>
       
   371       case checked_computation cTs T raw_computation ctxt' t of
       
   372         SOME x => conv x
       
   373       | NONE => Conv.all_conv));
       
   374 
       
   375 local
       
   376 
       
   377 fun holds ct = Thm.mk_binop @{cterm "Pure.eq :: prop \<Rightarrow> prop \<Rightarrow> prop"}
       
   378   ct @{cprop "PROP Code_Generator.holds"};
       
   379 
       
   380 val (_, holds_oracle) = Context.>>> (Context.map_theory_result
       
   381   (Thm.add_oracle (@{binding holds}, holds)));
       
   382 
       
   383 in
       
   384 
       
   385 fun mount_computation_check ctxt cTs raw_computation =
       
   386   mount_computation_conv ctxt cTs @{typ prop} raw_computation
       
   387     (K holds_oracle);
       
   388 
       
   389 end;
       
   390 
   364 
   391 
   365 (** variants of universal runtime code generation **)
   392 (** variants of universal runtime code generation **)
   366 
   393 
   367 (*FIXME consolidate variants*)
   394 (*FIXME consolidate variants*)
   368 
   395 
   435   ||> funs_of_maps;
   462   ||> funs_of_maps;
   436 
   463 
   437 
   464 
   438 (** code and computation antiquotations **)
   465 (** code and computation antiquotations **)
   439 
   466 
       
   467 local
       
   468 
   440 val mount_computationN = prefix_this "mount_computation";
   469 val mount_computationN = prefix_this "mount_computation";
   441 
   470 val mount_computation_convN = prefix_this "mount_computation_conv";
   442 local
   471 val mount_computation_checkN = prefix_this "mount_computation_check";
   443 
   472 
   444 structure Code_Antiq_Data = Proof_Data
   473 structure Code_Antiq_Data = Proof_Data
   445 (
   474 (
   446   type T = { named_consts: string list,
   475   type T = { named_consts: string list,
   447     computation_Ts: typ list, computation_cTs: (string * typ) list,
   476     computation_Ts: typ list, computation_cTs: (string * typ) list,
   500 fun print body_code_for ctxt ctxt' =
   529 fun print body_code_for ctxt ctxt' =
   501   let
   530   let
   502     val position_index = current_position_index ctxt;
   531     val position_index = current_position_index ctxt;
   503     val (code, name_ofs) = (Lazy.force o #generated_code o Code_Antiq_Data.get) ctxt';
   532     val (code, name_ofs) = (Lazy.force o #generated_code o Code_Antiq_Data.get) ctxt';
   504     val context_code = if position_index = 0 then code else "";
   533     val context_code = if position_index = 0 then code else "";
   505     val body_code = body_code_for name_ofs (ML_Context.struct_name ctxt') position_index;
   534     val body_code = body_code_for name_ofs (ML_Context.struct_name ctxt');
   506   in (context_code, body_code) end;
   535   in (context_code, body_code) end;
   507 
   536 
   508 fun print_code ctxt const =
   537 fun print_code ctxt const =
   509   print (fn { name_for_const, ... } => fn prfx => fn _ =>
   538   print (fn { name_for_const, ... } => fn prfx =>
   510     Long_Name.append prfx (name_for_const const)) ctxt;
   539     Long_Name.append prfx (name_for_const const)) ctxt;
   511 
   540 
   512 fun print_computation ctxt T =
   541 fun print_computation kind ctxt T =
   513   print (fn { of_term_for_typ, ... } => fn prfx => fn _ =>
   542   print (fn { of_term_for_typ, ... } => fn prfx =>
   514     space_implode " " [
   543     space_implode " " [
   515       mount_computationN,
   544       kind,
   516       "(Context.proof_of (Context.the_generic_context ()))",
   545       "(Context.proof_of (Context.the_generic_context ()))",
   517       Long_Name.implode [prfx, generated_computationN, covered_constsN],
   546       Long_Name.implode [prfx, generated_computationN, covered_constsN],
   518       (ML_Syntax.atomic o ML_Syntax.print_typ) T,
   547       (ML_Syntax.atomic o ML_Syntax.print_typ) T,
   519       Long_Name.append prfx (of_term_for_typ T)
   548       Long_Name.append prfx (of_term_for_typ T)
   520     ]) ctxt;
   549     ]) ctxt;
   521 
   550 
       
   551 fun print_computation_check ctxt =
       
   552   print (fn { of_term_for_typ, ... } => fn prfx =>
       
   553     space_implode " " [
       
   554       mount_computation_checkN,
       
   555       "(Context.proof_of (Context.the_generic_context ()))",
       
   556       Long_Name.implode [prfx, generated_computationN, covered_constsN],
       
   557       Long_Name.append prfx (of_term_for_typ @{typ prop})
       
   558     ]) ctxt;
       
   559 
       
   560 fun prep_terms ctxt raw_ts =
       
   561   let
       
   562     val ts = map (Syntax.check_term ctxt) raw_ts;
       
   563   in
       
   564     (fold o fold_aterms)
       
   565       (fn (t as Const (cT as (_, T))) =>
       
   566         if not (monomorphic T) then error ("Polymorphic constant: " ^ Syntax.string_of_term ctxt t)
       
   567         else insert (op =) cT | _ => I) ts []
       
   568   end;
       
   569 
   522 in
   570 in
   523 
   571 
   524 fun ml_code_antiq raw_const ctxt =
   572 fun ml_code_antiq raw_const ctxt =
   525   let
   573   let
   526     val thy = Proof_Context.theory_of ctxt;
   574     val thy = Proof_Context.theory_of ctxt;
   527     val const = Code.check_const thy raw_const;
   575     val const = Code.check_const thy raw_const;
   528   in (print_code ctxt const, register_const const ctxt) end;
   576   in (print_code ctxt const, register_const const ctxt) end;
   529 
   577 
   530 fun ml_computation_antiq (raw_ts, raw_T) ctxt =
   578 fun gen_ml_computation_antiq kind (raw_ts, raw_T) ctxt =
   531   let
   579   let
   532     val ts = map (Syntax.check_term ctxt) raw_ts;
   580     val cTs = prep_terms ctxt raw_ts;
   533     val cTs = (fold o fold_aterms)
       
   534       (fn (t as Const (cT as (_, T))) =>
       
   535         if not (monomorphic T) then error ("Polymorphic constant: " ^ Syntax.string_of_term ctxt t)
       
   536         else insert (op =) cT | _ => I) ts [];
       
   537     val T = Syntax.check_typ ctxt raw_T;
   581     val T = Syntax.check_typ ctxt raw_T;
   538     val _ = if not (monomorphic T)
   582     val _ = if not (monomorphic T)
   539       then error ("Polymorphic type: " ^ Syntax.string_of_typ ctxt T)
   583       then error ("Polymorphic type: " ^ Syntax.string_of_typ ctxt T)
   540       else ();
   584       else ();
   541   in (print_computation ctxt T, register_computation cTs T ctxt) end;
   585   in (print_computation kind ctxt T, register_computation cTs T ctxt) end;
       
   586 
       
   587 val ml_computation_antiq = gen_ml_computation_antiq mount_computationN;
       
   588 
       
   589 val ml_computation_conv_antiq = gen_ml_computation_antiq mount_computation_convN;
       
   590 
       
   591 fun ml_computation_check_antiq raw_ts ctxt =
       
   592   let
       
   593     val cTs = insert (op =) (dest_Const @{const holds}) (prep_terms ctxt raw_ts);
       
   594   in (print_computation_check ctxt, register_computation cTs @{typ prop} ctxt) end;
   542 
   595 
   543 end; (*local*)
   596 end; (*local*)
   544 
   597 
   545 
   598 
   546 (** reflection support **)
   599 (** reflection support **)
   638 
   691 
   639 val _ =
   692 val _ =
   640   Theory.setup (ML_Antiquotation.declaration @{binding computation}
   693   Theory.setup (ML_Antiquotation.declaration @{binding computation}
   641     (Scan.repeat Args.term --| Scan.lift (Args.$$$ "::") -- Args.typ)
   694     (Scan.repeat Args.term --| Scan.lift (Args.$$$ "::") -- Args.typ)
   642        (fn _ => ml_computation_antiq));
   695        (fn _ => ml_computation_antiq));
       
   696 
       
   697 val _ =
       
   698   Theory.setup (ML_Antiquotation.declaration @{binding computation_conv}
       
   699     (Scan.repeat Args.term --| Scan.lift (Args.$$$ "::") -- Args.typ)
       
   700        (fn _ => ml_computation_conv_antiq));
       
   701 
       
   702 val _ =
       
   703   Theory.setup (ML_Antiquotation.declaration @{binding computation_check}
       
   704     (Scan.repeat Args.term) 
       
   705        (fn _ => ml_computation_check_antiq));
   643 
   706 
   644 local
   707 local
   645 
   708 
   646 val parse_datatype =
   709 val parse_datatype =
   647   Parse.name -- Scan.optional (@{keyword "="} |--
   710   Parse.name -- Scan.optional (@{keyword "="} |--