src/HOL/Tools/Quickcheck/exhaustive_generators.ML
changeset 42214 9ca13615c619
parent 42195 1e7b62c93f5d
child 42229 1491b7209e76
equal deleted inserted replaced
42213:bac7733a13c9 42214:9ca13615c619
    21 end;
    21 end;
    22 
    22 
    23 structure Exhaustive_Generators : EXHAUSTIVE_GENERATORS =
    23 structure Exhaustive_Generators : EXHAUSTIVE_GENERATORS =
    24 struct
    24 struct
    25 
    25 
    26 (* static options *)
       
    27 
       
    28 val define_foundationally = false
       
    29 
       
    30 (* dynamic options *)
    26 (* dynamic options *)
    31 
    27 
    32 val (smart_quantifier, setup_smart_quantifier) =
    28 val (smart_quantifier, setup_smart_quantifier) =
    33   Attrib.config_bool "quickcheck_smart_quantifier" (K true)
    29   Attrib.config_bool "quickcheck_smart_quantifier" (K true)
    34 
    30 
    69 
    65 
    70 fun mk_none_continuation (x, y) =
    66 fun mk_none_continuation (x, y) =
    71   let
    67   let
    72     val (T as Type(@{type_name "option"}, [T'])) = fastype_of x
    68     val (T as Type(@{type_name "option"}, [T'])) = fastype_of x
    73   in
    69   in
    74     Const (@{const_name "Quickcheck_Exhaustive.orelse"}, T --> T --> T)
    70     Const (@{const_name "Quickcheck_Exhaustive.orelse"}, T --> T --> T) $ x $ y
    75       $ x $ y
       
    76   end
    71   end
    77 
    72 
    78 (** datatypes **)
    73 (** datatypes **)
    79 
    74 
    80 (* constructing exhaustive generator instances on datatypes *)
    75 (* constructing exhaustive generator instances on datatypes *)
   155   THEN rtac @{thm wf_measure} 1
   150   THEN rtac @{thm wf_measure} 1
   156   THEN (REPEAT_DETERM (Simplifier.asm_full_simp_tac 
   151   THEN (REPEAT_DETERM (Simplifier.asm_full_simp_tac 
   157     (HOL_basic_ss addsimps [@{thm in_measure}, @{thm o_def}, @{thm snd_conv},
   152     (HOL_basic_ss addsimps [@{thm in_measure}, @{thm o_def}, @{thm snd_conv},
   158      @{thm nat_mono_iff}, less_int_pred] @ @{thms sum.cases}) 1))
   153      @{thm nat_mono_iff}, less_int_pred] @ @{thms sum.cases}) 1))
   159 
   154 
   160 fun pat_completeness_auto ctxt =
       
   161   Pat_Completeness.pat_completeness_tac ctxt 1
       
   162   THEN auto_tac (clasimpset_of ctxt)    
       
   163 
       
   164 
       
   165 (* creating the instances *)
   155 (* creating the instances *)
   166 
   156 
   167 fun instantiate_exhaustive_datatype config descr vs tycos prfx (names, auxnames) (Ts, Us) thy =
   157 fun instantiate_exhaustive_datatype config descr vs tycos prfx (names, auxnames) (Ts, Us) thy =
   168   let
   158   let
   169     val _ = Datatype_Aux.message config "Creating exhaustive generators ...";
   159     val _ = Datatype_Aux.message config "Creating exhaustive generators ...";
   170     val exhaustivesN = map (prefix (exhaustiveN ^ "_")) (names @ auxnames);
   160     val exhaustivesN = map (prefix (exhaustiveN ^ "_")) (names @ auxnames);
   171   in
   161   in
   172     thy
   162     thy
   173     |> Class.instantiation (tycos, vs, @{sort exhaustive})
   163     |> Class.instantiation (tycos, vs, @{sort exhaustive})
   174     |> (if define_foundationally then
   164     |> Quickcheck_Common.define_functions
   175       let
   165         (fn exhaustives => mk_equations descr vs tycos exhaustives (Ts, Us), SOME termination_tac)
   176         val exhaustives = map2 (fn name => fn T => Free (name, exhaustiveT T)) exhaustivesN (Ts @ Us)
   166         prfx ["f", "i"] exhaustivesN (map exhaustiveT (Ts @ Us))
   177         val eqs = mk_equations descr vs tycos exhaustives (Ts, Us)
       
   178       in
       
   179         Function.add_function
       
   180           (map (fn (name, T) =>
       
   181               Syntax.no_syn (Binding.conceal (Binding.name name), SOME (exhaustiveT T)))
       
   182                 (exhaustivesN ~~ (Ts @ Us)))
       
   183             (map (pair (apfst Binding.conceal Attrib.empty_binding)) eqs)
       
   184           Function_Common.default_config pat_completeness_auto
       
   185         #> snd
       
   186         #> Local_Theory.restore
       
   187         #> (fn lthy => Function.prove_termination NONE (termination_tac lthy) lthy)
       
   188         #> snd
       
   189       end
       
   190     else
       
   191       fold_map (fn (name, T) => Local_Theory.define
       
   192           ((Binding.conceal (Binding.name name), NoSyn),
       
   193             (apfst Binding.conceal Attrib.empty_binding, mk_undefined (exhaustiveT T)))
       
   194         #> apfst fst) (exhaustivesN ~~ (Ts @ Us))
       
   195       #> (fn (exhaustives, lthy) =>
       
   196         let
       
   197           val eqs_t = mk_equations descr vs tycos exhaustives (Ts, Us)
       
   198           val eqs = map (fn eq => Goal.prove lthy ["f", "i"] [] eq
       
   199             (fn _ => Skip_Proof.cheat_tac (ProofContext.theory_of lthy))) eqs_t
       
   200         in
       
   201           fold (fn (name, eq) => Local_Theory.note
       
   202           ((Binding.conceal (Binding.qualify true prfx
       
   203              (Binding.qualify true name (Binding.name "simps"))),
       
   204              Code.add_default_eqn_attrib :: map (Attrib.internal o K)
       
   205                [Simplifier.simp_add, Nitpick_Simps.add]), [eq]) #> snd) (exhaustivesN ~~ eqs) lthy
       
   206         end))
       
   207     |> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
   167     |> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
   208   end handle FUNCTION_TYPE =>
   168   end handle FUNCTION_TYPE =>
   209     (Datatype_Aux.message config
   169     (Datatype_Aux.message config
   210       "Creation of exhaustive generators failed because the datatype contains a function type";
   170       "Creation of exhaustive generators failed because the datatype contains a function type";
   211     thy)
   171     thy)