183 fun monomorphic_term thy insts default_T = |
183 fun monomorphic_term thy insts default_T = |
184 let |
184 let |
185 fun subst (T as TFree (v, S)) = |
185 fun subst (T as TFree (v, S)) = |
186 let |
186 let |
187 val T' = AList.lookup (op =) insts v |
187 val T' = AList.lookup (op =) insts v |
188 |> the_default (the_default T default_T) |
188 |> the_default default_T |
189 in if Sign.of_sort thy (T, S) then T' |
189 in if Sign.of_sort thy (T, S) then T' |
190 else error ("Type " ^ Syntax.string_of_typ_global thy T ^ |
190 else error ("Type " ^ Syntax.string_of_typ_global thy T ^ |
191 " to be substituted for variable " ^ |
191 " to be substituted for variable " ^ |
192 Syntax.string_of_typ_global thy T ^ "\ndoes not have sort " ^ |
192 Syntax.string_of_typ_global thy T ^ "\ndoes not have sort " ^ |
193 Syntax.string_of_sort_global thy S) |
193 Syntax.string_of_sort_global thy S) |
201 val thy = Proof.theory_of state; |
201 val thy = Proof.theory_of state; |
202 fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t |
202 fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t |
203 | strip t = t; |
203 | strip t = t; |
204 val {goal = st, ...} = Proof.raw_goal state; |
204 val {goal = st, ...} = Proof.raw_goal state; |
205 val (gi, frees) = Logic.goal_params (prop_of st) i; |
205 val (gi, frees) = Logic.goal_params (prop_of st) i; |
206 val default_T' = |
206 val gis' = Logic.list_implies (if no_assms then [] else assms, |
207 case default_T of |
|
208 [] => NONE |
|
209 | [T] => SOME T |
|
210 | _ => error "Multiple default types not yet supported" |
|
211 val gi' = Logic.list_implies (if no_assms then [] else assms, |
|
212 subst_bounds (frees, strip gi)) |
207 subst_bounds (frees, strip gi)) |
213 |> monomorphic_term thy insts default_T' |
208 |> (fn t => map (fn T => monomorphic_term thy insts T t) default_T) |
214 |> Object_Logic.atomize_term thy; |
209 |> map (Object_Logic.atomize_term thy); |
215 in gen_test_term ctxt quiet report generator_name size iterations gi' end; |
210 fun collect_results f reports [] = (NONE, rev reports) |
|
211 | collect_results f reports (t :: ts) = |
|
212 case f t of |
|
213 (SOME res, report) => (SOME res, rev (report :: reports)) |
|
214 | (NONE, report) => collect_results f (report :: reports) ts |
|
215 in (collect_results (gen_test_term ctxt quiet report generator_name size iterations) [] gis') end; |
|
216 |
|
217 (* pretty printing *) |
216 |
218 |
217 fun pretty_counterex ctxt NONE = Pretty.str "Quickcheck found no counterexample." |
219 fun pretty_counterex ctxt NONE = Pretty.str "Quickcheck found no counterexample." |
218 | pretty_counterex ctxt (SOME cex) = |
220 | pretty_counterex ctxt (SOME cex) = |
219 Pretty.chunks (Pretty.str "Quickcheck found a counterexample:\n" :: |
221 Pretty.chunks (Pretty.str "Quickcheck found a counterexample:\n" :: |
220 map (fn (s, t) => |
222 map (fn (s, t) => |
243 maps (fn (size, reports) => |
245 maps (fn (size, reports) => |
244 Pretty.str ("size " ^ string_of_int size ^ ":") :: pretty_reports' reports @ [Pretty.brk 1]) |
246 Pretty.str ("size " ^ string_of_int size ^ ":") :: pretty_reports' reports @ [Pretty.brk 1]) |
245 (rev reports)) |
247 (rev reports)) |
246 | pretty_reports ctxt NONE = Pretty.str "" |
248 | pretty_reports ctxt NONE = Pretty.str "" |
247 |
249 |
248 fun pretty_counterex_and_reports ctxt (cex, (timing, reports)) = |
250 fun pretty_counterex_and_reports ctxt (cex, timing_and_reports) = |
249 Pretty.chunks [pretty_counterex ctxt cex, pretty_reports ctxt reports] |
251 Pretty.chunks (pretty_counterex ctxt cex :: map (pretty_reports ctxt) (map snd timing_and_reports)) |
250 |
252 |
251 (* automatic testing *) |
253 (* automatic testing *) |
252 |
254 |
253 fun auto_quickcheck state = |
255 fun auto_quickcheck state = |
254 if not (!auto) then |
256 if not (!auto) then |