43 val set_default_param : (string * string) -> theory -> theory |
43 val set_default_param : (string * string) -> theory -> theory |
44 val get_default_param : theory -> string -> string option |
44 val get_default_param : theory -> string -> string option |
45 val get_default_params : theory -> (string * string) list |
45 val get_default_params : theory -> (string * string) list |
46 val actual_params : theory -> (string * string) list -> params |
46 val actual_params : theory -> (string * string) list -> params |
47 |
47 |
48 val find_model : theory -> params -> term -> bool -> unit |
48 val find_model : theory -> params -> term list -> term -> bool -> unit |
49 |
49 |
50 (* tries to find a model for a formula: *) |
50 (* tries to find a model for a formula: *) |
51 val satisfy_term : theory -> (string * string) list -> term -> unit |
51 val satisfy_term : |
|
52 theory -> (string * string) list -> term list -> term -> unit |
52 (* tries to find a model that refutes a formula: *) |
53 (* tries to find a model that refutes a formula: *) |
53 val refute_term : theory -> (string * string) list -> term -> unit |
54 val refute_term : |
54 val refute_goal : theory -> (string * string) list -> thm -> int -> unit |
55 theory -> (string * string) list -> term list -> term -> unit |
|
56 val refute_goal : |
|
57 Proof.context -> (string * string) list -> thm -> int -> unit |
55 |
58 |
56 val setup : theory -> theory |
59 val setup : theory -> theory |
57 |
60 |
58 (* ------------------------------------------------------------------------- *) |
61 (* ------------------------------------------------------------------------- *) |
59 (* Additional functions used by Nitpick (to be factored out) *) |
62 (* Additional functions used by Nitpick (to be factored out) *) |
151 (* "maxvars" int If >0, use at most 'maxvars' Boolean variables *) |
154 (* "maxvars" int If >0, use at most 'maxvars' Boolean variables *) |
152 (* when transforming the term into a propositional *) |
155 (* when transforming the term into a propositional *) |
153 (* formula. *) |
156 (* formula. *) |
154 (* "maxtime" int If >0, terminate after at most 'maxtime' seconds. *) |
157 (* "maxtime" int If >0, terminate after at most 'maxtime' seconds. *) |
155 (* "satsolver" string SAT solver to be used. *) |
158 (* "satsolver" string SAT solver to be used. *) |
|
159 (* "no_assms" bool If "true", assumptions in structured proofs are *) |
|
160 (* not considered. *) |
156 (* "expect" string Expected result ("genuine", "potential", "none", or *) |
161 (* "expect" string Expected result ("genuine", "potential", "none", or *) |
157 (* "unknown") *) |
162 (* "unknown"). *) |
158 (* ------------------------------------------------------------------------- *) |
163 (* ------------------------------------------------------------------------- *) |
159 |
164 |
160 type params = |
165 type params = |
161 { |
166 { |
162 sizes : (string * int) list, |
167 sizes : (string * int) list, |
163 minsize : int, |
168 minsize : int, |
164 maxsize : int, |
169 maxsize : int, |
165 maxvars : int, |
170 maxvars : int, |
166 maxtime : int, |
171 maxtime : int, |
167 satsolver: string, |
172 satsolver: string, |
|
173 no_assms : bool, |
168 expect : string |
174 expect : string |
169 }; |
175 }; |
170 |
176 |
171 (* ------------------------------------------------------------------------- *) |
177 (* ------------------------------------------------------------------------- *) |
172 (* interpretation: a term's interpretation is given by a variable of type *) |
178 (* interpretation: a term's interpretation is given by a variable of type *) |
358 |
364 |
359 (* theory -> (string * string) list -> params *) |
365 (* theory -> (string * string) list -> params *) |
360 |
366 |
361 fun actual_params thy override = |
367 fun actual_params thy override = |
362 let |
368 let |
|
369 (* (string * string) list * string -> bool *) |
|
370 fun read_bool (parms, name) = |
|
371 case AList.lookup (op =) parms name of |
|
372 SOME "true" => true |
|
373 | SOME "false" => false |
|
374 | SOME s => error ("parameter " ^ quote name ^ |
|
375 " (value is " ^ quote s ^ ") must be \"true\" or \"false\"") |
|
376 | NONE => error ("parameter " ^ quote name ^ |
|
377 " must be assigned a value") |
363 (* (string * string) list * string -> int *) |
378 (* (string * string) list * string -> int *) |
364 fun read_int (parms, name) = |
379 fun read_int (parms, name) = |
365 case AList.lookup (op =) parms name of |
380 case AList.lookup (op =) parms name of |
366 SOME s => (case Int.fromString s of |
381 SOME s => (case Int.fromString s of |
367 SOME i => i |
382 SOME i => i |
383 val maxsize = read_int (allparams, "maxsize") |
398 val maxsize = read_int (allparams, "maxsize") |
384 val maxvars = read_int (allparams, "maxvars") |
399 val maxvars = read_int (allparams, "maxvars") |
385 val maxtime = read_int (allparams, "maxtime") |
400 val maxtime = read_int (allparams, "maxtime") |
386 (* string *) |
401 (* string *) |
387 val satsolver = read_string (allparams, "satsolver") |
402 val satsolver = read_string (allparams, "satsolver") |
|
403 val no_assms = read_bool (allparams, "no_assms") |
388 val expect = the_default "" (AList.lookup (op =) allparams "expect") |
404 val expect = the_default "" (AList.lookup (op =) allparams "expect") |
389 (* all remaining parameters of the form "string=int" are collected in *) |
405 (* all remaining parameters of the form "string=int" are collected in *) |
390 (* 'sizes' *) |
406 (* 'sizes' *) |
391 (* TODO: it is currently not possible to specify a size for a type *) |
407 (* TODO: it is currently not possible to specify a size for a type *) |
392 (* whose name is one of the other parameters (e.g. 'maxvars') *) |
408 (* whose name is one of the other parameters (e.g. 'maxvars') *) |
393 (* (string * int) list *) |
409 (* (string * int) list *) |
394 val sizes = map_filter |
410 val sizes = map_filter |
395 (fn (name, value) => Option.map (pair name) (Int.fromString value)) |
411 (fn (name, value) => Option.map (pair name) (Int.fromString value)) |
396 (filter (fn (name, _) => name<>"minsize" andalso name<>"maxsize" |
412 (filter (fn (name, _) => name<>"minsize" andalso name<>"maxsize" |
397 andalso name<>"maxvars" andalso name<>"maxtime" |
413 andalso name<>"maxvars" andalso name<>"maxtime" |
398 andalso name<>"satsolver") allparams) |
414 andalso name<>"satsolver" andalso name<>"no_assms") allparams) |
399 in |
415 in |
400 {sizes=sizes, minsize=minsize, maxsize=maxsize, maxvars=maxvars, |
416 {sizes=sizes, minsize=minsize, maxsize=maxsize, maxvars=maxvars, |
401 maxtime=maxtime, satsolver=satsolver, expect=expect} |
417 maxtime=maxtime, satsolver=satsolver, no_assms=no_assms, expect=expect} |
402 end; |
418 end; |
403 |
419 |
404 |
420 |
405 (* ------------------------------------------------------------------------- *) |
421 (* ------------------------------------------------------------------------- *) |
406 (* TRANSLATION HOL -> PROPOSITIONAL LOGIC, BOOLEAN ASSIGNMENT -> MODEL *) |
422 (* TRANSLATION HOL -> PROPOSITIONAL LOGIC, BOOLEAN ASSIGNMENT -> MODEL *) |
1116 (* find_model: repeatedly calls 'interpret' with appropriate parameters, *) |
1132 (* find_model: repeatedly calls 'interpret' with appropriate parameters, *) |
1117 (* applies a SAT solver, and (in case a model is found) displays *) |
1133 (* applies a SAT solver, and (in case a model is found) displays *) |
1118 (* the model to the user by calling 'print_model' *) |
1134 (* the model to the user by calling 'print_model' *) |
1119 (* thy : the current theory *) |
1135 (* thy : the current theory *) |
1120 (* {...} : parameters that control the translation/model generation *) |
1136 (* {...} : parameters that control the translation/model generation *) |
|
1137 (* assm_ts : assumptions to be considered unless "no_assms" is specified *) |
1121 (* t : term to be translated into a propositional formula *) |
1138 (* t : term to be translated into a propositional formula *) |
1122 (* negate : if true, find a model that makes 't' false (rather than true) *) |
1139 (* negate : if true, find a model that makes 't' false (rather than true) *) |
1123 (* ------------------------------------------------------------------------- *) |
1140 (* ------------------------------------------------------------------------- *) |
1124 |
1141 |
1125 (* theory -> params -> Term.term -> bool -> unit *) |
1142 (* theory -> params -> Term.term -> bool -> unit *) |
1126 |
1143 |
1127 fun find_model thy {sizes, minsize, maxsize, maxvars, maxtime, satsolver, |
1144 fun find_model thy {sizes, minsize, maxsize, maxvars, maxtime, satsolver, |
1128 expect} t negate = |
1145 no_assms, expect} assm_ts t negate = |
1129 let |
1146 let |
1130 (* string -> unit *) |
1147 (* string -> unit *) |
1131 fun check_expect outcome_code = |
1148 fun check_expect outcome_code = |
1132 if expect = "" orelse outcome_code = expect then () |
1149 if expect = "" orelse outcome_code = expect then () |
1133 else error ("Unexpected outcome: " ^ quote outcome_code ^ ".") |
1150 else error ("Unexpected outcome: " ^ quote outcome_code ^ ".") |
1134 (* unit -> unit *) |
1151 (* unit -> unit *) |
1135 fun wrapper () = |
1152 fun wrapper () = |
1136 let |
1153 let |
1137 val timer = Timer.startRealTimer () |
1154 val timer = Timer.startRealTimer () |
|
1155 val t = if no_assms then t |
|
1156 else if negate then Logic.list_implies (assm_ts, t) |
|
1157 else Logic.mk_conjunction_list (t :: assm_ts) |
1138 val u = unfold_defs thy t |
1158 val u = unfold_defs thy t |
1139 val _ = tracing ("Unfolded term: " ^ Syntax.string_of_term_global thy u) |
1159 val _ = tracing ("Unfolded term: " ^ Syntax.string_of_term_global thy u) |
1140 val axioms = collect_axioms thy u |
1160 val axioms = collect_axioms thy u |
1141 (* Term.typ list *) |
1161 (* Term.typ list *) |
1142 val types = fold (union (op =) o ground_types thy) (u :: axioms) [] |
1162 val types = fold (union (op =) o ground_types thy) (u :: axioms) [] |
1268 (* satisfy_term: calls 'find_model' to find a model that satisfies 't' *) |
1288 (* satisfy_term: calls 'find_model' to find a model that satisfies 't' *) |
1269 (* params : list of '(name, value)' pairs used to override default *) |
1289 (* params : list of '(name, value)' pairs used to override default *) |
1270 (* parameters *) |
1290 (* parameters *) |
1271 (* ------------------------------------------------------------------------- *) |
1291 (* ------------------------------------------------------------------------- *) |
1272 |
1292 |
1273 (* theory -> (string * string) list -> Term.term -> unit *) |
1293 (* theory -> (string * string) list -> Term.term list -> Term.term -> unit *) |
1274 |
1294 |
1275 fun satisfy_term thy params t = |
1295 fun satisfy_term thy params assm_ts t = |
1276 find_model thy (actual_params thy params) t false; |
1296 find_model thy (actual_params thy params) assm_ts t false; |
1277 |
1297 |
1278 (* ------------------------------------------------------------------------- *) |
1298 (* ------------------------------------------------------------------------- *) |
1279 (* refute_term: calls 'find_model' to find a model that refutes 't' *) |
1299 (* refute_term: calls 'find_model' to find a model that refutes 't' *) |
1280 (* params : list of '(name, value)' pairs used to override default *) |
1300 (* params : list of '(name, value)' pairs used to override default *) |
1281 (* parameters *) |
1301 (* parameters *) |
1282 (* ------------------------------------------------------------------------- *) |
1302 (* ------------------------------------------------------------------------- *) |
1283 |
1303 |
1284 (* theory -> (string * string) list -> Term.term -> unit *) |
1304 (* theory -> (string * string) list -> Term.term list -> Term.term -> unit *) |
1285 |
1305 |
1286 fun refute_term thy params t = |
1306 fun refute_term thy params assm_ts t = |
1287 let |
1307 let |
1288 (* disallow schematic type variables, since we cannot properly negate *) |
1308 (* disallow schematic type variables, since we cannot properly negate *) |
1289 (* terms containing them (their logical meaning is that there EXISTS a *) |
1309 (* terms containing them (their logical meaning is that there EXISTS a *) |
1290 (* type s.t. ...; to refute such a formula, we would have to show that *) |
1310 (* type s.t. ...; to refute such a formula, we would have to show that *) |
1291 (* for ALL types, not ...) *) |
1311 (* for ALL types, not ...) *) |
1330 [] : (string * typ) list |
1350 [] : (string * typ) list |
1331 val strip_t = strip_all_body ex_closure |
1351 val strip_t = strip_all_body ex_closure |
1332 val frees = Term.rename_wrt_term strip_t (strip_all_vars ex_closure) |
1352 val frees = Term.rename_wrt_term strip_t (strip_all_vars ex_closure) |
1333 val subst_t = Term.subst_bounds (map Free frees, strip_t) |
1353 val subst_t = Term.subst_bounds (map Free frees, strip_t) |
1334 in |
1354 in |
1335 find_model thy (actual_params thy params) subst_t true |
1355 find_model thy (actual_params thy params) assm_ts subst_t true |
|
1356 handle REFUTE (s, s') => error ("REFUTE " ^ s ^ " " ^ s') (* ### *) |
1336 end; |
1357 end; |
1337 |
1358 |
1338 (* ------------------------------------------------------------------------- *) |
1359 (* ------------------------------------------------------------------------- *) |
1339 (* refute_goal *) |
1360 (* refute_goal *) |
1340 (* ------------------------------------------------------------------------- *) |
1361 (* ------------------------------------------------------------------------- *) |
1341 |
1362 |
1342 fun refute_goal thy params st i = |
1363 fun refute_goal ctxt params th i = |
1343 refute_term thy params (Logic.get_goal (Thm.prop_of st) i); |
1364 let |
|
1365 val t = th |> prop_of |
|
1366 in |
|
1367 if Logic.count_prems t = 0 then |
|
1368 priority "No subgoal!" |
|
1369 else |
|
1370 let |
|
1371 val assms = map term_of (Assumption.all_assms_of ctxt) |
|
1372 val (t, frees) = Logic.goal_params t i |
|
1373 in |
|
1374 refute_term (ProofContext.theory_of ctxt) params assms |
|
1375 (subst_bounds (frees, t)) |
|
1376 end |
|
1377 end |
1344 |
1378 |
1345 |
1379 |
1346 (* ------------------------------------------------------------------------- *) |
1380 (* ------------------------------------------------------------------------- *) |
1347 (* INTERPRETERS: Auxiliary Functions *) |
1381 (* INTERPRETERS: Auxiliary Functions *) |
1348 (* ------------------------------------------------------------------------- *) |
1382 (* ------------------------------------------------------------------------- *) |