1 /********************* */
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
12 ** \brief Proof rule enumeration
15 #include "cvc4_private.h"
17 #ifndef CVC4__EXPR__PROOF_RULE_H
18 #define CVC4__EXPR__PROOF_RULE_H
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
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.
35 * The following PfRule values include core rules and those categorized by
36 * theory, including the theory of equality.
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.
44 enum class PfRule
: uint32_t
46 //================================================= Core rules
47 //======================== Assume and Scope
48 // ======== Assumption (a leaf)
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).
60 // ======== Scope (a binder for assumptions)
62 // Arguments: (F1, ..., Fn)
64 // Conclusion: (=> (and F1 ... Fn) F) or (not (and F1 ... Fn)) if F is false
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.
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
83 // Notice that ids is a MethodId identifier, which determines how to convert
84 // the formulas F1, ..., Fn into substitutions.
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.
94 // ======== Substitution + Rewriting equality introduction
96 // In this rule, we provide a term t and conclude that it is equal to its
97 // rewritten form under a (proven) substitution.
99 // Children: (P1:F1, ..., Pn:Fn)
100 // Arguments: (t, (ids (idr)?)?)
101 // ---------------------------------------------------------------
102 // Conclusion: (= t t')
105 // Rewriter{idr}(t*sigma{ids}(Fn)*...*sigma{ids}(F1))
107 // In other words, from the point of view of Skolem forms, this rule
108 // transforms t to t' by standard substitution + rewriting.
110 // The argument ids and idr is optional and specify the identifier of the
111 // substitution and rewriter respectively to be used. For details, see
112 // theory/builtin/proof_checker.h.
114 // ======== Substitution + Rewriting predicate introduction
116 // In this rule, we provide a formula F and conclude it, under the condition
117 // that it rewrites to true under a proven substitution.
119 // Children: (P1:F1, ..., Pn:Fn)
120 // Arguments: (F, (ids (idr)?)?)
121 // ---------------------------------------------------------------
124 // Rewriter{idr}(toWitness(F)*sigma{ids}(Fn)*...*sigma{ids}(F1)) == true
125 // where ids and idr are method identifiers.
127 // Notice that we apply rewriting on the witness form of F, meaning that this
128 // rule may conclude an F whose Skolem form is justified by the definition of
129 // its (fresh) Skolem variables. Furthermore, notice that the rewriting and
130 // substitution is applied only within the side condition, meaning the
131 // rewritten form of the witness form of F does not escape this rule.
133 // ======== Substitution + Rewriting predicate elimination
135 // In this rule, if we have proven a formula F, then we may conclude its
136 // rewritten form under a proven substitution.
138 // Children: (P1:F, P2:F1, ..., P_{n+1}:Fn)
139 // Arguments: ((ids (idr)?)?)
140 // ----------------------------------------
144 // Rewriter{idr}(F*sigma{ids}(Fn)*...*sigma{ids}(F1)).
145 // where ids and idr are method identifiers.
147 // We rewrite only on the Skolem form of F, similar to MACRO_SR_EQ_INTRO.
149 // ======== Substitution + Rewriting predicate transform
151 // In this rule, if we have proven a formula F, then we may provide a formula
152 // G and conclude it if F and G are equivalent after rewriting under a proven
155 // Children: (P1:F, P2:F1, ..., P_{n+1}:Fn)
156 // Arguments: (G, (ids (idr)?)?)
157 // ----------------------------------------
160 // Rewriter{idr}(toWitness(F)*sigma{ids}(Fn)*...*sigma{ids}(F1)) ==
161 // Rewriter{idr}(toWitness(G)*sigma{ids}(Fn)*...*sigma{ids}(F1))
163 // Notice that we apply rewriting on the witness form of F and G, similar to
164 // MACRO_SR_PRED_INTRO.
165 MACRO_SR_PRED_TRANSFORM
,
166 // ======== Theory Rewrite
168 // Arguments: (t, preRewrite?)
169 // ----------------------------------------
170 // Conclusion: (= t t')
172 // t' is the result of applying either a pre-rewrite or a post-rewrite step
173 // to t (depending on the second argument).
176 //================================================= Processing rules
177 // ======== Preprocess
180 // ---------------------------------------------------------------
182 // where F is an equality of the form t = t' where t was replaced by t'
183 // based on some preprocessing pass, or otherwise F was added as a new
184 // assertion by some preprocessing pass.
186 //================================================= Boolean rules
190 // ---------------------
191 // Conclusion: (or F (not F))
193 // ======== Equality resolution
194 // Children: (P1:F1, P2:(= F1 F2))
196 // ---------------------
198 // Note this can optionally be seen as a macro for EQUIV_ELIM1+RESOLUTION.
200 // ======== And elimination
201 // Children: (P:(and F1 ... Fn))
203 // ---------------------
206 // ======== And introduction
207 // Children: (P1:F1 ... Pn:Fn))
209 // ---------------------
210 // Conclusion: (and P1 ... Pn)
212 // ======== Not Or elimination
213 // Children: (P:(not (or F1 ... Fn)))
215 // ---------------------
216 // Conclusion: (not Fi)
218 // ======== Implication elimination
219 // Children: (P:(=> F1 F2))
221 // ---------------------
222 // Conclusion: (or (not F1) F2)
224 // ======== Not Implication elimination version 1
225 // Children: (P:(not (=> F1 F2)))
227 // ---------------------
230 // ======== Not Implication elimination version 2
231 // Children: (P:(not (=> F1 F2)))
233 // ---------------------
234 // Conclusion: (not F2)
236 // ======== Equivalence elimination version 1
237 // Children: (P:(= F1 F2))
239 // ---------------------
240 // Conclusion: (or (not F1) F2)
242 // ======== Equivalence elimination version 2
243 // Children: (P:(= F1 F2))
245 // ---------------------
246 // Conclusion: (or F1 (not F2))
248 // ======== Not Equivalence elimination version 1
249 // Children: (P:(not (= F1 F2)))
251 // ---------------------
252 // Conclusion: (or F1 F2)
254 // ======== Not Equivalence elimination version 2
255 // Children: (P:(not (= F1 F2)))
257 // ---------------------
258 // Conclusion: (or (not F1) (not F2))
260 // ======== XOR elimination version 1
261 // Children: (P:(xor F1 F2)))
263 // ---------------------
264 // Conclusion: (or F1 F2)
266 // ======== XOR elimination version 2
267 // Children: (P:(xor F1 F2)))
269 // ---------------------
270 // Conclusion: (or (not F1) (not F2))
272 // ======== Not XOR elimination version 1
273 // Children: (P:(not (xor F1 F2)))
275 // ---------------------
276 // Conclusion: (or F1 (not F2))
278 // ======== Not XOR elimination version 2
279 // Children: (P:(not (xor F1 F2)))
281 // ---------------------
282 // Conclusion: (or (not F1) F2)
284 // ======== ITE elimination version 1
285 // Children: (P:(ite C F1 F2))
287 // ---------------------
288 // Conclusion: (or (not C) F1)
290 // ======== ITE elimination version 2
291 // Children: (P:(ite C F1 F2))
293 // ---------------------
294 // Conclusion: (or C F2)
296 // ======== Not ITE elimination version 1
297 // Children: (P:(not (ite C F1 F2)))
299 // ---------------------
300 // Conclusion: (or (not C) (not F1))
302 // ======== Not ITE elimination version 1
303 // Children: (P:(not (ite C F1 F2)))
305 // ---------------------
306 // Conclusion: (or C (not F2))
308 // ======== Not ITE elimination version 1
309 // Children: (P1:P P2:(not P))
311 // ---------------------
312 // Conclusion: (false)
315 //================================================= De Morgan rules
317 // Children: (P:(not (and F1 ... Fn))
319 // ---------------------
320 // Conclusion: (or (not F1) ... (not Fn))
322 //================================================= CNF rules
323 // ======== CNF And Pos
325 // Arguments: ((and F1 ... Fn), i)
326 // ---------------------
327 // Conclusion: (or (not (and F1 ... Fn)) Fi)
329 // ======== CNF And Neg
331 // Arguments: ((and F1 ... Fn))
332 // ---------------------
333 // Conclusion: (or (and F1 ... Fn) (not F1) ... (not Fn))
335 // ======== CNF Or Pos
337 // Arguments: ((or F1 ... Fn))
338 // ---------------------
339 // Conclusion: (or (not (or F1 ... Fn)) F1 ... Fn)
341 // ======== CNF Or Neg
343 // Arguments: ((or F1 ... Fn), i)
344 // ---------------------
345 // Conclusion: (or (or F1 ... Fn) (not Fi))
347 // ======== CNF Implies Pos
349 // Arguments: ((implies F1 F2))
350 // ---------------------
351 // Conclusion: (or (not (implies F1 F2)) (not F1) F2)
353 // ======== CNF Implies Neg version 1
355 // Arguments: ((implies F1 F2))
356 // ---------------------
357 // Conclusion: (or (implies F1 F2) F1)
359 // ======== CNF Implies Neg version 2
361 // Arguments: ((implies F1 F2))
362 // ---------------------
363 // Conclusion: (or (implies F1 F2) (not F2))
365 // ======== CNF Equiv Pos version 1
367 // Arguments: ((= F1 F2))
368 // ---------------------
369 // Conclusion: (or (not (= F1 F2)) (not F1) F2)
371 // ======== CNF Equiv Pos version 2
373 // Arguments: ((= F1 F2))
374 // ---------------------
375 // Conclusion: (or (not (= F1 F2)) F1 (not F2))
377 // ======== CNF Equiv Neg version 1
379 // Arguments: ((= F1 F2))
380 // ---------------------
381 // Conclusion: (or (= F1 F2) F1 F2)
383 // ======== CNF Equiv Neg version 2
385 // Arguments: ((= F1 F2))
386 // ---------------------
387 // Conclusion: (or (= F1 F2) (not F1) (not F2))
389 // ======== CNF Xor Pos version 1
391 // Arguments: ((xor F1 F2))
392 // ---------------------
393 // Conclusion: (or (not (xor F1 F2)) F1 F2)
395 // ======== CNF Xor Pos version 2
397 // Arguments: ((xor F1 F2))
398 // ---------------------
399 // Conclusion: (or (not (xor F1 F2)) (not F1) (not F2))
401 // ======== CNF Xor Neg version 1
403 // Arguments: ((xor F1 F2))
404 // ---------------------
405 // Conclusion: (or (xor F1 F2) (not F1) F2)
407 // ======== CNF Xor Neg version 2
409 // Arguments: ((xor F1 F2))
410 // ---------------------
411 // Conclusion: (or (xor F1 F2) F1 (not F2))
413 // ======== CNF ITE Pos version 1
415 // Arguments: ((ite C F1 F2))
416 // ---------------------
417 // Conclusion: (or (not (ite C F1 F2)) (not C) F1)
419 // ======== CNF ITE Pos version 2
421 // Arguments: ((ite C F1 F2))
422 // ---------------------
423 // Conclusion: (or (not (ite C F1 F2)) C F2)
425 // ======== CNF ITE Pos version 3
427 // Arguments: ((ite C F1 F2))
428 // ---------------------
429 // Conclusion: (or (not (ite C F1 F2)) F1 F2)
431 // ======== CNF ITE Neg version 1
433 // Arguments: ((ite C F1 F2))
434 // ---------------------
435 // Conclusion: (or (ite C F1 F2) (not C) (not F1))
437 // ======== CNF ITE Neg version 2
439 // Arguments: ((ite C F1 F2))
440 // ---------------------
441 // Conclusion: (or (ite C F1 F2) C (not F2))
443 // ======== CNF ITE Neg version 3
445 // Arguments: ((ite C F1 F2))
446 // ---------------------
447 // Conclusion: (or (ite C F1 F2) (not F1) (not F2))
450 //================================================= Equality rules
451 // ======== Reflexive
454 // ---------------------
455 // Conclusion: (= t t)
457 // ======== Symmetric
458 // Children: (P:(= t1 t2)) or (P:(not (= t1 t2)))
460 // -----------------------
461 // Conclusion: (= t2 t1) or (not (= t2 t1))
463 // ======== Transitivity
464 // Children: (P1:(= t1 t2), ..., Pn:(= t{n-1} tn))
466 // -----------------------
467 // Conclusion: (= t1 tn)
469 // ======== Congruence (subsumed by Substitute?)
470 // Children: (P1:(= t1 s1), ..., Pn:(= tn sn))
472 // ---------------------------------------------
473 // Conclusion: (= (f t1 ... tn) (f s1 ... sn))
475 // ======== True intro
478 // ----------------------------------------
479 // Conclusion: (= F true)
481 // ======== True elim
482 // Children: (P:(= F true)
484 // ----------------------------------------
487 // ======== False intro
488 // Children: (P:(not F))
490 // ----------------------------------------
491 // Conclusion: (= F false)
493 // ======== False elim
494 // Children: (P:(= F false)
496 // ----------------------------------------
497 // Conclusion: (not F)
500 //================================================= Quantifiers rules
501 // ======== Witness intro
502 // Children: (P:F[t])
504 // ----------------------------------------
505 // Conclusion: (= t (witness ((x T)) F[x]))
506 // where x is a BOUND_VARIABLE unique to the pair F,t.
508 // ======== Exists intro
509 // Children: (P:F[t])
511 // ----------------------------------------
512 // Conclusion: (exists ((x T)) F[x])
513 // where x is a BOUND_VARIABLE unique to the pair F,t.
515 // ======== Skolemize
516 // Children: (P:(exists ((x1 T1) ... (xn Tn)) F))
518 // ----------------------------------------
519 // Conclusion: F*sigma
520 // sigma maps x1 ... xn to their representative skolems obtained by
521 // SkolemManager::mkSkolemize, returned in the skolems argument of that
524 // ======== Instantiate
525 // Children: (P:(forall ((x1 T1) ... (xn Tn)) F))
526 // Arguments: (t1 ... tn)
527 // ----------------------------------------
528 // Conclusion: F*sigma
529 // sigma maps x1 ... xn to t1 ... tn.
532 //================================================= String rules
533 //======================== Core solver
534 // ======== Concat eq
535 // Children: (P1:(= (str.++ t1 ... tn t) (str.++ t1 ... tn s)))
536 // Arguments: (b), indicating if reverse direction
537 // ---------------------
538 // Conclusion: (= t s)
540 // Notice that t or s may be empty, in which case they are implicit in the
541 // concatenation above. For example, if
542 // P1 concludes (= x (str.++ x z)), then
543 // (CONCAT_EQ P1 :args false) concludes (= "" z)
545 // Also note that constants are split, such that if
546 // P1 concludes (= (str.++ "abc" x) (str.++ "a" y)), then
547 // (CONCAT_EQ P1 :args false) concludes (= (str.++ "bc" x) y)
548 // This splitting is done only for constants such that Word::splitConstant
551 // ======== Concat unify
552 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
553 // P2:(= (str.len t1) (str.len s1)))
554 // Arguments: (b), indicating if reverse direction
555 // ---------------------
556 // Conclusion: (= t1 s1)
558 // ======== Concat conflict
559 // Children: (P1:(= (str.++ c1 t) (str.++ c2 s)))
560 // Arguments: (b), indicating if reverse direction
561 // ---------------------
563 // Where c1, c2 are constants such that Word::splitConstant(c1,c2,index,b)
564 // is null, in other words, neither is a prefix of the other.
566 // ======== Concat split
567 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
568 // P2:(not (= (str.len t1) (str.len s1))))
569 // Arguments: (false)
570 // ---------------------
571 // Conclusion: (or (= t1 (str.++ s1 r_t)) (= s1 (str.++ t1 r_s)))
573 // r_t = (witness ((z String)) (= z (suf t1 (str.len s1)))),
574 // r_s = (witness ((z String)) (= z (suf s1 (str.len t1)))).
576 // or the reverse form of the above:
578 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
579 // P2:(not (= (str.len t2) (str.len s2))))
581 // ---------------------
582 // Conclusion: (or (= t2 (str.++ r_t s2)) (= s2 (str.++ r_s t2)))
584 // r_t = (witness ((z String)) (= z (pre t2 (- (str.len t2) (str.len
585 // s2))))), r_s = (witness ((z String)) (= z (pre s2 (- (str.len s2)
588 // Above, (suf x n) is shorthand for (str.substr x n (- (str.len x) n)) and
589 // (pre x n) is shorthand for (str.substr x 0 n).
591 // ======== Concat constant split
592 // Children: (P1:(= (str.++ t1 t2) (str.++ c s2)),
593 // P2:(not (= (str.len t1) 0)))
594 // Arguments: (false)
595 // ---------------------
596 // Conclusion: (= t1 (str.++ c r))
598 // r = (witness ((z String)) (= z (suf t1 1))).
600 // or the reverse form of the above:
602 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 c)),
603 // P2:(not (= (str.len t2) 0)))
605 // ---------------------
606 // Conclusion: (= t2 (str.++ r c))
608 // r = (witness ((z String)) (= z (pre t2 (- (str.len t2) 1)))).
610 // ======== Concat length propagate
611 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
612 // P2:(> (str.len t1) (str.len s1)))
613 // Arguments: (false)
614 // ---------------------
615 // Conclusion: (= t1 (str.++ s1 r_t))
617 // r_t = (witness ((z String)) (= z (suf t1 (str.len s1))))
619 // or the reverse form of the above:
621 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
622 // P2:(> (str.len t2) (str.len s2)))
623 // Arguments: (false)
624 // ---------------------
625 // Conclusion: (= t2 (str.++ r_t s2))
627 // r_t = (witness ((z String)) (= z (pre t2 (- (str.len t2) (str.len
630 // ======== Concat constant propagate
631 // Children: (P1:(= (str.++ t1 w1 t2) (str.++ w2 s)),
632 // P2:(not (= (str.len t1) 0)))
633 // Arguments: (false)
634 // ---------------------
635 // Conclusion: (= t1 (str.++ w3 r))
637 // w1, w2, w3, w4 are words,
640 // p = Word::overlap((suf w2 1), w1),
641 // r = (witness ((z String)) (= z (suf t1 (str.len w3)))).
642 // In other words, w4 is the largest suffix of (suf w2 1) that can contain a
643 // prefix of w1; since t1 is non-empty, w3 must therefore be contained in t1.
645 // or the reverse form of the above:
647 // Children: (P1:(= (str.++ t1 w1 t2) (str.++ s w2)),
648 // P2:(not (= (str.len t2) 0)))
650 // ---------------------
651 // Conclusion: (= t2 (str.++ r w3))
653 // w1, w2, w3, w4 are words,
654 // w3 is (suf w2 (- (str.len w2) p)),
655 // w4 is (pre w2 (- (str.len w2) p)),
656 // p = Word::roverlap((pre w2 (- (str.len w2) 1)), w1),
657 // r = (witness ((z String)) (= z (pre t2 (- (str.len t2) (str.len w3))))).
658 // In other words, w4 is the largest prefix of (pre w2 (- (str.len w2) 1))
659 // that can contain a suffix of w1; since t2 is non-empty, w3 must therefore
660 // be contained in t2.
662 // ======== String decompose
663 // Children: (P1: (>= (str.len t) n)
664 // Arguments: (false)
665 // ---------------------
666 // Conclusion: (and (= t (str.++ w1 w2)) (= (str.len w1) n))
668 // Children: (P1: (>= (str.len t) n)
670 // ---------------------
671 // Conclusion: (and (= t (str.++ w1 w2)) (= (str.len w2) n))
673 // w1 is (witness ((z String)) (= z (pre t n)))
674 // w2 is (witness ((z String)) (= z (suf t n)))
676 // ======== Length positive
679 // ---------------------
680 // Conclusion: (or (and (= (str.len t) 0) (= t "")) (> (str.len t 0)))
682 // ======== Length non-empty
683 // Children: (P1:(not (= t "")))
685 // ---------------------
686 // Conclusion: (not (= (str.len t) 0))
687 STRING_LENGTH_NON_EMPTY
,
688 //======================== Extended functions
689 // ======== Reduction
692 // ---------------------
693 // Conclusion: (and R (= t w))
694 // where w = strings::StringsPreprocess::reduce(t, R, ...).
695 // In other words, R is the reduction predicate for extended term t, and w is
696 // (witness ((z T)) (= z t))
697 // Notice that the free variables of R are w and the free variables of t.
699 // ======== Eager Reduction
701 // Arguments: (t, id?)
702 // ---------------------
704 // where R = strings::TermRegistry::eagerReduce(t, id).
705 STRING_EAGER_REDUCTION
,
706 //======================== Regular expressions
707 // ======== Regular expression intersection
708 // Children: (P:(str.in.re t R1), P:(str.in.re t R2))
710 // ---------------------
711 // Conclusion: (str.in.re t (re.inter R1 R2)).
713 // ======== Regular expression unfold positive
714 // Children: (P:(str.in.re t R))
716 // ---------------------
717 // Conclusion:(RegExpOpr::reduceRegExpPos((str.in.re t R))),
718 // corresponding to the one-step unfolding of the premise.
720 // ======== Regular expression unfold negative
721 // Children: (P:(not (str.in.re t R)))
723 // ---------------------
724 // Conclusion:(RegExpOpr::reduceRegExpNeg((not (str.in.re t R)))),
725 // corresponding to the one-step unfolding of the premise.
727 // ======== Regular expression unfold negative concat fixed
728 // Children: (P:(not (str.in.re t R)))
730 // ---------------------
731 // Conclusion:(RegExpOpr::reduceRegExpNegConcatFixed((not (str.in.re t
732 // R)),L,i)) where RegExpOpr::getRegExpConcatFixed((not (str.in.re t R)), i) =
733 // L. corresponding to the one-step unfolding of the premise, optimized for
734 // fixed length of component i of the regular expression concatenation R.
735 RE_UNFOLD_NEG_CONCAT_FIXED
,
736 // ======== Regular expression elimination
739 // ---------------------
741 // where R = strings::RegExpElimination::eliminate(F).
743 //======================== Code points
746 // ---------------------
747 // Conclusion:(or (= (str.code t) (- 1))
748 // (not (= (str.code t) (str.code s)))
751 // ======== Adding Inequalities
752 // Note: an ArithLiteral is a term of the form (>< poly const)
754 // >< is >=, >, ==, <, <=, or not(== ...).
755 // poly is a polynomial
756 // const is a rational constant
758 // Children: (P1:l1, ..., Pn:ln)
759 // where each li is an ArithLiteral
760 // not(= ...) is dis-allowed!
762 // Arguments: (k1, ..., kn), non-zero reals
763 // ---------------------
764 // Conclusion: (>< (* k t1) (* k t2))
765 // where >< is the fusion of the combination of the ><i, (flipping each it
766 // its ki is negative). >< is always one of <, <=
767 // NB: this implies that lower bounds must have negative ki,
768 // and upper bounds must have positive ki.
769 // t1 is the sum of the polynomials.
770 // t2 is the sum of the constants.
771 ARITH_SCALE_SUM_UPPER_BOUNDS
,
773 // ======== Tightening Strict Integer Upper Bounds
774 // Children: (P:(< i c))
775 // where i has integer type.
777 // ---------------------
778 // Conclusion: (<= i greatestIntLessThan(c)})
781 // ======== Tightening Strict Integer Lower Bounds
782 // Children: (P:(> i c))
783 // where i has integer type.
785 // ---------------------
786 // Conclusion: (>= i leastIntGreaterThan(c)})
789 // ======== Trichotomy of the reals
792 // ---------------------
794 // where (not A) (not B) and C
795 // are (> x c) (< x c) and (= x c)
797 // note that "not" here denotes arithmetic negation, flipping
801 // ======== Arithmetic operator elimination
804 // ---------------------
805 // Conclusion: arith::OperatorElim::getAxiomFor(t)
808 // ======== Int Trust
809 // Children: (P1 ... Pn)
811 // ---------------------
815 //================================================= Unknown rule
820 * Converts a proof rule to a string. Note: This function is also used in
821 * `safe_print()`. Changing this function name or signature will result in
822 * `safe_print()` printing "<unsupported>" instead of the proper strings for
825 * @param id The proof rule
826 * @return The name of the proof rule
828 const char* toString(PfRule id
);
831 * Writes a proof rule name to a stream.
833 * @param out The stream to write to
834 * @param id The proof rule to write to the stream
837 std::ostream
& operator<<(std::ostream
& out
, PfRule id
);
841 #endif /* CVC4__EXPR__PROOF_RULE_H */