src/HOL/Tools/Quickcheck/abstract_generators.ML
author bulwahn
Tue, 20 Dec 2011 17:39:56 +0100
changeset 45925 cd4243c025bb
child 45940 71970a26a269
permissions -rw-r--r--
quickcheck generators for abstract types; tuned
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45925
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     1
(*  Title:      HOL/Tools/Quickcheck/abstract_generators.ML
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     2
    Author:     Lukas Bulwahn, TU Muenchen
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     3
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     4
Quickcheck generators for abstract types.
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     5
*)
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     6
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     7
signature ABSTRACT_GENERATORS =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     8
sig
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
     9
  val quickcheck_generator : string -> term list -> theory -> theory
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    10
end;
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    11
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    12
structure Abstract_Generators : ABSTRACT_GENERATORS =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    13
struct
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    14
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    15
fun check_constrs ctxt tyco constrs =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    16
  let
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    17
    fun check_type c =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    18
      case try (dest_Type o body_type o fastype_of) c of
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    19
        NONE => error (Syntax.string_of_term ctxt c ^ " has mismatching result type.")
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    20
      | SOME (tyco', vs) => if not (tyco' = tyco) then
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    21
            error (Syntax.string_of_term ctxt c ^ " has mismatching result type. " ^
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    22
              "Expected type constructor " ^ quote tyco ^ ", but found " ^ quote tyco' ^ ".")
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    23
          else
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    24
            case try (map dest_TFree) vs of
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    25
              NONE => error (Syntax.string_of_term ctxt c ^ " has mismatching result type.")
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    26
            | SOME _ => ()
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    27
  in
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    28
    map check_type constrs
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    29
  end
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    30
  
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    31
fun gen_quickcheck_generator prep_tyco prep_term tyco_raw constrs_raw thy =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    32
  let
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    33
    val ctxt = Proof_Context.init_global thy
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    34
    val tyco = prep_tyco ctxt tyco_raw
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    35
    val constrs = map (prep_term ctxt) constrs_raw
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    36
    val _ = check_constrs ctxt tyco constrs 
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    37
    val vs = map dest_TFree (snd (dest_Type (body_type (fastype_of (hd constrs)))))
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    38
    val name = Long_Name.base_name tyco 
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    39
    fun mk_dconstrs (Const (s, T)) =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    40
        (s, map (Datatype_Aux.dtyp_of_typ [(tyco, vs)]) (binder_types T))
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    41
      | mk_dconstrs t = error (Syntax.string_of_term ctxt t ^
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    42
          " is not a valid constructor for quickcheck_generator, which expects a constant.")
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    43
    fun the_descr thy _ =
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    44
      let
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    45
        val descr = [(0, (tyco, map Datatype_Aux.DtTFree vs, map mk_dconstrs constrs))]
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    46
      in
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    47
        (descr, vs, [tyco], name, ([name], []), ([Type (tyco, map TFree vs)], []))
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    48
      end
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    49
  in
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    50
    Quickcheck_Common.ensure_sort (((@{sort typerep}, @{sort term_of}), @{sort full_exhaustive}),
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    51
        (the_descr, Exhaustive_Generators.instantiate_full_exhaustive_datatype))
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    52
      Datatype_Aux.default_config [tyco] thy
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    53
  end
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    54
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    55
val quickcheck_generator = gen_quickcheck_generator (K I) (K I)
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    56
  
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    57
val quickcheck_generator_cmd = gen_quickcheck_generator
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    58
  (fn ctxt => fst o dest_Type o Proof_Context.read_type_name_proper ctxt false) Syntax.read_term
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    59
  
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    60
val _ = Outer_Syntax.command "quickcheck_generator" "define quickcheck generators for abstract types"
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    61
    Keyword.thy_decl (Parse.type_const -- (Args.$$$ "constructors" |-- Parse.$$$ ":" |-- Parse.list1 Parse.term)
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    62
      >> (fn (tyco, constrs) => Toplevel.theory (quickcheck_generator_cmd tyco constrs)))
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    63
cd4243c025bb quickcheck generators for abstract types; tuned
bulwahn
parents:
diff changeset
    64
end;