src/HOL/Tools/Quickcheck/quickcheck_common.ML
changeset 50046 0051dc4f301f
parent 48272 db75b4005d9a
child 51126 df86080de4cb
equal deleted inserted replaced
50045:2214bc566f88 50046:0051dc4f301f
    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}