src/HOL/Tools/Quickcheck/quickcheck_common.ML
changeset 45721 d1fb55c2ed65
parent 45719 39c52a820f6e
child 45724 1f5fc44254d7
equal deleted inserted replaced
45720:d8fbd3fa0375 45721:d1fb55c2ed65
     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