b6b9f1ea8a31c21404611f9d343a95276d7f421d
[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 // Rewriter{idr}(t*sigma{ids}(Fn)*...*sigma{ids}(F1))
106 //
107 // In other words, from the point of view of Skolem forms, this rule
108 // transforms t to t' by standard substitution + rewriting.
109 //
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.
113 MACRO_SR_EQ_INTRO,
114 // ======== Substitution + Rewriting predicate introduction
115 //
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.
118 //
119 // Children: (P1:F1, ..., Pn:Fn)
120 // Arguments: (F, (ids (idr)?)?)
121 // ---------------------------------------------------------------
122 // Conclusion: F
123 // where
124 // Rewriter{idr}(toWitness(F)*sigma{ids}(Fn)*...*sigma{ids}(F1)) == true
125 // where ids and idr are method identifiers.
126 //
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.
132 MACRO_SR_PRED_INTRO,
133 // ======== Substitution + Rewriting predicate elimination
134 //
135 // In this rule, if we have proven a formula F, then we may conclude its
136 // rewritten form under a proven substitution.
137 //
138 // Children: (P1:F, P2:F1, ..., P_{n+1}:Fn)
139 // Arguments: ((ids (idr)?)?)
140 // ----------------------------------------
141 // Conclusion: F'
142 // where
143 // F' is
144 // Rewriter{idr}(F*sigma{ids}(Fn)*...*sigma{ids}(F1)).
145 // where ids and idr are method identifiers.
146 //
147 // We rewrite only on the Skolem form of F, similar to MACRO_SR_EQ_INTRO.
148 MACRO_SR_PRED_ELIM,
149 // ======== Substitution + Rewriting predicate transform
150 //
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
153 // substitution.
154 //
155 // Children: (P1:F, P2:F1, ..., P_{n+1}:Fn)
156 // Arguments: (G, (ids (idr)?)?)
157 // ----------------------------------------
158 // Conclusion: G
159 // where
160 // Rewriter{idr}(toWitness(F)*sigma{ids}(Fn)*...*sigma{ids}(F1)) ==
161 // Rewriter{idr}(toWitness(G)*sigma{ids}(Fn)*...*sigma{ids}(F1))
162 //
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
167 // Children: none
168 // Arguments: (t, preRewrite?)
169 // ----------------------------------------
170 // Conclusion: (= t t')
171 // where
172 // t' is the result of applying either a pre-rewrite or a post-rewrite step
173 // to t (depending on the second argument).
174 THEORY_REWRITE,
175
176 //================================================= Processing rules
177 // ======== Remove Term Formulas Axiom
178 // Children: none
179 // Arguments: (t)
180 // ---------------------------------------------------------------
181 // Conclusion: RemoveTermFormulas::getAxiomFor(t).
182 REMOVE_TERM_FORMULA_AXIOM,
183
184 //================================================= Trusted rules
185 // The rules in this section have the signature of a "trusted rule":
186 //
187 // Children: none
188 // Arguments: (F)
189 // ---------------------------------------------------------------
190 // Conclusion: F
191 //
192 // where F is an equality of the form t = t' where t was replaced by t'
193 // based on some preprocessing pass, or otherwise F was added as a new
194 // assertion by some preprocessing pass.
195 PREPROCESS,
196 // where F was added as a new assertion by some preprocessing pass.
197 PREPROCESS_LEMMA,
198 // where F is an equality of the form t = Theory::ppRewrite(t) for some
199 // theory. Notice this is a "trusted" rule.
200 THEORY_PREPROCESS,
201 // where F was added as a new assertion by theory preprocessing.
202 THEORY_PREPROCESS_LEMMA,
203 // where F is an existential (exists ((x T)) (P x)) used for introducing
204 // a witness term (witness ((x T)) (P x)).
205 WITNESS_AXIOM,
206
207 //================================================= Boolean rules
208 // ======== Split
209 // Children: none
210 // Arguments: (F)
211 // ---------------------
212 // Conclusion: (or F (not F))
213 SPLIT,
214 // ======== Equality resolution
215 // Children: (P1:F1, P2:(= F1 F2))
216 // Arguments: none
217 // ---------------------
218 // Conclusion: (F2)
219 // Note this can optionally be seen as a macro for EQUIV_ELIM1+RESOLUTION.
220 EQ_RESOLVE,
221 // ======== And elimination
222 // Children: (P:(and F1 ... Fn))
223 // Arguments: (i)
224 // ---------------------
225 // Conclusion: (Fi)
226 AND_ELIM,
227 // ======== And introduction
228 // Children: (P1:F1 ... Pn:Fn))
229 // Arguments: ()
230 // ---------------------
231 // Conclusion: (and P1 ... Pn)
232 AND_INTRO,
233 // ======== Not Or elimination
234 // Children: (P:(not (or F1 ... Fn)))
235 // Arguments: (i)
236 // ---------------------
237 // Conclusion: (not Fi)
238 NOT_OR_ELIM,
239 // ======== Implication elimination
240 // Children: (P:(=> F1 F2))
241 // Arguments: ()
242 // ---------------------
243 // Conclusion: (or (not F1) F2)
244 IMPLIES_ELIM,
245 // ======== Not Implication elimination version 1
246 // Children: (P:(not (=> F1 F2)))
247 // Arguments: ()
248 // ---------------------
249 // Conclusion: (F1)
250 NOT_IMPLIES_ELIM1,
251 // ======== Not Implication elimination version 2
252 // Children: (P:(not (=> F1 F2)))
253 // Arguments: ()
254 // ---------------------
255 // Conclusion: (not F2)
256 NOT_IMPLIES_ELIM2,
257 // ======== Equivalence elimination version 1
258 // Children: (P:(= F1 F2))
259 // Arguments: ()
260 // ---------------------
261 // Conclusion: (or (not F1) F2)
262 EQUIV_ELIM1,
263 // ======== Equivalence elimination version 2
264 // Children: (P:(= F1 F2))
265 // Arguments: ()
266 // ---------------------
267 // Conclusion: (or F1 (not F2))
268 EQUIV_ELIM2,
269 // ======== Not Equivalence elimination version 1
270 // Children: (P:(not (= F1 F2)))
271 // Arguments: ()
272 // ---------------------
273 // Conclusion: (or F1 F2)
274 NOT_EQUIV_ELIM1,
275 // ======== Not Equivalence elimination version 2
276 // Children: (P:(not (= F1 F2)))
277 // Arguments: ()
278 // ---------------------
279 // Conclusion: (or (not F1) (not F2))
280 NOT_EQUIV_ELIM2,
281 // ======== XOR elimination version 1
282 // Children: (P:(xor F1 F2)))
283 // Arguments: ()
284 // ---------------------
285 // Conclusion: (or F1 F2)
286 XOR_ELIM1,
287 // ======== XOR elimination version 2
288 // Children: (P:(xor F1 F2)))
289 // Arguments: ()
290 // ---------------------
291 // Conclusion: (or (not F1) (not F2))
292 XOR_ELIM2,
293 // ======== Not XOR elimination version 1
294 // Children: (P:(not (xor F1 F2)))
295 // Arguments: ()
296 // ---------------------
297 // Conclusion: (or F1 (not F2))
298 NOT_XOR_ELIM1,
299 // ======== Not XOR elimination version 2
300 // Children: (P:(not (xor F1 F2)))
301 // Arguments: ()
302 // ---------------------
303 // Conclusion: (or (not F1) F2)
304 NOT_XOR_ELIM2,
305 // ======== ITE elimination version 1
306 // Children: (P:(ite C F1 F2))
307 // Arguments: ()
308 // ---------------------
309 // Conclusion: (or (not C) F1)
310 ITE_ELIM1,
311 // ======== ITE elimination version 2
312 // Children: (P:(ite C F1 F2))
313 // Arguments: ()
314 // ---------------------
315 // Conclusion: (or C F2)
316 ITE_ELIM2,
317 // ======== Not ITE elimination version 1
318 // Children: (P:(not (ite C F1 F2)))
319 // Arguments: ()
320 // ---------------------
321 // Conclusion: (or (not C) (not F1))
322 NOT_ITE_ELIM1,
323 // ======== Not ITE elimination version 1
324 // Children: (P:(not (ite C F1 F2)))
325 // Arguments: ()
326 // ---------------------
327 // Conclusion: (or C (not F2))
328 NOT_ITE_ELIM2,
329 // ======== Not ITE elimination version 1
330 // Children: (P1:P P2:(not P))
331 // Arguments: ()
332 // ---------------------
333 // Conclusion: (false)
334 CONTRA,
335
336 //================================================= De Morgan rules
337 // ======== Not And
338 // Children: (P:(not (and F1 ... Fn))
339 // Arguments: ()
340 // ---------------------
341 // Conclusion: (or (not F1) ... (not Fn))
342 NOT_AND,
343 //================================================= CNF rules
344 // ======== CNF And Pos
345 // Children: ()
346 // Arguments: ((and F1 ... Fn), i)
347 // ---------------------
348 // Conclusion: (or (not (and F1 ... Fn)) Fi)
349 CNF_AND_POS,
350 // ======== CNF And Neg
351 // Children: ()
352 // Arguments: ((and F1 ... Fn))
353 // ---------------------
354 // Conclusion: (or (and F1 ... Fn) (not F1) ... (not Fn))
355 CNF_AND_NEG,
356 // ======== CNF Or Pos
357 // Children: ()
358 // Arguments: ((or F1 ... Fn))
359 // ---------------------
360 // Conclusion: (or (not (or F1 ... Fn)) F1 ... Fn)
361 CNF_OR_POS,
362 // ======== CNF Or Neg
363 // Children: ()
364 // Arguments: ((or F1 ... Fn), i)
365 // ---------------------
366 // Conclusion: (or (or F1 ... Fn) (not Fi))
367 CNF_OR_NEG,
368 // ======== CNF Implies Pos
369 // Children: ()
370 // Arguments: ((implies F1 F2))
371 // ---------------------
372 // Conclusion: (or (not (implies F1 F2)) (not F1) F2)
373 CNF_IMPLIES_POS,
374 // ======== CNF Implies Neg version 1
375 // Children: ()
376 // Arguments: ((implies F1 F2))
377 // ---------------------
378 // Conclusion: (or (implies F1 F2) F1)
379 CNF_IMPLIES_NEG1,
380 // ======== CNF Implies Neg version 2
381 // Children: ()
382 // Arguments: ((implies F1 F2))
383 // ---------------------
384 // Conclusion: (or (implies F1 F2) (not F2))
385 CNF_IMPLIES_NEG2,
386 // ======== CNF Equiv Pos version 1
387 // Children: ()
388 // Arguments: ((= F1 F2))
389 // ---------------------
390 // Conclusion: (or (not (= F1 F2)) (not F1) F2)
391 CNF_EQUIV_POS1,
392 // ======== CNF Equiv Pos version 2
393 // Children: ()
394 // Arguments: ((= F1 F2))
395 // ---------------------
396 // Conclusion: (or (not (= F1 F2)) F1 (not F2))
397 CNF_EQUIV_POS2,
398 // ======== CNF Equiv Neg version 1
399 // Children: ()
400 // Arguments: ((= F1 F2))
401 // ---------------------
402 // Conclusion: (or (= F1 F2) F1 F2)
403 CNF_EQUIV_NEG1,
404 // ======== CNF Equiv Neg version 2
405 // Children: ()
406 // Arguments: ((= F1 F2))
407 // ---------------------
408 // Conclusion: (or (= F1 F2) (not F1) (not F2))
409 CNF_EQUIV_NEG2,
410 // ======== CNF Xor Pos version 1
411 // Children: ()
412 // Arguments: ((xor F1 F2))
413 // ---------------------
414 // Conclusion: (or (not (xor F1 F2)) F1 F2)
415 CNF_XOR_POS1,
416 // ======== CNF Xor Pos version 2
417 // Children: ()
418 // Arguments: ((xor F1 F2))
419 // ---------------------
420 // Conclusion: (or (not (xor F1 F2)) (not F1) (not F2))
421 CNF_XOR_POS2,
422 // ======== CNF Xor Neg version 1
423 // Children: ()
424 // Arguments: ((xor F1 F2))
425 // ---------------------
426 // Conclusion: (or (xor F1 F2) (not F1) F2)
427 CNF_XOR_NEG1,
428 // ======== CNF Xor Neg version 2
429 // Children: ()
430 // Arguments: ((xor F1 F2))
431 // ---------------------
432 // Conclusion: (or (xor F1 F2) F1 (not F2))
433 CNF_XOR_NEG2,
434 // ======== CNF ITE Pos version 1
435 // Children: ()
436 // Arguments: ((ite C F1 F2))
437 // ---------------------
438 // Conclusion: (or (not (ite C F1 F2)) (not C) F1)
439 CNF_ITE_POS1,
440 // ======== CNF ITE Pos version 2
441 // Children: ()
442 // Arguments: ((ite C F1 F2))
443 // ---------------------
444 // Conclusion: (or (not (ite C F1 F2)) C F2)
445 CNF_ITE_POS2,
446 // ======== CNF ITE Pos version 3
447 // Children: ()
448 // Arguments: ((ite C F1 F2))
449 // ---------------------
450 // Conclusion: (or (not (ite C F1 F2)) F1 F2)
451 CNF_ITE_POS3,
452 // ======== CNF ITE Neg version 1
453 // Children: ()
454 // Arguments: ((ite C F1 F2))
455 // ---------------------
456 // Conclusion: (or (ite C F1 F2) (not C) (not F1))
457 CNF_ITE_NEG1,
458 // ======== CNF ITE Neg version 2
459 // Children: ()
460 // Arguments: ((ite C F1 F2))
461 // ---------------------
462 // Conclusion: (or (ite C F1 F2) C (not F2))
463 CNF_ITE_NEG2,
464 // ======== CNF ITE Neg version 3
465 // Children: ()
466 // Arguments: ((ite C F1 F2))
467 // ---------------------
468 // Conclusion: (or (ite C F1 F2) (not F1) (not F2))
469 CNF_ITE_NEG3,
470
471 //================================================= Equality rules
472 // ======== Reflexive
473 // Children: none
474 // Arguments: (t)
475 // ---------------------
476 // Conclusion: (= t t)
477 REFL,
478 // ======== Symmetric
479 // Children: (P:(= t1 t2)) or (P:(not (= t1 t2)))
480 // Arguments: none
481 // -----------------------
482 // Conclusion: (= t2 t1) or (not (= t2 t1))
483 SYMM,
484 // ======== Transitivity
485 // Children: (P1:(= t1 t2), ..., Pn:(= t{n-1} tn))
486 // Arguments: none
487 // -----------------------
488 // Conclusion: (= t1 tn)
489 TRANS,
490 // ======== Congruence
491 // Children: (P1:(= t1 s1), ..., Pn:(= tn sn))
492 // Arguments: (<kind> f?)
493 // ---------------------------------------------
494 // Conclusion: (= (<kind> f? t1 ... tn) (<kind> f? s1 ... sn))
495 // Notice that f must be provided iff <kind> is a parameterized kind, e.g.
496 // APPLY_UF. The actual node for <kind> is constructible via
497 // ProofRuleChecker::mkKindNode.
498 CONG,
499 // ======== True intro
500 // Children: (P:F)
501 // Arguments: none
502 // ----------------------------------------
503 // Conclusion: (= F true)
504 TRUE_INTRO,
505 // ======== True elim
506 // Children: (P:(= F true)
507 // Arguments: none
508 // ----------------------------------------
509 // Conclusion: F
510 TRUE_ELIM,
511 // ======== False intro
512 // Children: (P:(not F))
513 // Arguments: none
514 // ----------------------------------------
515 // Conclusion: (= F false)
516 FALSE_INTRO,
517 // ======== False elim
518 // Children: (P:(= F false)
519 // Arguments: none
520 // ----------------------------------------
521 // Conclusion: (not F)
522 FALSE_ELIM,
523 // ======== HO trust
524 // Children: none
525 // Arguments: (t)
526 // ---------------------
527 // Conclusion: (= t TheoryUfRewriter::getHoApplyForApplyUf(t))
528 // For example, this rule concludes (f x y) = (HO_APPLY (HO_APPLY f x) y)
529 HO_APP_ENCODE,
530 // ======== Congruence
531 // Children: (P1:(= f g), P2:(= t1 s1), ..., Pn+1:(= tn sn))
532 // Arguments: ()
533 // ---------------------------------------------
534 // Conclusion: (= (f t1 ... tn) (g s1 ... sn))
535 // Notice that this rule is only used when the application kinds are APPLY_UF.
536 HO_CONG,
537
538 //================================================= Quantifiers rules
539 // ======== Witness intro
540 // Children: (P:F[t])
541 // Arguments: (t)
542 // ----------------------------------------
543 // Conclusion: (= t (witness ((x T)) F[x]))
544 // where x is a BOUND_VARIABLE unique to the pair F,t.
545 WITNESS_INTRO,
546 // ======== Exists intro
547 // Children: (P:F[t])
548 // Arguments: (t)
549 // ----------------------------------------
550 // Conclusion: (exists ((x T)) F[x])
551 // where x is a BOUND_VARIABLE unique to the pair F,t.
552 EXISTS_INTRO,
553 // ======== Skolemize
554 // Children: (P:(exists ((x1 T1) ... (xn Tn)) F))
555 // Arguments: none
556 // ----------------------------------------
557 // Conclusion: F*sigma
558 // sigma maps x1 ... xn to their representative skolems obtained by
559 // SkolemManager::mkSkolemize, returned in the skolems argument of that
560 // method.
561 SKOLEMIZE,
562 // ======== Instantiate
563 // Children: (P:(forall ((x1 T1) ... (xn Tn)) F))
564 // Arguments: (t1 ... tn)
565 // ----------------------------------------
566 // Conclusion: F*sigma
567 // sigma maps x1 ... xn to t1 ... tn.
568 INSTANTIATE,
569
570 //================================================= String rules
571 //======================== Core solver
572 // ======== Concat eq
573 // Children: (P1:(= (str.++ t1 ... tn t) (str.++ t1 ... tn s)))
574 // Arguments: (b), indicating if reverse direction
575 // ---------------------
576 // Conclusion: (= t s)
577 //
578 // Notice that t or s may be empty, in which case they are implicit in the
579 // concatenation above. For example, if
580 // P1 concludes (= x (str.++ x z)), then
581 // (CONCAT_EQ P1 :args false) concludes (= "" z)
582 //
583 // Also note that constants are split, such that if
584 // P1 concludes (= (str.++ "abc" x) (str.++ "a" y)), then
585 // (CONCAT_EQ P1 :args false) concludes (= (str.++ "bc" x) y)
586 // This splitting is done only for constants such that Word::splitConstant
587 // returns non-null.
588 CONCAT_EQ,
589 // ======== Concat unify
590 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
591 // P2:(= (str.len t1) (str.len s1)))
592 // Arguments: (b), indicating if reverse direction
593 // ---------------------
594 // Conclusion: (= t1 s1)
595 CONCAT_UNIFY,
596 // ======== Concat conflict
597 // Children: (P1:(= (str.++ c1 t) (str.++ c2 s)))
598 // Arguments: (b), indicating if reverse direction
599 // ---------------------
600 // Conclusion: false
601 // Where c1, c2 are constants such that Word::splitConstant(c1,c2,index,b)
602 // is null, in other words, neither is a prefix of the other.
603 CONCAT_CONFLICT,
604 // ======== Concat split
605 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
606 // P2:(not (= (str.len t1) (str.len s1))))
607 // Arguments: (false)
608 // ---------------------
609 // Conclusion: (or (= t1 (str.++ s1 r_t)) (= s1 (str.++ t1 r_s)))
610 // where
611 // r_t = (witness ((z String)) (= z (suf t1 (str.len s1)))),
612 // r_s = (witness ((z String)) (= z (suf s1 (str.len t1)))).
613 //
614 // or the reverse form of the above:
615 //
616 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
617 // P2:(not (= (str.len t2) (str.len s2))))
618 // Arguments: (true)
619 // ---------------------
620 // Conclusion: (or (= t2 (str.++ r_t s2)) (= s2 (str.++ r_s t2)))
621 // where
622 // r_t = (witness ((z String)) (= z (pre t2 (- (str.len t2) (str.len
623 // s2))))), r_s = (witness ((z String)) (= z (pre s2 (- (str.len s2)
624 // (str.len t2))))).
625 //
626 // Above, (suf x n) is shorthand for (str.substr x n (- (str.len x) n)) and
627 // (pre x n) is shorthand for (str.substr x 0 n).
628 CONCAT_SPLIT,
629 // ======== Concat constant split
630 // Children: (P1:(= (str.++ t1 t2) (str.++ c s2)),
631 // P2:(not (= (str.len t1) 0)))
632 // Arguments: (false)
633 // ---------------------
634 // Conclusion: (= t1 (str.++ c r))
635 // where
636 // r = (witness ((z String)) (= z (suf t1 1))).
637 //
638 // or the reverse form of the above:
639 //
640 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 c)),
641 // P2:(not (= (str.len t2) 0)))
642 // Arguments: (true)
643 // ---------------------
644 // Conclusion: (= t2 (str.++ r c))
645 // where
646 // r = (witness ((z String)) (= z (pre t2 (- (str.len t2) 1)))).
647 CONCAT_CSPLIT,
648 // ======== Concat length propagate
649 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
650 // P2:(> (str.len t1) (str.len s1)))
651 // Arguments: (false)
652 // ---------------------
653 // Conclusion: (= t1 (str.++ s1 r_t))
654 // where
655 // r_t = (witness ((z String)) (= z (suf t1 (str.len s1))))
656 //
657 // or the reverse form of the above:
658 //
659 // Children: (P1:(= (str.++ t1 t2) (str.++ s1 s2)),
660 // P2:(> (str.len t2) (str.len s2)))
661 // Arguments: (false)
662 // ---------------------
663 // Conclusion: (= t2 (str.++ r_t s2))
664 // where
665 // r_t = (witness ((z String)) (= z (pre t2 (- (str.len t2) (str.len
666 // s2))))).
667 CONCAT_LPROP,
668 // ======== Concat constant propagate
669 // Children: (P1:(= (str.++ t1 w1 t2) (str.++ w2 s)),
670 // P2:(not (= (str.len t1) 0)))
671 // Arguments: (false)
672 // ---------------------
673 // Conclusion: (= t1 (str.++ w3 r))
674 // where
675 // w1, w2, w3, w4 are words,
676 // w3 is (pre w2 p),
677 // w4 is (suf w2 p),
678 // p = Word::overlap((suf w2 1), w1),
679 // r = (witness ((z String)) (= z (suf t1 (str.len w3)))).
680 // In other words, w4 is the largest suffix of (suf w2 1) that can contain a
681 // prefix of w1; since t1 is non-empty, w3 must therefore be contained in t1.
682 //
683 // or the reverse form of the above:
684 //
685 // Children: (P1:(= (str.++ t1 w1 t2) (str.++ s w2)),
686 // P2:(not (= (str.len t2) 0)))
687 // Arguments: (true)
688 // ---------------------
689 // Conclusion: (= t2 (str.++ r w3))
690 // where
691 // w1, w2, w3, w4 are words,
692 // w3 is (suf w2 (- (str.len w2) p)),
693 // w4 is (pre w2 (- (str.len w2) p)),
694 // p = Word::roverlap((pre w2 (- (str.len w2) 1)), w1),
695 // r = (witness ((z String)) (= z (pre t2 (- (str.len t2) (str.len w3))))).
696 // In other words, w4 is the largest prefix of (pre w2 (- (str.len w2) 1))
697 // that can contain a suffix of w1; since t2 is non-empty, w3 must therefore
698 // be contained in t2.
699 CONCAT_CPROP,
700 // ======== String decompose
701 // Children: (P1: (>= (str.len t) n)
702 // Arguments: (false)
703 // ---------------------
704 // Conclusion: (and (= t (str.++ w1 w2)) (= (str.len w1) n))
705 // or
706 // Children: (P1: (>= (str.len t) n)
707 // Arguments: (true)
708 // ---------------------
709 // Conclusion: (and (= t (str.++ w1 w2)) (= (str.len w2) n))
710 // where
711 // w1 is (witness ((z String)) (= z (pre t n)))
712 // w2 is (witness ((z String)) (= z (suf t n)))
713 STRING_DECOMPOSE,
714 // ======== Length positive
715 // Children: none
716 // Arguments: (t)
717 // ---------------------
718 // Conclusion: (or (and (= (str.len t) 0) (= t "")) (> (str.len t 0)))
719 STRING_LENGTH_POS,
720 // ======== Length non-empty
721 // Children: (P1:(not (= t "")))
722 // Arguments: none
723 // ---------------------
724 // Conclusion: (not (= (str.len t) 0))
725 STRING_LENGTH_NON_EMPTY,
726 //======================== Extended functions
727 // ======== Reduction
728 // Children: none
729 // Arguments: (t)
730 // ---------------------
731 // Conclusion: (and R (= t w))
732 // where w = strings::StringsPreprocess::reduce(t, R, ...).
733 // In other words, R is the reduction predicate for extended term t, and w is
734 // (witness ((z T)) (= z t))
735 // Notice that the free variables of R are w and the free variables of t.
736 STRING_REDUCTION,
737 // ======== Eager Reduction
738 // Children: none
739 // Arguments: (t, id?)
740 // ---------------------
741 // Conclusion: R
742 // where R = strings::TermRegistry::eagerReduce(t, id).
743 STRING_EAGER_REDUCTION,
744 //======================== Regular expressions
745 // ======== Regular expression intersection
746 // Children: (P:(str.in.re t R1), P:(str.in.re t R2))
747 // Arguments: none
748 // ---------------------
749 // Conclusion: (str.in.re t (re.inter R1 R2)).
750 RE_INTER,
751 // ======== Regular expression unfold positive
752 // Children: (P:(str.in.re t R))
753 // Arguments: none
754 // ---------------------
755 // Conclusion:(RegExpOpr::reduceRegExpPos((str.in.re t R))),
756 // corresponding to the one-step unfolding of the premise.
757 RE_UNFOLD_POS,
758 // ======== Regular expression unfold negative
759 // Children: (P:(not (str.in.re t R)))
760 // Arguments: none
761 // ---------------------
762 // Conclusion:(RegExpOpr::reduceRegExpNeg((not (str.in.re t R)))),
763 // corresponding to the one-step unfolding of the premise.
764 RE_UNFOLD_NEG,
765 // ======== Regular expression unfold negative concat fixed
766 // Children: (P:(not (str.in.re t R)))
767 // Arguments: none
768 // ---------------------
769 // Conclusion:(RegExpOpr::reduceRegExpNegConcatFixed((not (str.in.re t
770 // R)),L,i)) where RegExpOpr::getRegExpConcatFixed((not (str.in.re t R)), i) =
771 // L. corresponding to the one-step unfolding of the premise, optimized for
772 // fixed length of component i of the regular expression concatenation R.
773 RE_UNFOLD_NEG_CONCAT_FIXED,
774 // ======== Regular expression elimination
775 // Children: (P:F)
776 // Arguments: none
777 // ---------------------
778 // Conclusion: R
779 // where R = strings::RegExpElimination::eliminate(F).
780 RE_ELIM,
781 //======================== Code points
782 // Children: none
783 // Arguments: (t, s)
784 // ---------------------
785 // Conclusion:(or (= (str.code t) (- 1))
786 // (not (= (str.code t) (str.code s)))
787 // (not (= t s)))
788 STRING_CODE_INJ,
789 //======================== Sequence unit
790 // Children: (P:(= (seq.unit x) (seq.unit y)))
791 // Arguments: none
792 // ---------------------
793 // Conclusion:(= x y)
794 // Also applies to the case where (seq.unit y) is a constant sequence
795 // of length one.
796 STRING_SEQ_UNIT_INJ,
797 // ======== String Trust
798 // Children: none
799 // Arguments: (Q)
800 // ---------------------
801 // Conclusion: (Q)
802 STRING_TRUST,
803
804 //================================================= Arithmetic rules
805 // ======== Adding Inequalities
806 // Note: an ArithLiteral is a term of the form (>< poly const)
807 // where
808 // >< is >=, >, ==, <, <=, or not(== ...).
809 // poly is a polynomial
810 // const is a rational constant
811
812 // Children: (P1:l1, ..., Pn:ln)
813 // where each li is an ArithLiteral
814 // not(= ...) is dis-allowed!
815 //
816 // Arguments: (k1, ..., kn), non-zero reals
817 // ---------------------
818 // Conclusion: (>< (* k t1) (* k t2))
819 // where >< is the fusion of the combination of the ><i, (flipping each it
820 // its ki is negative). >< is always one of <, <=
821 // NB: this implies that lower bounds must have negative ki,
822 // and upper bounds must have positive ki.
823 // t1 is the sum of the polynomials.
824 // t2 is the sum of the constants.
825 ARITH_SCALE_SUM_UPPER_BOUNDS,
826
827 // ======== Tightening Strict Integer Upper Bounds
828 // Children: (P:(< i c))
829 // where i has integer type.
830 // Arguments: none
831 // ---------------------
832 // Conclusion: (<= i greatestIntLessThan(c)})
833 INT_TIGHT_UB,
834
835 // ======== Tightening Strict Integer Lower Bounds
836 // Children: (P:(> i c))
837 // where i has integer type.
838 // Arguments: none
839 // ---------------------
840 // Conclusion: (>= i leastIntGreaterThan(c)})
841 INT_TIGHT_LB,
842
843 // ======== Trichotomy of the reals
844 // Children: (A B)
845 // Arguments: (C)
846 // ---------------------
847 // Conclusion: (C),
848 // where (not A) (not B) and C
849 // are (> x c) (< x c) and (= x c)
850 // in some order
851 // note that "not" here denotes arithmetic negation, flipping
852 // >= to <, etc.
853 ARITH_TRICHOTOMY,
854
855 // ======== Arithmetic operator elimination
856 // Children: none
857 // Arguments: (t)
858 // ---------------------
859 // Conclusion: arith::OperatorElim::getAxiomFor(t)
860 ARITH_OP_ELIM_AXIOM,
861
862 // ======== Int Trust
863 // Children: (P1 ... Pn)
864 // Arguments: (Q)
865 // ---------------------
866 // Conclusion: (Q)
867 INT_TRUST,
868
869 //================================================= Unknown rule
870 UNKNOWN,
871 };
872
873 /**
874 * Converts a proof rule to a string. Note: This function is also used in
875 * `safe_print()`. Changing this function name or signature will result in
876 * `safe_print()` printing "<unsupported>" instead of the proper strings for
877 * the enum values.
878 *
879 * @param id The proof rule
880 * @return The name of the proof rule
881 */
882 const char* toString(PfRule id);
883
884 /**
885 * Writes a proof rule name to a stream.
886 *
887 * @param out The stream to write to
888 * @param id The proof rule to write to the stream
889 * @return The stream
890 */
891 std::ostream& operator<<(std::ostream& out, PfRule id);
892
893 /** Hash function for proof rules */
894 struct PfRuleHashFunction
895 {
896 size_t operator()(PfRule id) const;
897 }; /* struct PfRuleHashFunction */
898
899 } // namespace CVC4
900
901 #endif /* CVC4__EXPR__PROOF_RULE_H */