src/Tools/quickcheck.ML
author bulwahn
Wed, 30 Mar 2011 09:44:16 +0200
changeset 42159 234ec7011e5d
parent 42089 904897d0c5bd
child 42162 00899500c6ca
permissions -rw-r--r--
generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30824
bc6b24882834 fixed header;
wenzelm
parents: 30473
diff changeset
     1
(*  Title:      Tools/quickcheck.ML
40246
c03fc7d3fa97 changed global fixed timeout to a configurable timeout for quickcheck; test parameters in quickcheck are now fully passed around with the context
bulwahn
parents: 40225
diff changeset
     2
    Author:     Stefan Berghofer, Florian Haftmann, Lukas Bulwahn, TU Muenchen
28256
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
     3
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
     4
Generic counterexample search engine.
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
     5
*)
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
     6
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
     7
signature QUICKCHECK =
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
     8
sig
37910
555287ba8d8d reordering quickcheck signature; exporting test_params and inspection function
bulwahn
parents: 37909
diff changeset
     9
  val setup: theory -> theory
555287ba8d8d reordering quickcheck signature; exporting test_params and inspection function
bulwahn
parents: 37909
diff changeset
    10
  (* configuration *)
32740
9dd0a2f83429 explicit indication of Unsynchronized.ref;
wenzelm
parents: 32297
diff changeset
    11
  val auto: bool Unsynchronized.ref
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
    12
  val tester : string Config.T
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    13
  val size : int Config.T
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    14
  val iterations : int Config.T
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    15
  val no_assms : bool Config.T
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    16
  val report : bool Config.T
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    17
  val timing : bool Config.T
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    18
  val quiet : bool Config.T
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    19
  val timeout : real Config.T
40648
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
    20
  val finite_types : bool Config.T
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
    21
  val finite_type_size : int Config.T
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
    22
  datatype expectation = No_Expectation | No_Counterexample | Counterexample;
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    23
  datatype test_params = Test_Params of {default_type: typ list, expect : expectation};
40246
c03fc7d3fa97 changed global fixed timeout to a configurable timeout for quickcheck; test parameters in quickcheck are now fully passed around with the context
bulwahn
parents: 40225
diff changeset
    24
  val test_params_of : Proof.context -> test_params
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
    25
  val map_test_params : (typ list * expectation -> typ list * expectation)
40246
c03fc7d3fa97 changed global fixed timeout to a configurable timeout for quickcheck; test parameters in quickcheck are now fully passed around with the context
bulwahn
parents: 40225
diff changeset
    26
    -> Context.generic -> Context.generic
42089
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    27
  datatype report = Report of
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    28
    { iterations : int, raised_match_errors : int,
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    29
      satisfied_assms : int list, positive_concl_tests : int }
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    30
  (* registering generators *)
37910
555287ba8d8d reordering quickcheck signature; exporting test_params and inspection function
bulwahn
parents: 37909
diff changeset
    31
  val add_generator:
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
    32
    string * (Proof.context -> (term * term list) list -> int list -> term list option * report option)
39252
8f176e575a49 changing the container for the quickcheck options to a generic data
bulwahn
parents: 39138
diff changeset
    33
      -> Context.generic -> Context.generic
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
    34
  val add_batch_generator:
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
    35
    string * (Proof.context -> term list -> (int -> term list option) list)
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
    36
      -> Context.generic -> Context.generic
42089
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    37
  (* quickcheck's result *)
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    38
  datatype result =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    39
    Result of
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    40
     {counterexample : (string * term) list option,
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    41
      evaluation_terms : (term * term) list option,
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    42
      timings : (string * int) list,
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    43
      reports : (int * report) list}
42089
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    44
  val counterexample_of : result -> (string * term) list option
904897d0c5bd adapting mutabelle; exporting more Quickcheck functions
bulwahn
parents: 42088
diff changeset
    45
  val timings_of : result -> (string * int) list
37910
555287ba8d8d reordering quickcheck signature; exporting test_params and inspection function
bulwahn
parents: 37909
diff changeset
    46
  (* testing terms and proof states *)
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    47
  val test_term: Proof.context -> bool * bool -> term * term list -> result
40648
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
    48
  val test_goal_terms:
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
    49
    Proof.context -> bool * bool -> (string * typ) list -> (term * term list) list  
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    50
      -> result list
37909
583543ad6ad1 changed default types to a list of types; extended quickcheck parameters to be a list of values to parse a list of default types
bulwahn
parents: 36960
diff changeset
    51
  val quickcheck: (string * string list) list -> int -> Proof.state -> (string * term) list option
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
    52
  (* testing a batch of terms *)
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
    53
  val test_terms: Proof.context -> term list -> (string * term) list option list option
28256
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
    54
end;
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
    55
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
    56
structure Quickcheck : QUICKCHECK =
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
    57
struct
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
    58
30980
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    59
(* preferences *)
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    60
32740
9dd0a2f83429 explicit indication of Unsynchronized.ref;
wenzelm
parents: 32297
diff changeset
    61
val auto = Unsynchronized.ref false;
30980
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    62
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    63
val _ =
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    64
  ProofGeneralPgip.add_preference Preferences.category_tracing
39616
8052101883c3 renamed setmp_noncritical to Unsynchronized.setmp to emphasize its meaning;
wenzelm
parents: 39329
diff changeset
    65
  (Unsynchronized.setmp auto true (fn () =>
30980
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    66
    Preferences.bool_pref auto
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    67
      "auto-quickcheck"
39329
0a85f960ac50 make Auto Solve part of the "Auto Tools"
blanchet
parents: 39324
diff changeset
    68
      "Run Quickcheck automatically.") ());
30980
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
    69
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
    70
(* quickcheck report *)
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
    71
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
    72
datatype report = Report of
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
    73
  { iterations : int, raised_match_errors : int,
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
    74
    satisfied_assms : int list, positive_concl_tests : int }
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
    75
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    76
(* Quickcheck Result *)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    77
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    78
datatype result = Result of
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    79
  { counterexample : (string * term) list option, evaluation_terms : (term * term) list option,
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    80
    timings : (string * int) list, reports : (int * report) list}
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    81
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    82
val empty_result =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    83
  Result {counterexample = NONE, evaluation_terms = NONE, timings = [], reports = []}
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    84
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    85
fun counterexample_of (Result r) = #counterexample r
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    86
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    87
fun found_counterexample (Result r) = is_some (#counterexample r)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    88
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    89
fun response_of (Result r) = case (#counterexample r, #evaluation_terms r) of
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    90
    (SOME ts, SOME evals) => SOME (ts, evals)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    91
  | (NONE, NONE) => NONE
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    92
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    93
fun timings_of (Result r) = #timings r
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    94
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    95
fun set_reponse names eval_terms (SOME ts) (Result r) =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    96
  let
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    97
    val (ts1, ts2) = chop (length names) ts
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    98
  in
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
    99
    Result {counterexample = SOME (names ~~ ts1), evaluation_terms = SOME (eval_terms ~~ ts2),
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   100
      timings = #timings r, reports = #reports r}
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   101
  end
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   102
  | set_reponse _ _ NONE result = result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   103
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   104
fun cons_timing timing (Result r) =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   105
  Result {counterexample = #counterexample r, evaluation_terms = #evaluation_terms r,
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   106
    timings = cons timing (#timings r), reports = #reports r}
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   107
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   108
fun cons_report size (SOME report) (Result r) =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   109
  Result {counterexample = #counterexample r, evaluation_terms = #evaluation_terms r,
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   110
    timings = #timings r, reports = cons (size, report) (#reports r)}
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   111
  | cons_report _ NONE result = result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   112
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   113
fun add_timing timing result_ref = (result_ref := cons_timing timing (!result_ref))
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   114
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   115
fun add_report size report result_ref = (result_ref := cons_report size report (!result_ref))
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   116
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   117
fun add_response names eval_terms response result_ref =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   118
  (result_ref := set_reponse names eval_terms response (!result_ref))
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   119
37929
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   120
(* expectation *)
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   121
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   122
datatype expectation = No_Expectation | No_Counterexample | Counterexample;
37929
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   123
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   124
fun merge_expectation (expect1, expect2) =
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   125
  if expect1 = expect2 then expect1 else No_Expectation
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   126
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   127
(* quickcheck configuration -- default parameters, test generators *)
40908
e8806880819e adding configuration quickcheck_tester
bulwahn
parents: 40906
diff changeset
   128
val (tester, setup_tester) = Attrib.config_string "quickcheck_tester" (K "")
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   129
val (size, setup_size) = Attrib.config_int "quickcheck_size" (K 10)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   130
val (iterations, setup_iterations) = Attrib.config_int "quickcheck_iterations" (K 100)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   131
val (no_assms, setup_no_assms) = Attrib.config_bool "quickcheck_no_assms" (K false)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   132
val (report, setup_report) = Attrib.config_bool "quickcheck_report" (K true)
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   133
val (timing, setup_timing) = Attrib.config_bool "quickcheck_timing" (K false)
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   134
val (quiet, setup_quiet) = Attrib.config_bool "quickcheck_quiet" (K false)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   135
val (timeout, setup_timeout) = Attrib.config_real "quickcheck_timeout" (K 30.0)
40646
3dfa41e89738 adding option finite_types to quickcheck
bulwahn
parents: 40644
diff changeset
   136
val (finite_types, setup_finite_types) = Attrib.config_bool "quickcheck_finite_types" (K true)
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   137
val (finite_type_size, setup_finite_type_size) =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   138
  Attrib.config_int "quickcheck_finite_type_size" (K 3)
38759
37a9092de102 simplification/standardization of some theory data;
wenzelm
parents: 38390
diff changeset
   139
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   140
val setup_config =
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   141
  setup_tester #> setup_size #> setup_iterations #> setup_no_assms #> setup_report #> setup_timing
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   142
    #> setup_quiet #> setup_timeout #> setup_finite_types #> setup_finite_type_size
40646
3dfa41e89738 adding option finite_types to quickcheck
bulwahn
parents: 40644
diff changeset
   143
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   144
datatype test_params = Test_Params of
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   145
  {default_type: typ list, expect : expectation};
38759
37a9092de102 simplification/standardization of some theory data;
wenzelm
parents: 38390
diff changeset
   146
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   147
fun dest_test_params (Test_Params {default_type, expect}) = (default_type, expect);
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   148
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   149
fun make_test_params (default_type, expect) =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   150
  Test_Params {default_type = default_type, expect = expect};
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   151
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   152
fun map_test_params' f (Test_Params {default_type, expect}) =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   153
  make_test_params (f (default_type, expect));
38759
37a9092de102 simplification/standardization of some theory data;
wenzelm
parents: 38390
diff changeset
   154
37a9092de102 simplification/standardization of some theory data;
wenzelm
parents: 38390
diff changeset
   155
fun merge_test_params
41472
f6ab14e61604 misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents: 41086
diff changeset
   156
  (Test_Params {default_type = default_type1, expect = expect1},
f6ab14e61604 misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents: 41086
diff changeset
   157
    Test_Params {default_type = default_type2, expect = expect2}) =
f6ab14e61604 misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents: 41086
diff changeset
   158
  make_test_params
f6ab14e61604 misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents: 41086
diff changeset
   159
    (merge (op =) (default_type1, default_type2), merge_expectation (expect1, expect2));
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   160
39252
8f176e575a49 changing the container for the quickcheck options to a generic data
bulwahn
parents: 39138
diff changeset
   161
structure Data = Generic_Data
33522
737589bb9bb8 adapted Theory_Data;
wenzelm
parents: 33291
diff changeset
   162
(
38759
37a9092de102 simplification/standardization of some theory data;
wenzelm
parents: 38390
diff changeset
   163
  type T =
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   164
    ((string * (Proof.context -> (term * term list) list -> int list -> term list option * report option)) list
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   165
      * (string * (Proof.context -> term list -> (int -> term list option) list)) list)
38759
37a9092de102 simplification/standardization of some theory data;
wenzelm
parents: 38390
diff changeset
   166
      * test_params;
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   167
  val empty = (([], []), Test_Params {default_type = [], expect = No_Expectation});
28256
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
   168
  val extend = I;
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   169
  fun merge (((generators1, batch_generators1), params1), ((generators2, batch_generators2), params2)) : T =
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   170
    ((AList.merge (op =) (K true) (generators1, generators2),
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   171
    AList.merge (op =) (K true) (batch_generators1, batch_generators2)),
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   172
      merge_test_params (params1, params2));
33522
737589bb9bb8 adapted Theory_Data;
wenzelm
parents: 33291
diff changeset
   173
);
28256
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
   174
39252
8f176e575a49 changing the container for the quickcheck options to a generic data
bulwahn
parents: 39138
diff changeset
   175
val test_params_of = snd o Data.get o Context.Proof;
37910
555287ba8d8d reordering quickcheck signature; exporting test_params and inspection function
bulwahn
parents: 37909
diff changeset
   176
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   177
val default_type = fst o dest_test_params o test_params_of
40246
c03fc7d3fa97 changed global fixed timeout to a configurable timeout for quickcheck; test parameters in quickcheck are now fully passed around with the context
bulwahn
parents: 40225
diff changeset
   178
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   179
val expect = snd o dest_test_params o test_params_of
40246
c03fc7d3fa97 changed global fixed timeout to a configurable timeout for quickcheck; test parameters in quickcheck are now fully passed around with the context
bulwahn
parents: 40225
diff changeset
   180
c03fc7d3fa97 changed global fixed timeout to a configurable timeout for quickcheck; test parameters in quickcheck are now fully passed around with the context
bulwahn
parents: 40225
diff changeset
   181
val map_test_params = Data.map o apsnd o map_test_params'
39253
0c47d615a69b removing report from the arguments of the quickcheck functions and refering to it by picking it from the context
bulwahn
parents: 39252
diff changeset
   182
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   183
val add_generator = Data.map o apfst o apfst o AList.update (op =);
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   184
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   185
val add_batch_generator = Data.map o apfst o apsnd o AList.update (op =);
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   186
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   187
(* generating tests *)
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   188
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   189
fun gen_mk_tester lookup ctxt v =
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   190
  let
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   191
    val name = Config.get ctxt tester
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   192
    val tester = case lookup ctxt name
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   193
      of NONE => error ("No such quickcheck tester: " ^ name)
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   194
      | SOME tester => tester ctxt;
40235
87998864284e use Exn.interruptible_capture to keep user-code interruptible (Exn.capture not immediately followed by Exn.release here);
wenzelm
parents: 40225
diff changeset
   195
  in
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   196
    if Config.get ctxt quiet then
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   197
      try tester v
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   198
    else
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   199
      let
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   200
        val tester = Exn.interruptible_capture tester v
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   201
      in case Exn.get_result tester of
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   202
          NONE => SOME (Exn.release tester)
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   203
        | SOME tester => SOME tester
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   204
      end
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   205
  end
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   206
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   207
val mk_tester = gen_mk_tester (fn ctxt =>
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   208
  AList.lookup (op =) ((fst o fst o Data.get o Context.Proof) ctxt))
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   209
val mk_batch_tester = gen_mk_tester (fn ctxt => AList.lookup (op =) ((snd o fst o Data.get o Context.Proof) ctxt))
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   210
  
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   211
(* testing propositions *)
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   212
42028
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   213
fun check_test_term t =
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   214
  let
29266
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 28952
diff changeset
   215
    val _ = (null (Term.add_tvars t []) andalso null (Term.add_tfrees t [])) orelse
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   216
      error "Term to be tested contains type variables";
29266
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 28952
diff changeset
   217
    val _ = null (Term.add_vars t []) orelse
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   218
      error "Term to be tested contains schematic variables";
42028
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   219
  in () end
28256
4e7f7d52f855 added quickcheck.ML
haftmann
parents:
diff changeset
   220
42014
75417ef605ba simplified various cpu_time clones (!): eliminated odd Exn.capture/Exn.release (no need to "stop" timing);
wenzelm
parents: 42012
diff changeset
   221
fun cpu_time description e =
75417ef605ba simplified various cpu_time clones (!): eliminated odd Exn.capture/Exn.release (no need to "stop" timing);
wenzelm
parents: 42012
diff changeset
   222
  let val ({cpu, ...}, result) = Timing.timing e ()
75417ef605ba simplified various cpu_time clones (!): eliminated odd Exn.capture/Exn.release (no need to "stop" timing);
wenzelm
parents: 42012
diff changeset
   223
  in (result, (description, Time.toMilliseconds cpu)) end
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   224
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   225
fun limit ctxt (limit_time, is_interactive) f exc () =
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   226
  if limit_time then
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   227
      TimeLimit.timeLimit (seconds (Config.get ctxt timeout)) f ()
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   228
    handle TimeLimit.TimeOut =>
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   229
      if is_interactive then exc () else raise TimeLimit.TimeOut
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   230
  else
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   231
    f ()
41753
dbd00d8a4784 quickcheck invokes TimeLimit.timeLimit only in one separate function
bulwahn
parents: 41735
diff changeset
   232
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   233
fun test_term ctxt (limit_time, is_interactive) (t, eval_terms) =
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   234
  let
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   235
    fun message s = if Config.get ctxt quiet then () else Output.urgent_message s
42028
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   236
    val _ = check_test_term t
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   237
    val names = Term.add_free_names t []
40366
a2866dbfbe6b changing timeout to real value; handling Interrupt and Timeout more like nitpick does
bulwahn
parents: 40253
diff changeset
   238
    val current_size = Unsynchronized.ref 0
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   239
    val current_result = Unsynchronized.ref empty_result 
42087
5e236f6ef04f changing timeout behaviour of quickcheck to proceed after command rather than failing; adding a test case for timeout
bulwahn
parents: 42032
diff changeset
   240
    fun excipit () =
5e236f6ef04f changing timeout behaviour of quickcheck to proceed after command rather than failing; adding a test case for timeout
bulwahn
parents: 42032
diff changeset
   241
      "Quickcheck ran out of time while testing at size " ^ string_of_int (!current_size)
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   242
    val (test_fun, comp_time) = cpu_time "quickcheck compilation"
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   243
      (fn () => mk_tester ctxt [(t, eval_terms)]);
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   244
    val _ = add_timing comp_time current_result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   245
    fun with_size test_fun k =
40911
7febf76e0a69 moving iteration of tests to the testers in quickcheck
bulwahn
parents: 40910
diff changeset
   246
      if k > Config.get ctxt size then
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   247
        NONE
40911
7febf76e0a69 moving iteration of tests to the testers in quickcheck
bulwahn
parents: 40910
diff changeset
   248
      else
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   249
        let
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   250
          val _ = message ("Test data size: " ^ string_of_int k)
40648
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   251
          val _ = current_size := k
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   252
          val ((result, report), timing) =
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   253
            cpu_time ("size " ^ string_of_int k) (fn () => test_fun [1, k - 1])
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   254
          val _ = add_timing timing current_result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   255
          val _ = add_report k report current_result
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   256
        in
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   257
          case result of NONE => with_size test_fun (k + 1) | SOME q => SOME q
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   258
        end;
34948
2d5f2a9f7601 refactoring the predicate compiler; adding theories for Sequences; adding retrieval to Spec_Rules; adding timing to Quickcheck
bulwahn
parents: 34128
diff changeset
   259
  in
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   260
    case test_fun of NONE => !current_result
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   261
      | SOME test_fun =>
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   262
        limit ctxt (limit_time, is_interactive) (fn () =>
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   263
          let
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   264
            val (response, exec_time) =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   265
              cpu_time "quickcheck execution" (fn () => with_size test_fun 1)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   266
            val _ = add_response names eval_terms response current_result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   267
            val _ = add_timing exec_time current_result
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   268
          in
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   269
            !current_result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   270
          end) (fn () => (message (excipit ()); !current_result)) ()
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   271
  end;
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   272
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   273
fun test_terms ctxt ts =
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   274
  let
42028
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   275
    val _ = map check_test_term ts
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   276
    val namess = map (fn t => Term.add_free_names t []) ts
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   277
    val test_funs = mk_batch_tester ctxt ts
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   278
    fun with_size tester k =
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   279
      if k > Config.get ctxt size then NONE
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   280
      else case tester k of SOME ts => SOME ts | NONE => with_size tester (k + 1)
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   281
    val results =
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   282
      Option.map (map (fn test_fun => TimeLimit.timeLimit (seconds (Config.get ctxt timeout))
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   283
            (fn () => with_size test_fun 1)  ()
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   284
           handle TimeLimit.TimeOut => NONE)) test_funs
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   285
  in
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   286
    Option.map (map2 (fn names => Option.map (fn ts => names ~~ ts)) namess) results
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   287
  end
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   288
41086
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   289
(* FIXME: this function shows that many assumptions are made upon the generation *)
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   290
(* In the end there is probably no generic quickcheck interface left... *)
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   291
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   292
fun test_term_with_increasing_cardinality ctxt (limit_time, is_interactive) ts =
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   293
  let
41086
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   294
    val thy = ProofContext.theory_of ctxt
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   295
    fun message s = if Config.get ctxt quiet then () else Output.urgent_message s
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   296
    val (ts', eval_terms) = split_list ts
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   297
    val _ = map check_test_term ts'
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   298
    val names = Term.add_free_names (hd ts') []
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   299
    val Ts = map snd (Term.add_frees (hd ts') [])
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   300
    val current_result = Unsynchronized.ref empty_result 
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   301
    val (test_fun, comp_time) = cpu_time "quickcheck compilation" (fn () => mk_tester ctxt ts)
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   302
    val _ = add_timing comp_time current_result
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   303
    fun test_card_size (card, size) =
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   304
      (* FIXME: why decrement size by one? *)
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   305
      let
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   306
        val (ts, timing) = cpu_time ("size " ^ string_of_int size ^ " and card " ^ string_of_int card)
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   307
          (fn () => fst ((the test_fun) [card - 1, size - 1]))
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   308
        val _ = add_timing timing current_result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   309
      in
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   310
        Option.map (pair card) ts
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   311
      end
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   312
    val enumeration_card_size =
41086
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   313
      if forall (fn T => Sign.of_sort thy (T,  ["Enum.enum"])) Ts then
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   314
        (* size does not matter *)
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   315
        map (rpair 0) (1 upto (length ts))
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   316
      else
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   317
        (* size does matter *)
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   318
        map_product pair (1 upto (length ts)) (1 upto (Config.get ctxt size))
b4cccce25d9a if only finite types and no real datatypes occur in the quantifiers only enumerate cardinality not size in quickcheck
bulwahn
parents: 41043
diff changeset
   319
        |> sort (fn ((c1, s1), (c2, s2)) => int_ord ((c1 + s1), (c2 + s2)))
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   320
    in
42159
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   321
      case test_fun of
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   322
          NONE => !current_result
234ec7011e5d generalizing compilation scheme of quickcheck generators to multiple arguments; changing random and exhaustive tester to use one code invocation for polymorphic instances with multiple cardinalities
bulwahn
parents: 42089
diff changeset
   323
        | SOME test_fun =>
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   324
        limit ctxt (limit_time, is_interactive) (fn () =>
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   325
          let
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   326
            val _ = case get_first test_card_size enumeration_card_size of
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   327
              SOME (card, ts) => add_response names (nth eval_terms (card - 1)) (SOME ts) current_result
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   328
            | NONE => ()
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   329
          in !current_result end)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   330
          (fn () => (message "Quickcheck ran out of time"; !current_result)) ()
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   331
    end
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   332
40647
6e92ca8e981b adding prototype for finite_type instantiations
bulwahn
parents: 40646
diff changeset
   333
fun get_finite_types ctxt =
6e92ca8e981b adding prototype for finite_type instantiations
bulwahn
parents: 40646
diff changeset
   334
  fst (chop (Config.get ctxt finite_type_size)
6e92ca8e981b adding prototype for finite_type instantiations
bulwahn
parents: 40646
diff changeset
   335
    (map (Type o rpair []) ["Enum.finite_1", "Enum.finite_2", "Enum.finite_3",
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   336
     "Enum.finite_4", "Enum.finite_5"]))
40647
6e92ca8e981b adding prototype for finite_type instantiations
bulwahn
parents: 40646
diff changeset
   337
37913
e85f5ad02a8f correcting wellsortedness check and improving error message
bulwahn
parents: 37912
diff changeset
   338
exception WELLSORTED of string
e85f5ad02a8f correcting wellsortedness check and improving error message
bulwahn
parents: 37912
diff changeset
   339
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   340
fun monomorphic_term thy insts default_T =
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   341
  let
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   342
    fun subst (T as TFree (v, S)) =
40903
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   343
      let
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   344
        val T' = AList.lookup (op =) insts v
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   345
          |> the_default default_T
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   346
      in if Sign.of_sort thy (T', S) then T'
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   347
        else raise (WELLSORTED ("For instantiation with default_type " ^
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   348
          Syntax.string_of_typ_global thy default_T ^
40903
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   349
          ":\n" ^ Syntax.string_of_typ_global thy T' ^
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   350
          " to be substituted for variable " ^
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   351
          Syntax.string_of_typ_global thy T ^ " does not have sort " ^
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   352
          Syntax.string_of_sort_global thy S))
1332f6e856b9 corrected indentation
bulwahn
parents: 40656
diff changeset
   353
      end
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   354
      | subst T = T;
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   355
  in (map_types o map_atyps) subst end;
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   356
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   357
datatype wellsorted_error = Wellsorted_Error of string | Term of term * term list
37913
e85f5ad02a8f correcting wellsortedness check and improving error message
bulwahn
parents: 37912
diff changeset
   358
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   359
fun test_goal_terms lthy (limit_time, is_interactive) insts check_goals =
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   360
  let
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   361
    fun map_goal_and_eval_terms f (check_goal, eval_terms) = (f check_goal, map f eval_terms)
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   362
    val thy = ProofContext.theory_of lthy
40926
c600f6ae4b09 only instantiate type variable if there exists some in quickcheck
bulwahn
parents: 40916
diff changeset
   363
    val default_insts =
c600f6ae4b09 only instantiate type variable if there exists some in quickcheck
bulwahn
parents: 40916
diff changeset
   364
      if Config.get lthy finite_types then (get_finite_types lthy) else (default_type lthy)
40647
6e92ca8e981b adding prototype for finite_type instantiations
bulwahn
parents: 40646
diff changeset
   365
    val inst_goals =
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   366
      map (fn (check_goal, eval_terms) =>
40926
c600f6ae4b09 only instantiate type variable if there exists some in quickcheck
bulwahn
parents: 40916
diff changeset
   367
        if not (null (Term.add_tfree_names check_goal [])) then
c600f6ae4b09 only instantiate type variable if there exists some in quickcheck
bulwahn
parents: 40916
diff changeset
   368
          map (fn T =>
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   369
            (pair (SOME T) o Term o apfst (Object_Logic.atomize_term thy))
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   370
              (map_goal_and_eval_terms (monomorphic_term thy insts T) (check_goal, eval_terms))
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   371
              handle WELLSORTED s => (SOME T, Wellsorted_Error s)) default_insts
40926
c600f6ae4b09 only instantiate type variable if there exists some in quickcheck
bulwahn
parents: 40916
diff changeset
   372
        else
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   373
          [(NONE, Term (Object_Logic.atomize_term thy check_goal, eval_terms))]) check_goals
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   374
    val error_msg =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   375
      cat_lines
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   376
        (maps (map_filter (fn (_, Term t) => NONE | (_, Wellsorted_Error s) => SOME s)) inst_goals)
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   377
    fun is_wellsorted_term (T, Term t) = SOME (T, t)
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   378
      | is_wellsorted_term (_, Wellsorted_Error s) = NONE
37913
e85f5ad02a8f correcting wellsortedness check and improving error message
bulwahn
parents: 37912
diff changeset
   379
    val correct_inst_goals =
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   380
      case map (map_filter is_wellsorted_term) inst_goals of
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   381
        [[]] => error error_msg
37913
e85f5ad02a8f correcting wellsortedness check and improving error message
bulwahn
parents: 37912
diff changeset
   382
      | xs => xs
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   383
    val _ = if Config.get lthy quiet then () else warning error_msg
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   384
    fun collect_results f [] results = results
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   385
      | collect_results f (t :: ts) results =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   386
        let
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   387
          val result = f t
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   388
        in
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   389
          if found_counterexample result then
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   390
            (result :: results)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   391
          else
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   392
            collect_results f ts (result :: results)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   393
        end
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   394
    fun test_term' goal =
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   395
      case goal of
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   396
        [(NONE, t)] => test_term lthy (limit_time, is_interactive) t
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   397
      | ts => test_term_with_increasing_cardinality lthy (limit_time, is_interactive) (map snd ts)
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   398
  in
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   399
    if Config.get lthy finite_types then
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   400
      collect_results test_term' correct_inst_goals []
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   401
    else
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   402
      collect_results (test_term lthy (limit_time, is_interactive)) (maps (map snd) correct_inst_goals) []
41043
3750bdac1327 testing smartly in two dimensions (cardinality and size) in quickcheck
bulwahn
parents: 40931
diff changeset
   403
  end;
37912
247042107f93 using multiple default types in quickcheck
bulwahn
parents: 37911
diff changeset
   404
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   405
fun test_goal (time_limit, is_interactive) (insts, eval_terms) i state =
40648
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   406
  let
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   407
    val lthy = Proof.context_of state;
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   408
    val thy = Proof.theory_of state;
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   409
    fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   410
      | strip t = t;
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   411
    val {goal = st, ...} = Proof.raw_goal state;
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   412
    val (gi, frees) = Logic.goal_params (prop_of st) i;
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   413
    val some_locale = case (Option.map #target o Named_Target.peek) lthy
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   414
     of NONE => NONE
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   415
      | SOME "" => NONE
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   416
      | SOME locale => SOME locale;
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   417
    val assms = if Config.get lthy no_assms then [] else case some_locale
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   418
     of NONE => Assumption.all_assms_of lthy
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   419
      | SOME locale => Assumption.local_assms_of lthy (Locale.init locale thy);
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   420
    val proto_goal = Logic.list_implies (map Thm.term_of assms, subst_bounds (frees, strip gi));
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   421
    val check_goals = case some_locale
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   422
     of NONE => [(proto_goal, eval_terms)]
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   423
      | SOME locale =>
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   424
        map (fn (_, phi) => (Morphism.term phi proto_goal, map (Morphism.term phi) eval_terms))
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   425
          (Locale.registrations_of (Context.Theory thy) (*FIXME*) locale);
40648
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   426
  in
41754
aa94a003dcdf quickcheck can be invoked with its internal timelimit or without
bulwahn
parents: 41753
diff changeset
   427
    test_goal_terms lthy (time_limit, is_interactive) insts check_goals
40648
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   428
  end
1598ec648b0d splitting test_goal function in two functions; exporting new configurations in quickcheck; iterations depend on generator_name in quickcheck
bulwahn
parents: 40647
diff changeset
   429
37912
247042107f93 using multiple default types in quickcheck
bulwahn
parents: 37911
diff changeset
   430
(* pretty printing *)
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   431
40225
2de5dd0cd3a2 clear identification
blanchet
parents: 40148
diff changeset
   432
fun tool_name auto = (if auto then "Auto " else "") ^ "Quickcheck"
2de5dd0cd3a2 clear identification
blanchet
parents: 40148
diff changeset
   433
2de5dd0cd3a2 clear identification
blanchet
parents: 40148
diff changeset
   434
fun pretty_counterex ctxt auto NONE = Pretty.str (tool_name auto ^ " found no counterexample.")
42028
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   435
  | pretty_counterex ctxt auto (SOME (cex, eval_terms)) =
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   436
      Pretty.chunks ((Pretty.str (tool_name auto ^ " found a counterexample:\n") ::
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   437
        map (fn (s, t) =>
42028
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   438
          Pretty.block [Pretty.str (s ^ " ="), Pretty.brk 1, Syntax.pretty_term ctxt t]) (rev cex))
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   439
        @ (Pretty.str ("Evaluated terms:\n") ::
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   440
        map (fn (t, u) =>
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   441
          Pretty.block [Syntax.pretty_term ctxt t, Pretty.str " =", Pretty.brk 1, Syntax.pretty_term ctxt u])
bd6515e113b2 passing a term with free variables to the quickcheck tester functions instead of an lambda expression because this is more natural with passing further evaluation terms; added output of evaluation terms; added evaluation of terms in the exhaustive testing
bulwahn
parents: 42026
diff changeset
   442
          (rev eval_terms)));
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   443
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   444
fun pretty_report (Report {iterations = iterations, raised_match_errors = raised_match_errors,
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   445
    satisfied_assms = satisfied_assms, positive_concl_tests = positive_concl_tests}) =
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   446
  let
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   447
    fun pretty_stat s i = Pretty.block ([Pretty.str (s ^ ": " ^ string_of_int i)])
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   448
  in
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   449
     ([pretty_stat "iterations" iterations,
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   450
     pretty_stat "match exceptions" raised_match_errors]
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   451
     @ map_index
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   452
       (fn (i, n) => pretty_stat ("satisfied " ^ string_of_int (i + 1) ^ ". assumption") n)
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   453
       satisfied_assms
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   454
     @ [pretty_stat "positive conclusion tests" positive_concl_tests])
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   455
  end
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   456
35380
6ac5b81a763d adopting Mutabelle to quickcheck reporting; improving quickcheck reporting
bulwahn
parents: 35379
diff changeset
   457
fun pretty_reports ctxt (SOME reports) =
40916
9928083506b6 improving presentation of quickcheck reports
bulwahn
parents: 40912
diff changeset
   458
  Pretty.chunks (Pretty.fbrk :: Pretty.str "Quickcheck report:" ::
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   459
    maps (fn (size, report) =>
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   460
      Pretty.str ("size " ^ string_of_int size ^ ":") :: pretty_report report @ [Pretty.brk 1])
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   461
      (rev reports))
35380
6ac5b81a763d adopting Mutabelle to quickcheck reporting; improving quickcheck reporting
bulwahn
parents: 35379
diff changeset
   462
  | pretty_reports ctxt NONE = Pretty.str ""
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   463
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   464
fun pretty_timings timings =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   465
  Pretty.chunks (Pretty.fbrk :: Pretty.str "timings:" ::
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   466
    maps (fn (label, time) =>
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   467
      Pretty.str (label ^ ": " ^ string_of_int time ^ " ms") :: Pretty.brk 1 :: []) (rev timings))
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   468
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   469
fun pretty_counterex_and_reports ctxt auto (result :: _) =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   470
  Pretty.chunks (pretty_counterex ctxt auto (response_of result) ::
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   471
    (* map (pretty_reports ctxt) (reports_of result) :: *)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   472
    (if Config.get ctxt timing then cons (pretty_timings (timings_of result)) else I) [])
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   473
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   474
(* automatic testing *)
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   475
33561
ab01b72715ef introduced Auto Nitpick in addition to Auto Quickcheck;
blanchet
parents: 33560
diff changeset
   476
fun auto_quickcheck state =
40931
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   477
  let
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   478
    val ctxt = Proof.context_of state;
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   479
    val res =
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   480
      state
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   481
      |> Proof.map_context (Config.put report false #> Config.put quiet true)
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   482
      |> try (test_goal (false, false) ([], []) 1);
40931
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   483
  in
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   484
    case res of
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   485
      NONE => (false, state)
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   486
    | SOME (result :: _) => if found_counterexample result then
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   487
        (true, Proof.goal_message (K (Pretty.chunks [Pretty.str "",
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   488
          Pretty.mark Markup.hilite (pretty_counterex ctxt true (response_of result))])) state)
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   489
      else
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   490
        (false, state)
40931
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   491
  end
33561
ab01b72715ef introduced Auto Nitpick in addition to Auto Quickcheck;
blanchet
parents: 33560
diff changeset
   492
40931
061b8257ab9f run synchronous Auto Tools in parallel
blanchet
parents: 40926
diff changeset
   493
val setup = Auto_Tools.register_tool (auto, auto_quickcheck)
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   494
  #> setup_config
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   495
30980
fe0855471964 misc cleanup of auto_solve and quickcheck:
wenzelm
parents: 30973
diff changeset
   496
(* Isar commands *)
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   497
28336
a8edf4c69a79 fixed quickcheck parameter syntax
haftmann
parents: 28315
diff changeset
   498
fun read_nat s = case (Library.read_int o Symbol.explode) s
a8edf4c69a79 fixed quickcheck parameter syntax
haftmann
parents: 28315
diff changeset
   499
 of (k, []) => if k >= 0 then k
a8edf4c69a79 fixed quickcheck parameter syntax
haftmann
parents: 28315
diff changeset
   500
      else error ("Not a natural number: " ^ s)
a8edf4c69a79 fixed quickcheck parameter syntax
haftmann
parents: 28315
diff changeset
   501
  | (_, _ :: _) => error ("Not a natural number: " ^ s);
37909
583543ad6ad1 changed default types to a list of types; extended quickcheck parameters to be a list of values to parse a list of default types
bulwahn
parents: 36960
diff changeset
   502
34128
8650a073dd9b made Quickcheck take structured proof assumptions into account (like Refute and Nitpick) by default;
blanchet
parents: 33583
diff changeset
   503
fun read_bool "false" = false
8650a073dd9b made Quickcheck take structured proof assumptions into account (like Refute and Nitpick) by default;
blanchet
parents: 33583
diff changeset
   504
  | read_bool "true" = true
8650a073dd9b made Quickcheck take structured proof assumptions into account (like Refute and Nitpick) by default;
blanchet
parents: 33583
diff changeset
   505
  | read_bool s = error ("Not a Boolean value: " ^ s)
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   506
40366
a2866dbfbe6b changing timeout to real value; handling Interrupt and Timeout more like nitpick does
bulwahn
parents: 40253
diff changeset
   507
fun read_real s =
a2866dbfbe6b changing timeout to real value; handling Interrupt and Timeout more like nitpick does
bulwahn
parents: 40253
diff changeset
   508
  case (Real.fromString s) of
a2866dbfbe6b changing timeout to real value; handling Interrupt and Timeout more like nitpick does
bulwahn
parents: 40253
diff changeset
   509
    SOME s => s
a2866dbfbe6b changing timeout to real value; handling Interrupt and Timeout more like nitpick does
bulwahn
parents: 40253
diff changeset
   510
  | NONE => error ("Not a real number: " ^ s)
a2866dbfbe6b changing timeout to real value; handling Interrupt and Timeout more like nitpick does
bulwahn
parents: 40253
diff changeset
   511
37929
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   512
fun read_expectation "no_expectation" = No_Expectation
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   513
  | read_expectation "no_counterexample" = No_Counterexample
37929
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   514
  | read_expectation "counterexample" = Counterexample
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   515
  | read_expectation s = error ("Not an expectation value: " ^ s)
37929
22e0797857e6 adding checking of expected result for the tool quickcheck; annotated a few quickcheck examples
bulwahn
parents: 37913
diff changeset
   516
41862
a38536bf2736 adding function Quickcheck.test_terms to provide checking a batch of terms
bulwahn
parents: 41754
diff changeset
   517
fun valid_tester_name genctxt = AList.defined (op =) (fst (fst (Data.get genctxt)))
40912
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   518
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   519
fun parse_tester name genctxt =
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   520
  if valid_tester_name genctxt name then
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   521
    Config.put_generic tester name genctxt
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   522
  else
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   523
    error ("Unknown tester: " ^ name)
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   524
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   525
fun parse_test_param ("tester", [arg]) = parse_tester arg
40909
e006d1e06920 renamed parameter from generator to tester; quickcheck only applies one tester on invocation
bulwahn
parents: 40908
diff changeset
   526
  | parse_test_param ("size", [arg]) = Config.put_generic size (read_nat arg)
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   527
  | parse_test_param ("iterations", [arg]) = Config.put_generic iterations (read_nat arg)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   528
  | parse_test_param ("default_type", arg) = (fn gen_ctxt =>
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   529
    map_test_params
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   530
      ((apfst o K) (map (ProofContext.read_typ (Context.proof_of gen_ctxt)) arg)) gen_ctxt)
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   531
  | parse_test_param ("no_assms", [arg]) = Config.put_generic no_assms (read_bool arg)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   532
  | parse_test_param ("expect", [arg]) = map_test_params ((apsnd o K) (read_expectation arg))
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   533
  | parse_test_param ("report", [arg]) = Config.put_generic report (read_bool arg)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   534
  | parse_test_param ("quiet", [arg]) = Config.put_generic quiet (read_bool arg)
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   535
  | parse_test_param ("timeout", [arg]) = Config.put_generic timeout (read_real arg)
40646
3dfa41e89738 adding option finite_types to quickcheck
bulwahn
parents: 40644
diff changeset
   536
  | parse_test_param ("finite_types", [arg]) = Config.put_generic finite_types (read_bool arg)
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   537
  | parse_test_param ("finite_type_size", [arg]) =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   538
    Config.put_generic finite_type_size (read_nat arg)
40912
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   539
  | parse_test_param (name, _) = fn genctxt =>
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   540
    if valid_tester_name genctxt name then
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   541
      Config.put_generic tester name genctxt
1108529100ce checking if parameter is name of a tester which allows e.g. quickcheck[random]
bulwahn
parents: 40911
diff changeset
   542
    else error ("Unknown tester or test parameter: " ^ name);
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   543
42025
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   544
fun parse_test_param_inst (name, arg) ((insts, eval_terms), ctxt) =
28336
a8edf4c69a79 fixed quickcheck parameter syntax
haftmann
parents: 28315
diff changeset
   545
      case try (ProofContext.read_typ ctxt) name
42025
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   546
       of SOME (TFree (v, _)) =>
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   547
         ((AList.update (op =) (v, ProofContext.read_typ ctxt (the_single arg)) insts, eval_terms), ctxt)
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   548
        | NONE => (case name of
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   549
            "eval" => ((insts, eval_terms @ map (Syntax.read_term ctxt) arg), ctxt)
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   550
          | _ => ((insts, eval_terms), Context.proof_map (parse_test_param (name, arg)) ctxt));
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   551
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   552
fun quickcheck_params_cmd args = Context.theory_map (fold parse_test_param args);
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   553
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   554
fun check_expectation state results =
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   555
  (if found_counterexample (hd results) andalso expect (Proof.context_of state) = No_Counterexample
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   556
  then
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   557
    error ("quickcheck expected to find no counterexample but found one")
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   558
  else
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   559
    (if not (found_counterexample (hd results)) andalso expect (Proof.context_of state) = Counterexample
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   560
    then
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   561
      error ("quickcheck expected to find a counterexample but did not find one")
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   562
    else ()))
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   563
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   564
fun gen_quickcheck args i state =
40644
0850a2a16dce changed old-style quickcheck configurations to new Config.T configurations
bulwahn
parents: 40643
diff changeset
   565
  state
42025
cb5b1e85b32e adding eval option to quickcheck
bulwahn
parents: 41862
diff changeset
   566
  |> Proof.map_context_result (fn ctxt => fold parse_test_param_inst args (([], []), ctxt))
42026
da9b58f1db42 adding option of evaluating terms after invocation in quickcheck
bulwahn
parents: 42025
diff changeset
   567
  |> (fn ((insts, eval_terms), state') => test_goal (true, true) (insts, eval_terms) i state'
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   568
  |> tap (check_expectation state'))
32297
3a4081abb3f7 Quickcheck callable from ML
boehmes
parents: 31599
diff changeset
   569
42088
8d00484551fe making quickcheck's result value more formal; allowing more result information to be returned after timeout; adding output of timing information in quickcheck
bulwahn
parents: 42087
diff changeset
   570
fun quickcheck args i state = counterexample_of (hd (gen_quickcheck args i state))
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   571
32297
3a4081abb3f7 Quickcheck callable from ML
boehmes
parents: 31599
diff changeset
   572
fun quickcheck_cmd args i state =
35378
95d0e3adf38e added basic reporting of test cases to quickcheck
bulwahn
parents: 35324
diff changeset
   573
  gen_quickcheck args i (Toplevel.proof_of state)
40225
2de5dd0cd3a2 clear identification
blanchet
parents: 40148
diff changeset
   574
  |> Pretty.writeln o pretty_counterex_and_reports (Toplevel.context_of state) false;
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   575
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   576
val parse_arg =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   577
  Parse.name --
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   578
    (Scan.optional (Parse.$$$ "=" |--
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   579
      (((Parse.name || Parse.float_number) >> single) ||
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   580
        (Parse.$$$ "[" |-- Parse.list1 Parse.name --| Parse.$$$ "]"))) ["true"]);
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   581
41517
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   582
val parse_args =
7267fb5b724b observe line length limit;
wenzelm
parents: 41472
diff changeset
   583
  Parse.$$$ "[" |-- Parse.list1 parse_arg --| Parse.$$$ "]" || Scan.succeed [];
28336
a8edf4c69a79 fixed quickcheck parameter syntax
haftmann
parents: 28315
diff changeset
   584
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   585
val _ =
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   586
  Outer_Syntax.command "quickcheck_params" "set parameters for random testing" Keyword.thy_decl
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   587
    (parse_args >> (fn args => Toplevel.theory (quickcheck_params_cmd args)));
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   588
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   589
val _ =
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   590
  Outer_Syntax.improper_command "quickcheck" "try to find counterexample for subgoal" Keyword.diag
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   591
    (parse_args -- Scan.optional Parse.nat 1
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36610
diff changeset
   592
      >> (fn (args, i) => Toplevel.no_timing o Toplevel.keep (quickcheck_cmd args i)));
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   593
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   594
end;
28309
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   595
c24bc53c815c some steps towards generic quickcheck framework
haftmann
parents: 28256
diff changeset
   596
28315
d3cf88fe77bc generic quickcheck framework
haftmann
parents: 28309
diff changeset
   597
val auto_quickcheck = Quickcheck.auto;