summary |
shortlog |
changelog |
graph |
tags |
branches |
files |
changeset |
file |
revisions |
annotate |
diff |
raw

src/HOL/Library/Old_SMT.thy

author | wenzelm |

Sun Nov 02 17:20:45 2014 +0100 (2014-11-02) | |

changeset 58881 | b9556a055632 |

parent 58825 | 2065f49da190 |

child 59966 | c01cea2ba71e |

permissions | -rw-r--r-- |

modernized header;

1 (* Title: HOL/Library/Old_SMT.thy

2 Author: Sascha Boehme, TU Muenchen

3 *)

5 section {* Old Version of Bindings to Satisfiability Modulo Theories (SMT) solvers *}

7 theory Old_SMT

8 imports "../Real" "../Word/Word"

9 keywords "old_smt_status" :: diag

10 begin

12 ML_file "Old_SMT/old_smt_utils.ML"

13 ML_file "Old_SMT/old_smt_failure.ML"

14 ML_file "Old_SMT/old_smt_config.ML"

17 subsection {* Triggers for quantifier instantiation *}

19 text {*

20 Some SMT solvers support patterns as a quantifier instantiation

21 heuristics. Patterns may either be positive terms (tagged by "pat")

22 triggering quantifier instantiations -- when the solver finds a

23 term matching a positive pattern, it instantiates the corresponding

24 quantifier accordingly -- or negative terms (tagged by "nopat")

25 inhibiting quantifier instantiations. A list of patterns

26 of the same kind is called a multipattern, and all patterns in a

27 multipattern are considered conjunctively for quantifier instantiation.

28 A list of multipatterns is called a trigger, and their multipatterns

29 act disjunctively during quantifier instantiation. Each multipattern

30 should mention at least all quantified variables of the preceding

31 quantifier block.

32 *}

34 typedecl pattern

36 consts

37 pat :: "'a \<Rightarrow> pattern"

38 nopat :: "'a \<Rightarrow> pattern"

40 definition trigger :: "pattern list list \<Rightarrow> bool \<Rightarrow> bool" where "trigger _ P = P"

43 subsection {* Quantifier weights *}

45 text {*

46 Weight annotations to quantifiers influence the priority of quantifier

47 instantiations. They should be handled with care for solvers, which support

48 them, because incorrect choices of weights might render a problem unsolvable.

49 *}

51 definition weight :: "int \<Rightarrow> bool \<Rightarrow> bool" where "weight _ P = P"

53 text {*

54 Weights must be non-negative. The value @{text 0} is equivalent to providing

55 no weight at all.

57 Weights should only be used at quantifiers and only inside triggers (if the

58 quantifier has triggers). Valid usages of weights are as follows:

60 \begin{itemize}

61 \item

62 @{term "\<forall>x. trigger [[pat (P x)]] (weight 2 (P x))"}

63 \item

64 @{term "\<forall>x. weight 3 (P x)"}

65 \end{itemize}

66 *}

69 subsection {* Higher-order encoding *}

71 text {*

72 Application is made explicit for constants occurring with varying

73 numbers of arguments. This is achieved by the introduction of the

74 following constant.

75 *}

77 definition fun_app where "fun_app f = f"

79 text {*

80 Some solvers support a theory of arrays which can be used to encode

81 higher-order functions. The following set of lemmas specifies the

82 properties of such (extensional) arrays.

83 *}

85 lemmas array_rules = ext fun_upd_apply fun_upd_same fun_upd_other

86 fun_upd_upd fun_app_def

89 subsection {* First-order logic *}

91 text {*

92 Some SMT solvers only accept problems in first-order logic, i.e.,

93 where formulas and terms are syntactically separated. When

94 translating higher-order into first-order problems, all

95 uninterpreted constants (those not built-in in the target solver)

96 are treated as function symbols in the first-order sense. Their

97 occurrences as head symbols in atoms (i.e., as predicate symbols) are

98 turned into terms by logically equating such atoms with @{term True}.

99 For technical reasons, @{term True} and @{term False} occurring inside

100 terms are replaced by the following constants.

101 *}

103 definition term_true where "term_true = True"

104 definition term_false where "term_false = False"

107 subsection {* Integer division and modulo for Z3 *}

109 definition z3div :: "int \<Rightarrow> int \<Rightarrow> int" where

110 "z3div k l = (if 0 \<le> l then k div l else -(k div (-l)))"

112 definition z3mod :: "int \<Rightarrow> int \<Rightarrow> int" where

113 "z3mod k l = (if 0 \<le> l then k mod l else k mod (-l))"

116 subsection {* Setup *}

118 ML_file "Old_SMT/old_smt_builtin.ML"

119 ML_file "Old_SMT/old_smt_datatypes.ML"

120 ML_file "Old_SMT/old_smt_normalize.ML"

121 ML_file "Old_SMT/old_smt_translate.ML"

122 ML_file "Old_SMT/old_smt_solver.ML"

123 ML_file "Old_SMT/old_smtlib_interface.ML"

124 ML_file "Old_SMT/old_z3_interface.ML"

125 ML_file "Old_SMT/old_z3_proof_parser.ML"

126 ML_file "Old_SMT/old_z3_proof_tools.ML"

127 ML_file "Old_SMT/old_z3_proof_literals.ML"

128 ML_file "Old_SMT/old_z3_proof_methods.ML"

129 named_theorems old_z3_simp "simplification rules for Z3 proof reconstruction"

130 ML_file "Old_SMT/old_z3_proof_reconstruction.ML"

131 ML_file "Old_SMT/old_z3_model.ML"

132 ML_file "Old_SMT/old_smt_setup_solvers.ML"

134 setup {*

135 Old_SMT_Config.setup #>

136 Old_SMT_Normalize.setup #>

137 Old_SMTLIB_Interface.setup #>

138 Old_Z3_Interface.setup #>

139 Old_SMT_Setup_Solvers.setup

140 *}

142 method_setup old_smt = {*

143 Scan.optional Attrib.thms [] >>

144 (fn thms => fn ctxt =>

145 METHOD (fn facts => HEADGOAL (Old_SMT_Solver.smt_tac ctxt (thms @ facts))))

146 *} "apply an SMT solver to the current goal"

149 subsection {* Configuration *}

151 text {*

152 The current configuration can be printed by the command

153 @{text old_smt_status}, which shows the values of most options.

154 *}

158 subsection {* General configuration options *}

160 text {*

161 The option @{text old_smt_solver} can be used to change the target SMT

162 solver. The possible values can be obtained from the @{text old_smt_status}

163 command.

165 Due to licensing restrictions, Yices and Z3 are not installed/enabled

166 by default. Z3 is free for non-commercial applications and can be enabled

167 by setting Isabelle system option @{text z3_non_commercial} to @{text yes}.

168 *}

170 declare [[ old_smt_solver = z3 ]]

172 text {*

173 Since SMT solvers are potentially non-terminating, there is a timeout

174 (given in seconds) to restrict their runtime. A value greater than

175 120 (seconds) is in most cases not advisable.

176 *}

178 declare [[ old_smt_timeout = 20 ]]

180 text {*

181 SMT solvers apply randomized heuristics. In case a problem is not

182 solvable by an SMT solver, changing the following option might help.

183 *}

185 declare [[ old_smt_random_seed = 1 ]]

187 text {*

188 In general, the binding to SMT solvers runs as an oracle, i.e, the SMT

189 solvers are fully trusted without additional checks. The following

190 option can cause the SMT solver to run in proof-producing mode, giving

191 a checkable certificate. This is currently only implemented for Z3.

192 *}

194 declare [[ old_smt_oracle = false ]]

196 text {*

197 Each SMT solver provides several commandline options to tweak its

198 behaviour. They can be passed to the solver by setting the following

199 options.

200 *}

202 declare [[ old_cvc3_options = "" ]]

203 declare [[ old_yices_options = "" ]]

204 declare [[ old_z3_options = "" ]]

206 text {*

207 Enable the following option to use built-in support for datatypes and

208 records. Currently, this is only implemented for Z3 running in oracle

209 mode.

210 *}

212 declare [[ old_smt_datatypes = false ]]

214 text {*

215 The SMT method provides an inference mechanism to detect simple triggers

216 in quantified formulas, which might increase the number of problems

217 solvable by SMT solvers (note: triggers guide quantifier instantiations

218 in the SMT solver). To turn it on, set the following option.

219 *}

221 declare [[ old_smt_infer_triggers = false ]]

223 text {*

224 The SMT method monomorphizes the given facts, that is, it tries to

225 instantiate all schematic type variables with fixed types occurring

226 in the problem. This is a (possibly nonterminating) fixed-point

227 construction whose cycles are limited by the following option.

228 *}

230 declare [[ monomorph_max_rounds = 5 ]]

232 text {*

233 In addition, the number of generated monomorphic instances is limited

234 by the following option.

235 *}

237 declare [[ monomorph_max_new_instances = 500 ]]

241 subsection {* Certificates *}

243 text {*

244 By setting the option @{text old_smt_certificates} to the name of a file,

245 all following applications of an SMT solver a cached in that file.

246 Any further application of the same SMT solver (using the very same

247 configuration) re-uses the cached certificate instead of invoking the

248 solver. An empty string disables caching certificates.

250 The filename should be given as an explicit path. It is good

251 practice to use the name of the current theory (with ending

252 @{text ".certs"} instead of @{text ".thy"}) as the certificates file.

253 Certificate files should be used at most once in a certain theory context,

254 to avoid race conditions with other concurrent accesses.

255 *}

257 declare [[ old_smt_certificates = "" ]]

259 text {*

260 The option @{text old_smt_read_only_certificates} controls whether only

261 stored certificates are should be used or invocation of an SMT solver

262 is allowed. When set to @{text true}, no SMT solver will ever be

263 invoked and only the existing certificates found in the configured

264 cache are used; when set to @{text false} and there is no cached

265 certificate for some proposition, then the configured SMT solver is

266 invoked.

267 *}

269 declare [[ old_smt_read_only_certificates = false ]]

273 subsection {* Tracing *}

275 text {*

276 The SMT method, when applied, traces important information. To

277 make it entirely silent, set the following option to @{text false}.

278 *}

280 declare [[ old_smt_verbose = true ]]

282 text {*

283 For tracing the generated problem file given to the SMT solver as

284 well as the returned result of the solver, the option

285 @{text old_smt_trace} should be set to @{text true}.

286 *}

288 declare [[ old_smt_trace = false ]]

290 text {*

291 From the set of assumptions given to the SMT solver, those assumptions

292 used in the proof are traced when the following option is set to

293 @{term true}. This only works for Z3 when it runs in non-oracle mode

294 (see options @{text old_smt_solver} and @{text old_smt_oracle} above).

295 *}

297 declare [[ old_smt_trace_used_facts = false ]]

301 subsection {* Schematic rules for Z3 proof reconstruction *}

303 text {*

304 Several prof rules of Z3 are not very well documented. There are two

305 lemma groups which can turn failing Z3 proof reconstruction attempts

306 into succeeding ones: the facts in @{text z3_rule} are tried prior to

307 any implemented reconstruction procedure for all uncertain Z3 proof

308 rules; the facts in @{text z3_simp} are only fed to invocations of

309 the simplifier when reconstructing theory-specific proof steps.

310 *}

312 lemmas [old_z3_rule] =

313 refl eq_commute conj_commute disj_commute simp_thms nnf_simps

314 ring_distribs field_simps times_divide_eq_right times_divide_eq_left

315 if_True if_False not_not

317 lemma [old_z3_rule]:

318 "(P \<and> Q) = (\<not>(\<not>P \<or> \<not>Q))"

319 "(P \<and> Q) = (\<not>(\<not>Q \<or> \<not>P))"

320 "(\<not>P \<and> Q) = (\<not>(P \<or> \<not>Q))"

321 "(\<not>P \<and> Q) = (\<not>(\<not>Q \<or> P))"

322 "(P \<and> \<not>Q) = (\<not>(\<not>P \<or> Q))"

323 "(P \<and> \<not>Q) = (\<not>(Q \<or> \<not>P))"

324 "(\<not>P \<and> \<not>Q) = (\<not>(P \<or> Q))"

325 "(\<not>P \<and> \<not>Q) = (\<not>(Q \<or> P))"

326 by auto

328 lemma [old_z3_rule]:

329 "(P \<longrightarrow> Q) = (Q \<or> \<not>P)"

330 "(\<not>P \<longrightarrow> Q) = (P \<or> Q)"

331 "(\<not>P \<longrightarrow> Q) = (Q \<or> P)"

332 "(True \<longrightarrow> P) = P"

333 "(P \<longrightarrow> True) = True"

334 "(False \<longrightarrow> P) = True"

335 "(P \<longrightarrow> P) = True"

336 by auto

338 lemma [old_z3_rule]:

339 "((P = Q) \<longrightarrow> R) = (R | (Q = (\<not>P)))"

340 by auto

342 lemma [old_z3_rule]:

343 "(\<not>True) = False"

344 "(\<not>False) = True"

345 "(x = x) = True"

346 "(P = True) = P"

347 "(True = P) = P"

348 "(P = False) = (\<not>P)"

349 "(False = P) = (\<not>P)"

350 "((\<not>P) = P) = False"

351 "(P = (\<not>P)) = False"

352 "((\<not>P) = (\<not>Q)) = (P = Q)"

353 "\<not>(P = (\<not>Q)) = (P = Q)"

354 "\<not>((\<not>P) = Q) = (P = Q)"

355 "(P \<noteq> Q) = (Q = (\<not>P))"

356 "(P = Q) = ((\<not>P \<or> Q) \<and> (P \<or> \<not>Q))"

357 "(P \<noteq> Q) = ((\<not>P \<or> \<not>Q) \<and> (P \<or> Q))"

358 by auto

360 lemma [old_z3_rule]:

361 "(if P then P else \<not>P) = True"

362 "(if \<not>P then \<not>P else P) = True"

363 "(if P then True else False) = P"

364 "(if P then False else True) = (\<not>P)"

365 "(if P then Q else True) = ((\<not>P) \<or> Q)"

366 "(if P then Q else True) = (Q \<or> (\<not>P))"

367 "(if P then Q else \<not>Q) = (P = Q)"

368 "(if P then Q else \<not>Q) = (Q = P)"

369 "(if P then \<not>Q else Q) = (P = (\<not>Q))"

370 "(if P then \<not>Q else Q) = ((\<not>Q) = P)"

371 "(if \<not>P then x else y) = (if P then y else x)"

372 "(if P then (if Q then x else y) else x) = (if P \<and> (\<not>Q) then y else x)"

373 "(if P then (if Q then x else y) else x) = (if (\<not>Q) \<and> P then y else x)"

374 "(if P then (if Q then x else y) else y) = (if P \<and> Q then x else y)"

375 "(if P then (if Q then x else y) else y) = (if Q \<and> P then x else y)"

376 "(if P then x else if P then y else z) = (if P then x else z)"

377 "(if P then x else if Q then x else y) = (if P \<or> Q then x else y)"

378 "(if P then x else if Q then x else y) = (if Q \<or> P then x else y)"

379 "(if P then x = y else x = z) = (x = (if P then y else z))"

380 "(if P then x = y else y = z) = (y = (if P then x else z))"

381 "(if P then x = y else z = y) = (y = (if P then x else z))"

382 by auto

384 lemma [old_z3_rule]:

385 "0 + (x::int) = x"

386 "x + 0 = x"

387 "x + x = 2 * x"

388 "0 * x = 0"

389 "1 * x = x"

390 "x + y = y + x"

391 by auto

393 lemma [old_z3_rule]: (* for def-axiom *)

394 "P = Q \<or> P \<or> Q"

395 "P = Q \<or> \<not>P \<or> \<not>Q"

396 "(\<not>P) = Q \<or> \<not>P \<or> Q"

397 "(\<not>P) = Q \<or> P \<or> \<not>Q"

398 "P = (\<not>Q) \<or> \<not>P \<or> Q"

399 "P = (\<not>Q) \<or> P \<or> \<not>Q"

400 "P \<noteq> Q \<or> P \<or> \<not>Q"

401 "P \<noteq> Q \<or> \<not>P \<or> Q"

402 "P \<noteq> (\<not>Q) \<or> P \<or> Q"

403 "(\<not>P) \<noteq> Q \<or> P \<or> Q"

404 "P \<or> Q \<or> P \<noteq> (\<not>Q)"

405 "P \<or> Q \<or> (\<not>P) \<noteq> Q"

406 "P \<or> \<not>Q \<or> P \<noteq> Q"

407 "\<not>P \<or> Q \<or> P \<noteq> Q"

408 "P \<or> y = (if P then x else y)"

409 "P \<or> (if P then x else y) = y"

410 "\<not>P \<or> x = (if P then x else y)"

411 "\<not>P \<or> (if P then x else y) = x"

412 "P \<or> R \<or> \<not>(if P then Q else R)"

413 "\<not>P \<or> Q \<or> \<not>(if P then Q else R)"

414 "\<not>(if P then Q else R) \<or> \<not>P \<or> Q"

415 "\<not>(if P then Q else R) \<or> P \<or> R"

416 "(if P then Q else R) \<or> \<not>P \<or> \<not>Q"

417 "(if P then Q else R) \<or> P \<or> \<not>R"

418 "(if P then \<not>Q else R) \<or> \<not>P \<or> Q"

419 "(if P then Q else \<not>R) \<or> P \<or> R"

420 by auto

422 ML_file "Old_SMT/old_smt_real.ML"

423 ML_file "Old_SMT/old_smt_word.ML"

425 hide_type (open) pattern

426 hide_const fun_app term_true term_false z3div z3mod

427 hide_const (open) trigger pat nopat weight

429 end