splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
authorbulwahn
Mon, 22 Nov 2010 11:34:54 +0100
changeset 408961598ec648b0d
parent 40895 6e92ca8e981b
child 40897 dc1b5aa908ff
splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
src/Tools/quickcheck.ML
     1.1 --- a/src/Tools/quickcheck.ML	Mon Nov 22 11:34:53 2010 +0100
     1.2 +++ b/src/Tools/quickcheck.ML	Mon Nov 22 11:34:54 2010 +0100
     1.3 @@ -16,6 +16,8 @@
     1.4    val report : bool Config.T
     1.5    val quiet : bool Config.T
     1.6    val timeout : real Config.T
     1.7 +  val finite_types : bool Config.T
     1.8 +  val finite_type_size : int Config.T
     1.9    datatype report = Report of
    1.10      { iterations : int, raised_match_errors : int,
    1.11        satisfied_assms : int list, positive_concl_tests : int }
    1.12 @@ -32,6 +34,9 @@
    1.13      (string * term) list option * ((string * int) list * ((int * report list) list) option)
    1.14    val test_term: Proof.context -> string option -> term ->
    1.15      (string * term) list option * ((string * int) list * ((int * report list) list) option)
    1.16 +  val test_goal_terms:
    1.17 +    Proof.context -> string option * (string * typ) list -> term list
    1.18 +      -> (string * term) list option * ((string * int) list * ((int * report list) list) option) list
    1.19    val quickcheck: (string * string list) list -> int -> Proof.state -> (string * term) list option
    1.20  end;
    1.21  
    1.22 @@ -199,6 +204,10 @@
    1.23       apsnd (rpair NONE) (apfst (Option.map (curry (op ~~) names)) result)
    1.24     end
    1.25  
    1.26 +(* we actually assume we know the generators and its behaviour *)
    1.27 +fun is_iteratable "small" = false
    1.28 +  | is_iteratable "random" = true
    1.29 +  
    1.30  fun test_term ctxt generator_name t =
    1.31    let
    1.32      val (names, t') = prep_test_term t;
    1.33 @@ -223,15 +232,24 @@
    1.34        satisfied_assms = [], positive_concl_tests = 0 }
    1.35      fun with_testers k [] = (NONE, [])
    1.36        | with_testers k (tester :: testers) =
    1.37 -          case iterate (fn () => tester (k - 1)) (Config.get ctxt iterations) empty_report
    1.38 +        let
    1.39 +          val niterations = case generator_name of
    1.40 +            SOME generator_name =>
    1.41 +              if is_iteratable generator_name then Config.get ctxt iterations else 1
    1.42 +          | NONE => Config.get ctxt iterations
    1.43 +          val (result, timing) = cpu_time ("size " ^ string_of_int k)
    1.44 +            (fn () => iterate (fn () => tester (k - 1)) niterations empty_report)
    1.45 +        in
    1.46 +          case result
    1.47             of (NONE, report) => apsnd (cons report) (with_testers k testers)
    1.48 -            | (SOME q, report) => (SOME q, [report]);
    1.49 +            | (SOME q, report) => (SOME q, [report])
    1.50 +        end
    1.51      fun with_size k reports =
    1.52        if k > Config.get ctxt size then (NONE, reports)
    1.53        else
    1.54         (if Config.get ctxt quiet then () else Output.urgent_message ("Test data size: " ^ string_of_int k);
    1.55          let
    1.56 -          val _ = current_size := k  
    1.57 +          val _ = current_size := k
    1.58            val (result, new_report) = with_testers k testers
    1.59            val reports = ((k, new_report) :: reports)
    1.60          in case result of NONE => with_size (k + 1) reports | SOME q => (SOME q, reports) end);
    1.61 @@ -272,26 +290,9 @@
    1.62  
    1.63  datatype wellsorted_error = Wellsorted_Error of string | Term of term
    1.64  
    1.65 -fun test_goal (generator_name, insts) i state =
    1.66 +fun test_goal_terms lthy (generator_name, insts) check_goals =
    1.67    let
    1.68 -    val lthy = Proof.context_of state;
    1.69 -    val thy = Proof.theory_of state;
    1.70 -    fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t
    1.71 -      | strip t = t;
    1.72 -    val {goal = st, ...} = Proof.raw_goal state;
    1.73 -    val (gi, frees) = Logic.goal_params (prop_of st) i;
    1.74 -    val some_locale = case (Option.map #target o Named_Target.peek) lthy
    1.75 -     of NONE => NONE
    1.76 -      | SOME "" => NONE
    1.77 -      | SOME locale => SOME locale;
    1.78 -    val assms = if Config.get lthy no_assms then [] else case some_locale
    1.79 -     of NONE => Assumption.all_assms_of lthy
    1.80 -      | SOME locale => Assumption.local_assms_of lthy (Locale.init locale thy);
    1.81 -    val proto_goal = Logic.list_implies (map Thm.term_of assms, subst_bounds (frees, strip gi));
    1.82 -    val check_goals = case some_locale
    1.83 -     of NONE => [proto_goal]
    1.84 -      | SOME locale => map (fn (_, phi) => Morphism.term phi proto_goal)
    1.85 -        (Locale.registrations_of (Context.Theory thy) (*FIXME*) locale);
    1.86 +    val thy = ProofContext.theory_of lthy 
    1.87      val inst_goals =
    1.88        if Config.get lthy finite_types then 
    1.89          maps (fn check_goal => map (fn T =>
    1.90 @@ -314,6 +315,30 @@
    1.91          | (NONE, report) => collect_results f (report :: reports) ts
    1.92    in collect_results (test_term lthy generator_name) [] correct_inst_goals end;
    1.93  
    1.94 +fun test_goal (generator_name, insts) i state =
    1.95 +  let
    1.96 +    val lthy = Proof.context_of state;
    1.97 +    val thy = Proof.theory_of state;
    1.98 +    fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t
    1.99 +      | strip t = t;
   1.100 +    val {goal = st, ...} = Proof.raw_goal state;
   1.101 +    val (gi, frees) = Logic.goal_params (prop_of st) i;
   1.102 +    val some_locale = case (Option.map #target o Named_Target.peek) lthy
   1.103 +     of NONE => NONE
   1.104 +      | SOME "" => NONE
   1.105 +      | SOME locale => SOME locale;
   1.106 +    val assms = if Config.get lthy no_assms then [] else case some_locale
   1.107 +     of NONE => Assumption.all_assms_of lthy
   1.108 +      | SOME locale => Assumption.local_assms_of lthy (Locale.init locale thy);
   1.109 +    val proto_goal = Logic.list_implies (map Thm.term_of assms, subst_bounds (frees, strip gi));
   1.110 +    val check_goals = case some_locale
   1.111 +     of NONE => [proto_goal]
   1.112 +      | SOME locale => map (fn (_, phi) => Morphism.term phi proto_goal)
   1.113 +        (Locale.registrations_of (Context.Theory thy) (*FIXME*) locale);
   1.114 +  in
   1.115 +    test_goal_terms lthy (generator_name, insts) check_goals
   1.116 +  end
   1.117 +
   1.118  (* pretty printing *)
   1.119  
   1.120  fun tool_name auto = (if auto then "Auto " else "") ^ "Quickcheck"