38397
|
1 |
(* Title: HOL/Tools/quickcheck_record.ML
|
|
2 |
Author: Florian Haftmann, TU Muenchen
|
|
3 |
|
|
4 |
Quickcheck generators for records.
|
|
5 |
*)
|
|
6 |
|
|
7 |
signature QUICKCHECK_RECORD =
|
|
8 |
sig
|
38528
|
9 |
val ensure_random_typecopy: string -> (string * sort) list -> string
|
|
10 |
-> typ -> theory -> theory
|
38397
|
11 |
end;
|
|
12 |
|
|
13 |
structure Quickcheck_Record : QUICKCHECK_RECORD =
|
|
14 |
struct
|
|
15 |
|
|
16 |
fun termifyT T = HOLogic.mk_prodT (T, @{typ "unit => term"})
|
|
17 |
val size = @{term "i::code_numeral"};
|
|
18 |
|
|
19 |
fun mk_random_typecopy tyco vs constr T' thy =
|
|
20 |
let
|
|
21 |
val mk_const = curry (Sign.mk_const thy);
|
|
22 |
val Ts = map TFree vs;
|
|
23 |
val T = Type (tyco, Ts);
|
|
24 |
val Tm = termifyT T;
|
|
25 |
val Tm' = termifyT T';
|
|
26 |
val v = "x";
|
|
27 |
val t_v = Free (v, Tm');
|
|
28 |
val t_constr = Const (constr, T' --> T);
|
|
29 |
val lhs = HOLogic.mk_random T size;
|
|
30 |
val rhs = HOLogic.mk_ST [((HOLogic.mk_random T' size, @{typ Random.seed}), SOME (v, Tm'))]
|
|
31 |
(HOLogic.mk_return Tm @{typ Random.seed}
|
|
32 |
(mk_const "Code_Evaluation.valapp" [T', T]
|
|
33 |
$ HOLogic.mk_prod (t_constr, Abs ("u", @{typ unit}, HOLogic.reflect_term t_constr)) $ t_v))
|
|
34 |
@{typ Random.seed} (SOME Tm, @{typ Random.seed});
|
|
35 |
val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
|
|
36 |
in
|
|
37 |
thy
|
|
38 |
|> Class.instantiation ([tyco], vs, @{sort random})
|
|
39 |
|> `(fn lthy => Syntax.check_term lthy eq)
|
|
40 |
|-> (fn eq => Specification.definition (NONE, (apfst Binding.conceal Attrib.empty_binding, eq)))
|
|
41 |
|> snd
|
|
42 |
|> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
|
|
43 |
end;
|
|
44 |
|
38528
|
45 |
fun ensure_random_typecopy tyco raw_vs constr raw_T thy =
|
38397
|
46 |
let
|
|
47 |
val constrain = curry (Sorts.inter_sort (Sign.classes_of thy));
|
|
48 |
val T = map_atyps (fn TFree (v, sort) =>
|
|
49 |
TFree (v, constrain sort @{sort random})) raw_T;
|
|
50 |
val vs' = Term.add_tfreesT T [];
|
|
51 |
val vs = map (fn (v, sort) =>
|
|
52 |
(v, the_default (constrain sort @{sort typerep}) (AList.lookup (op =) vs' v))) raw_vs;
|
|
53 |
val can_inst = Sign.of_sort thy (T, @{sort random});
|
|
54 |
in if can_inst then mk_random_typecopy tyco vs constr T thy else thy end;
|
|
55 |
|
|
56 |
end;
|