968 >> (fn ((print_modes, soln), t) => Toplevel.keep |
968 >> (fn ((print_modes, soln), t) => Toplevel.keep |
969 (values_cmd print_modes soln t))); (*FIXME does not preserve the previous functionality*) |
969 (values_cmd print_modes soln t))); (*FIXME does not preserve the previous functionality*) |
970 |
970 |
971 (* quickcheck generator *) |
971 (* quickcheck generator *) |
972 |
972 |
973 (* FIXME: large copy of Predicate_Compile_Quickcheck - refactor out commons *) |
973 (* FIXME: a small clone of Predicate_Compile_Quickcheck - maybe refactor out commons *) |
974 |
|
975 fun strip_imp_prems (Const(@{const_name HOL.implies}, _) $ A $ B) = A :: strip_imp_prems B |
|
976 | strip_imp_prems _ = []; |
|
977 |
|
978 fun strip_imp_concl (Const(@{const_name HOL.implies}, _) $ A $ B) = strip_imp_concl B |
|
979 | strip_imp_concl A = A : term; |
|
980 |
|
981 fun strip_horn A = (strip_imp_prems A, strip_imp_concl A); |
|
982 |
974 |
983 fun quickcheck ctxt t size = |
975 fun quickcheck ctxt t size = |
984 let |
976 let |
985 val options = code_options_of (ProofContext.theory_of ctxt) |
977 val options = code_options_of (ProofContext.theory_of ctxt) |
986 val thy = Theory.copy (ProofContext.theory_of ctxt) |
978 val thy = Theory.copy (ProofContext.theory_of ctxt) |
987 val (vs, t') = strip_abs t |
979 val ((((full_constname, constT), vs'), intro), thy1) = |
988 val vs' = Variable.variant_frees ctxt [] vs |
980 Predicate_Compile_Aux.define_quickcheck_predicate t thy |
989 val Ts = map snd vs' |
|
990 val t'' = subst_bounds (map Free (rev vs'), t') |
|
991 val (prems, concl) = strip_horn t'' |
|
992 val constname = "quickcheck" |
|
993 val full_constname = Sign.full_bname thy constname |
|
994 val constT = Ts ---> @{typ bool} |
|
995 val thy1 = Sign.add_consts_i [(Binding.name constname, constT, NoSyn)] thy |
|
996 val const = Const (full_constname, constT) |
|
997 val t = Logic.list_implies |
|
998 (map HOLogic.mk_Trueprop (prems @ [HOLogic.mk_not concl]), |
|
999 HOLogic.mk_Trueprop (list_comb (Const (full_constname, constT), map Free vs'))) |
|
1000 val tac = fn _ => Skip_Proof.cheat_tac thy1 |
|
1001 val intro = Goal.prove (ProofContext.init_global thy1) (map fst vs') [] t tac |
|
1002 val thy2 = Context.theory_map (Predicate_Compile_Alternative_Defs.add_thm intro) thy1 |
981 val thy2 = Context.theory_map (Predicate_Compile_Alternative_Defs.add_thm intro) thy1 |
1003 val thy3 = Predicate_Compile.preprocess preprocess_options const thy2 |
982 val thy3 = Predicate_Compile.preprocess preprocess_options (Const (full_constname, constT)) thy2 |
1004 val ctxt' = ProofContext.init_global thy3 |
983 val ctxt' = ProofContext.init_global thy3 |
1005 val _ = tracing "Generating prolog program..." |
984 val _ = tracing "Generating prolog program..." |
1006 val (p, constant_table) = generate (NONE, true) ctxt' full_constname |
985 val (p, constant_table) = generate (NONE, true) ctxt' full_constname |
1007 |> add_ground_predicates ctxt' (#limited_types options) |
986 |> add_ground_predicates ctxt' (#limited_types options) |
1008 |> add_limited_predicates (#limited_predicates options) |
987 |> add_limited_predicates (#limited_predicates options) |
1013 val tss = run (#timeout system_config, #prolog_system system_config) |
992 val tss = run (#timeout system_config, #prolog_system system_config) |
1014 p (translate_const constant_table full_constname, map (Var o fst) vs') (map fst vs') (SOME 1) |
993 p (translate_const constant_table full_constname, map (Var o fst) vs') (map fst vs') (SOME 1) |
1015 val _ = tracing "Restoring terms..." |
994 val _ = tracing "Restoring terms..." |
1016 val res = |
995 val res = |
1017 case tss of |
996 case tss of |
1018 [ts] => SOME (map (restore_term ctxt' constant_table) (ts ~~ Ts)) |
997 [ts] => SOME (map (restore_term ctxt' constant_table) (ts ~~ map snd vs')) |
1019 | _ => NONE |
998 | _ => NONE |
1020 val empty_report = ([], false) |
999 val empty_report = ([], false) |
1021 in |
1000 in |
1022 (res, empty_report) |
1001 (res, empty_report) |
1023 end; |
1002 end; |