src/Tools/quickcheck.ML
changeset 43112 3117573292b8
parent 43029 3e060b1c844b
child 43113 7226051e8b89
equal deleted inserted replaced
43084:946c8e171ffd 43112:3117573292b8
    29   val map_test_params : (typ list * expectation -> typ list * expectation)
    29   val map_test_params : (typ list * expectation -> typ list * expectation)
    30     -> Context.generic -> Context.generic
    30     -> Context.generic -> Context.generic
    31   datatype report = Report of
    31   datatype report = Report of
    32     { iterations : int, raised_match_errors : int,
    32     { iterations : int, raised_match_errors : int,
    33       satisfied_assms : int list, positive_concl_tests : int }
    33       satisfied_assms : int list, positive_concl_tests : int }
    34   (* registering generators *)
       
    35   val add_generator:
       
    36     string * (Proof.context -> (term * term list) list -> int list -> term list option * report option)
       
    37       -> Context.generic -> Context.generic
       
    38   val add_batch_generator:
       
    39     string * (Proof.context -> term list -> (int -> term list option) list)
       
    40       -> Context.generic -> Context.generic
       
    41   val add_batch_validator:
       
    42     string * (Proof.context -> term list -> (int -> bool) list)
       
    43       -> Context.generic -> Context.generic
       
    44   (* quickcheck's result *)
    34   (* quickcheck's result *)
    45   datatype result =
    35   datatype result =
    46     Result of
    36     Result of
    47      {counterexample : (string * term) list option,
    37      {counterexample : (string * term) list option,
    48       evaluation_terms : (term * term) list option,
    38       evaluation_terms : (term * term) list option,
    49       timings : (string * int) list,
    39       timings : (string * int) list,
    50       reports : (int * report) list}
    40       reports : (int * report) list}
    51   val counterexample_of : result -> (string * term) list option
    41   val counterexample_of : result -> (string * term) list option
    52   val timings_of : result -> (string * int) list
    42   val timings_of : result -> (string * int) list
       
    43   (* registering generators *)
       
    44   val add_generator:
       
    45     string * (Proof.context -> (term * term list) list -> int list -> term list option * report option)
       
    46       -> Context.generic -> Context.generic
       
    47   val add_tester:
       
    48     string * (Proof.context -> bool * bool -> (string * typ) list -> (term * term list) list -> result list)
       
    49       -> Context.generic -> Context.generic
       
    50   val add_batch_generator:
       
    51     string * (Proof.context -> term list -> (int -> term list option) list)
       
    52       -> Context.generic -> Context.generic
       
    53   val add_batch_validator:
       
    54     string * (Proof.context -> term list -> (int -> bool) list)
       
    55       -> Context.generic -> Context.generic
    53   (* testing terms and proof states *)
    56   (* testing terms and proof states *)
    54   val test_term: Proof.context -> bool * bool -> term * term list -> result
    57   val test_term: Proof.context -> bool * bool -> term * term list -> result
    55   val test_goal_terms:
    58   val test_goal_terms:
    56     Proof.context -> bool * bool -> (string * typ) list -> (term * term list) list  
    59     Proof.context -> bool * bool -> (string * typ) list -> (term * term list) list  
    57       -> result list
    60       -> result list
   172     (merge (op =) (default_type1, default_type2), merge_expectation (expect1, expect2));
   175     (merge (op =) (default_type1, default_type2), merge_expectation (expect1, expect2));
   173 
   176 
   174 structure Data = Generic_Data
   177 structure Data = Generic_Data
   175 (
   178 (
   176   type T =
   179   type T =
   177     ((string * (Proof.context -> (term * term list) list -> int list -> term list option * report option)) list
   180     (((string * (Proof.context -> (term * term list) list -> int list -> term list option * report option)) list
       
   181       * (string * (Proof.context -> bool * bool -> (string * typ) list -> (term * term list) list -> result list)) list)
   178       * ((string * (Proof.context -> term list -> (int -> term list option) list)) list
   182       * ((string * (Proof.context -> term list -> (int -> term list option) list)) list
   179       * ((string * (Proof.context -> term list -> (int -> bool) list)) list)))
   183       * ((string * (Proof.context -> term list -> (int -> bool) list)) list)))
   180       * test_params;
   184       * test_params;
   181   val empty = (([], ([], [])), Test_Params {default_type = [], expect = No_Expectation});
   185   val empty = ((([], []), ([], [])), Test_Params {default_type = [], expect = No_Expectation});
   182   val extend = I;
   186   val extend = I;
   183   fun merge (((generators1, (batch_generators1, batch_validators1)), params1),
   187   fun merge ((((generators1, testers1), (batch_generators1, batch_validators1)), params1),
   184     ((generators2, (batch_generators2, batch_validators2)), params2)) : T =
   188     (((generators2, testers2), (batch_generators2, batch_validators2)), params2)) : T =
   185     ((AList.merge (op =) (K true) (generators1, generators2),
   189     (((AList.merge (op =) (K true) (generators1, generators2),
   186      (AList.merge (op =) (K true) (batch_generators1, batch_generators2),
   190        AList.merge (op =) (K true) (testers1, testers2)),
   187       AList.merge (op =) (K true) (batch_validators1, batch_validators2))),
   191       (AList.merge (op =) (K true) (batch_generators1, batch_generators2),
       
   192        AList.merge (op =) (K true) (batch_validators1, batch_validators2))),
   188       merge_test_params (params1, params2));
   193       merge_test_params (params1, params2));
   189 );
   194 );
   190 
   195 
   191 val test_params_of = snd o Data.get o Context.Proof;
   196 val test_params_of = snd o Data.get o Context.Proof;
   192 
   197 
   194 
   199 
   195 val expect = snd o dest_test_params o test_params_of
   200 val expect = snd o dest_test_params o test_params_of
   196 
   201 
   197 val map_test_params = Data.map o apsnd o map_test_params'
   202 val map_test_params = Data.map o apsnd o map_test_params'
   198 
   203 
   199 val add_generator = Data.map o apfst o apfst o AList.update (op =);
   204 val add_generator = Data.map o apfst o apfst o apfst o AList.update (op =);
       
   205 
       
   206 val add_tester = Data.map o apfst o apfst o apsnd o AList.update (op =);
   200 
   207 
   201 val add_batch_generator = Data.map o apfst o apsnd o apfst o AList.update (op =);
   208 val add_batch_generator = Data.map o apfst o apsnd o apfst o AList.update (op =);
   202 
   209 
   203 val add_batch_validator = Data.map o apfst o apsnd o apsnd o AList.update (op =);
   210 val add_batch_validator = Data.map o apfst o apsnd o apsnd o AList.update (op =);
   204 
   211 
   221         | SOME tester => SOME tester
   228         | SOME tester => SOME tester
   222       end
   229       end
   223   end
   230   end
   224 
   231 
   225 val mk_tester =
   232 val mk_tester =
   226   gen_mk_tester (fn ctxt => AList.lookup (op =) ((fst o fst o Data.get o Context.Proof) ctxt))
   233   gen_mk_tester (fn ctxt => AList.lookup (op =) ((fst o fst o fst o Data.get o Context.Proof) ctxt))
   227 val mk_batch_tester =
   234 val mk_batch_tester =
   228   gen_mk_tester (fn ctxt => AList.lookup (op =) ((fst o snd o fst o Data.get o Context.Proof) ctxt))
   235   gen_mk_tester (fn ctxt => AList.lookup (op =) ((fst o snd o fst o Data.get o Context.Proof) ctxt))
   229 val mk_batch_validator =
   236 val mk_batch_validator =
   230   gen_mk_tester (fn ctxt => AList.lookup (op =) ((snd o snd o fst o Data.get o Context.Proof) ctxt))
   237   gen_mk_tester (fn ctxt => AList.lookup (op =) ((snd o snd o fst o Data.get o Context.Proof) ctxt))
       
   238 
       
   239   
       
   240 fun lookup_tester ctxt = AList.lookup (op =) ((snd o fst o fst o Data.get o Context.Proof) ctxt)
   231 
   241 
   232 (* testing propositions *)
   242 (* testing propositions *)
   233 
   243 
   234 fun check_test_term t =
   244 fun check_test_term t =
   235   let
   245   let
   468     val check_goals = case some_locale
   478     val check_goals = case some_locale
   469      of NONE => [(proto_goal, eval_terms)]
   479      of NONE => [(proto_goal, eval_terms)]
   470       | SOME locale =>
   480       | SOME locale =>
   471         map (fn (_, phi) => (Morphism.term phi proto_goal, map (Morphism.term phi) eval_terms))
   481         map (fn (_, phi) => (Morphism.term phi proto_goal, map (Morphism.term phi) eval_terms))
   472           (Locale.registrations_of (Context.Theory thy) (*FIXME*) locale);
   482           (Locale.registrations_of (Context.Theory thy) (*FIXME*) locale);
   473   in
   483     val test_goals = the_default test_goal_terms (lookup_tester lthy (Config.get lthy tester))
   474     test_goal_terms lthy (time_limit, is_interactive) insts check_goals
   484   in
       
   485     test_goals lthy (time_limit, is_interactive) insts check_goals
   475   end
   486   end
   476 
   487 
   477 (* pretty printing *)
   488 (* pretty printing *)
   478 
   489 
   479 fun tool_name auto = (if auto then "Auto " else "") ^ "Quickcheck"
   490 fun tool_name auto = (if auto then "Auto " else "") ^ "Quickcheck"
   542 fun read_expectation "no_expectation" = No_Expectation
   553 fun read_expectation "no_expectation" = No_Expectation
   543   | read_expectation "no_counterexample" = No_Counterexample
   554   | read_expectation "no_counterexample" = No_Counterexample
   544   | read_expectation "counterexample" = Counterexample
   555   | read_expectation "counterexample" = Counterexample
   545   | read_expectation s = error ("Not an expectation value: " ^ s)
   556   | read_expectation s = error ("Not an expectation value: " ^ s)
   546 
   557 
   547 fun valid_tester_name genctxt = AList.defined (op =) (fst (fst (Data.get genctxt)))
   558 fun valid_tester_name genctxt = AList.defined (op =) (fst (fst (fst (Data.get genctxt))))
   548 
   559 
   549 fun parse_tester name genctxt =
   560 fun parse_tester name genctxt =
   550   if valid_tester_name genctxt name then
   561   if valid_tester_name genctxt name then
   551     Config.put_generic tester name genctxt
   562     Config.put_generic tester name genctxt
   552   else
   563   else