src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML
changeset 55440 721b4561007a
parent 55414 eab03e9cee8a
parent 55437 3fd63b92ea3b
child 55757 9fc71814b8c1
equal deleted inserted replaced
55428:0ab52bf7b5e6 55440:721b4561007a
     9   type seed = Random_Engine.seed
     9   type seed = Random_Engine.seed
    10   type mode = Predicate_Compile_Aux.mode
    10   type mode = Predicate_Compile_Aux.mode
    11   type options = Predicate_Compile_Aux.options
    11   type options = Predicate_Compile_Aux.options
    12   type compilation = Predicate_Compile_Aux.compilation
    12   type compilation = Predicate_Compile_Aux.compilation
    13   type compilation_funs = Predicate_Compile_Aux.compilation_funs
    13   type compilation_funs = Predicate_Compile_Aux.compilation_funs
    14   
    14 
    15   val setup : theory -> theory
    15   val setup : theory -> theory
    16   val code_pred : options -> string -> Proof.context -> Proof.state
    16   val code_pred : options -> string -> Proof.context -> Proof.state
    17   val code_pred_cmd : options -> string -> Proof.context -> Proof.state
    17   val code_pred_cmd : options -> string -> Proof.context -> Proof.state
    18   val values_cmd : string list -> mode option list option
    18   val values_cmd : string list -> mode option list option ->
    19     -> ((string option * bool) * (compilation * int list)) -> int -> string -> Toplevel.state -> unit
    19     ((string option * bool) * (compilation * int list)) -> int -> string -> Toplevel.state -> unit
    20 
    20 
    21   val values_timeout : real Config.T
    21   val values_timeout : real Config.T
    22   
    22 
    23   val print_stored_rules : Proof.context -> unit
    23   val print_stored_rules : Proof.context -> unit
    24   val print_all_modes : compilation -> Proof.context -> unit
    24   val print_all_modes : compilation -> Proof.context -> unit
    25 
    25 
    26   val put_pred_result : (unit -> term Predicate.pred) -> Proof.context -> Proof.context
    26   val put_pred_result : (unit -> term Predicate.pred) -> Proof.context -> Proof.context
    27   val put_pred_random_result : (unit -> seed -> term Predicate.pred * seed) ->
    27   val put_pred_random_result : (unit -> seed -> term Predicate.pred * seed) ->
    28     Proof.context -> Proof.context
    28     Proof.context -> Proof.context
    29   val put_dseq_result : (unit -> term Limited_Sequence.dseq) -> Proof.context -> Proof.context
    29   val put_dseq_result : (unit -> term Limited_Sequence.dseq) -> Proof.context -> Proof.context
    30   val put_dseq_random_result : (unit -> Code_Numeral.natural -> Code_Numeral.natural -> seed -> term Limited_Sequence.dseq * seed) ->
    30   val put_dseq_random_result :
       
    31     (unit -> Code_Numeral.natural -> Code_Numeral.natural -> seed ->
       
    32       term Limited_Sequence.dseq * seed) ->
    31     Proof.context -> Proof.context
    33     Proof.context -> Proof.context
    32   val put_new_dseq_result : (unit -> Code_Numeral.natural -> term Lazy_Sequence.lazy_sequence) ->
    34   val put_new_dseq_result : (unit -> Code_Numeral.natural -> term Lazy_Sequence.lazy_sequence) ->
    33     Proof.context -> Proof.context
    35     Proof.context -> Proof.context
    34   val put_lseq_random_result :
    36   val put_lseq_random_result :
    35     (unit -> Code_Numeral.natural -> Code_Numeral.natural -> seed -> Code_Numeral.natural -> term Lazy_Sequence.lazy_sequence) ->
    37     (unit -> Code_Numeral.natural -> Code_Numeral.natural -> seed -> Code_Numeral.natural ->
       
    38       term Lazy_Sequence.lazy_sequence) ->
    36     Proof.context -> Proof.context
    39     Proof.context -> Proof.context
    37   val put_lseq_random_stats_result :
    40   val put_lseq_random_stats_result :
    38     (unit -> Code_Numeral.natural -> Code_Numeral.natural -> seed -> Code_Numeral.natural -> (term * Code_Numeral.natural) Lazy_Sequence.lazy_sequence) ->
    41     (unit -> Code_Numeral.natural -> Code_Numeral.natural -> seed -> Code_Numeral.natural ->
       
    42       (term * Code_Numeral.natural) Lazy_Sequence.lazy_sequence) ->
    39     Proof.context -> Proof.context
    43     Proof.context -> Proof.context
    40 
    44 
    41   val code_pred_intro_attrib : attribute
    45   val code_pred_intro_attrib : attribute
    42   (* used by Quickcheck_Generator *) 
    46   (* used by Quickcheck_Generator *)
    43   (* temporary for testing of the compilation *)
    47   (* temporary for testing of the compilation *)
    44   val add_equations : options -> string list -> theory -> theory
    48   val add_equations : options -> string list -> theory -> theory
    45   val add_depth_limited_random_equations : options -> string list -> theory -> theory
    49   val add_depth_limited_random_equations : options -> string list -> theory -> theory
    46   val add_random_dseq_equations : options -> string list -> theory -> theory
    50   val add_random_dseq_equations : options -> string list -> theory -> theory
    47   val add_new_random_dseq_equations : options -> string list -> theory -> theory
    51   val add_new_random_dseq_equations : options -> string list -> theory -> theory
    52     ((string * typ) list * string list * string list * (string * mode list) list *
    56     ((string * typ) list * string list * string list * (string * mode list) list *
    53       (string *  (Term.term list * Predicate_Compile_Aux.indprem list) list) list)
    57       (string *  (Term.term list * Predicate_Compile_Aux.indprem list) list) list)
    54   type mode_analysis_options =
    58   type mode_analysis_options =
    55    {use_generators : bool,
    59    {use_generators : bool,
    56     reorder_premises : bool,
    60     reorder_premises : bool,
    57     infer_pos_and_neg_modes : bool}  
    61     infer_pos_and_neg_modes : bool}
    58   datatype mode_derivation = Mode_App of mode_derivation * mode_derivation | Context of mode
    62   datatype mode_derivation = Mode_App of mode_derivation * mode_derivation | Context of mode
    59     | Mode_Pair of mode_derivation * mode_derivation | Term of mode
    63     | Mode_Pair of mode_derivation * mode_derivation | Term of mode
    60   val head_mode_of : mode_derivation -> mode
    64   val head_mode_of : mode_derivation -> mode
    61   type moded_clause = term list * (Predicate_Compile_Aux.indprem * mode_derivation) list
    65   type moded_clause = term list * (Predicate_Compile_Aux.indprem * mode_derivation) list
    62   type 'a pred_mode_table = (string * ((bool * mode) * 'a) list) list
    66   type 'a pred_mode_table = (string * ((bool * mode) * 'a) list) list
    88 
    92 
    89 fun mk_tracing s t =
    93 fun mk_tracing s t =
    90   Const(@{const_name Code_Evaluation.tracing},
    94   Const(@{const_name Code_Evaluation.tracing},
    91     @{typ String.literal} --> (fastype_of t) --> (fastype_of t)) $ (HOLogic.mk_literal s) $ t
    95     @{typ String.literal} --> (fastype_of t) --> (fastype_of t)) $ (HOLogic.mk_literal s) $ t
    92 
    96 
       
    97 
    93 (* representation of inferred clauses with modes *)
    98 (* representation of inferred clauses with modes *)
    94 
    99 
    95 type moded_clause = term list * (indprem * mode_derivation) list
   100 type moded_clause = term list * (indprem * mode_derivation) list
    96 
   101 
    97 type 'a pred_mode_table = (string * ((bool * mode) * 'a) list) list
   102 type 'a pred_mode_table = (string * ((bool * mode) * 'a) list) list
       
   103 
    98 
   104 
    99 (* diagnostic display functions *)
   105 (* diagnostic display functions *)
   100 
   106 
   101 fun print_modes options modes =
   107 fun print_modes options modes =
   102   if show_modes options then
   108   if show_modes options then
   150   end
   156   end
   151 
   157 
   152 (* validity checks *)
   158 (* validity checks *)
   153 
   159 
   154 fun check_expected_modes options _ modes =
   160 fun check_expected_modes options _ modes =
   155   case expected_modes options of
   161   (case expected_modes options of
   156     SOME (s, ms) => (case AList.lookup (op =) modes s of
   162     SOME (s, ms) =>
   157       SOME modes =>
   163       (case AList.lookup (op =) modes s of
   158         let
   164         SOME modes =>
   159           val modes' = map snd modes
   165           let
   160         in
   166             val modes' = map snd modes
   161           if not (eq_set eq_mode (ms, modes')) then
   167           in
   162             error ("expected modes were not inferred:\n"
   168             if not (eq_set eq_mode (ms, modes')) then
   163             ^ "  inferred modes for " ^ s ^ ": " ^ commas (map string_of_mode modes')  ^ "\n"
   169               error ("expected modes were not inferred:\n"
   164             ^ "  expected modes for " ^ s ^ ": " ^ commas (map string_of_mode ms))
   170               ^ "  inferred modes for " ^ s ^ ": " ^ commas (map string_of_mode modes')  ^ "\n"
   165           else ()
   171               ^ "  expected modes for " ^ s ^ ": " ^ commas (map string_of_mode ms))
   166         end
   172             else ()
   167       | NONE => ())
   173           end
   168   | NONE => ()
   174         | NONE => ())
       
   175   | NONE => ())
   169 
   176 
   170 fun check_proposed_modes options preds modes errors =
   177 fun check_proposed_modes options preds modes errors =
   171   map (fn (s, _) => case proposed_modes options s of
   178   map (fn (s, _) =>
   172     SOME ms => (case AList.lookup (op =) modes s of
   179     case proposed_modes options s of
   173       SOME inferred_ms =>
   180       SOME ms =>
   174         let
   181         (case AList.lookup (op =) modes s of
   175           val preds_without_modes = map fst (filter (null o snd) modes)
   182           SOME inferred_ms =>
   176           val modes' = map snd inferred_ms
   183             let
   177         in
   184               val preds_without_modes = map fst (filter (null o snd) modes)
   178           if not (eq_set eq_mode (ms, modes')) then
   185               val modes' = map snd inferred_ms
   179             error ("expected modes were not inferred:\n"
   186             in
   180             ^ "  inferred modes for " ^ s ^ ": " ^ commas (map string_of_mode modes')  ^ "\n"
   187               if not (eq_set eq_mode (ms, modes')) then
   181             ^ "  expected modes for " ^ s ^ ": " ^ commas (map string_of_mode ms) ^ "\n"
   188                 error ("expected modes were not inferred:\n"
   182             ^ (if show_invalid_clauses options then
   189                 ^ "  inferred modes for " ^ s ^ ": " ^ commas (map string_of_mode modes')  ^ "\n"
   183             ("For the following clauses, the following modes could not be inferred: " ^ "\n"
   190                 ^ "  expected modes for " ^ s ^ ": " ^ commas (map string_of_mode ms) ^ "\n"
   184             ^ cat_lines errors) else "") ^
   191                 ^ (if show_invalid_clauses options then
   185             (if not (null preds_without_modes) then
   192                 ("For the following clauses, the following modes could not be inferred: " ^ "\n"
   186               "\n" ^ "No mode inferred for the predicates " ^ commas preds_without_modes
   193                 ^ cat_lines errors) else "") ^
   187             else ""))
   194                 (if not (null preds_without_modes) then
   188           else ()
   195                   "\n" ^ "No mode inferred for the predicates " ^ commas preds_without_modes
   189         end
   196                 else ""))
   190       | NONE => ())
   197               else ()
   191   | NONE => ()) preds
   198             end
       
   199         | NONE => ())
       
   200     | NONE => ()) preds
   192 
   201 
   193 fun check_matches_type ctxt predname T ms =
   202 fun check_matches_type ctxt predname T ms =
   194   let
   203   let
   195     fun check (Fun (m1, m2)) (Type("fun", [T1,T2])) = check m1 T1 andalso check m2 T2
   204     fun check (Fun (m1, m2)) (Type("fun", [T1,T2])) = check m1 T1 andalso check m2 T2
   196       | check m (Type("fun", _)) = (m = Input orelse m = Output)
   205       | check m (Type("fun", _)) = (m = Input orelse m = Output)
   197       | check (Pair (m1, m2)) (Type (@{type_name Product_Type.prod}, [T1, T2])) =
   206       | check (Pair (m1, m2)) (Type (@{type_name Product_Type.prod}, [T1, T2])) =
   198           check m1 T1 andalso check m2 T2 
   207           check m1 T1 andalso check m2 T2
   199       | check Input _ = true
   208       | check Input _ = true
   200       | check Output _ = true
   209       | check Output _ = true
   201       | check Bool @{typ bool} = true
   210       | check Bool @{typ bool} = true
   202       | check _ _ = false
   211       | check _ _ = false
   203     fun check_consistent_modes ms =
   212     fun check_consistent_modes ms =
   204       if forall (fn Fun _ => true | _ => false) ms then
   213       if forall (fn Fun _ => true | _ => false) ms then
   205         pairself check_consistent_modes (split_list (map (fn Fun (m1, m2) => (m1, m2)) ms))
   214         pairself check_consistent_modes (split_list (map (fn Fun (m1, m2) => (m1, m2)) ms))
   206         |> (fn (res1, res2) => res1 andalso res2) 
   215         |> (fn (res1, res2) => res1 andalso res2)
   207       else if forall (fn Input => true | Output => true | Pair _ => true | _ => false) ms then
   216       else if forall (fn Input => true | Output => true | Pair _ => true | _ => false) ms then
   208         true
   217         true
   209       else if forall (fn Bool => true | _ => false) ms then
   218       else if forall (fn Bool => true | _ => false) ms then
   210         true
   219         true
   211       else
   220       else
   212         false
   221         false
   213     val _ = map
   222     val _ =
   214       (fn mode =>
   223       map (fn mode =>
   215         if length (strip_fun_mode mode) = length (binder_types T)
   224         if length (strip_fun_mode mode) = length (binder_types T)
   216           andalso (forall (uncurry check) (strip_fun_mode mode ~~ binder_types T)) then ()
   225           andalso (forall (uncurry check) (strip_fun_mode mode ~~ binder_types T)) then ()
   217         else error (string_of_mode mode ^ " is not a valid mode for " ^ Syntax.string_of_typ ctxt T
   226         else
   218         ^ " at predicate " ^ predname)) ms
   227           error (string_of_mode mode ^ " is not a valid mode for " ^
       
   228             Syntax.string_of_typ ctxt T ^ " at predicate " ^ predname)) ms
   219     val _ =
   229     val _ =
   220      if check_consistent_modes ms then ()
   230       if check_consistent_modes ms then ()
   221      else error (commas (map string_of_mode ms) ^
   231       else
   222        " are inconsistent modes for predicate " ^ predname)
   232         error (commas (map string_of_mode ms) ^ " are inconsistent modes for predicate " ^ predname)
   223   in
   233   in
   224     ms
   234     ms
   225   end
   235   end
   226 
   236 
       
   237 
   227 (* compilation modifiers *)
   238 (* compilation modifiers *)
   228 
   239 
   229 structure Comp_Mod =
   240 structure Comp_Mod =  (* FIXME proper signature *)
   230 struct
   241 struct
   231 
   242 
   232 datatype comp_modifiers = Comp_Modifiers of
   243 datatype comp_modifiers = Comp_Modifiers of
   233 {
   244 {
   234   compilation : compilation,
   245   compilation : compilation,
   261     (Comp_Modifiers {compilation = compilation, function_name_prefix = function_name_prefix,
   272     (Comp_Modifiers {compilation = compilation, function_name_prefix = function_name_prefix,
   262     compfuns = compfuns', mk_random = mk_random, modify_funT = modify_funT,
   273     compfuns = compfuns', mk_random = mk_random, modify_funT = modify_funT,
   263     additional_arguments = additional_arguments, wrap_compilation = wrap_compilation,
   274     additional_arguments = additional_arguments, wrap_compilation = wrap_compilation,
   264     transform_additional_arguments = transform_additional_arguments})
   275     transform_additional_arguments = transform_additional_arguments})
   265 
   276 
   266 end;
   277 end
   267 
   278 
   268 fun unlimited_compfuns_of true New_Pos_Random_DSeq =
   279 fun unlimited_compfuns_of true New_Pos_Random_DSeq =
   269     New_Pos_Random_Sequence_CompFuns.depth_unlimited_compfuns
   280       New_Pos_Random_Sequence_CompFuns.depth_unlimited_compfuns
   270   | unlimited_compfuns_of false New_Pos_Random_DSeq =
   281   | unlimited_compfuns_of false New_Pos_Random_DSeq =
   271     New_Neg_Random_Sequence_CompFuns.depth_unlimited_compfuns
   282       New_Neg_Random_Sequence_CompFuns.depth_unlimited_compfuns
   272   | unlimited_compfuns_of true Pos_Generator_DSeq =
   283   | unlimited_compfuns_of true Pos_Generator_DSeq =
   273     New_Pos_DSequence_CompFuns.depth_unlimited_compfuns
   284       New_Pos_DSequence_CompFuns.depth_unlimited_compfuns
   274   | unlimited_compfuns_of false Pos_Generator_DSeq =
   285   | unlimited_compfuns_of false Pos_Generator_DSeq =
   275     New_Neg_DSequence_CompFuns.depth_unlimited_compfuns
   286       New_Neg_DSequence_CompFuns.depth_unlimited_compfuns
   276   | unlimited_compfuns_of _ c =
   287   | unlimited_compfuns_of _ c =
   277     raise Fail ("No unlimited compfuns for compilation " ^ string_of_compilation c)
   288       raise Fail ("No unlimited compfuns for compilation " ^ string_of_compilation c)
   278 
   289 
   279 fun limited_compfuns_of true Predicate_Compile_Aux.New_Pos_Random_DSeq =
   290 fun limited_compfuns_of true Predicate_Compile_Aux.New_Pos_Random_DSeq =
   280     New_Pos_Random_Sequence_CompFuns.depth_limited_compfuns
   291       New_Pos_Random_Sequence_CompFuns.depth_limited_compfuns
   281   | limited_compfuns_of false Predicate_Compile_Aux.New_Pos_Random_DSeq =
   292   | limited_compfuns_of false Predicate_Compile_Aux.New_Pos_Random_DSeq =
   282     New_Neg_Random_Sequence_CompFuns.depth_limited_compfuns
   293       New_Neg_Random_Sequence_CompFuns.depth_limited_compfuns
   283   | limited_compfuns_of true Pos_Generator_DSeq =
   294   | limited_compfuns_of true Pos_Generator_DSeq =
   284     New_Pos_DSequence_CompFuns.depth_limited_compfuns
   295       New_Pos_DSequence_CompFuns.depth_limited_compfuns
   285   | limited_compfuns_of false Pos_Generator_DSeq =
   296   | limited_compfuns_of false Pos_Generator_DSeq =
   286     New_Neg_DSequence_CompFuns.depth_limited_compfuns
   297       New_Neg_DSequence_CompFuns.depth_limited_compfuns
   287   | limited_compfuns_of _ c =
   298   | limited_compfuns_of _ c =
   288     raise Fail ("No limited compfuns for compilation " ^ string_of_compilation c)
   299       raise Fail ("No limited compfuns for compilation " ^ string_of_compilation c)
   289 
   300 
   290 val depth_limited_comp_modifiers = Comp_Mod.Comp_Modifiers
   301 val depth_limited_comp_modifiers = Comp_Mod.Comp_Modifiers
   291   {
   302   {
   292   compilation = Depth_Limited,
   303   compilation = Depth_Limited,
   293   function_name_prefix = "depth_limited_",
   304   function_name_prefix = "depth_limited_",
   326   compilation = Random,
   337   compilation = Random,
   327   function_name_prefix = "random_",
   338   function_name_prefix = "random_",
   328   compfuns = Predicate_Comp_Funs.compfuns,
   339   compfuns = Predicate_Comp_Funs.compfuns,
   329   mk_random = (fn T => fn additional_arguments =>
   340   mk_random = (fn T => fn additional_arguments =>
   330   list_comb (Const(@{const_name Random_Pred.iter},
   341   list_comb (Const(@{const_name Random_Pred.iter},
   331   [@{typ natural}, @{typ natural}, @{typ Random.seed}] ---> 
   342   [@{typ natural}, @{typ natural}, @{typ Random.seed}] --->
   332     Predicate_Comp_Funs.mk_monadT T), additional_arguments)),
   343     Predicate_Comp_Funs.mk_monadT T), additional_arguments)),
   333   modify_funT = (fn T =>
   344   modify_funT = (fn T =>
   334     let
   345     let
   335       val (Ts, U) = strip_type T
   346       val (Ts, U) = strip_type T
   336       val Ts' = [@{typ natural}, @{typ natural}, @{typ Random.seed}]
   347       val Ts' = [@{typ natural}, @{typ natural}, @{typ Random.seed}]
   352   compilation = Depth_Limited_Random,
   363   compilation = Depth_Limited_Random,
   353   function_name_prefix = "depth_limited_random_",
   364   function_name_prefix = "depth_limited_random_",
   354   compfuns = Predicate_Comp_Funs.compfuns,
   365   compfuns = Predicate_Comp_Funs.compfuns,
   355   mk_random = (fn T => fn additional_arguments =>
   366   mk_random = (fn T => fn additional_arguments =>
   356   list_comb (Const(@{const_name Random_Pred.iter},
   367   list_comb (Const(@{const_name Random_Pred.iter},
   357   [@{typ natural}, @{typ natural}, @{typ Random.seed}] ---> 
   368   [@{typ natural}, @{typ natural}, @{typ Random.seed}] --->
   358     Predicate_Comp_Funs.mk_monadT T), tl additional_arguments)),
   369     Predicate_Comp_Funs.mk_monadT T), tl additional_arguments)),
   359   modify_funT = (fn T =>
   370   modify_funT = (fn T =>
   360     let
   371     let
   361       val (Ts, U) = strip_type T
   372       val (Ts, U) = strip_type T
   362       val Ts' = [@{typ natural}, @{typ natural}, @{typ natural},
   373       val Ts' = [@{typ natural}, @{typ natural}, @{typ natural},
   503   additional_arguments = K [],
   514   additional_arguments = K [],
   504   wrap_compilation = K (K (K (K (K I))))
   515   wrap_compilation = K (K (K (K (K I))))
   505    : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
   516    : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
   506   transform_additional_arguments = K I : (indprem -> term list -> term list)
   517   transform_additional_arguments = K I : (indprem -> term list -> term list)
   507   }
   518   }
   508   
   519 
   509 val neg_generator_dseq_comp_modifiers = Comp_Mod.Comp_Modifiers
   520 val neg_generator_dseq_comp_modifiers = Comp_Mod.Comp_Modifiers
   510   {
   521   {
   511   compilation = Neg_Generator_DSeq,
   522   compilation = Neg_Generator_DSeq,
   512   function_name_prefix = "generator_dseq_neg_",
   523   function_name_prefix = "generator_dseq_neg_",
   513   compfuns = New_Neg_DSequence_CompFuns.depth_limited_compfuns,
   524   compfuns = New_Neg_DSequence_CompFuns.depth_limited_compfuns,
   532   modify_funT = I,
   543   modify_funT = I,
   533   additional_arguments = K [],
   544   additional_arguments = K [],
   534   wrap_compilation = K (K (K (K (K I))))
   545   wrap_compilation = K (K (K (K (K I))))
   535    : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
   546    : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
   536   transform_additional_arguments = K I : (indprem -> term list -> term list)
   547   transform_additional_arguments = K I : (indprem -> term list -> term list)
   537   }  
   548   }
   538 
   549 
   539 val neg_generator_cps_comp_modifiers = Comp_Mod.Comp_Modifiers
   550 val neg_generator_cps_comp_modifiers = Comp_Mod.Comp_Modifiers
   540   {
   551   {
   541   compilation = Neg_Generator_CPS,
   552   compilation = Neg_Generator_CPS,
   542   function_name_prefix = "generator_cps_neg_",
   553   function_name_prefix = "generator_cps_neg_",
   546   additional_arguments = K [],
   557   additional_arguments = K [],
   547   wrap_compilation = K (K (K (K (K I))))
   558   wrap_compilation = K (K (K (K (K I))))
   548    : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
   559    : (compilation_funs -> string -> typ -> mode -> term list -> term -> term),
   549   transform_additional_arguments = K I : (indprem -> term list -> term list)
   560   transform_additional_arguments = K I : (indprem -> term list -> term list)
   550   }
   561   }
   551   
   562 
   552 fun negative_comp_modifiers_of comp_modifiers =
   563 fun negative_comp_modifiers_of comp_modifiers =
   553     (case Comp_Mod.compilation comp_modifiers of
   564   (case Comp_Mod.compilation comp_modifiers of
   554       Pos_Random_DSeq => neg_random_dseq_comp_modifiers
   565     Pos_Random_DSeq => neg_random_dseq_comp_modifiers
   555     | Neg_Random_DSeq => pos_random_dseq_comp_modifiers
   566   | Neg_Random_DSeq => pos_random_dseq_comp_modifiers
   556     | New_Pos_Random_DSeq => new_neg_random_dseq_comp_modifiers
   567   | New_Pos_Random_DSeq => new_neg_random_dseq_comp_modifiers
   557     | New_Neg_Random_DSeq => new_pos_random_dseq_comp_modifiers 
   568   | New_Neg_Random_DSeq => new_pos_random_dseq_comp_modifiers
   558     | Pos_Generator_DSeq => neg_generator_dseq_comp_modifiers
   569   | Pos_Generator_DSeq => neg_generator_dseq_comp_modifiers
   559     | Neg_Generator_DSeq => pos_generator_dseq_comp_modifiers
   570   | Neg_Generator_DSeq => pos_generator_dseq_comp_modifiers
   560     | Pos_Generator_CPS => neg_generator_cps_comp_modifiers
   571   | Pos_Generator_CPS => neg_generator_cps_comp_modifiers
   561     | Neg_Generator_CPS => pos_generator_cps_comp_modifiers
   572   | Neg_Generator_CPS => pos_generator_cps_comp_modifiers
   562     | _ => comp_modifiers)
   573   | _ => comp_modifiers)
       
   574 
   563 
   575 
   564 (* term construction *)
   576 (* term construction *)
   565 
   577 
   566 fun mk_v (names, vs) s T = (case AList.lookup (op =) vs s of
   578 fun mk_v (names, vs) s T =
   567       NONE => (Free (s, T), (names, (s, [])::vs))
   579   (case AList.lookup (op =) vs s of
   568     | SOME xs =>
   580     NONE => (Free (s, T), (names, (s, [])::vs))
   569         let
   581   | SOME xs =>
   570           val s' = singleton (Name.variant_list names) s;
   582       let
   571           val v = Free (s', T)
   583         val s' = singleton (Name.variant_list names) s;
   572         in
   584         val v = Free (s', T)
   573           (v, (s'::names, AList.update (op =) (s, v::xs) vs))
   585       in
   574         end);
   586         (v, (s'::names, AList.update (op =) (s, v::xs) vs))
       
   587       end);
   575 
   588 
   576 fun distinct_v (Free (s, T)) nvs = mk_v nvs s T
   589 fun distinct_v (Free (s, T)) nvs = mk_v nvs s T
   577   | distinct_v (t $ u) nvs =
   590   | distinct_v (t $ u) nvs =
   578       let
   591       let
   579         val (t', nvs') = distinct_v t nvs;
   592         val (t', nvs') = distinct_v t nvs;
   585 (** specific rpred functions -- move them to the correct place in this file *)
   598 (** specific rpred functions -- move them to the correct place in this file *)
   586 fun mk_Eval_of (P as (Free _), T) mode =
   599 fun mk_Eval_of (P as (Free _), T) mode =
   587   let
   600   let
   588     fun mk_bounds (Type (@{type_name Product_Type.prod}, [T1, T2])) i =
   601     fun mk_bounds (Type (@{type_name Product_Type.prod}, [T1, T2])) i =
   589           let
   602           let
   590             val (bs2, i') = mk_bounds T2 i 
   603             val (bs2, i') = mk_bounds T2 i
   591             val (bs1, i'') = mk_bounds T1 i'
   604             val (bs1, i'') = mk_bounds T1 i'
   592           in
   605           in
   593             (HOLogic.pair_const T1 T2 $ bs1 $ bs2, i'' + 1)
   606             (HOLogic.pair_const T1 T2 $ bs1 $ bs2, i'' + 1)
   594           end
   607           end
   595       | mk_bounds _ i = (Bound i, i + 1)
   608       | mk_bounds _ i = (Bound i, i + 1)
   606     val inner_term = Predicate_Comp_Funs.mk_Eval (list_comb (P, inargs), fst (mk_tuple (outargs ~~ outTs)))
   619     val inner_term = Predicate_Comp_Funs.mk_Eval (list_comb (P, inargs), fst (mk_tuple (outargs ~~ outTs)))
   607   in
   620   in
   608     fold_rev mk_split_abs (binder_types T) inner_term
   621     fold_rev mk_split_abs (binder_types T) inner_term
   609   end
   622   end
   610 
   623 
   611 fun compile_arg compilation_modifiers _ _ param_modes arg = 
   624 fun compile_arg compilation_modifiers _ _ param_modes arg =
   612   let
   625   let
   613     fun map_params (t as Free (f, T)) =
   626     fun map_params (t as Free (f, T)) =
   614       (case (AList.lookup (op =) param_modes f) of
   627           (case (AList.lookup (op =) param_modes f) of
   615           SOME mode =>
   628               SOME mode =>
   616             let
   629                 let
   617               val T' = Comp_Mod.funT_of compilation_modifiers mode T
   630                   val T' = Comp_Mod.funT_of compilation_modifiers mode T
   618             in
   631                 in
   619               mk_Eval_of (Free (f, T'), T) mode
   632                   mk_Eval_of (Free (f, T'), T) mode
   620             end
   633                 end
   621         | NONE => t)
   634           | NONE => t)
   622       | map_params t = t
   635       | map_params t = t
   623   in
   636   in
   624     map_aterms map_params arg
   637     map_aterms map_params arg
   625   end
   638   end
   626 
   639 
   652 fun compile_expr compilation_modifiers ctxt (t, deriv) param_modes additional_arguments =
   665 fun compile_expr compilation_modifiers ctxt (t, deriv) param_modes additional_arguments =
   653   let
   666   let
   654     val compfuns = Comp_Mod.compfuns compilation_modifiers
   667     val compfuns = Comp_Mod.compfuns compilation_modifiers
   655     fun expr_of (t, deriv) =
   668     fun expr_of (t, deriv) =
   656       (case (t, deriv) of
   669       (case (t, deriv) of
   657         (t, Term Input) => SOME (compile_arg compilation_modifiers additional_arguments ctxt param_modes t)
   670         (t, Term Input) =>
       
   671           SOME (compile_arg compilation_modifiers additional_arguments ctxt param_modes t)
   658       | (_, Term Output) => NONE
   672       | (_, Term Output) => NONE
   659       | (Const (name, T), Context mode) =>
   673       | (Const (name, T), Context mode) =>
   660         (case alternative_compilation_of ctxt name mode of
   674           (case alternative_compilation_of ctxt name mode of
   661           SOME alt_comp => SOME (alt_comp compfuns T)
   675             SOME alt_comp => SOME (alt_comp compfuns T)
   662         | NONE =>
   676           | NONE =>
   663           SOME (Const (function_name_of (Comp_Mod.compilation compilation_modifiers)
   677             SOME (Const (function_name_of (Comp_Mod.compilation compilation_modifiers)
   664             ctxt name mode,
   678               ctxt name mode,
   665             Comp_Mod.funT_of compilation_modifiers mode T)))
   679               Comp_Mod.funT_of compilation_modifiers mode T)))
   666       | (Free (s, T), Context m) =>
   680       | (Free (s, T), Context m) =>
   667         (case (AList.lookup (op =) param_modes s) of
   681           (case (AList.lookup (op =) param_modes s) of
   668           SOME _ => SOME (Free (s, Comp_Mod.funT_of compilation_modifiers m T))
   682             SOME _ => SOME (Free (s, Comp_Mod.funT_of compilation_modifiers m T))
   669         | NONE =>
   683           | NONE =>
   670         let
   684               let
   671           val bs = map (pair "x") (binder_types (fastype_of t))
   685                 val bs = map (pair "x") (binder_types (fastype_of t))
   672           val bounds = map Bound (rev (0 upto (length bs) - 1))
   686                 val bounds = map Bound (rev (0 upto (length bs) - 1))
   673         in SOME (fold_rev Term.abs bs (mk_if compfuns (list_comb (t, bounds)))) end)
   687               in SOME (fold_rev Term.abs bs (mk_if compfuns (list_comb (t, bounds)))) end)
   674       | (t, Context _) =>
   688       | (t, Context _) =>
   675         let
   689           let
   676           val bs = map (pair "x") (binder_types (fastype_of t))
   690             val bs = map (pair "x") (binder_types (fastype_of t))
   677           val bounds = map Bound (rev (0 upto (length bs) - 1))
   691             val bounds = map Bound (rev (0 upto (length bs) - 1))
   678         in SOME (fold_rev Term.abs bs (mk_if compfuns (list_comb (t, bounds)))) end
   692           in SOME (fold_rev Term.abs bs (mk_if compfuns (list_comb (t, bounds)))) end
   679       | (Const (@{const_name Pair}, _) $ t1 $ t2, Mode_Pair (d1, d2)) =>
   693       | (Const (@{const_name Pair}, _) $ t1 $ t2, Mode_Pair (d1, d2)) =>
   680         (case (expr_of (t1, d1), expr_of (t2, d2)) of
   694           (case (expr_of (t1, d1), expr_of (t2, d2)) of
   681           (NONE, NONE) => NONE
   695             (NONE, NONE) => NONE
   682         | (NONE, SOME t) => SOME t
   696           | (NONE, SOME t) => SOME t
   683         | (SOME t, NONE) => SOME t
   697           | (SOME t, NONE) => SOME t
   684         | (SOME t1, SOME t2) => SOME (HOLogic.mk_prod (t1, t2)))
   698           | (SOME t1, SOME t2) => SOME (HOLogic.mk_prod (t1, t2)))
   685       | (t1 $ t2, Mode_App (deriv1, deriv2)) =>
   699       | (t1 $ t2, Mode_App (deriv1, deriv2)) =>
   686         (case (expr_of (t1, deriv1), expr_of (t2, deriv2)) of
   700           (case (expr_of (t1, deriv1), expr_of (t2, deriv2)) of
   687           (SOME t, NONE) => SOME t
   701             (SOME t, NONE) => SOME t
   688          | (SOME t, SOME u) => SOME (t $ u)
   702            | (SOME t, SOME u) => SOME (t $ u)
   689          | _ => error "something went wrong here!"))
   703            | _ => error "something went wrong here!"))
   690   in
   704   in
   691     list_comb (the (expr_of (t, deriv)), additional_arguments)
   705     list_comb (the (expr_of (t, deriv)), additional_arguments)
   692   end
   706   end
   693 
   707 
   694 fun compile_clause compilation_modifiers ctxt all_vs param_modes additional_arguments
   708 fun compile_clause compilation_modifiers ctxt all_vs param_modes additional_arguments
   719             val (out_ts'', (names'', constr_vs')) = fold_map distinct_v
   733             val (out_ts'', (names'', constr_vs')) = fold_map distinct_v
   720               out_ts' ((names', map (rpair []) vs))
   734               out_ts' ((names', map (rpair []) vs))
   721             val mode = head_mode_of deriv
   735             val mode = head_mode_of deriv
   722             val additional_arguments' =
   736             val additional_arguments' =
   723               Comp_Mod.transform_additional_arguments compilation_modifiers p additional_arguments
   737               Comp_Mod.transform_additional_arguments compilation_modifiers p additional_arguments
   724             val (compiled_clause, rest) = case p of
   738             val (compiled_clause, rest) =
   725                Prem t =>
   739               (case p of
   726                  let
   740                 Prem t =>
   727                    val u =
   741                   let
   728                      compile_expr compilation_modifiers ctxt (t, deriv) param_modes additional_arguments'
   742                     val u =
   729                    val (_, out_ts''') = split_mode mode (snd (strip_comb t))
   743                       compile_expr compilation_modifiers ctxt (t, deriv)
   730                    val rest = compile_prems out_ts''' vs' names'' ps
   744                        param_modes additional_arguments'
   731                  in
   745                     val (_, out_ts''') = split_mode mode (snd (strip_comb t))
   732                    (u, rest)
   746                     val rest = compile_prems out_ts''' vs' names'' ps
   733                  end
   747                   in
   734              | Negprem t =>
   748                     (u, rest)
   735                  let
   749                   end
   736                    val neg_compilation_modifiers =
   750               | Negprem t =>
   737                      negative_comp_modifiers_of compilation_modifiers
   751                   let
   738                    val u = mk_not compfuns
   752                     val neg_compilation_modifiers =
   739                      (compile_expr neg_compilation_modifiers ctxt (t, deriv) param_modes additional_arguments')
   753                       negative_comp_modifiers_of compilation_modifiers
   740                    val (_, out_ts''') = split_mode mode (snd (strip_comb t))
   754                     val u =
   741                    val rest = compile_prems out_ts''' vs' names'' ps
   755                      mk_not compfuns
   742                  in
   756                        (compile_expr neg_compilation_modifiers ctxt (t, deriv)
   743                    (u, rest)
   757                          param_modes additional_arguments')
   744                  end
   758                     val (_, out_ts''') = split_mode mode (snd (strip_comb t))
   745              | Sidecond t =>
   759                     val rest = compile_prems out_ts''' vs' names'' ps
   746                  let
   760                   in
   747                    val t = compile_arg compilation_modifiers additional_arguments
   761                     (u, rest)
   748                      ctxt param_modes t
   762                   end
   749                    val rest = compile_prems [] vs' names'' ps;
   763               | Sidecond t =>
   750                  in
   764                   let
   751                    (mk_if compfuns t, rest)
   765                     val t = compile_arg compilation_modifiers additional_arguments
   752                  end
   766                       ctxt param_modes t
   753              | Generator (v, T) =>
   767                     val rest = compile_prems [] vs' names'' ps;
   754                  let
   768                   in
   755                    val u = Comp_Mod.mk_random compilation_modifiers T additional_arguments
   769                     (mk_if compfuns t, rest)
   756                    val rest = compile_prems [Free (v, T)]  vs' names'' ps;
   770                   end
   757                  in
   771               | Generator (v, T) =>
   758                    (u, rest)
   772                   let
   759                  end
   773                     val u = Comp_Mod.mk_random compilation_modifiers T additional_arguments
       
   774                     val rest = compile_prems [Free (v, T)]  vs' names'' ps;
       
   775                   in
       
   776                     (u, rest)
       
   777                   end)
   760           in
   778           in
   761             compile_match constr_vs' eqs out_ts''
   779             compile_match constr_vs' eqs out_ts''
   762               (mk_bind compfuns (compiled_clause, rest))
   780               (mk_bind compfuns (compiled_clause, rest))
   763           end
   781           end
   764     val prem_t = compile_prems in_ts' (map fst param_modes) all_vs' moded_ps;
   782     val prem_t = compile_prems in_ts' (map fst param_modes) all_vs' moded_ps
   765   in
   783   in
   766     mk_bind compfuns (mk_single compfuns inp, prem_t)
   784     mk_bind compfuns (mk_single compfuns inp, prem_t)
   767   end
   785   end
       
   786 
   768 
   787 
   769 (* switch detection *)
   788 (* switch detection *)
   770 
   789 
   771 (** argument position of an inductive predicates and the executable functions **)
   790 (** argument position of an inductive predicates and the executable functions **)
   772 
   791 
   774 
   793 
   775 fun input_positions_pair Input = [[]]
   794 fun input_positions_pair Input = [[]]
   776   | input_positions_pair Output = []
   795   | input_positions_pair Output = []
   777   | input_positions_pair (Fun _) = []
   796   | input_positions_pair (Fun _) = []
   778   | input_positions_pair (Pair (m1, m2)) =
   797   | input_positions_pair (Pair (m1, m2)) =
   779     map (cons 1) (input_positions_pair m1) @ map (cons 2) (input_positions_pair m2)
   798       map (cons 1) (input_positions_pair m1) @ map (cons 2) (input_positions_pair m2)
   780 
   799 
   781 fun input_positions_of_mode mode = flat (map_index
   800 fun input_positions_of_mode mode =
   782    (fn (i, Input) => [(i, [])]
   801   flat
   783    | (_, Output) => []
   802     (map_index
   784    | (_, Fun _) => []
   803       (fn (i, Input) => [(i, [])]
   785    | (i, m as Pair _) => map (pair i) (input_positions_pair m))
   804         | (_, Output) => []
   786      (Predicate_Compile_Aux.strip_fun_mode mode))
   805         | (_, Fun _) => []
       
   806         | (i, m as Pair _) => map (pair i) (input_positions_pair m))
       
   807       (Predicate_Compile_Aux.strip_fun_mode mode))
   787 
   808 
   788 fun argument_position_pair _ [] = []
   809 fun argument_position_pair _ [] = []
   789   | argument_position_pair (Pair (Fun _, m2)) (2 :: is) = argument_position_pair m2 is
   810   | argument_position_pair (Pair (Fun _, m2)) (2 :: is) = argument_position_pair m2 is
   790   | argument_position_pair (Pair (m1, m2)) (i :: is) =
   811   | argument_position_pair (Pair (m1, m2)) (i :: is) =
   791     (if eq_mode (m1, Output) andalso i = 2 then
   812       (if eq_mode (m1, Output) andalso i = 2 then
   792       argument_position_pair m2 is
   813         argument_position_pair m2 is
   793     else if eq_mode (m2, Output) andalso i = 1 then
   814       else if eq_mode (m2, Output) andalso i = 1 then
   794       argument_position_pair m1 is
   815         argument_position_pair m1 is
   795     else (i :: argument_position_pair (if i = 1 then m1 else m2) is))
   816       else (i :: argument_position_pair (if i = 1 then m1 else m2) is))
   796 
   817 
   797 fun argument_position_of mode (i, is) =
   818 fun argument_position_of mode (i, is) =
   798   (i - (length (filter (fn Output => true | Fun _ => true | _ => false)
   819   (i - (length (filter (fn Output => true | Fun _ => true | _ => false)
   799     (List.take (strip_fun_mode mode, i)))),
   820     (List.take (strip_fun_mode mode, i)))),
   800   argument_position_pair (nth (strip_fun_mode mode) i) is)
   821   argument_position_pair (nth (strip_fun_mode mode) i) is)
   802 fun nth_pair [] t = t
   823 fun nth_pair [] t = t
   803   | nth_pair (1 :: is) (Const (@{const_name Pair}, _) $ t1 $ _) = nth_pair is t1
   824   | nth_pair (1 :: is) (Const (@{const_name Pair}, _) $ t1 $ _) = nth_pair is t1
   804   | nth_pair (2 :: is) (Const (@{const_name Pair}, _) $ _ $ t2) = nth_pair is t2
   825   | nth_pair (2 :: is) (Const (@{const_name Pair}, _) $ _ $ t2) = nth_pair is t2
   805   | nth_pair _ _ = raise Fail "unexpected input for nth_tuple"
   826   | nth_pair _ _ = raise Fail "unexpected input for nth_tuple"
   806 
   827 
       
   828 
   807 (** switch detection analysis **)
   829 (** switch detection analysis **)
   808 
   830 
   809 fun find_switch_test ctxt (i, is) (ts, _) =
   831 fun find_switch_test ctxt (i, is) (ts, _) =
   810   let
   832   let
   811     val t = nth_pair is (nth ts i)
   833     val t = nth_pair is (nth ts i)
   812     val T = fastype_of t
   834     val T = fastype_of t
   813   in
   835   in
   814     case T of
   836     (case T of
   815       TFree _ => NONE
   837       TFree _ => NONE
   816     | Type (Tcon, _) =>
   838     | Type (Tcon, _) =>
   817       (case Ctr_Sugar.ctr_sugar_of ctxt Tcon of
   839         (case Ctr_Sugar.ctr_sugar_of ctxt Tcon of
   818         NONE => NONE
   840           NONE => NONE
   819       | SOME {ctrs, ...} =>
   841         | SOME {ctrs, ...} =>
   820         (case strip_comb t of
   842             (case strip_comb t of
   821           (Var _, []) => NONE
   843               (Var _, []) => NONE
   822         | (Free _, []) => NONE
   844             | (Free _, []) => NONE
   823         | (Const (c, T), _) =>
   845             | (Const (c, T), _) =>
   824           if AList.defined (op =) (map_filter (try dest_Const) ctrs) c then SOME (c, T) else NONE))
   846                 if AList.defined (op =) (map_filter (try dest_Const) ctrs) c
       
   847                 then SOME (c, T) else NONE)))
   825   end
   848   end
   826 
   849 
   827 fun partition_clause ctxt pos moded_clauses =
   850 fun partition_clause ctxt pos moded_clauses =
   828   let
   851   let
   829     fun insert_list eq (key, value) = AList.map_default eq (key, []) (cons value)
   852     fun insert_list eq (key, value) = AList.map_default eq (key, []) (cons value)
   830     fun find_switch_test' moded_clause (cases, left) =
   853     fun find_switch_test' moded_clause (cases, left) =
   831       case find_switch_test ctxt pos moded_clause of
   854       (case find_switch_test ctxt pos moded_clause of
   832         SOME (c, T) => (insert_list (op =) ((c, T), moded_clause) cases, left)
   855         SOME (c, T) => (insert_list (op =) ((c, T), moded_clause) cases, left)
   833       | NONE => (cases, moded_clause :: left)
   856       | NONE => (cases, moded_clause :: left))
   834   in
   857   in
   835     fold find_switch_test' moded_clauses ([], [])
   858     fold find_switch_test' moded_clauses ([], [])
   836   end
   859   end
   837 
   860 
   838 datatype switch_tree =
   861 datatype switch_tree =
   844       let
   867       let
   845         val ord = option_ord (rev_order o int_ord o (pairself (length o snd o snd)))
   868         val ord = option_ord (rev_order o int_ord o (pairself (length o snd o snd)))
   846         val partition = partition_clause ctxt input_position moded_clauses
   869         val partition = partition_clause ctxt input_position moded_clauses
   847         val switch = if (length (fst partition) > 1) then SOME (input_position, partition) else NONE
   870         val switch = if (length (fst partition) > 1) then SOME (input_position, partition) else NONE
   848       in
   871       in
   849         case ord (switch, best_switch) of LESS => best_switch
   872         (case ord (switch, best_switch) of
   850           | EQUAL => best_switch | GREATER => switch
   873           LESS => best_switch
       
   874         | EQUAL => best_switch
       
   875         | GREATER => switch)
   851       end
   876       end
   852     fun detect_switches moded_clauses =
   877     fun detect_switches moded_clauses =
   853       case fold (select_best_switch moded_clauses) (input_positions_of_mode mode) NONE of
   878       (case fold (select_best_switch moded_clauses) (input_positions_of_mode mode) NONE of
   854         SOME (best_pos, (switched_on, left_clauses)) =>
   879         SOME (best_pos, (switched_on, left_clauses)) =>
   855           Node ((best_pos, map (apsnd detect_switches) switched_on),
   880           Node ((best_pos, map (apsnd detect_switches) switched_on),
   856             detect_switches left_clauses)
   881             detect_switches left_clauses)
   857       | NONE => Atom moded_clauses
   882       | NONE => Atom moded_clauses)
   858   in
   883   in
   859     detect_switches moded_clauses
   884     detect_switches moded_clauses
   860   end
   885   end
   861 
   886 
       
   887 
   862 (** compilation of detected switches **)
   888 (** compilation of detected switches **)
   863 
   889 
   864 fun destruct_constructor_pattern (pat, obj) =
   890 fun destruct_constructor_pattern (pat, obj) =
   865   (case strip_comb pat of
   891   (case strip_comb pat of
   866     (Free _, []) => cons (pat, obj)
   892       (Free _, []) => cons (pat, obj)
   867   | (Const (c, T), pat_args) =>
   893   | (Const (c, T), pat_args) =>
   868     (case strip_comb obj of
   894       (case strip_comb obj of
   869       (Const (c', T'), obj_args) =>
   895         (Const (c', T'), obj_args) =>
   870         (if c = c' andalso T = T' then
   896           (if c = c' andalso T = T' then
   871           fold destruct_constructor_pattern (pat_args ~~ obj_args)
   897             fold destruct_constructor_pattern (pat_args ~~ obj_args)
   872         else raise Fail "pattern and object mismatch")
   898           else raise Fail "pattern and object mismatch")
   873     | _ => raise Fail "unexpected object")
   899       | _ => raise Fail "unexpected object")
   874   | _ => raise Fail "unexpected pattern")
   900   | _ => raise Fail "unexpected pattern")
   875 
       
   876 
   901 
   877 fun compile_switch compilation_modifiers ctxt all_vs param_modes additional_arguments mode
   902 fun compile_switch compilation_modifiers ctxt all_vs param_modes additional_arguments mode
   878   in_ts' outTs switch_tree =
   903   in_ts' outTs switch_tree =
   879   let
   904   let
   880     val compfuns = Comp_Mod.compfuns compilation_modifiers
   905     val compfuns = Comp_Mod.compfuns compilation_modifiers
   919         end
   944         end
   920         val switch = Case_Translation.make_case ctxt Case_Translation.Quiet Name.context inp_var
   945         val switch = Case_Translation.make_case ctxt Case_Translation.Quiet Name.context inp_var
   921           ((map compile_single_case switched_clauses) @
   946           ((map compile_single_case switched_clauses) @
   922             [(xt, mk_empty compfuns (HOLogic.mk_tupleT outTs))])
   947             [(xt, mk_empty compfuns (HOLogic.mk_tupleT outTs))])
   923       in
   948       in
   924         case compile_switch_tree all_vs ctxt_eqs left_clauses of
   949         (case compile_switch_tree all_vs ctxt_eqs left_clauses of
   925           NONE => SOME switch
   950           NONE => SOME switch
   926         | SOME left_comp => SOME (mk_plus compfuns (switch, left_comp))
   951         | SOME left_comp => SOME (mk_plus compfuns (switch, left_comp)))
   927       end
   952       end
   928   in
   953   in
   929     compile_switch_tree all_vs [] switch_tree
   954     compile_switch_tree all_vs [] switch_tree
   930   end
   955   end
   931 
   956 
       
   957 
   932 (* compilation of predicates *)
   958 (* compilation of predicates *)
   933 
   959 
   934 fun compile_pred options compilation_modifiers ctxt all_vs param_vs s T (pol, mode) moded_cls =
   960 fun compile_pred options compilation_modifiers ctxt all_vs param_vs s T (pol, mode) moded_cls =
   935   let
   961   let
   936     val is_terminating = false (* FIXME: requires an termination analysis *)  
   962     val is_terminating = false (* FIXME: requires an termination analysis *)
   937     val compilation_modifiers =
   963     val compilation_modifiers =
   938       (if pol then compilation_modifiers else
   964       (if pol then compilation_modifiers else
   939         negative_comp_modifiers_of compilation_modifiers)
   965         negative_comp_modifiers_of compilation_modifiers)
   940       |> (if is_depth_limited_compilation (Comp_Mod.compilation compilation_modifiers) then
   966       |> (if is_depth_limited_compilation (Comp_Mod.compilation compilation_modifiers) then
   941            (if is_terminating then
   967            (if is_terminating then
   942              (Comp_Mod.set_compfuns (unlimited_compfuns_of pol (Comp_Mod.compilation compilation_modifiers)))
   968               (Comp_Mod.set_compfuns
   943            else
   969                 (unlimited_compfuns_of pol (Comp_Mod.compilation compilation_modifiers)))
   944              (Comp_Mod.set_compfuns (limited_compfuns_of pol (Comp_Mod.compilation compilation_modifiers))))
   970             else
   945          else I)
   971               (Comp_Mod.set_compfuns
   946     val additional_arguments = Comp_Mod.additional_arguments compilation_modifiers
   972                 (limited_compfuns_of pol (Comp_Mod.compilation compilation_modifiers))))
   947       (all_vs @ param_vs)
   973           else I)
       
   974     val additional_arguments =
       
   975       Comp_Mod.additional_arguments compilation_modifiers (all_vs @ param_vs)
   948     val compfuns = Comp_Mod.compfuns compilation_modifiers
   976     val compfuns = Comp_Mod.compfuns compilation_modifiers
   949     fun is_param_type (T as Type ("fun",[_ , T'])) =
   977     fun is_param_type (T as Type ("fun",[_ , T'])) =
   950       is_some (try (dest_monadT compfuns) T) orelse is_param_type T'
   978           is_some (try (dest_monadT compfuns) T) orelse is_param_type T'
   951       | is_param_type T = is_some (try (dest_monadT compfuns) T)
   979       | is_param_type T = is_some (try (dest_monadT compfuns) T)
   952     val (inpTs, outTs) = split_map_modeT (fn m => fn T => (SOME (funT_of compfuns m T), NONE)) mode
   980     val (inpTs, outTs) =
   953       (binder_types T)
   981       split_map_modeT (fn m => fn T => (SOME (funT_of compfuns m T), NONE)) mode
       
   982         (binder_types T)
   954     val funT = Comp_Mod.funT_of compilation_modifiers mode T
   983     val funT = Comp_Mod.funT_of compilation_modifiers mode T
   955     val (in_ts, _) = fold_map (fold_map_aterms_prodT (curry HOLogic.mk_prod)
   984     val (in_ts, _) =
   956       (fn T => fn (param_vs, names) =>
   985       fold_map (fold_map_aterms_prodT (curry HOLogic.mk_prod)
   957         if is_param_type T then
   986         (fn T => fn (param_vs, names) =>
   958           (Free (hd param_vs, T), (tl param_vs, names))
   987           if is_param_type T then
   959         else
   988             (Free (hd param_vs, T), (tl param_vs, names))
   960           let
   989           else
   961             val new = singleton (Name.variant_list names) "x"
   990             let
   962           in (Free (new, T), (param_vs, new :: names)) end)) inpTs
   991               val new = singleton (Name.variant_list names) "x"
       
   992             in (Free (new, T), (param_vs, new :: names)) end)) inpTs
   963         (param_vs, (all_vs @ param_vs))
   993         (param_vs, (all_vs @ param_vs))
   964     val in_ts' = map_filter (map_filter_prod
   994     val in_ts' =
   965       (fn t as Free (x, _) => if member (op =) param_vs x then NONE else SOME t | t => SOME t)) in_ts
   995       map_filter (map_filter_prod
       
   996         (fn t as Free (x, _) =>
       
   997           if member (op =) param_vs x then NONE else SOME t | t => SOME t)) in_ts
   966     val param_modes = param_vs ~~ ho_arg_modes_of mode
   998     val param_modes = param_vs ~~ ho_arg_modes_of mode
   967     val compilation =
   999     val compilation =
   968       if detect_switches options then
  1000       if detect_switches options then
   969         the_default (mk_empty compfuns (HOLogic.mk_tupleT outTs))
  1001         the_default (mk_empty compfuns (HOLogic.mk_tupleT outTs))
   970           (compile_switch compilation_modifiers ctxt all_vs param_modes additional_arguments mode
  1002           (compile_switch compilation_modifiers ctxt all_vs param_modes additional_arguments mode
   971             in_ts' outTs (mk_switch_tree ctxt mode moded_cls))
  1003             in_ts' outTs (mk_switch_tree ctxt mode moded_cls))
   972       else
  1004       else
   973         let
  1005         let
   974           val cl_ts =
  1006           val cl_ts =
   975             map (fn (ts, moded_prems) => 
  1007             map (fn (ts, moded_prems) =>
   976               compile_clause compilation_modifiers ctxt all_vs param_modes additional_arguments
  1008               compile_clause compilation_modifiers ctxt all_vs param_modes additional_arguments
   977                 (HOLogic.mk_tuple in_ts') (split_mode mode ts) moded_prems) moded_cls;
  1009                 (HOLogic.mk_tuple in_ts') (split_mode mode ts) moded_prems) moded_cls
   978         in
  1010         in
   979           Comp_Mod.wrap_compilation compilation_modifiers compfuns s T mode additional_arguments
  1011           Comp_Mod.wrap_compilation compilation_modifiers compfuns s T mode additional_arguments
   980             (if null cl_ts then
  1012             (if null cl_ts then
   981               mk_empty compfuns (HOLogic.mk_tupleT outTs)
  1013               mk_empty compfuns (HOLogic.mk_tupleT outTs)
   982             else
  1014             else
   983               foldr1 (mk_plus compfuns) cl_ts)
  1015               foldr1 (mk_plus compfuns) cl_ts)
   984         end
  1016         end
   985     val fun_const =
  1017     val fun_const =
   986       Const (function_name_of (Comp_Mod.compilation compilation_modifiers)
  1018       Const (function_name_of (Comp_Mod.compilation compilation_modifiers) ctxt s mode, funT)
   987       ctxt s mode, funT)
       
   988   in
  1019   in
   989     HOLogic.mk_Trueprop
  1020     HOLogic.mk_Trueprop
   990       (HOLogic.mk_eq (list_comb (fun_const, in_ts @ additional_arguments), compilation))
  1021       (HOLogic.mk_eq (list_comb (fun_const, in_ts @ additional_arguments), compilation))
   991   end;
  1022   end
       
  1023 
   992 
  1024 
   993 (* Definition of executable functions and their intro and elim rules *)
  1025 (* Definition of executable functions and their intro and elim rules *)
   994 
  1026 
   995 fun strip_split_abs (Const (@{const_name case_prod}, _) $ t) = strip_split_abs t
  1027 fun strip_split_abs (Const (@{const_name case_prod}, _) $ t) = strip_split_abs t
   996   | strip_split_abs (Abs (_, _, t)) = strip_split_abs t
  1028   | strip_split_abs (Abs (_, _, t)) = strip_split_abs t
   997   | strip_split_abs t = t
  1029   | strip_split_abs t = t
   998 
  1030 
   999 fun mk_args is_eval (m as Pair (m1, m2), T as Type (@{type_name Product_Type.prod}, [T1, T2])) names =
  1031 fun mk_args is_eval (m as Pair (m1, m2), T as Type (@{type_name Product_Type.prod}, [T1, T2])) names =
  1000     if eq_mode (m, Input) orelse eq_mode (m, Output) then
  1032       if eq_mode (m, Input) orelse eq_mode (m, Output) then
       
  1033         let
       
  1034           val x = singleton (Name.variant_list names) "x"
       
  1035         in
       
  1036           (Free (x, T), x :: names)
       
  1037         end
       
  1038       else
       
  1039         let
       
  1040           val (t1, names') = mk_args is_eval (m1, T1) names
       
  1041           val (t2, names'') = mk_args is_eval (m2, T2) names'
       
  1042         in
       
  1043           (HOLogic.mk_prod (t1, t2), names'')
       
  1044         end
       
  1045   | mk_args is_eval ((m as Fun _), T) names =
       
  1046       let
       
  1047         val funT = funT_of Predicate_Comp_Funs.compfuns m T
       
  1048         val x = singleton (Name.variant_list names) "x"
       
  1049         val (args, _) = fold_map (mk_args is_eval) (strip_fun_mode m ~~ binder_types T) (x :: names)
       
  1050         val (inargs, outargs) = split_map_mode (fn _ => fn t => (SOME t, NONE)) m args
       
  1051         val t = fold_rev HOLogic.tupled_lambda args (Predicate_Comp_Funs.mk_Eval
       
  1052           (list_comb (Free (x, funT), inargs), HOLogic.mk_tuple outargs))
       
  1053       in
       
  1054         (if is_eval then t else Free (x, funT), x :: names)
       
  1055       end
       
  1056   | mk_args _ (_, T) names =
  1001       let
  1057       let
  1002         val x = singleton (Name.variant_list names) "x"
  1058         val x = singleton (Name.variant_list names) "x"
  1003       in
  1059       in
  1004         (Free (x, T), x :: names)
  1060         (Free (x, T), x :: names)
  1005       end
  1061       end
  1006     else
       
  1007       let
       
  1008         val (t1, names') = mk_args is_eval (m1, T1) names
       
  1009         val (t2, names'') = mk_args is_eval (m2, T2) names'
       
  1010       in
       
  1011         (HOLogic.mk_prod (t1, t2), names'')
       
  1012       end
       
  1013   | mk_args is_eval ((m as Fun _), T) names =
       
  1014     let
       
  1015       val funT = funT_of Predicate_Comp_Funs.compfuns m T
       
  1016       val x = singleton (Name.variant_list names) "x"
       
  1017       val (args, _) = fold_map (mk_args is_eval) (strip_fun_mode m ~~ binder_types T) (x :: names)
       
  1018       val (inargs, outargs) = split_map_mode (fn _ => fn t => (SOME t, NONE)) m args
       
  1019       val t = fold_rev HOLogic.tupled_lambda args (Predicate_Comp_Funs.mk_Eval
       
  1020         (list_comb (Free (x, funT), inargs), HOLogic.mk_tuple outargs))
       
  1021     in
       
  1022       (if is_eval then t else Free (x, funT), x :: names)
       
  1023     end
       
  1024   | mk_args is_eval (_, T) names =
       
  1025     let
       
  1026       val x = singleton (Name.variant_list names) "x"
       
  1027     in
       
  1028       (Free (x, T), x :: names)
       
  1029     end
       
  1030 
  1062 
  1031 fun create_intro_elim_rule ctxt mode defthm mode_id funT pred =
  1063 fun create_intro_elim_rule ctxt mode defthm mode_id funT pred =
  1032   let
  1064   let
  1033     val funtrm = Const (mode_id, funT)
  1065     val funtrm = Const (mode_id, funT)
  1034     val Ts = binder_types (fastype_of pred)
  1066     val Ts = binder_types (fastype_of pred)
  1051     val funpropE = HOLogic.mk_Trueprop (Predicate_Comp_Funs.mk_Eval (list_comb (funtrm, inargs),
  1083     val funpropE = HOLogic.mk_Trueprop (Predicate_Comp_Funs.mk_Eval (list_comb (funtrm, inargs),
  1052                     if null outargs then Free("y", HOLogic.unitT) else HOLogic.mk_tuple outargs))
  1084                     if null outargs then Free("y", HOLogic.unitT) else HOLogic.mk_tuple outargs))
  1053     val funpropI = HOLogic.mk_Trueprop (Predicate_Comp_Funs.mk_Eval (list_comb (funtrm, inargs),
  1085     val funpropI = HOLogic.mk_Trueprop (Predicate_Comp_Funs.mk_Eval (list_comb (funtrm, inargs),
  1054                      HOLogic.mk_tuple outargs))
  1086                      HOLogic.mk_tuple outargs))
  1055     val introtrm = Logic.list_implies (predpropI :: param_eqs, funpropI)
  1087     val introtrm = Logic.list_implies (predpropI :: param_eqs, funpropI)
  1056     val simprules = [defthm, @{thm eval_pred},
  1088     val simprules =
  1057       @{thm "split_beta"}, @{thm "fst_conv"}, @{thm "snd_conv"}, @{thm pair_collapse}]
  1089       [defthm, @{thm eval_pred},
       
  1090         @{thm "split_beta"}, @{thm "fst_conv"}, @{thm "snd_conv"}, @{thm pair_collapse}]
  1058     val unfolddef_tac =
  1091     val unfolddef_tac =
  1059       Simplifier.asm_full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps simprules) 1
  1092       Simplifier.asm_full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps simprules) 1
  1060     val introthm = Goal.prove ctxt
  1093     val introthm = Goal.prove ctxt
  1061       (argnames @ hoarg_names' @ ["y"]) [] introtrm (fn _ => unfolddef_tac)
  1094       (argnames @ hoarg_names' @ ["y"]) [] introtrm (fn _ => unfolddef_tac)
  1062     val P = HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT));
  1095     val P = HOLogic.mk_Trueprop (Free ("P", HOLogic.boolT));
  1081       else NONE
  1114       else NONE
  1082   in
  1115   in
  1083     ((introthm, elimthm), opt_neg_introthm)
  1116     ((introthm, elimthm), opt_neg_introthm)
  1084   end
  1117   end
  1085 
  1118 
  1086 fun create_constname_of_mode options thy prefix name _ mode = 
  1119 fun create_constname_of_mode options thy prefix name _ mode =
  1087   let
  1120   let
  1088     val system_proposal = prefix ^ (Long_Name.base_name name)
  1121     val system_proposal = prefix ^ (Long_Name.base_name name) ^ "_" ^ ascii_string_of_mode mode
  1089       ^ "_" ^ ascii_string_of_mode mode
       
  1090     val name = the_default system_proposal (proposed_names options name mode)
  1122     val name = the_default system_proposal (proposed_names options name mode)
  1091   in
  1123   in
  1092     Sign.full_bname thy name
  1124     Sign.full_bname thy name
  1093   end;
  1125   end
  1094 
  1126 
  1095 fun create_definitions options preds (name, modes) thy =
  1127 fun create_definitions options preds (name, modes) thy =
  1096   let
  1128   let
  1097     val compfuns = Predicate_Comp_Funs.compfuns
  1129     val compfuns = Predicate_Comp_Funs.compfuns
  1098     val T = AList.lookup (op =) preds name |> the
  1130     val T = AList.lookup (op =) preds name |> the
  1180 
  1212 
  1181 (* preparation of introduction rules into special datastructures *)
  1213 (* preparation of introduction rules into special datastructures *)
  1182 fun dest_prem ctxt params t =
  1214 fun dest_prem ctxt params t =
  1183   (case strip_comb t of
  1215   (case strip_comb t of
  1184     (v as Free _, _) => if member (op =) params v then Prem t else Sidecond t
  1216     (v as Free _, _) => if member (op =) params v then Prem t else Sidecond t
  1185   | (c as Const (@{const_name Not}, _), [t]) => (case dest_prem ctxt params t of
  1217   | (c as Const (@{const_name Not}, _), [t]) =>
  1186       Prem t => Negprem t
  1218       (case dest_prem ctxt params t of
  1187     | Negprem _ => error ("Double negation not allowed in premise: " ^
  1219         Prem t => Negprem t
  1188         Syntax.string_of_term ctxt (c $ t)) 
  1220       | Negprem _ => error ("Double negation not allowed in premise: " ^
  1189     | Sidecond t => Sidecond (c $ t))
  1221           Syntax.string_of_term ctxt (c $ t))
       
  1222       | Sidecond t => Sidecond (c $ t))
  1190   | (Const (s, _), _) =>
  1223   | (Const (s, _), _) =>
  1191     if is_registered ctxt s then Prem t else Sidecond t
  1224       if is_registered ctxt s then Prem t else Sidecond t
  1192   | _ => Sidecond t)
  1225   | _ => Sidecond t)
  1193 
  1226 
  1194 fun prepare_intrs options ctxt prednames intros =
  1227 fun prepare_intrs options ctxt prednames intros =
  1195   let
  1228   let
  1196     val thy = Proof_Context.theory_of ctxt
  1229     val thy = Proof_Context.theory_of ctxt
  1203     fun generate_modes s T =
  1236     fun generate_modes s T =
  1204       if member (op =) (no_higher_order_predicate options) s then
  1237       if member (op =) (no_higher_order_predicate options) s then
  1205         all_smodes_of_typ T
  1238         all_smodes_of_typ T
  1206       else
  1239       else
  1207         all_modes_of_typ T
  1240         all_modes_of_typ T
  1208     val all_modes = 
  1241     val all_modes =
  1209       map (fn (s, T) =>
  1242       map (fn (s, T) =>
  1210         (s, case proposed_modes options s of
  1243         (s,
       
  1244           (case proposed_modes options s of
  1211             SOME ms => check_matches_type ctxt s T ms
  1245             SOME ms => check_matches_type ctxt s T ms
  1212           | NONE => generate_modes s T)) preds
  1246           | NONE => generate_modes s T))) preds
  1213     val params =
  1247     val params =
  1214       case intrs of
  1248       (case intrs of
  1215         [] =>
  1249         [] =>
  1216           let
  1250           let
  1217             val T = snd (hd preds)
  1251             val T = snd (hd preds)
  1218             val one_mode = hd (the (AList.lookup (op =) all_modes (fst (hd preds))))
  1252             val one_mode = hd (the (AList.lookup (op =) all_modes (fst (hd preds))))
  1219             val paramTs =
  1253             val paramTs =
  1222               (1 upto length paramTs))
  1256               (1 upto length paramTs))
  1223           in
  1257           in
  1224             map2 (curry Free) param_names paramTs
  1258             map2 (curry Free) param_names paramTs
  1225           end
  1259           end
  1226       | (intr :: _) =>
  1260       | (intr :: _) =>
  1227         let
  1261           let
  1228           val (p, args) = strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl intr))
  1262             val (p, args) = strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl intr))
  1229           val one_mode = hd (the (AList.lookup (op =) all_modes (fst (dest_Const p))))
  1263             val one_mode = hd (the (AList.lookup (op =) all_modes (fst (dest_Const p))))
  1230         in
  1264           in
  1231           ho_args_of one_mode args
  1265             ho_args_of one_mode args
  1232         end
  1266           end)
  1233     val param_vs = map (fst o dest_Free) params
  1267     val param_vs = map (fst o dest_Free) params
  1234     fun add_clause intr clauses =
  1268     fun add_clause intr clauses =
  1235       let
  1269       let
  1236         val (Const (name, _), ts) = strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl intr))
  1270         val (Const (name, _), ts) =
  1237         val prems = map (dest_prem ctxt params o HOLogic.dest_Trueprop) (Logic.strip_imp_prems intr)
  1271           strip_comb (HOLogic.dest_Trueprop (Logic.strip_imp_concl intr))
       
  1272         val prems =
       
  1273           map (dest_prem ctxt params o HOLogic.dest_Trueprop) (Logic.strip_imp_prems intr)
  1238       in
  1274       in
  1239         AList.update op = (name, these (AList.lookup op = clauses name) @
  1275         AList.update op =
  1240           [(ts, prems)]) clauses
  1276           (name, these (AList.lookup op = clauses name) @ [(ts, prems)])
       
  1277           clauses
  1241       end;
  1278       end;
  1242     val clauses = fold add_clause intrs []
  1279     val clauses = fold add_clause intrs []
  1243   in
  1280   in
  1244     (preds, all_vs, param_vs, all_modes, clauses)
  1281     (preds, all_vs, param_vs, all_modes, clauses)
  1245   end;
  1282   end
  1246 
  1283 
  1247 (* sanity check of introduction rules *)
  1284 (* sanity check of introduction rules *)
  1248 (* TODO: rethink check with new modes *)
  1285 (* TODO: rethink check with new modes *)
  1249 (*
  1286 (*
  1250 fun check_format_of_intro_rule thy intro =
  1287 fun check_format_of_intro_rule thy intro =
  1257         if length (HOLogic.strip_tuple arg) = length Ts then
  1294         if length (HOLogic.strip_tuple arg) = length Ts then
  1258           true
  1295           true
  1259         else
  1296         else
  1260           error ("Format of introduction rule is invalid: tuples must be expanded:"
  1297           error ("Format of introduction rule is invalid: tuples must be expanded:"
  1261           ^ (Syntax.string_of_term_global thy arg) ^ " in " ^
  1298           ^ (Syntax.string_of_term_global thy arg) ^ " in " ^
  1262           (Display.string_of_thm_global thy intro)) 
  1299           (Display.string_of_thm_global thy intro))
  1263       | _ => true
  1300       | _ => true
  1264     val prems = Logic.strip_imp_prems (prop_of intro)
  1301     val prems = Logic.strip_imp_prems (prop_of intro)
  1265     fun check_prem (Prem t) = forall check_arg args
  1302     fun check_prem (Prem t) = forall check_arg args
  1266       | check_prem (Negprem t) = forall check_arg args
  1303       | check_prem (Negprem t) = forall check_arg args
  1267       | check_prem _ = true
  1304       | check_prem _ = true
  1286           error "Introduction and elimination rules do not match!"
  1323           error "Introduction and elimination rules do not match!"
  1287         else true
  1324         else true
  1288       end
  1325       end
  1289   in forall check prednames end
  1326   in forall check prednames end
  1290 *)
  1327 *)
       
  1328 
  1291 
  1329 
  1292 (* create code equation *)
  1330 (* create code equation *)
  1293 
  1331 
  1294 fun add_code_equations ctxt preds result_thmss =
  1332 fun add_code_equations ctxt preds result_thmss =
  1295   let
  1333   let
  1320       end
  1358       end
  1321   in
  1359   in
  1322     map2 add_code_equation preds result_thmss
  1360     map2 add_code_equation preds result_thmss
  1323   end
  1361   end
  1324 
  1362 
       
  1363 
  1325 (** main function of predicate compiler **)
  1364 (** main function of predicate compiler **)
  1326 
  1365 
  1327 datatype steps = Steps of
  1366 datatype steps = Steps of
  1328   {
  1367   {
  1329   define_functions : options -> (string * typ) list -> string * (bool * mode) list -> theory -> theory,
  1368   define_functions : options -> (string * typ) list -> string * (bool * mode) list -> theory -> theory,
  1339 fun add_equations_of steps mode_analysis_options options prednames thy =
  1378 fun add_equations_of steps mode_analysis_options options prednames thy =
  1340   let
  1379   let
  1341     fun dest_steps (Steps s) = s
  1380     fun dest_steps (Steps s) = s
  1342     val compilation = Comp_Mod.compilation (#comp_modifiers (dest_steps steps))
  1381     val compilation = Comp_Mod.compilation (#comp_modifiers (dest_steps steps))
  1343     val ctxt = Proof_Context.init_global thy
  1382     val ctxt = Proof_Context.init_global thy
  1344     val _ = print_step options
  1383     val _ =
  1345       ("Starting predicate compiler (compilation: " ^ string_of_compilation compilation
  1384       print_step options
  1346         ^ ") for predicates " ^ commas prednames ^ "...")
  1385         ("Starting predicate compiler (compilation: " ^ string_of_compilation compilation ^
  1347       (*val _ = check_intros_elim_match thy prednames*)
  1386           ") for predicates " ^ commas prednames ^ "...")
  1348       (*val _ = map (check_format_of_intro_rule thy) (maps (intros_of thy) prednames)*)
  1387     (*val _ = check_intros_elim_match thy prednames*)
       
  1388     (*val _ = map (check_format_of_intro_rule thy) (maps (intros_of thy) prednames)*)
  1349     val _ =
  1389     val _ =
  1350       if show_intermediate_results options then
  1390       if show_intermediate_results options then
  1351         tracing (commas (map (Display.string_of_thm ctxt) (maps (intros_of ctxt) prednames)))
  1391         tracing (commas (map (Display.string_of_thm ctxt) (maps (intros_of ctxt) prednames)))
  1352       else ()
  1392       else ()
  1353     val (preds, all_vs, param_vs, all_modes, clauses) =
  1393     val (preds, all_vs, param_vs, all_modes, clauses) =
  1390         [attrib])] thy))
  1430         [attrib])] thy))
  1391       result_thms' thy'')
  1431       result_thms' thy'')
  1392   in
  1432   in
  1393     thy'''
  1433     thy'''
  1394   end
  1434   end
  1395   
  1435 
  1396 fun gen_add_equations steps options names thy =
  1436 fun gen_add_equations steps options names thy =
  1397   let
  1437   let
  1398     fun dest_steps (Steps s) = s
  1438     fun dest_steps (Steps s) = s
  1399     val defined = defined_functions (Comp_Mod.compilation (#comp_modifiers (dest_steps steps)))
  1439     val defined = defined_functions (Comp_Mod.compilation (#comp_modifiers (dest_steps steps)))
  1400     val thy' = extend_intro_graph names thy;
  1440     val thy' = extend_intro_graph names thy;
  1497 
  1537 
  1498 val add_new_random_dseq_equations = gen_add_equations
  1538 val add_new_random_dseq_equations = gen_add_equations
  1499   (Steps {
  1539   (Steps {
  1500   define_functions =
  1540   define_functions =
  1501     fn options => fn preds => fn (s, modes) =>
  1541     fn options => fn preds => fn (s, modes) =>
  1502     let
  1542       let
  1503       val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
  1543         val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
  1504       val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
  1544         val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
  1505     in define_functions new_pos_random_dseq_comp_modifiers New_Pos_Random_Sequence_CompFuns.depth_limited_compfuns
  1545       in
  1506       options preds (s, pos_modes)
  1546         define_functions new_pos_random_dseq_comp_modifiers
  1507       #> define_functions new_neg_random_dseq_comp_modifiers New_Neg_Random_Sequence_CompFuns.depth_limited_compfuns
  1547           New_Pos_Random_Sequence_CompFuns.depth_limited_compfuns
  1508       options preds (s, neg_modes)
  1548           options preds (s, pos_modes) #>
  1509     end,
  1549         define_functions new_neg_random_dseq_comp_modifiers
       
  1550           New_Neg_Random_Sequence_CompFuns.depth_limited_compfuns
       
  1551           options preds (s, neg_modes)
       
  1552       end,
  1510   prove = prove_by_skip,
  1553   prove = prove_by_skip,
  1511   add_code_equations = K (K I),
  1554   add_code_equations = K (K I),
  1512   comp_modifiers = new_pos_random_dseq_comp_modifiers,
  1555   comp_modifiers = new_pos_random_dseq_comp_modifiers,
  1513   use_generators = true,
  1556   use_generators = true,
  1514   qname = "new_random_dseq_equation"})
  1557   qname = "new_random_dseq_equation"})
  1515 
  1558 
  1516 val add_generator_dseq_equations = gen_add_equations
  1559 val add_generator_dseq_equations = gen_add_equations
  1517   (Steps {
  1560   (Steps {
  1518   define_functions =
  1561   define_functions =
  1519   fn options => fn preds => fn (s, modes) =>
  1562     fn options => fn preds => fn (s, modes) =>
  1520     let
  1563       let
  1521       val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
  1564         val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
  1522       val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
  1565         val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
  1523     in 
  1566       in
  1524       define_functions pos_generator_dseq_comp_modifiers New_Pos_DSequence_CompFuns.depth_limited_compfuns
  1567         define_functions pos_generator_dseq_comp_modifiers
  1525         options preds (s, pos_modes)
  1568           New_Pos_DSequence_CompFuns.depth_limited_compfuns options preds (s, pos_modes) #>
  1526       #> define_functions neg_generator_dseq_comp_modifiers New_Neg_DSequence_CompFuns.depth_limited_compfuns
  1569         define_functions neg_generator_dseq_comp_modifiers
  1527         options preds (s, neg_modes)
  1570           New_Neg_DSequence_CompFuns.depth_limited_compfuns options preds (s, neg_modes)
  1528     end,
  1571       end,
  1529   prove = prove_by_skip,
  1572   prove = prove_by_skip,
  1530   add_code_equations = K (K I),
  1573   add_code_equations = K (K I),
  1531   comp_modifiers = pos_generator_dseq_comp_modifiers,
  1574   comp_modifiers = pos_generator_dseq_comp_modifiers,
  1532   use_generators = true,
  1575   use_generators = true,
  1533   qname = "generator_dseq_equation"})
  1576   qname = "generator_dseq_equation"})
  1534 
  1577 
  1535 val add_generator_cps_equations = gen_add_equations
  1578 val add_generator_cps_equations = gen_add_equations
  1536   (Steps {
  1579   (Steps {
  1537   define_functions =
  1580   define_functions =
  1538   fn options => fn preds => fn (s, modes) =>
  1581     fn options => fn preds => fn (s, modes) =>
  1539     let
  1582       let
  1540       val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
  1583         val pos_modes = map_filter (fn (true, m) => SOME m | _ => NONE) modes
  1541       val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
  1584         val neg_modes = map_filter (fn (false, m) => SOME m | _ => NONE) modes
  1542     in 
  1585       in
  1543       define_functions pos_generator_cps_comp_modifiers Pos_Bounded_CPS_Comp_Funs.compfuns
  1586         define_functions pos_generator_cps_comp_modifiers Pos_Bounded_CPS_Comp_Funs.compfuns
  1544         options preds (s, pos_modes)
  1587           options preds (s, pos_modes)
  1545       #> define_functions neg_generator_cps_comp_modifiers Neg_Bounded_CPS_Comp_Funs.compfuns
  1588         #> define_functions neg_generator_cps_comp_modifiers Neg_Bounded_CPS_Comp_Funs.compfuns
  1546         options preds (s, neg_modes)
  1589           options preds (s, neg_modes)
  1547     end,
  1590       end,
  1548   prove = prove_by_skip,
  1591   prove = prove_by_skip,
  1549   add_code_equations = K (K I),
  1592   add_code_equations = K (K I),
  1550   comp_modifiers = pos_generator_cps_comp_modifiers,
  1593   comp_modifiers = pos_generator_cps_comp_modifiers,
  1551   use_generators = true,
  1594   use_generators = true,
  1552   qname = "generator_cps_equation"})
  1595   qname = "generator_cps_equation"})
  1553   
  1596 
  1554   
  1597 
  1555 (** user interface **)
  1598 (** user interface **)
  1556 
  1599 
  1557 (* code_pred_intro attribute *)
  1600 (* code_pred_intro attribute *)
  1558 
  1601 
  1559 fun attrib' f opt_case_name =
  1602 fun attrib' f opt_case_name =
  1567 
  1610 
  1568 (* values_timeout configuration *)
  1611 (* values_timeout configuration *)
  1569 
  1612 
  1570 val default_values_timeout = if ML_System.is_smlnj then 1200.0 else 40.0
  1613 val default_values_timeout = if ML_System.is_smlnj then 1200.0 else 40.0
  1571 
  1614 
  1572 val values_timeout = Attrib.setup_config_real @{binding values_timeout} (K default_values_timeout)
  1615 val values_timeout =
  1573 
  1616   Attrib.setup_config_real @{binding values_timeout} (K default_values_timeout)
  1574 val setup = PredData.put (Graph.empty) #>
  1617 
       
  1618 val setup =
       
  1619   PredData.put (Graph.empty) #>
  1575   Attrib.setup @{binding code_pred_intro} (Scan.lift (Scan.option Args.name) >> attrib' add_intro)
  1620   Attrib.setup @{binding code_pred_intro} (Scan.lift (Scan.option Args.name) >> attrib' add_intro)
  1576     "adding alternative introduction rules for code generation of inductive predicates"
  1621     "adding alternative introduction rules for code generation of inductive predicates"
  1577 
  1622 
  1578 fun qualified_binding a =
  1623 fun qualified_binding a =
  1579   Binding.qualify true (Long_Name.qualifier a) (Binding.name (Long_Name.base_name a));
  1624   Binding.qualify true (Long_Name.qualifier a) (Binding.name (Long_Name.base_name a));
  1591     fun mk_cases const =
  1636     fun mk_cases const =
  1592       let
  1637       let
  1593         val T = Sign.the_const_type thy' const
  1638         val T = Sign.the_const_type thy' const
  1594         val pred = Const (const, T)
  1639         val pred = Const (const, T)
  1595         val intros = intros_of ctxt' const
  1640         val intros = intros_of ctxt' const
  1596       in mk_casesrule lthy' pred intros end  
  1641       in mk_casesrule lthy' pred intros end
  1597     val cases_rules = map mk_cases preds
  1642     val cases_rules = map mk_cases preds
  1598     val cases =
  1643     val cases =
  1599       map2 (fn pred_name => fn case_rule => Rule_Cases.Case {fixes = [],
  1644       map2 (fn pred_name => fn case_rule => Rule_Cases.Case {fixes = [],
  1600         assumes =
  1645         assumes =
  1601           (Binding.name "that", tl (Logic.strip_imp_prems case_rule)) ::
  1646           (Binding.name "that", tl (Logic.strip_imp_prems case_rule)) ::
  1632   end;
  1677   end;
  1633 
  1678 
  1634 val code_pred = generic_code_pred (K I);
  1679 val code_pred = generic_code_pred (K I);
  1635 val code_pred_cmd = generic_code_pred Code.read_const
  1680 val code_pred_cmd = generic_code_pred Code.read_const
  1636 
  1681 
       
  1682 
  1637 (* transformation for code generation *)
  1683 (* transformation for code generation *)
  1638 
  1684 
  1639 (* FIXME just one data slot (record) per program unit *)
  1685 (* FIXME just one data slot (record) per program unit *)
  1640 
  1686 
  1641 structure Pred_Result = Proof_Data
  1687 structure Pred_Result = Proof_Data
  1694 );
  1740 );
  1695 val put_lseq_random_stats_result = Lseq_Random_Stats_Result.put;
  1741 val put_lseq_random_stats_result = Lseq_Random_Stats_Result.put;
  1696 
  1742 
  1697 fun dest_special_compr t =
  1743 fun dest_special_compr t =
  1698   let
  1744   let
  1699     val (inner_t, T_compr) = case t of (Const (@{const_name Collect}, _) $ Abs (_, T, t)) => (t, T)
  1745     val (inner_t, T_compr) =
  1700       | _ => raise TERM ("dest_special_compr", [t])
  1746       (case t of
       
  1747         (Const (@{const_name Collect}, _) $ Abs (_, T, t)) => (t, T)
       
  1748       | _ => raise TERM ("dest_special_compr", [t]))
  1701     val (Ts, conj) = apfst (map snd) (Predicate_Compile_Aux.strip_ex inner_t)
  1749     val (Ts, conj) = apfst (map snd) (Predicate_Compile_Aux.strip_ex inner_t)
  1702     val [eq, body] = HOLogic.dest_conj conj
  1750     val [eq, body] = HOLogic.dest_conj conj
  1703     val rhs = case HOLogic.dest_eq eq of
  1751     val rhs =
       
  1752       (case HOLogic.dest_eq eq of
  1704         (Bound i, rhs) => if i = length Ts then rhs else raise TERM ("dest_special_compr", [t])
  1753         (Bound i, rhs) => if i = length Ts then rhs else raise TERM ("dest_special_compr", [t])
  1705       | _ => raise TERM ("dest_special_compr", [t])
  1754       | _ => raise TERM ("dest_special_compr", [t]))
  1706     val output_names = Name.variant_list (fold Term.add_free_names [rhs, body] [])
  1755     val output_names = Name.variant_list (fold Term.add_free_names [rhs, body] [])
  1707       (map (fn i => "x" ^ string_of_int i) (1 upto length Ts))
  1756       (map (fn i => "x" ^ string_of_int i) (1 upto length Ts))
  1708     val output_frees = map2 (curry Free) output_names (rev Ts)
  1757     val output_frees = map2 (curry Free) output_names (rev Ts)
  1709     val body = subst_bounds (output_frees, body)
  1758     val body = subst_bounds (output_frees, body)
  1710     val output = subst_bounds (output_frees, rhs)
  1759     val output = subst_bounds (output_frees, rhs)
  1711   in
  1760   in
  1712     (((body, output), T_compr), output_names)
  1761     (((body, output), T_compr), output_names)
  1713   end
  1762   end
  1714 
  1763 
  1715 fun dest_general_compr ctxt t_compr =
  1764 fun dest_general_compr ctxt t_compr =
  1716   let      
  1765   let
  1717     val inner_t = case t_compr of (Const (@{const_name Collect}, _) $ t) => t
  1766     val inner_t =
  1718       | _ => error ("Not a set comprehension: " ^ Syntax.string_of_term ctxt t_compr);    
  1767       (case t_compr of
       
  1768         (Const (@{const_name Collect}, _) $ t) => t
       
  1769       | _ => error ("Not a set comprehension: " ^ Syntax.string_of_term ctxt t_compr))
  1719     val (body, Ts, fp) = HOLogic.strip_psplits inner_t;
  1770     val (body, Ts, fp) = HOLogic.strip_psplits inner_t;
  1720     val output_names = Name.variant_list (Term.add_free_names body [])
  1771     val output_names = Name.variant_list (Term.add_free_names body [])
  1721       (map (fn i => "x" ^ string_of_int i) (1 upto length Ts))
  1772       (map (fn i => "x" ^ string_of_int i) (1 upto length Ts))
  1722     val output_frees = map2 (curry Free) output_names (rev Ts)
  1773     val output_frees = map2 (curry Free) output_names (rev Ts)
  1723     val body = subst_bounds (output_frees, body)
  1774     val body = subst_bounds (output_frees, body)
  1732   (compilation, _) t_compr =
  1783   (compilation, _) t_compr =
  1733   let
  1784   let
  1734     val compfuns = Comp_Mod.compfuns comp_modifiers
  1785     val compfuns = Comp_Mod.compfuns comp_modifiers
  1735     val all_modes_of = all_modes_of compilation
  1786     val all_modes_of = all_modes_of compilation
  1736     val (((body, output), T_compr), output_names) =
  1787     val (((body, output), T_compr), output_names) =
  1737       case try dest_special_compr t_compr of SOME r => r | NONE => dest_general_compr ctxt t_compr
  1788       (case try dest_special_compr t_compr of
       
  1789         SOME r => r
       
  1790       | NONE => dest_general_compr ctxt t_compr)
  1738     val (Const (name, _), all_args) =
  1791     val (Const (name, _), all_args) =
  1739       case strip_comb body of
  1792       (case strip_comb body of
  1740         (Const (name, T), all_args) => (Const (name, T), all_args)
  1793         (Const (name, T), all_args) => (Const (name, T), all_args)
  1741       | (head, _) => error ("Not a constant: " ^ Syntax.string_of_term ctxt head)
  1794       | (head, _) => error ("Not a constant: " ^ Syntax.string_of_term ctxt head))
  1742   in
  1795   in
  1743     if defined_functions compilation ctxt name then
  1796     if defined_functions compilation ctxt name then
  1744       let
  1797       let
  1745         fun extract_mode (Const (@{const_name Pair}, _) $ t1 $ t2) = Pair (extract_mode t1, extract_mode t2)
  1798         fun extract_mode (Const (@{const_name Pair}, _) $ t1 $ t2) =
  1746           | extract_mode (Free (x, _)) = if member (op =) output_names x then Output else Input
  1799               Pair (extract_mode t1, extract_mode t2)
       
  1800           | extract_mode (Free (x, _)) =
       
  1801               if member (op =) output_names x then Output else Input
  1747           | extract_mode _ = Input
  1802           | extract_mode _ = Input
  1748         val user_mode = fold_rev (curry Fun) (map extract_mode all_args) Bool
  1803         val user_mode = fold_rev (curry Fun) (map extract_mode all_args) Bool
  1749         fun valid modes1 modes2 =
  1804         fun valid modes1 modes2 =
  1750           case int_ord (length modes1, length modes2) of
  1805           (case int_ord (length modes1, length modes2) of
  1751             GREATER => error "Not enough mode annotations"
  1806             GREATER => error "Not enough mode annotations"
  1752           | LESS => error "Too many mode annotations"
  1807           | LESS => error "Too many mode annotations"
  1753           | EQUAL => forall (fn (_, NONE) => true | (m, SOME m2) => eq_mode (m, m2))
  1808           | EQUAL =>
  1754             (modes1 ~~ modes2)
  1809               forall (fn (_, NONE) => true | (m, SOME m2) => eq_mode (m, m2)) (modes1 ~~ modes2))
  1755         fun mode_instance_of (m1, m2) =
  1810         fun mode_instance_of (m1, m2) =
  1756           let
  1811           let
  1757             fun instance_of (Fun _, Input) = true
  1812             fun instance_of (Fun _, Input) = true
  1758               | instance_of (Input, Input) = true
  1813               | instance_of (Input, Input) = true
  1759               | instance_of (Output, Output) = true
  1814               | instance_of (Output, Output) = true
  1777               null missing_vars andalso
  1832               null missing_vars andalso
  1778               mode_instance_of (p_mode, user_mode) andalso
  1833               mode_instance_of (p_mode, user_mode) andalso
  1779               the_default true (Option.map (valid modes) param_user_modes)
  1834               the_default true (Option.map (valid modes) param_user_modes)
  1780             end)
  1835             end)
  1781           |> map fst
  1836           |> map fst
  1782         val deriv = case derivs of
  1837         val deriv =
  1783             [] => error ("No mode possible for comprehension "
  1838           (case derivs of
  1784                     ^ Syntax.string_of_term ctxt t_compr)
  1839             [] =>
       
  1840               error ("No mode possible for comprehension " ^ Syntax.string_of_term ctxt t_compr)
  1785           | [d] => d
  1841           | [d] => d
  1786           | d :: _ :: _ => (warning ("Multiple modes possible for comprehension "
  1842           | d :: _ :: _ =>
  1787                     ^ Syntax.string_of_term ctxt t_compr); d);
  1843               (warning ("Multiple modes possible for comprehension " ^
       
  1844                 Syntax.string_of_term ctxt t_compr); d))
  1788         val (_, outargs) = split_mode (head_mode_of deriv) all_args
  1845         val (_, outargs) = split_mode (head_mode_of deriv) all_args
  1789         val t_pred = compile_expr comp_modifiers ctxt
  1846         val t_pred = compile_expr comp_modifiers ctxt
  1790           (body, deriv) [] additional_arguments;
  1847           (body, deriv) [] additional_arguments;
  1791         val T_pred = dest_monadT compfuns (fastype_of t_pred)
  1848         val T_pred = dest_monadT compfuns (fastype_of t_pred)
  1792         val arrange = HOLogic.tupled_lambda (HOLogic.mk_tuple outargs) output
  1849         val arrange = HOLogic.tupled_lambda (HOLogic.mk_tuple outargs) output
  1804         fun count' i [] = i
  1861         fun count' i [] = i
  1805           | count' i (x' :: xs) = if x = x' then count' (i + 1) xs else count' i xs
  1862           | count' i (x' :: xs) = if x = x' then count' (i + 1) xs else count' i xs
  1806       in count' 0 xs end
  1863       in count' 0 xs end
  1807     fun accumulate xs = (map (fn x => (x, count xs x)) o sort int_ord o distinct (op =)) xs;
  1864     fun accumulate xs = (map (fn x => (x, count xs x)) o sort int_ord o distinct (op =)) xs;
  1808     val comp_modifiers =
  1865     val comp_modifiers =
  1809       case compilation of
  1866       (case compilation of
  1810           Pred => predicate_comp_modifiers
  1867         Pred => predicate_comp_modifiers
  1811         | Random => random_comp_modifiers
  1868       | Random => random_comp_modifiers
  1812         | Depth_Limited => depth_limited_comp_modifiers
  1869       | Depth_Limited => depth_limited_comp_modifiers
  1813         | Depth_Limited_Random => depth_limited_random_comp_modifiers
  1870       | Depth_Limited_Random => depth_limited_random_comp_modifiers
  1814         (*| Annotated => annotated_comp_modifiers*)
  1871       (*| Annotated => annotated_comp_modifiers*)
  1815         | DSeq => dseq_comp_modifiers
  1872       | DSeq => dseq_comp_modifiers
  1816         | Pos_Random_DSeq => pos_random_dseq_comp_modifiers
  1873       | Pos_Random_DSeq => pos_random_dseq_comp_modifiers
  1817         | New_Pos_Random_DSeq => new_pos_random_dseq_comp_modifiers
  1874       | New_Pos_Random_DSeq => new_pos_random_dseq_comp_modifiers
  1818         | Pos_Generator_DSeq => pos_generator_dseq_comp_modifiers
  1875       | Pos_Generator_DSeq => pos_generator_dseq_comp_modifiers)
  1819     val compfuns = Comp_Mod.compfuns comp_modifiers
  1876     val compfuns = Comp_Mod.compfuns comp_modifiers
  1820     val additional_arguments =
  1877     val additional_arguments =
  1821       case compilation of
  1878       (case compilation of
  1822         Pred => []
  1879         Pred => []
  1823       | Random => map (HOLogic.mk_number @{typ "natural"}) arguments @
  1880       | Random =>
  1824         [@{term "(1, 1) :: natural * natural"}]
  1881           map (HOLogic.mk_number @{typ "natural"}) arguments @
       
  1882             [@{term "(1, 1) :: natural * natural"}]
  1825       | Annotated => []
  1883       | Annotated => []
  1826       | Depth_Limited => [HOLogic.mk_number @{typ "natural"} (hd arguments)]
  1884       | Depth_Limited => [HOLogic.mk_number @{typ "natural"} (hd arguments)]
  1827       | Depth_Limited_Random => map (HOLogic.mk_number @{typ "natural"}) arguments @
  1885       | Depth_Limited_Random =>
  1828         [@{term "(1, 1) :: natural * natural"}]
  1886           map (HOLogic.mk_number @{typ "natural"}) arguments @
       
  1887             [@{term "(1, 1) :: natural * natural"}]
  1829       | DSeq => []
  1888       | DSeq => []
  1830       | Pos_Random_DSeq => []
  1889       | Pos_Random_DSeq => []
  1831       | New_Pos_Random_DSeq => []
  1890       | New_Pos_Random_DSeq => []
  1832       | Pos_Generator_DSeq => []
  1891       | Pos_Generator_DSeq => [])
  1833     val t = analyze_compr ctxt (comp_modifiers, additional_arguments) param_user_modes options t_compr;
  1892     val t =
  1834     val T = dest_monadT compfuns (fastype_of t);
  1893       analyze_compr ctxt (comp_modifiers, additional_arguments) param_user_modes options t_compr
       
  1894     val T = dest_monadT compfuns (fastype_of t)
  1835     val t' =
  1895     val t' =
  1836       if stats andalso compilation = New_Pos_Random_DSeq then
  1896       if stats andalso compilation = New_Pos_Random_DSeq then
  1837         mk_map compfuns T (HOLogic.mk_prodT (HOLogic.termT, @{typ natural}))
  1897         mk_map compfuns T (HOLogic.mk_prodT (HOLogic.termT, @{typ natural}))
  1838           (absdummy T (HOLogic.mk_prod (HOLogic.term_of_const T $ Bound 0,
  1898           (absdummy T (HOLogic.mk_prod (HOLogic.term_of_const T $ Bound 0,
  1839             @{term natural_of_nat} $ (HOLogic.size_const T $ Bound 0)))) t
  1899             @{term natural_of_nat} $ (HOLogic.size_const T $ Bound 0)))) t
  1889                     t' [] nrandom size seed depth))) ()))
  1949                     t' [] nrandom size seed depth))) ()))
  1890             else rpair NONE
  1950             else rpair NONE
  1891               (TimeLimit.timeLimit time_limit (fn () => fst (Lazy_Sequence.yieldn k
  1951               (TimeLimit.timeLimit time_limit (fn () => fst (Lazy_Sequence.yieldn k
  1892                 (Code_Runtime.dynamic_value_strict
  1952                 (Code_Runtime.dynamic_value_strict
  1893                   (Lseq_Random_Result.get, put_lseq_random_result, "Predicate_Compile_Core.put_lseq_random_result")
  1953                   (Lseq_Random_Result.get, put_lseq_random_result, "Predicate_Compile_Core.put_lseq_random_result")
  1894                   thy NONE 
  1954                   thy NONE
  1895                   (fn proc => fn g => fn nrandom => fn size => fn s => fn depth => g nrandom size s depth
  1955                   (fn proc => fn g => fn nrandom => fn size => fn s => fn depth => g nrandom size s depth
  1896                     |> Lazy_Sequence.map proc)
  1956                     |> Lazy_Sequence.map proc)
  1897                     t' [] nrandom size seed depth))) ())
  1957                     t' [] nrandom size seed depth))) ())
  1898           end
  1958           end
  1899       | _ =>
  1959       | _ =>
  1907   let
  1967   let
  1908     val ((T, ts), statistics) = eval ctxt stats param_user_modes comp_options k t_compr
  1968     val ((T, ts), statistics) = eval ctxt stats param_user_modes comp_options k t_compr
  1909     val setT = HOLogic.mk_setT T
  1969     val setT = HOLogic.mk_setT T
  1910     val elems = HOLogic.mk_set T ts
  1970     val elems = HOLogic.mk_set T ts
  1911     val ([dots], ctxt') =
  1971     val ([dots], ctxt') =
  1912       Proof_Context.add_fixes [(@{binding dots}, SOME setT, Mixfix ("...", [], 1000))] ctxt 
  1972       Proof_Context.add_fixes [(@{binding dots}, SOME setT, Mixfix ("...", [], 1000))] ctxt
  1913     (* check expected values *)
  1973     (* check expected values *)
  1914     val union = Const (@{const_abbrev Set.union}, setT --> setT --> setT)
  1974     val union = Const (@{const_abbrev Set.union}, setT --> setT --> setT)
  1915     val () =
  1975     val () =
  1916       case raw_expected of
  1976       (case raw_expected of
  1917         NONE => ()
  1977         NONE => ()
  1918       | SOME s =>
  1978       | SOME s =>
  1919         if eq_set (op =) (HOLogic.dest_set (Syntax.read_term ctxt s), ts) then ()
  1979         if eq_set (op =) (HOLogic.dest_set (Syntax.read_term ctxt s), ts) then ()
  1920         else
  1980         else
  1921           error ("expected and computed values do not match:\n" ^
  1981           error ("expected and computed values do not match:\n" ^
  1922             "expected values: " ^ Syntax.string_of_term ctxt (Syntax.read_term ctxt s) ^ "\n" ^
  1982             "expected values: " ^ Syntax.string_of_term ctxt (Syntax.read_term ctxt s) ^ "\n" ^
  1923             "computed values: " ^ Syntax.string_of_term ctxt elems ^ "\n")
  1983             "computed values: " ^ Syntax.string_of_term ctxt elems ^ "\n"))
  1924   in
  1984   in
  1925     ((if k = ~1 orelse length ts < k then elems else union $ elems $ Free (dots, setT), statistics), ctxt')
  1985     ((if k = ~1 orelse length ts < k then elems else union $ elems $ Free (dots, setT), statistics),
       
  1986       ctxt')
  1926   end;
  1987   end;
  1927 
  1988 
  1928 fun values_cmd print_modes param_user_modes options k raw_t state =
  1989 fun values_cmd print_modes param_user_modes options k raw_t state =
  1929   let
  1990   let
  1930     val ctxt = Toplevel.context_of state
  1991     val ctxt = Toplevel.context_of state
  1931     val t = Syntax.read_term ctxt raw_t
  1992     val t = Syntax.read_term ctxt raw_t
  1932     val ((t', stats), ctxt') = values param_user_modes options k t ctxt
  1993     val ((t', stats), ctxt') = values param_user_modes options k t ctxt
  1933     val ty' = Term.type_of t'
  1994     val ty' = Term.type_of t'
  1934     val ctxt'' = Variable.auto_fixes t' ctxt'
  1995     val ctxt'' = Variable.auto_fixes t' ctxt'
  1935     val pretty_stat =
  1996     val pretty_stat =
  1936       case stats of
  1997       (case stats of
  1937           NONE => []
  1998         NONE => []
  1938         | SOME xs =>
  1999       | SOME xs =>
  1939           let
  2000           let
  1940             val total = fold (curry (op +)) (map snd xs) 0
  2001             val total = fold (curry (op +)) (map snd xs) 0
  1941             fun pretty_entry (s, n) =
  2002             fun pretty_entry (s, n) =
  1942               [Pretty.str "size", Pretty.brk 1,
  2003               [Pretty.str "size", Pretty.brk 1,
  1943                Pretty.str (string_of_int s), Pretty.str ":", Pretty.brk 1,
  2004                Pretty.str (string_of_int s), Pretty.str ":", Pretty.brk 1,
  1944                Pretty.str (string_of_int n), Pretty.fbrk]
  2005                Pretty.str (string_of_int n), Pretty.fbrk]
  1945           in
  2006           in
  1946             [Pretty.fbrk, Pretty.str "Statistics:", Pretty.fbrk,
  2007             [Pretty.fbrk, Pretty.str "Statistics:", Pretty.fbrk,
  1947              Pretty.str "total:", Pretty.brk 1, Pretty.str (string_of_int total), Pretty.fbrk]
  2008              Pretty.str "total:", Pretty.brk 1, Pretty.str (string_of_int total), Pretty.fbrk] @
  1948              @ maps pretty_entry xs
  2009               maps pretty_entry xs
  1949           end
  2010           end)
  1950     val p = Print_Mode.with_modes print_modes (fn () =>
  2011   in
       
  2012     Print_Mode.with_modes print_modes (fn () =>
  1951       Pretty.block ([Pretty.quote (Syntax.pretty_term ctxt'' t'), Pretty.fbrk,
  2013       Pretty.block ([Pretty.quote (Syntax.pretty_term ctxt'' t'), Pretty.fbrk,
  1952         Pretty.str "::", Pretty.brk 1, Pretty.quote (Syntax.pretty_typ ctxt'' ty')]
  2014         Pretty.str "::", Pretty.brk 1, Pretty.quote (Syntax.pretty_typ ctxt'' ty')]
  1953         @ pretty_stat)) ();
  2015         @ pretty_stat)) ()
  1954   in Pretty.writeln p end;
  2016   end |> Pretty.writeln
  1955 
  2017 
  1956 end;
  2018 end