src/HOL/Spec_Check/spec_check.ML
changeset 52254 994055f7db80
parent 52253 afca6a99a361
child 52256 24f59223430d
equal deleted inserted replaced
52253:afca6a99a361 52254:994055f7db80
    13   val sort_examples : bool Config.T
    13   val sort_examples : bool Config.T
    14   val show_stats : bool Config.T
    14   val show_stats : bool Config.T
    15   val column_width : int Config.T
    15   val column_width : int Config.T
    16   val style : string Config.T
    16   val style : string Config.T
    17 
    17 
    18   type output_style = Context.generic -> string ->
    18   type output_style = Proof.context -> string ->
    19     {status : string option * Property.result * (Property.stats  * string option list) -> unit,
    19     {status : string option * Property.result * (Property.stats  * string option list) -> unit,
    20      finish: Property.stats * string option list -> unit}
    20      finish: Property.stats * string option list -> unit}
    21 
    21 
    22   val register_style : (string * output_style) -> theory -> theory
    22   val register_style : (string * output_style) -> theory -> theory
    23 
    23 
    24   val checkGen : Context.generic ->
    24   val checkGen : Proof.context ->
    25     'a Generator.gen * ('a -> string) option -> string * 'a Property.prop -> unit
    25     'a Generator.gen * ('a -> string) option -> string * 'a Property.prop -> unit
    26 
    26 
    27   val check_property : Proof.context -> string -> unit
    27   val check_property : Proof.context -> string -> unit
    28 end;
    28 end;
    29 
    29 
    44 open Property
    44 open Property
    45 
    45 
    46 type ('a, 'b) reader = 'b -> ('a * 'b) option
    46 type ('a, 'b) reader = 'b -> ('a * 'b) option
    47 type 'a rep = ('a -> string) option
    47 type 'a rep = ('a -> string) option
    48 
    48 
    49 type output_style = Context.generic -> string ->
    49 type output_style = Proof.context -> string ->
    50   {status: string option * Property.result * (Property.stats * string option list) -> unit,
    50   {status: string option * Property.result * (Property.stats * string option list) -> unit,
    51    finish: Property.stats * string option list -> unit}
    51    finish: Property.stats * string option list -> unit}
    52 
    52 
    53 fun limit context gen = Generator.limit (Config.get_generic context gen_max) gen
    53 fun limit ctxt gen = Generator.limit (Config.get ctxt gen_max) gen
    54 
    54 
    55 structure Style = Theory_Data
    55 structure Style = Theory_Data
    56 (
    56 (
    57   type T = output_style Symtab.table
    57   type T = output_style Symtab.table
    58   val empty = Symtab.empty
    58   val empty = Symtab.empty
    59   val extend = I
    59   val extend = I
    60   fun merge data : T = Symtab.merge (K true) data
    60   fun merge data : T = Symtab.merge (K true) data
    61 )
    61 )
    62 
    62 
    63 fun get_style context =
    63 fun get_style ctxt =
    64   let val name = Config.get_generic context style
    64   let val name = Config.get ctxt style in
    65   in case Symtab.lookup (Style.get (Context.theory_of context)) name of
    65     (case Symtab.lookup (Style.get (Proof_Context.theory_of ctxt)) name of
    66       SOME style => style context
    66       SOME style => style ctxt
    67     | NONE => error ("No style called " ^ quote name ^ " found")
    67     | NONE => error ("No style called " ^ quote name ^ " found"))
    68   end
    68   end
    69 
    69 
    70 fun register_style (name, style) = Style.map (Symtab.update (name, style))
    70 fun register_style (name, style) = Style.map (Symtab.update (name, style))
    71 
    71 
    72 
    72 
    73 (* testing functions *)
    73 (* testing functions *)
    74 
    74 
    75 fun cpsCheck context s0 shrink (next, show) (tag, prop) =
    75 fun cpsCheck ctxt s0 shrink (next, show) (tag, prop) =
    76   let
    76   let
    77     val apply_show = case show of NONE => (fn _ => NONE) | SOME f => SOME o f
    77     val apply_show = case show of NONE => (fn _ => NONE) | SOME f => SOME o f
    78 
    78 
    79     val {status, finish} = get_style context tag
    79     val {status, finish} = get_style ctxt tag
    80     fun status' (obj, result, (stats, badobjs)) =
    80     fun status' (obj, result, (stats, badobjs)) =
    81       let
    81       let
    82         val badobjs' = if Property.failure result then obj :: badobjs else badobjs
    82         val badobjs' = if Property.failure result then obj :: badobjs else badobjs
    83         val _ = status (apply_show obj, result, (stats, map apply_show badobjs'))
    83         val _ = status (apply_show obj, result, (stats, map apply_show badobjs'))
    84       in badobjs' end
    84       in badobjs' end
    94         | NONE => status' (obj, result, (stats', badobjs))
    94         | NONE => status' (obj, result, (stats', badobjs))
    95       end
    95       end
    96 
    96 
    97     fun iter (NONE, (stats, badobjs)) = finish (stats, map apply_show badobjs)
    97     fun iter (NONE, (stats, badobjs)) = finish (stats, map apply_show badobjs)
    98       | iter (SOME (obj, stream), (stats, badobjs)) =
    98       | iter (SOME (obj, stream), (stats, badobjs)) =
    99         if #count stats >= Config.get_generic context gen_target then
    99         if #count stats >= Config.get ctxt gen_target then
   100           finish (stats, map apply_show badobjs)
   100           finish (stats, map apply_show badobjs)
   101         else
   101         else
   102           let
   102           let
   103             val (result, stats') = Property.test prop (obj, stats)
   103             val (result, stats') = Property.test prop (obj, stats)
   104             val badobjs' = if Property.failure result then
   104             val badobjs' = if Property.failure result then
   108           in iter (next stream, (stats', badobjs')) end
   108           in iter (next stream, (stats', badobjs')) end
   109   in
   109   in
   110     fn stream => iter (next stream, (s0, []))
   110     fn stream => iter (next stream, (s0, []))
   111   end
   111   end
   112 
   112 
   113 fun check' context s0 = cpsCheck context s0 (fn _ => [])
   113 fun check' ctxt s0 = cpsCheck ctxt s0 (fn _ => [])
   114 fun check context = check' context Property.stats
   114 fun check ctxt = check' ctxt Property.stats
   115 fun checks context = cpsCheck context Property.stats
   115 fun checks ctxt = cpsCheck ctxt Property.stats
   116 
   116 
   117 fun checkGen context (gen, show) (tag, prop) =
   117 fun checkGen ctxt (gen, show) (tag, prop) =
   118   check' context {count=0, tags=[("__GEN", 0)]} (limit context gen, show) (tag, prop) Generator.stream
   118   check' ctxt {count = 0, tags = [("__GEN", 0)]}
       
   119     (limit ctxt gen, show) (tag, prop) Generator.stream
   119 
   120 
   120 fun checkGenShrink context shrink (gen, show) (tag, prop) =
   121 fun checkGenShrink ctxt shrink (gen, show) (tag, prop) =
   121   cpsCheck context {count=0, tags=[("__GEN", 0)]} shrink
   122   cpsCheck ctxt {count=0, tags=[("__GEN", 0)]} shrink
   122     (limit context gen, show) (tag, prop) Generator.stream
   123     (limit ctxt gen, show) (tag, prop) Generator.stream
   123 
   124 
   124 fun checkOne context show (tag, prop) obj =
   125 fun checkOne ctxt show (tag, prop) obj =
   125   check context (List.getItem, show) (tag, prop) [obj]
   126   check ctxt (List.getItem, show) (tag, prop) [obj]
   126 
   127 
   127 (*call the compiler and pass resulting type string to the parser*)
   128 (*call the compiler and pass resulting type string to the parser*)
   128 fun determine_type ctxt s =
   129 fun determine_type ctxt s =
   129   let
   130   let
   130     val ret = Unsynchronized.ref "return"
   131     val ret = Unsynchronized.ref "return"
   154 fun input_split s =
   155 fun input_split s =
   155   let
   156   let
   156     fun dot c = c = #"."
   157     fun dot c = c = #"."
   157     fun space c = c = #" "
   158     fun space c = c = #" "
   158     val (head, code) = Substring.splitl (not o dot) (Substring.full s)
   159     val (head, code) = Substring.splitl (not o dot) (Substring.full s)
   159   in (String.tokens space (Substring.string head),
   160   in
       
   161    (String.tokens space (Substring.string head),
   160     Substring.string (Substring.dropl dot code))
   162     Substring.string (Substring.dropl dot code))
   161   end;
   163   end;
   162 
   164 
   163 (*create the function from the input*)
   165 (*create the function from the input*)
   164 fun make_fun s =
   166 fun make_fun s =
   174 (*read input and perform the test*)
   176 (*read input and perform the test*)
   175 fun gen_check_property check ctxt s =
   177 fun gen_check_property check ctxt s =
   176   let
   178   let
   177     val func = make_fun s
   179     val func = make_fun s
   178     val (_, ty) = determine_type ctxt func
   180     val (_, ty) = determine_type ctxt func
   179   in run_test ctxt (check (Proof_Context.theory_of ctxt) "Check" (ty, func)) end;
   181   in run_test ctxt (check ctxt "Check" (ty, func)) end;
   180 
   182 
   181 val check_property = gen_check_property Gen_Construction.build_check
   183 val check_property = gen_check_property Gen_Construction.build_check
   182 (*val check_property_safe = gen_check_property Gen_Construction.safe_check*)
   184 (*val check_property_safe = gen_check_property Gen_Construction.safe_check*)
   183 
   185 
   184 (*perform test for specification function*)
   186 (*perform test for specification function*)
   185 fun gen_check_property_f check ctxt s =
   187 fun gen_check_property_f check ctxt s =
   186   let
   188   let
   187     val (name, ty) = determine_type ctxt s
   189     val (name, ty) = determine_type ctxt s
   188   in run_test ctxt (check (Proof_Context.theory_of ctxt) name (ty, s)) end;
   190   in run_test ctxt (check ctxt name (ty, s)) end;
   189 
   191 
   190 val check_property_f = gen_check_property_f Gen_Construction.build_check
   192 val check_property_f = gen_check_property_f Gen_Construction.build_check
   191 (*val check_property_safe_f_ = gen_check_property_f Gen_Construction.safe_check*)
   193 (*val check_property_safe_f_ = gen_check_property_f Gen_Construction.safe_check*)
   192 
   194 
   193 end;
   195 end;