1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 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. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* Equality proof checker utility. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__THEORY__BUILTIN__PROOF_CHECKER_H |
19 |
|
#define CVC5__THEORY__BUILTIN__PROOF_CHECKER_H |
20 |
|
|
21 |
|
#include "expr/node.h" |
22 |
|
#include "expr/proof_checker.h" |
23 |
|
#include "expr/proof_node.h" |
24 |
|
#include "theory/quantifiers/extended_rewrite.h" |
25 |
|
|
26 |
|
namespace cvc5 { |
27 |
|
namespace theory { |
28 |
|
|
29 |
|
/** |
30 |
|
* Identifiers for rewriters and substitutions, which we abstractly |
31 |
|
* classify as "methods". Methods have a unique identifier in the internal |
32 |
|
* proof calculus implemented by the checker below. |
33 |
|
* |
34 |
|
* A "rewriter" is abstractly a method from Node to Node, where the output |
35 |
|
* is semantically equivalent to the input. The identifiers below list |
36 |
|
* various methods that have this contract. This identifier is used |
37 |
|
* in a number of the builtin rules. |
38 |
|
* |
39 |
|
* A substitution is a method for turning a formula into a substitution. |
40 |
|
*/ |
41 |
|
enum class MethodId : uint32_t |
42 |
|
{ |
43 |
|
//---------------------------- Rewriters |
44 |
|
// Rewriter::rewrite(n) |
45 |
|
RW_REWRITE, |
46 |
|
// d_ext_rew.extendedRewrite(n); |
47 |
|
RW_EXT_REWRITE, |
48 |
|
// Rewriter::rewriteExtEquality(n) |
49 |
|
RW_REWRITE_EQ_EXT, |
50 |
|
// Evaluator::evaluate(n) |
51 |
|
RW_EVALUATE, |
52 |
|
// identity |
53 |
|
RW_IDENTITY, |
54 |
|
// theory preRewrite, note this is only intended to be used as an argument |
55 |
|
// to THEORY_REWRITE in the final proof. It is not implemented in |
56 |
|
// applyRewrite below, see documentation in proof_rule.h for THEORY_REWRITE. |
57 |
|
RW_REWRITE_THEORY_PRE, |
58 |
|
// same as above, for theory postRewrite |
59 |
|
RW_REWRITE_THEORY_POST, |
60 |
|
//---------------------------- Substitutions |
61 |
|
// (= x y) is interpreted as x -> y, using Node::substitute |
62 |
|
SB_DEFAULT, |
63 |
|
// P, (not P) are interpreted as P -> true, P -> false using Node::substitute |
64 |
|
SB_LITERAL, |
65 |
|
// P is interpreted as P -> true using Node::substitute |
66 |
|
SB_FORMULA, |
67 |
|
//---------------------------- Substitution applications |
68 |
|
// multiple substitutions are applied sequentially |
69 |
|
SBA_SEQUENTIAL, |
70 |
|
// multiple substitutions are applied simultaneously |
71 |
|
SBA_SIMUL, |
72 |
|
// multiple substitutions are applied to fix point |
73 |
|
SBA_FIXPOINT |
74 |
|
// For example, for x -> u, y -> f(z), z -> g(x), applying this substituion to |
75 |
|
// y gives: |
76 |
|
// - f(g(x)) for SBA_SEQUENTIAL |
77 |
|
// - f(z) for SBA_SIMUL |
78 |
|
// - f(g(u)) for SBA_FIXPOINT |
79 |
|
// Notice that SBA_FIXPOINT should provide a terminating rewrite system |
80 |
|
// as a substitution, or else non-termination will occur during proof |
81 |
|
// checking. |
82 |
|
}; |
83 |
|
/** Converts a rewriter id to a string. */ |
84 |
|
const char* toString(MethodId id); |
85 |
|
/** Write a rewriter id to out */ |
86 |
|
std::ostream& operator<<(std::ostream& out, MethodId id); |
87 |
|
/** Make a method id node */ |
88 |
|
Node mkMethodId(MethodId id); |
89 |
|
|
90 |
|
namespace builtin { |
91 |
|
|
92 |
|
/** A checker for builtin proofs */ |
93 |
|
class BuiltinProofRuleChecker : public ProofRuleChecker |
94 |
|
{ |
95 |
|
public: |
96 |
9459 |
BuiltinProofRuleChecker() {} |
97 |
9459 |
~BuiltinProofRuleChecker() {} |
98 |
|
/** |
99 |
|
* Apply rewrite on n (in skolem form). This encapsulates the exact behavior |
100 |
|
* of a REWRITE step in a proof. |
101 |
|
* |
102 |
|
* @param n The node to rewrite, |
103 |
|
* @param idr The method identifier of the rewriter, by default RW_REWRITE |
104 |
|
* specifying a call to Rewriter::rewrite. |
105 |
|
* @return The rewritten form of n. |
106 |
|
*/ |
107 |
|
Node applyRewrite(Node n, MethodId idr = MethodId::RW_REWRITE); |
108 |
|
/** |
109 |
|
* Get substitution for literal exp. Updates vars/subs to the substitution |
110 |
|
* specified by exp for the substitution method ids. |
111 |
|
*/ |
112 |
|
static bool getSubstitutionForLit(Node exp, |
113 |
|
TNode& var, |
114 |
|
TNode& subs, |
115 |
|
MethodId ids = MethodId::SB_DEFAULT); |
116 |
|
/** |
117 |
|
* Get substitution for formula exp. Adds to vars/subs to the substitution |
118 |
|
* specified by exp for the substitution method ids, which may be multiple |
119 |
|
* substitutions if exp is of kind AND and ids is SB_DEFAULT (note the other |
120 |
|
* substitution types always interpret applications of AND as a formula). |
121 |
|
* The vector "from" are the literals from exp that each substitution in |
122 |
|
* vars/subs are based on. For example, if exp is (and (= x t) (= y s)), then |
123 |
|
* vars = { x, y }, subs = { t, s }, from = { (= x y), (= y s) }. |
124 |
|
*/ |
125 |
|
static bool getSubstitutionFor(Node exp, |
126 |
|
std::vector<TNode>& vars, |
127 |
|
std::vector<TNode>& subs, |
128 |
|
std::vector<TNode>& from, |
129 |
|
MethodId ids = MethodId::SB_DEFAULT); |
130 |
|
|
131 |
|
/** |
132 |
|
* Apply substitution on n in skolem form. This encapsulates the exact |
133 |
|
* behavior of a SUBS step in a proof. |
134 |
|
* |
135 |
|
* @param n The node to substitute, |
136 |
|
* @param exp The (set of) equalities/literals/formulas that the substitution |
137 |
|
* is derived from |
138 |
|
* @param ids The method identifier of the substitution, by default SB_DEFAULT |
139 |
|
* specifying that lhs/rhs of equalities are interpreted as a substitution. |
140 |
|
* @param ida The method identifier of the substitution application, by |
141 |
|
* default SB_SEQUENTIAL specifying that substitutions are to be applied |
142 |
|
* sequentially |
143 |
|
* @return The substituted form of n. |
144 |
|
*/ |
145 |
|
static Node applySubstitution(Node n, |
146 |
|
Node exp, |
147 |
|
MethodId ids = MethodId::SB_DEFAULT, |
148 |
|
MethodId ida = MethodId::SBA_SEQUENTIAL); |
149 |
|
static Node applySubstitution(Node n, |
150 |
|
const std::vector<Node>& exp, |
151 |
|
MethodId ids = MethodId::SB_DEFAULT, |
152 |
|
MethodId ida = MethodId::SBA_SEQUENTIAL); |
153 |
|
/** Apply substitution + rewriting |
154 |
|
* |
155 |
|
* Combines the above two steps. |
156 |
|
* |
157 |
|
* @param n The node to substitute and rewrite, |
158 |
|
* @param exp The (set of) equalities corresponding to the substitution |
159 |
|
* @param ids The method identifier of the substitution. |
160 |
|
* @param ida The method identifier of the substitution application. |
161 |
|
* @param idr The method identifier of the rewriter. |
162 |
|
* @return The substituted, rewritten form of n. |
163 |
|
*/ |
164 |
|
Node applySubstitutionRewrite(Node n, |
165 |
|
const std::vector<Node>& exp, |
166 |
|
MethodId ids = MethodId::SB_DEFAULT, |
167 |
|
MethodId ida = MethodId::SBA_SEQUENTIAL, |
168 |
|
MethodId idr = MethodId::RW_REWRITE); |
169 |
|
/** get a method identifier from a node, return false if we fail */ |
170 |
|
static bool getMethodId(TNode n, MethodId& i); |
171 |
|
/** |
172 |
|
* Get method identifiers from args starting at the given index. Store their |
173 |
|
* values into ids, ida, and idr. This method returns false if args does not |
174 |
|
* contain valid method identifiers at position index in args. |
175 |
|
*/ |
176 |
|
bool getMethodIds(const std::vector<Node>& args, |
177 |
|
MethodId& ids, |
178 |
|
MethodId& ida, |
179 |
|
MethodId& idr, |
180 |
|
size_t index); |
181 |
|
/** |
182 |
|
* Add method identifiers ids, ida and idr as nodes to args. This does not add |
183 |
|
* ids, ida or idr if their values are the default ones. |
184 |
|
*/ |
185 |
|
static void addMethodIds(std::vector<Node>& args, |
186 |
|
MethodId ids, |
187 |
|
MethodId ida, |
188 |
|
MethodId idr); |
189 |
|
|
190 |
|
/** get a TheoryId from a node, return false if we fail */ |
191 |
|
static bool getTheoryId(TNode n, TheoryId& tid); |
192 |
|
/** Make a TheoryId into a node */ |
193 |
|
static Node mkTheoryIdNode(TheoryId tid); |
194 |
|
|
195 |
|
/** Register all rules owned by this rule checker into pc. */ |
196 |
|
void registerTo(ProofChecker* pc) override; |
197 |
|
protected: |
198 |
|
/** Return the conclusion of the given proof step, or null if it is invalid */ |
199 |
|
Node checkInternal(PfRule id, |
200 |
|
const std::vector<Node>& children, |
201 |
|
const std::vector<Node>& args) override; |
202 |
|
|
203 |
|
/** extended rewriter object */ |
204 |
|
quantifiers::ExtendedRewriter d_ext_rewriter; |
205 |
|
}; |
206 |
|
|
207 |
|
} // namespace builtin |
208 |
|
} // namespace theory |
209 |
|
} // namespace cvc5 |
210 |
|
|
211 |
|
#endif /* CVC5__THEORY__BUILTIN__PROOF_CHECKER_H */ |