Proof Rules and Checker for Arithmetic (#4665)
[cvc5.git] / src / expr / proof_rule.h
1 /********************* */
2 /*! \file proof_rule.h
3 ** \verbatim
4 ** Top contributors (to current version):
5 ** Haniel Barbosa, Andrew Reynolds
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
11 **
12 ** \brief Proof rule enumeration
13 **/
14
15 #include "cvc4_private.h"
16
17 #ifndef CVC4__EXPR__PROOF_RULE_H
18 #define CVC4__EXPR__PROOF_RULE_H
19
20 #include <iosfwd>
21
22 namespace CVC4 {
23
24 /**
25 * An enumeration for proof rules. This enumeration is analogous to Kind for
26 * Node objects. In the documentation below, P:F denotes a ProofNode that
27 * proves formula F.
28 *
29 * Conceptually, the following proof rules form a calculus whose target
30 * user is the Node-level theory solvers. This means that the rules below
31 * are designed to reason about, among other things, common operations on Node
32 * objects like Rewriter::rewrite or Node::substitute. It is intended to be
33 * translated or printed in other formats.
34 *
35 * The following PfRule values include core rules and those categorized by
36 * theory, including the theory of equality.
37 *
38 * The "core rules" include two distinguished rules which have special status:
39 * (1) ASSUME, which represents an open leaf in a proof.
40 * (2) SCOPE, which closes the scope of assumptions.
41 * The core rules additionally correspond to generic operations that are done
42 * internally on nodes, e.g. calling Rewriter::rewrite.
43 */
44 enum class PfRule : uint32_t
45 {
46 //================================================= Core rules
47 //======================== Assume and Scope
48 // ======== Assumption (a leaf)
49 // Children: none
50 // Arguments: (F)
51 // --------------
52 // Conclusion: F
53 //
54 // This rule has special status, in that an application of assume is an
55 // open leaf in a proof that is not (yet) justified. An assume leaf is
56 // analogous to a free variable in a term, where we say "F is a free
57 // assumption in proof P" if it contains an application of F that is not
58 // bound by SCOPE (see below).
59 ASSUME,
60 // ======== Scope (a binder for assumptions)
61 // Children: (P:F)
62 // Arguments: (F1, ..., Fn)
63 // --------------
64 // Conclusion: (=> (and F1 ... Fn) F) or (not (and F1 ... Fn)) if F is false
65 //
66 // This rule has a dual purpose with ASSUME. It is a way to close
67 // assumptions in a proof. We require that F1 ... Fn are free assumptions in
68 // P and say that F1, ..., Fn are not free in (SCOPE P). In other words, they
69 // are bound by this application. For example, the proof node:
70 // (SCOPE (ASSUME F) :args F)
71 // has the conclusion (=> F F) and has no free assumptions. More generally, a
72 // proof with no free assumptions always concludes a valid formula.
73 SCOPE,
74
75 //======================== Builtin theory (common node operations)
76 // ======== Substitution
77 // Children: (P1:F1, ..., Pn:Fn)
78 // Arguments: (t, (ids)?)
79 // ---------------------------------------------------------------
80 // Conclusion: (= t t*sigma{ids}(Fn)*...*sigma{ids}(F1))
81 // where sigma{ids}(Fi) are substitutions, which notice are applied in
82 // reverse order.
83 // Notice that ids is a MethodId identifier, which determines how to convert
84 // the formulas F1, ..., Fn into substitutions.
85 SUBS,
86 // ======== Rewrite
87 // Children: none
88 // Arguments: (t, (idr)?)
89 // ----------------------------------------
90 // Conclusion: (= t Rewriter{idr}(t))
91 // where idr is a MethodId identifier, which determines the kind of rewriter
92 // to apply, e.g. Rewriter::rewrite.
93 REWRITE,
94 // ======== Substitution + Rewriting equality introduction
95 //
96 // In this rule, we provide a term t and conclude that it is equal to its
97 // rewritten form under a (proven) substitution.
98 //
99 // Children: (P1:F1, ..., Pn:Fn)
100 // Arguments: (t, (ids (idr)?)?)
101 // ---------------------------------------------------------------
102 // Conclusion: (= t t')
103 // where
104 // t' is
105 // toWitness(Rewriter{idr}(toSkolem(t)*sigma{ids}(Fn)*...*sigma{ids}(F1)))
106 // toSkolem(...) converts terms from witness form to Skolem form,
107 // toWitness(...) converts terms from Skolem form to witness form.
108 //
109 // Notice that:
110 // toSkolem(t')=Rewriter{idr}(toSkolem(t)*sigma{ids}(Fn)*...*sigma{ids}(F1))
111 // In other words, from the point of view of Skolem forms, this rule
112 // transforms t to t' by standard substitution + rewriting.
113 //
114 // The argument ids and idr is optional and specify the identifier of the
115 // substitution and rewriter respectively to be used. For details, see
116 // theory/builtin/proof_checker.h.
117 MACRO_SR_EQ_INTRO,
118 // ======== Substitution + Rewriting predicate introduction
119 //
120 // In this rule, we provide a formula F and conclude it, under the condition
121 // that it rewrites to true under a proven substitution.
122 //
123 // Children: (P1:F1, ..., Pn:Fn)
124 // Arguments: (F, (ids (idr)?)?)
125 // ---------------------------------------------------------------
126 // Conclusion: F
127 // where
128 // Rewriter{idr}(F*sigma{ids}(Fn)*...*sigma{ids}(F1)) == true
129 // where ids and idr are method identifiers.
130 //
131 // Notice that we apply rewriting on the witness form of F, meaning that this
132 // rule may conclude an F whose Skolem form is justified by the definition of
133 // its (fresh) Skolem variables. Furthermore, notice that the rewriting and
134 // substitution is applied only within the side condition, meaning the
135 // rewritten form of the witness form of F does not escape this rule.
136 MACRO_SR_PRED_INTRO,
137 // ======== Substitution + Rewriting predicate elimination
138 //
139 // In this rule, if we have proven a formula F, then we may conclude its
140 // rewritten form under a proven substitution.
141 //
142 // Children: (P1:F, P2:F1, ..., P_{n+1}:Fn)
143 // Arguments: ((ids (idr)?)?)
144 // ----------------------------------------
145 // Conclusion: F'
146 // where
147 // F' is
148 // toWitness(Rewriter{idr}(toSkolem(F)*sigma{ids}(Fn)*...*sigma{ids}(F1)).
149 // where ids and idr are method identifiers.
150 //
151 // We rewrite only on the Skolem form of F, similar to MACRO_SR_EQ_INTRO.
152 MACRO_SR_PRED_ELIM,
153 // ======== Substitution + Rewriting predicate transform
154 //
155 // In this rule, if we have proven a formula F, then we may provide a formula
156 // G and conclude it if F and G are equivalent after rewriting under a proven
157 // substitution.
158 //
159 // Children: (P1:F, P2:F1, ..., P_{n+1}:Fn)
160 // Arguments: (G, (ids (idr)?)?)
161 // ----------------------------------------
162 // Conclusion: G
163 // where
164 // Rewriter{idr}(F*sigma{ids}(Fn)*...*sigma{ids}(F1)) ==
165 // Rewriter{idr}(G*sigma{ids}(Fn)*...*sigma{ids}(F1))
166 //
167 // Notice that we apply rewriting on the witness form of F and G, similar to
168 // MACRO_SR_PRED_INTRO.
169 MACRO_SR_PRED_TRANSFORM,
170
171 //================================================= Boolean rules
172 // ======== Split
173 // Children: none
174 // Arguments: (F)
175 // ---------------------
176 // Conclusion: (or F (not F))
177 SPLIT,
178 // ======== And elimination
179 // Children: (P:(and F1 ... Fn))
180 // Arguments: (i)
181 // ---------------------
182 // Conclusion: (Fi)
183 AND_ELIM,
184 // ======== And introduction
185 // Children: (P1:F1 ... Pn:Fn))
186 // Arguments: ()
187 // ---------------------
188 // Conclusion: (and P1 ... Pn)
189 AND_INTRO,
190 // ======== Not Or elimination
191 // Children: (P:(not (or F1 ... Fn)))
192 // Arguments: (i)
193 // ---------------------
194 // Conclusion: (not Fi)
195 NOT_OR_ELIM,
196 // ======== Implication elimination
197 // Children: (P:(=> F1 F2))
198 // Arguments: ()
199 // ---------------------
200 // Conclusion: (or (not F1) F2)
201 IMPLIES_ELIM,
202 // ======== Not Implication elimination version 1
203 // Children: (P:(not (=> F1 F2)))
204 // Arguments: ()
205 // ---------------------
206 // Conclusion: (F1)
207 NOT_IMPLIES_ELIM1,
208 // ======== Not Implication elimination version 2
209 // Children: (P:(not (=> F1 F2)))
210 // Arguments: ()
211 // ---------------------
212 // Conclusion: (not F2)
213 NOT_IMPLIES_ELIM2,
214 // ======== Equivalence elimination version 1
215 // Children: (P:(= F1 F2))
216 // Arguments: ()
217 // ---------------------
218 // Conclusion: (or (not F1) F2)
219 EQUIV_ELIM1,
220 // ======== Equivalence elimination version 2
221 // Children: (P:(= F1 F2))
222 // Arguments: ()
223 // ---------------------
224 // Conclusion: (or F1 (not F2))
225 EQUIV_ELIM2,
226 // ======== Not Equivalence elimination version 1
227 // Children: (P:(not (= F1 F2)))
228 // Arguments: ()
229 // ---------------------
230 // Conclusion: (or F1 F2)
231 NOT_EQUIV_ELIM1,
232 // ======== Not Equivalence elimination version 2
233 // Children: (P:(not (= F1 F2)))
234 // Arguments: ()
235 // ---------------------
236 // Conclusion: (or (not F1) (not F2))
237 NOT_EQUIV_ELIM2,
238 // ======== XOR elimination version 1
239 // Children: (P:(xor F1 F2)))
240 // Arguments: ()
241 // ---------------------
242 // Conclusion: (or F1 F2)
243 XOR_ELIM1,
244 // ======== XOR elimination version 2
245 // Children: (P:(xor F1 F2)))
246 // Arguments: ()
247 // ---------------------
248 // Conclusion: (or (not F1) (not F2))
249 XOR_ELIM2,
250 // ======== Not XOR elimination version 1
251 // Children: (P:(not (xor F1 F2)))
252 // Arguments: ()
253 // ---------------------
254 // Conclusion: (or F1 (not F2))
255 NOT_XOR_ELIM1,
256 // ======== Not XOR elimination version 2
257 // Children: (P:(not (xor F1 F2)))
258 // Arguments: ()
259 // ---------------------
260 // Conclusion: (or (not F1) F2)
261 NOT_XOR_ELIM2,
262 // ======== ITE elimination version 1
263 // Children: (P:(ite C F1 F2))
264 // Arguments: ()
265 // ---------------------
266 // Conclusion: (or (not C) F1)
267 ITE_ELIM1,
268 // ======== ITE elimination version 2
269 // Children: (P:(ite C F1 F2))
270 // Arguments: ()
271 // ---------------------
272 // Conclusion: (or C F2)
273 ITE_ELIM2,
274 // ======== Not ITE elimination version 1
275 // Children: (P:(not (ite C F1 F2)))
276 // Arguments: ()
277 // ---------------------
278 // Conclusion: (or (not C) (not F1))
279 NOT_ITE_ELIM1,
280 // ======== Not ITE elimination version 1
281 // Children: (P:(not (ite C F1 F2)))
282 // Arguments: ()
283 // ---------------------
284 // Conclusion: (or C (not F2))
285 NOT_ITE_ELIM2,
286 // ======== Not ITE elimination version 1
287 // Children: (P1:P P2:(not P))
288 // Arguments: ()
289 // ---------------------
290 // Conclusion: (false)
291 CONTRA,
292
293 //================================================= De Morgan rules
294 // ======== Not And
295 // Children: (P:(not (and F1 ... Fn))
296 // Arguments: ()
297 // ---------------------
298 // Conclusion: (or (not F1) ... (not Fn))
299 NOT_AND,
300 //================================================= CNF rules
301 // ======== CNF And Pos
302 // Children: ()
303 // Arguments: ((and F1 ... Fn), i)
304 // ---------------------
305 // Conclusion: (or (not (and F1 ... Fn)) Fi)
306 CNF_AND_POS,
307 // ======== CNF And Neg
308 // Children: ()
309 // Arguments: ((and F1 ... Fn))
310 // ---------------------
311 // Conclusion: (or (and F1 ... Fn) (not F1) ... (not Fn))
312 CNF_AND_NEG,
313 // ======== CNF Or Pos
314 // Children: ()
315 // Arguments: ((or F1 ... Fn))
316 // ---------------------
317 // Conclusion: (or (not (or F1 ... Fn)) F1 ... Fn)
318 CNF_OR_POS,
319 // ======== CNF Or Neg
320 // Children: ()
321 // Arguments: ((or F1 ... Fn), i)
322 // ---------------------
323 // Conclusion: (or (or F1 ... Fn) (not Fi))
324 CNF_OR_NEG,
325 // ======== CNF Implies Pos
326 // Children: ()
327 // Arguments: ((implies F1 F2))
328 // ---------------------
329 // Conclusion: (or (not (implies F1 F2)) (not F1) F2)
330 CNF_IMPLIES_POS,
331 // ======== CNF Implies Neg version 1
332 // Children: ()
333 // Arguments: ((implies F1 F2))
334 // ---------------------
335 // Conclusion: (or (implies F1 F2) F1)
336 CNF_IMPLIES_NEG1,
337 // ======== CNF Implies Neg version 2
338 // Children: ()
339 // Arguments: ((implies F1 F2))
340 // ---------------------
341 // Conclusion: (or (implies F1 F2) (not F2))
342 CNF_IMPLIES_NEG2,
343 // ======== CNF Equiv Pos version 1
344 // Children: ()
345 // Arguments: ((= F1 F2))
346 // ---------------------
347 // Conclusion: (or (not (= F1 F2)) (not F1) F2)
348 CNF_EQUIV_POS1,
349 // ======== CNF Equiv Pos version 2
350 // Children: ()
351 // Arguments: ((= F1 F2))
352 // ---------------------
353 // Conclusion: (or (not (= F1 F2)) F1 (not F2))
354 CNF_EQUIV_POS2,
355 // ======== CNF Equiv Neg version 1
356 // Children: ()
357 // Arguments: ((= F1 F2))
358 // ---------------------
359 // Conclusion: (or (= F1 F2) F1 F2)
360 CNF_EQUIV_NEG1,
361 // ======== CNF Equiv Neg version 2
362 // Children: ()
363 // Arguments: ((= F1 F2))
364 // ---------------------
365 // Conclusion: (or (= F1 F2) (not F1) (not F2))
366 CNF_EQUIV_NEG2,
367 // ======== CNF Xor Pos version 1
368 // Children: ()
369 // Arguments: ((xor F1 F2))
370 // ---------------------
371 // Conclusion: (or (not (xor F1 F2)) F1 F2)
372 CNF_XOR_POS1,
373 // ======== CNF Xor Pos version 2
374 // Children: ()
375 // Arguments: ((xor F1 F2))
376 // ---------------------
377 // Conclusion: (or (not (xor F1 F2)) (not F1) (not F2))
378 CNF_XOR_POS2,
379 // ======== CNF Xor Neg version 1
380 // Children: ()
381 // Arguments: ((xor F1 F2))
382 // ---------------------
383 // Conclusion: (or (xor F1 F2) (not F1) F2)
384 CNF_XOR_NEG1,
385 // ======== CNF Xor Neg version 2
386 // Children: ()
387 // Arguments: ((xor F1 F2))
388 // ---------------------
389 // Conclusion: (or (xor F1 F2) F1 (not F2))
390 CNF_XOR_NEG2,
391 // ======== CNF ITE Pos version 1
392 // Children: ()
393 // Arguments: ((ite C F1 F2))
394 // ---------------------
395 // Conclusion: (or (not (ite C F1 F2)) (not C) F1)
396 CNF_ITE_POS1,
397 // ======== CNF ITE Pos version 2
398 // Children: ()
399 // Arguments: ((ite C F1 F2))
400 // ---------------------
401 // Conclusion: (or (not (ite C F1 F2)) C F2)
402 CNF_ITE_POS2,
403 // ======== CNF ITE Pos version 3
404 // Children: ()
405 // Arguments: ((ite C F1 F2))
406 // ---------------------
407 // Conclusion: (or (not (ite C F1 F2)) F1 F2)
408 CNF_ITE_POS3,
409 // ======== CNF ITE Neg version 1
410 // Children: ()
411 // Arguments: ((ite C F1 F2))
412 // ---------------------
413 // Conclusion: (or (ite C F1 F2) (not C) (not F1))
414 CNF_ITE_NEG1,
415 // ======== CNF ITE Neg version 2
416 // Children: ()
417 // Arguments: ((ite C F1 F2))
418 // ---------------------
419 // Conclusion: (or (ite C F1 F2) C (not F2))
420 CNF_ITE_NEG2,
421 // ======== CNF ITE Neg version 3
422 // Children: ()
423 // Arguments: ((ite C F1 F2))
424 // ---------------------
425 // Conclusion: (or (ite C F1 F2) (not F1) (not F2))
426 CNF_ITE_NEG3,
427
428 //================================================= Equality rules
429 // ======== Reflexive
430 // Children: none
431 // Arguments: (t)
432 // ---------------------
433 // Conclusion: (= t t)
434 REFL,
435 // ======== Symmetric
436 // Children: (P:(= t1 t2)) or (P:(not (= t1 t2)))
437 // Arguments: none
438 // -----------------------
439 // Conclusion: (= t2 t1) or (not (= t2 t1))
440 SYMM,
441 // ======== Transitivity
442 // Children: (P1:(= t1 t2), ..., Pn:(= t{n-1} tn))
443 // Arguments: none
444 // -----------------------
445 // Conclusion: (= t1 tn)
446 TRANS,
447 // ======== Congruence (subsumed by Substitute?)
448 // Children: (P1:(= t1 s1), ..., Pn:(= tn sn))
449 // Arguments: (f)
450 // ---------------------------------------------
451 // Conclusion: (= (f t1 ... tn) (f s1 ... sn))
452 CONG,
453 // ======== True intro
454 // Children: (P:F)
455 // Arguments: none
456 // ----------------------------------------
457 // Conclusion: (= F true)
458 TRUE_INTRO,
459 // ======== True elim
460 // Children: (P:(= F true)
461 // Arguments: none
462 // ----------------------------------------
463 // Conclusion: F
464 TRUE_ELIM,
465 // ======== False intro
466 // Children: (P:(not F))
467 // Arguments: none
468 // ----------------------------------------
469 // Conclusion: (= F false)
470 FALSE_INTRO,
471 // ======== False elim
472 // Children: (P:(= F false)
473 // Arguments: none
474 // ----------------------------------------
475 // Conclusion: (not F)
476 FALSE_ELIM,
477
478 //================================================= Quantifiers rules
479 // ======== Witness intro
480 // Children: (P:F[t])
481 // Arguments: (t)
482 // ----------------------------------------
483 // Conclusion: (= t (witness ((x T)) F[x]))
484 // where x is a BOUND_VARIABLE unique to the pair F,t.
485 WITNESS_INTRO,
486 // ======== Exists intro
487 // Children: (P:F[t])
488 // Arguments: (t)
489 // ----------------------------------------
490 // Conclusion: (exists ((x T)) F[x])
491 // where x is a BOUND_VARIABLE unique to the pair F,t.
492 EXISTS_INTRO,
493 // ======== Skolemize
494 // Children: (P:(exists ((x1 T1) ... (xn Tn)) F))
495 // Arguments: none
496 // ----------------------------------------
497 // Conclusion: F*sigma
498 // sigma maps x1 ... xn to their representative skolems obtained by
499 // SkolemManager::mkSkolemize, returned in the skolems argument of that
500 // method.
501 SKOLEMIZE,
502 // ======== Instantiate
503 // Children: (P:(forall ((x1 T1) ... (xn Tn)) F))
504 // Arguments: (t1 ... tn)
505 // ----------------------------------------
506 // Conclusion: F*sigma
507 // sigma maps x1 ... xn to t1 ... tn.
508 INSTANTIATE,
509
510 // ======== Adding Inequalities
511 // Note: an ArithLiteral is a term of the form (>< poly const)
512 // where
513 // >< is >=, >, ==, <, <=, or not(== ...).
514 // poly is a polynomial
515 // const is a rational constant
516
517 // Children: (P1:l1, ..., Pn:ln)
518 // where each li is an ArithLiteral
519 // not(= ...) is dis-allowed!
520 //
521 // Arguments: (k1, ..., kn), non-zero reals
522 // ---------------------
523 // Conclusion: (>< (* k t1) (* k t2))
524 // where >< is the fusion of the combination of the ><i, (flipping each it
525 // its ki is negative). >< is always one of <, <=
526 // NB: this implies that lower bounds must have negative ki,
527 // and upper bounds must have positive ki.
528 // t1 is the sum of the polynomials.
529 // t2 is the sum of the constants.
530 ARITH_SCALE_SUM_UPPER_BOUNDS,
531
532 // ======== Tightening Strict Integer Upper Bounds
533 // Children: (P:(< i c))
534 // where i has integer type.
535 // Arguments: none
536 // ---------------------
537 // Conclusion: (<= i greatestIntLessThan(c)})
538 INT_TIGHT_UB,
539
540 // ======== Tightening Strict Integer Lower Bounds
541 // Children: (P:(> i c))
542 // where i has integer type.
543 // Arguments: none
544 // ---------------------
545 // Conclusion: (>= i leastIntGreaterThan(c)})
546 INT_TIGHT_LB,
547
548 // ======== Trichotomy of the reals
549 // Children: (A B)
550 // Arguments: (C)
551 // ---------------------
552 // Conclusion: (C),
553 // where (not A) (not B) and C
554 // are (> x c) (< x c) and (= x c)
555 // in some order
556 // note that "not" here denotes arithmetic negation, flipping
557 // >= to <, etc.
558 ARITH_TRICHOTOMY,
559
560 // ======== Arithmetic operator elimination
561 // Children: none
562 // Arguments: (t)
563 // ---------------------
564 // Conclusion: arith::OperatorElim::getAxiomFor(t)
565 ARITH_OP_ELIM_AXIOM,
566
567 // ======== Int Trust
568 // Children: (P1 ... Pn)
569 // Arguments: (Q)
570 // ---------------------
571 // Conclusion: (Q)
572 INT_TRUST,
573
574 //================================================= Unknown rule
575 UNKNOWN,
576 };
577
578 /**
579 * Converts a proof rule to a string. Note: This function is also used in
580 * `safe_print()`. Changing this function name or signature will result in
581 * `safe_print()` printing "<unsupported>" instead of the proper strings for
582 * the enum values.
583 *
584 * @param id The proof rule
585 * @return The name of the proof rule
586 */
587 const char* toString(PfRule id);
588
589 /**
590 * Writes a proof rule name to a stream.
591 *
592 * @param out The stream to write to
593 * @param id The proof rule to write to the stream
594 * @return The stream
595 */
596 std::ostream& operator<<(std::ostream& out, PfRule id);
597
598 } // namespace CVC4
599
600 #endif /* CVC4__EXPR__PROOF_RULE_H */