5 *) |
5 *) |
6 |
6 |
7 signature QUICKCHECK_COMMON = |
7 signature QUICKCHECK_COMMON = |
8 sig |
8 sig |
9 val strip_imp : term -> (term list * term) |
9 val strip_imp : term -> (term list * term) |
|
10 val reflect_bool : bool -> term |
10 val define_functions : ((term list -> term list) * (Proof.context -> tactic) option) |
11 val define_functions : ((term list -> term list) * (Proof.context -> tactic) option) |
11 -> string -> string list -> string list -> typ list -> Proof.context -> Proof.context |
12 -> string -> string list -> string list -> typ list -> Proof.context -> Proof.context |
12 val perhaps_constrain: theory -> (typ * sort) list -> (string * sort) list |
13 val perhaps_constrain: theory -> (typ * sort) list -> (string * sort) list |
13 -> (string * sort -> string * sort) option |
14 -> (string * sort -> string * sort) option |
14 val instantiate_goals: Proof.context -> (string * typ) list -> (term * term list) list |
15 val instantiate_goals: Proof.context -> (string * typ) list -> (term * term list) list |
15 -> (typ option * (term * term list)) list list |
16 -> (typ option * (term * term list)) list list |
16 val mk_safe_if : Proof.context -> (term * term * term) -> term |
17 val mk_safe_if : Proof.context -> term * term * (bool -> term) -> term |
17 val collect_results : ('a -> Quickcheck.result) -> 'a list -> Quickcheck.result list -> Quickcheck.result list |
18 val collect_results : ('a -> Quickcheck.result) -> 'a list -> Quickcheck.result list -> Quickcheck.result list |
18 type compile_generator = |
19 type compile_generator = |
19 Proof.context -> (term * term list) list -> int list -> term list option * Quickcheck.report option |
20 Proof.context -> (term * term list) list -> int list -> term list option * Quickcheck.report option |
20 val generator_test_goal_terms : |
21 val generator_test_goal_terms : |
21 string * compile_generator -> Proof.context -> bool -> (string * typ) list |
22 string * compile_generator -> Proof.context -> bool -> (string * typ) list |
42 |
43 |
43 (* HOLogic's term functions *) |
44 (* HOLogic's term functions *) |
44 |
45 |
45 fun strip_imp (Const(@{const_name HOL.implies},_) $ A $ B) = apfst (cons A) (strip_imp B) |
46 fun strip_imp (Const(@{const_name HOL.implies},_) $ A $ B) = apfst (cons A) (strip_imp B) |
46 | strip_imp A = ([], A) |
47 | strip_imp A = ([], A) |
|
48 |
|
49 fun reflect_bool b = if b then @{term "True"} else @{term "False"} |
47 |
50 |
48 fun mk_undefined T = Const(@{const_name undefined}, T) |
51 fun mk_undefined T = Const(@{const_name undefined}, T) |
49 |
52 |
50 (* testing functions: testing with increasing sizes (and cardinalities) *) |
53 (* testing functions: testing with increasing sizes (and cardinalities) *) |
51 |
54 |
139 handle TimeLimit.TimeOut => NONE)) test_funs) |
142 handle TimeLimit.TimeOut => NONE)) test_funs) |
140 in |
143 in |
141 (Option.map (map2 (fn names => Option.map (fn ts => names ~~ ts)) namess) results, |
144 (Option.map (map2 (fn names => Option.map (fn ts => names ~~ ts)) namess) results, |
142 [comp_time, exec_time]) |
145 [comp_time, exec_time]) |
143 end |
146 end |
144 |
|
145 |
147 |
146 fun test_term_with_cardinality (name, compile) ctxt catch_code_errors ts = |
148 fun test_term_with_cardinality (name, compile) ctxt catch_code_errors ts = |
147 let |
149 let |
148 val thy = Proof_Context.theory_of ctxt |
150 val thy = Proof_Context.theory_of ctxt |
149 val (ts', eval_terms) = split_list ts |
151 val (ts', eval_terms) = split_list ts |
267 end |
269 end |
268 |
270 |
269 (* compilation of testing functions *) |
271 (* compilation of testing functions *) |
270 |
272 |
271 fun mk_safe_if ctxt (cond, then_t, else_t) = |
273 fun mk_safe_if ctxt (cond, then_t, else_t) = |
272 @{term "Quickcheck.catch_match :: term list option => term list option => term list option"} |
274 @{term "Quickcheck.catch_match :: (bool * term list) option => (bool * term list) option => (bool * term list) option"} |
273 $ (@{term "If :: bool => term list option => term list option => term list option"} |
275 $ (@{term "If :: bool => (bool * term list) option => (bool * term list) option => (bool * term list) option"} |
274 $ cond $ then_t $ else_t) |
276 $ cond $ then_t $ else_t true) |
275 $ (if Config.get ctxt Quickcheck.potential then else_t else @{term "None :: term list option"}); |
277 $ (if Config.get ctxt Quickcheck.potential then else_t false else @{term "None :: term list option"}); |
276 |
278 |
277 fun collect_results f [] results = results |
279 fun collect_results f [] results = results |
278 | collect_results f (t :: ts) results = |
280 | collect_results f (t :: ts) results = |
279 let |
281 let |
280 val result = f t |
282 val result = f t |
377 (** generic parametric compilation **) |
379 (** generic parametric compilation **) |
378 |
380 |
379 fun gen_mk_parametric_generator_expr ((mk_generator_expr, out_of_bounds), T) ctxt ts = |
381 fun gen_mk_parametric_generator_expr ((mk_generator_expr, out_of_bounds), T) ctxt ts = |
380 let |
382 let |
381 val if_t = Const (@{const_name "If"}, @{typ bool} --> T --> T --> T) |
383 val if_t = Const (@{const_name "If"}, @{typ bool} --> T --> T --> T) |
382 fun mk_if (index, (t, eval_terms)) else_t = |
384 fun mk_if (index, (t, eval_terms)) else_t = if_t $ |
383 if_t $ (HOLogic.eq_const @{typ code_numeral} $ Bound 0 $ HOLogic.mk_number @{typ code_numeral} index) $ |
385 (HOLogic.eq_const @{typ code_numeral} $ Bound 0 $ HOLogic.mk_number @{typ code_numeral} index) $ |
384 (mk_generator_expr ctxt (t, eval_terms)) $ else_t |
386 (mk_generator_expr ctxt (t, eval_terms)) $ else_t |
385 in |
387 in |
386 absdummy @{typ "code_numeral"} (fold_rev mk_if (1 upto (length ts) ~~ ts) out_of_bounds) |
388 absdummy @{typ "code_numeral"} (fold_rev mk_if (1 upto (length ts) ~~ ts) out_of_bounds) |
387 end |
389 end |
388 |
390 |