src/Tools/quickcheck.ML
changeset 37912 247042107f93
parent 37911 8f99e3880864
child 37913 e85f5ad02a8f
equal deleted inserted replaced
37911:8f99e3880864 37912:247042107f93
   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