81 val abort_potential = Config.get ctxt Quickcheck.abort_potential |
81 val abort_potential = Config.get ctxt Quickcheck.abort_potential |
82 val _ = check_test_term t |
82 val _ = check_test_term t |
83 val names = Term.add_free_names t [] |
83 val names = Term.add_free_names t [] |
84 val current_size = Unsynchronized.ref 0 |
84 val current_size = Unsynchronized.ref 0 |
85 val current_result = Unsynchronized.ref Quickcheck.empty_result |
85 val current_result = Unsynchronized.ref Quickcheck.empty_result |
86 fun excipit () = |
|
87 "Quickcheck ran out of time while testing at size " ^ string_of_int (!current_size) |
|
88 val act = if catch_code_errors then try else (fn f => SOME o f) |
86 val act = if catch_code_errors then try else (fn f => SOME o f) |
89 val (test_fun, comp_time) = cpu_time "quickcheck compilation" |
87 val (test_fun, comp_time) = cpu_time "quickcheck compilation" |
90 (fn () => act (compile ctxt) [(t, eval_terms)]); |
88 (fn () => act (compile ctxt) [(t, eval_terms)]); |
91 val _ = Quickcheck.add_timing comp_time current_result |
89 val _ = Quickcheck.add_timing comp_time current_result |
92 fun with_size test_fun genuine_only k = |
90 fun with_size test_fun genuine_only k = |
132 val _ = Quickcheck.add_response names eval_terms response current_result |
130 val _ = Quickcheck.add_response names eval_terms response current_result |
133 val _ = Quickcheck.add_timing exec_time current_result |
131 val _ = Quickcheck.add_timing exec_time current_result |
134 in !current_result end |
132 in !current_result end |
135 end; |
133 end; |
136 |
134 |
137 fun validate_terms ctxt ts = |
|
138 let |
|
139 val _ = map check_test_term ts |
|
140 val size = Config.get ctxt Quickcheck.size |
|
141 val (test_funs, comp_time) = cpu_time "quickcheck batch compilation" |
|
142 (fn () => Quickcheck.mk_batch_validator ctxt ts) |
|
143 fun with_size tester k = |
|
144 if k > size then true |
|
145 else if tester k then with_size tester (k + 1) else false |
|
146 val (results, exec_time) = cpu_time "quickcheck batch execution" (fn () => |
|
147 Option.map (map (fn test_fun => |
|
148 TimeLimit.timeLimit (seconds (Config.get ctxt Quickcheck.timeout)) |
|
149 (fn () => with_size test_fun 1) () |
|
150 handle TimeLimit.TimeOut => true)) test_funs) |
|
151 in |
|
152 (results, [comp_time, exec_time]) |
|
153 end |
|
154 |
|
155 fun test_terms ctxt ts = |
|
156 let |
|
157 val _ = map check_test_term ts |
|
158 val size = Config.get ctxt Quickcheck.size |
|
159 val namess = map (fn t => Term.add_free_names t []) ts |
|
160 val (test_funs, comp_time) = |
|
161 cpu_time "quickcheck batch compilation" (fn () => Quickcheck.mk_batch_tester ctxt ts) |
|
162 fun with_size tester k = |
|
163 if k > size then NONE |
|
164 else case tester k of SOME ts => SOME ts | NONE => with_size tester (k + 1) |
|
165 val (results, exec_time) = cpu_time "quickcheck batch execution" (fn () => |
|
166 Option.map (map (fn test_fun => |
|
167 TimeLimit.timeLimit (seconds (Config.get ctxt Quickcheck.timeout)) |
|
168 (fn () => with_size test_fun 1) () |
|
169 handle TimeLimit.TimeOut => NONE)) test_funs) |
|
170 in |
|
171 (Option.map (map2 (fn names => Option.map (fn ts => names ~~ ts)) namess) results, |
|
172 [comp_time, exec_time]) |
|
173 end |
|
174 |
|
175 fun test_term_with_cardinality (name, (size_matters_for, compile)) ctxt catch_code_errors ts = |
135 fun test_term_with_cardinality (name, (size_matters_for, compile)) ctxt catch_code_errors ts = |
176 let |
136 let |
177 val genuine_only = Config.get ctxt Quickcheck.genuine_only |
137 val genuine_only = Config.get ctxt Quickcheck.genuine_only |
178 val abort_potential = Config.get ctxt Quickcheck.abort_potential |
138 val abort_potential = Config.get ctxt Quickcheck.abort_potential |
179 val thy = Proof_Context.theory_of ctxt |
139 val thy = Proof_Context.theory_of ctxt |
292 val register_predicate = Subtype_Predicates.map o AList.update (op =) |
252 val register_predicate = Subtype_Predicates.map o AList.update (op =) |
293 |
253 |
294 fun subtype_preprocess ctxt (T, (t, ts)) = |
254 fun subtype_preprocess ctxt (T, (t, ts)) = |
295 let |
255 let |
296 val preds = Subtype_Predicates.get (Context.Proof ctxt) |
256 val preds = Subtype_Predicates.get (Context.Proof ctxt) |
297 fun matches (p $ x) = AList.defined Term.could_unify preds p |
257 fun matches (p $ _) = AList.defined Term.could_unify preds p |
298 fun get_match (p $ x) = Option.map (rpair x) (AList.lookup Term.could_unify preds p) |
258 fun get_match (p $ x) = Option.map (rpair x) (AList.lookup Term.could_unify preds p) |
299 fun subst_of (tyco, v as Free (x, repT)) = |
259 fun subst_of (tyco, v as Free (x, repT)) = |
300 let |
260 let |
301 val [(info, _)] = Typedef.get_info ctxt tyco |
261 val [(info, _)] = Typedef.get_info ctxt tyco |
302 val repT' = Logic.varifyT_global (#rep_type info) |
262 val repT' = Logic.varifyT_global (#rep_type info) |
328 handle WELLSORTED s => (SOME T, Wellsorted_Error s)) (default_insts lthy) |
288 handle WELLSORTED s => (SOME T, Wellsorted_Error s)) (default_insts lthy) |
329 else |
289 else |
330 [(NONE, Term (preprocess lthy check_goal, eval_terms))]) goals |
290 [(NONE, Term (preprocess lthy check_goal, eval_terms))]) goals |
331 val error_msg = |
291 val error_msg = |
332 cat_lines |
292 cat_lines |
333 (maps (map_filter (fn (_, Term t) => NONE | (_, Wellsorted_Error s) => SOME s)) inst_goals) |
293 (maps (map_filter (fn (_, Term _) => NONE | (_, Wellsorted_Error s) => SOME s)) inst_goals) |
334 fun is_wellsorted_term (T, Term t) = SOME (T, t) |
294 fun is_wellsorted_term (T, Term t) = SOME (T, t) |
335 | is_wellsorted_term (_, Wellsorted_Error s) = NONE |
295 | is_wellsorted_term (_, Wellsorted_Error _) = NONE |
336 val correct_inst_goals = |
296 val correct_inst_goals = |
337 case map (map_filter is_wellsorted_term) inst_goals of |
297 case map (map_filter is_wellsorted_term) inst_goals of |
338 [[]] => error error_msg |
298 [[]] => error error_msg |
339 | xs => xs |
299 | xs => xs |
340 val _ = if Config.get lthy Quickcheck.quiet then () else warning error_msg |
300 val _ = if Config.get lthy Quickcheck.quiet then () else warning error_msg |
496 fun make_set T1 [] = Const (@{const_abbrev Set.empty}, T1 --> @{typ bool}) |
456 fun make_set T1 [] = Const (@{const_abbrev Set.empty}, T1 --> @{typ bool}) |
497 | make_set T1 ((_, @{const False}) :: tps) = make_set T1 tps |
457 | make_set T1 ((_, @{const False}) :: tps) = make_set T1 tps |
498 | make_set T1 ((t1, @{const True}) :: tps) = |
458 | make_set T1 ((t1, @{const True}) :: tps) = |
499 Const (@{const_name insert}, T1 --> (T1 --> @{typ bool}) --> T1 --> @{typ bool}) |
459 Const (@{const_name insert}, T1 --> (T1 --> @{typ bool}) --> T1 --> @{typ bool}) |
500 $ t1 $ (make_set T1 tps) |
460 $ t1 $ (make_set T1 tps) |
501 | make_set T1 ((_, t) :: tps) = raise TERM ("make_set", [t]) |
461 | make_set T1 ((_, t) :: _) = raise TERM ("make_set", [t]) |
502 |
462 |
503 fun make_coset T [] = Const (@{const_abbrev UNIV}, T --> @{typ bool}) |
463 fun make_coset T [] = Const (@{const_abbrev UNIV}, T --> @{typ bool}) |
504 | make_coset T tps = |
464 | make_coset T tps = |
505 let |
465 let |
506 val U = T --> @{typ bool} |
466 val U = T --> @{typ bool} |