1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Morgan Deters |
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 |
|
* The quantifiers registry. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "theory/quantifiers/quantifiers_registry.h" |
17 |
|
|
18 |
|
#include "options/quantifiers_options.h" |
19 |
|
#include "theory/quantifiers/quant_module.h" |
20 |
|
#include "theory/quantifiers/term_util.h" |
21 |
|
|
22 |
|
namespace cvc5 { |
23 |
|
namespace theory { |
24 |
|
namespace quantifiers { |
25 |
|
|
26 |
15271 |
QuantifiersRegistry::QuantifiersRegistry(Env& env) |
27 |
|
: QuantifiersUtil(env), |
28 |
|
d_quantAttr(), |
29 |
15271 |
d_quantBoundInf(options::fmfTypeCompletionThresh(), |
30 |
15271 |
options::finiteModelFind()), |
31 |
45813 |
d_quantPreproc(env) |
32 |
|
{ |
33 |
15271 |
} |
34 |
|
|
35 |
79440 |
void QuantifiersRegistry::registerQuantifier(Node q) |
36 |
|
{ |
37 |
79440 |
if (d_inst_constants.find(q) != d_inst_constants.end()) |
38 |
|
{ |
39 |
53336 |
return; |
40 |
|
} |
41 |
26104 |
Assert(q.getKind() == kind::FORALL); |
42 |
26104 |
NodeManager* nm = NodeManager::currentNM(); |
43 |
52208 |
Debug("quantifiers-engine") |
44 |
26104 |
<< "Instantiation constants for " << q << " : " << std::endl; |
45 |
87516 |
for (size_t i = 0, nvars = q[0].getNumChildren(); i < nvars; i++) |
46 |
|
{ |
47 |
61412 |
d_vars[q].push_back(q[0][i]); |
48 |
|
// make instantiation constants |
49 |
122824 |
Node ic = nm->mkInstConstant(q[0][i].getType()); |
50 |
61412 |
d_inst_constants_map[ic] = q; |
51 |
61412 |
d_inst_constants[q].push_back(ic); |
52 |
61412 |
Debug("quantifiers-engine") << " " << ic << std::endl; |
53 |
|
// set the var number attribute |
54 |
|
InstVarNumAttribute ivna; |
55 |
61412 |
ic.setAttribute(ivna, i); |
56 |
|
InstConstantAttribute ica; |
57 |
61412 |
ic.setAttribute(ica, q); |
58 |
|
} |
59 |
|
// compute attributes |
60 |
26104 |
d_quantAttr.computeAttributes(q); |
61 |
|
} |
62 |
|
|
63 |
34949 |
bool QuantifiersRegistry::reset(Theory::Effort e) { return true; } |
64 |
|
|
65 |
34949 |
std::string QuantifiersRegistry::identify() const |
66 |
|
{ |
67 |
34949 |
return "QuantifiersRegistry"; |
68 |
|
} |
69 |
|
|
70 |
521392 |
QuantifiersModule* QuantifiersRegistry::getOwner(Node q) const |
71 |
|
{ |
72 |
521392 |
std::map<Node, QuantifiersModule*>::const_iterator it = d_owner.find(q); |
73 |
521392 |
if (it == d_owner.end()) |
74 |
|
{ |
75 |
456929 |
return nullptr; |
76 |
|
} |
77 |
64463 |
return it->second; |
78 |
|
} |
79 |
|
|
80 |
3421 |
void QuantifiersRegistry::setOwner(Node q, |
81 |
|
QuantifiersModule* m, |
82 |
|
int32_t priority) |
83 |
|
{ |
84 |
3421 |
QuantifiersModule* mo = getOwner(q); |
85 |
3421 |
if (mo == m) |
86 |
|
{ |
87 |
|
return; |
88 |
|
} |
89 |
3421 |
if (mo != nullptr) |
90 |
|
{ |
91 |
4 |
if (priority <= d_owner_priority[q]) |
92 |
|
{ |
93 |
8 |
Trace("quant-warn") << "WARNING: setting owner of " << q << " to " |
94 |
8 |
<< (m ? m->identify() : "null") |
95 |
8 |
<< ", but already has owner " << mo->identify() |
96 |
4 |
<< " with higher priority!" << std::endl; |
97 |
4 |
return; |
98 |
|
} |
99 |
|
} |
100 |
3417 |
d_owner[q] = m; |
101 |
3417 |
d_owner_priority[q] = priority; |
102 |
|
} |
103 |
|
|
104 |
459966 |
bool QuantifiersRegistry::hasOwnership(Node q, QuantifiersModule* m) const |
105 |
|
{ |
106 |
459966 |
QuantifiersModule* mo = getOwner(q); |
107 |
459966 |
return mo == m || mo == nullptr; |
108 |
|
} |
109 |
|
|
110 |
65861 |
Node QuantifiersRegistry::getInstantiationConstant(Node q, size_t i) const |
111 |
|
{ |
112 |
|
std::map<Node, std::vector<Node> >::const_iterator it = |
113 |
65861 |
d_inst_constants.find(q); |
114 |
65861 |
if (it != d_inst_constants.end()) |
115 |
|
{ |
116 |
65861 |
return it->second[i]; |
117 |
|
} |
118 |
|
return Node::null(); |
119 |
|
} |
120 |
|
|
121 |
28024 |
size_t QuantifiersRegistry::getNumInstantiationConstants(Node q) const |
122 |
|
{ |
123 |
|
std::map<Node, std::vector<Node> >::const_iterator it = |
124 |
28024 |
d_inst_constants.find(q); |
125 |
28024 |
if (it != d_inst_constants.end()) |
126 |
|
{ |
127 |
28024 |
return it->second.size(); |
128 |
|
} |
129 |
|
return 0; |
130 |
|
} |
131 |
|
|
132 |
163159 |
Node QuantifiersRegistry::getInstConstantBody(Node q) |
133 |
|
{ |
134 |
163159 |
std::map<Node, Node>::const_iterator it = d_inst_const_body.find(q); |
135 |
163159 |
if (it == d_inst_const_body.end()) |
136 |
|
{ |
137 |
48724 |
Node n = substituteBoundVariablesToInstConstants(q[1], q); |
138 |
24362 |
d_inst_const_body[q] = n; |
139 |
24362 |
return n; |
140 |
|
} |
141 |
138797 |
return it->second; |
142 |
|
} |
143 |
|
|
144 |
33996 |
Node QuantifiersRegistry::substituteBoundVariablesToInstConstants(Node n, |
145 |
|
Node q) |
146 |
|
{ |
147 |
33996 |
registerQuantifier(q); |
148 |
33996 |
std::vector<Node>& vars = d_vars.at(q); |
149 |
33996 |
std::vector<Node>& consts = d_inst_constants.at(q); |
150 |
33996 |
Assert(vars.size() == q[0].getNumChildren()); |
151 |
33996 |
Assert(vars.size() == consts.size()); |
152 |
33996 |
return n.substitute(vars.begin(), vars.end(), consts.begin(), consts.end()); |
153 |
|
} |
154 |
|
|
155 |
19348 |
Node QuantifiersRegistry::substituteInstConstantsToBoundVariables(Node n, |
156 |
|
Node q) |
157 |
|
{ |
158 |
19348 |
registerQuantifier(q); |
159 |
19348 |
std::vector<Node>& vars = d_vars.at(q); |
160 |
19348 |
std::vector<Node>& consts = d_inst_constants.at(q); |
161 |
19348 |
Assert(vars.size() == q[0].getNumChildren()); |
162 |
19348 |
Assert(vars.size() == consts.size()); |
163 |
19348 |
return n.substitute(consts.begin(), consts.end(), vars.begin(), vars.end()); |
164 |
|
} |
165 |
|
|
166 |
4 |
Node QuantifiersRegistry::substituteBoundVariables( |
167 |
|
Node n, Node q, const std::vector<Node>& terms) |
168 |
|
{ |
169 |
4 |
registerQuantifier(q); |
170 |
4 |
std::vector<Node>& vars = d_vars.at(q); |
171 |
4 |
Assert(vars.size() == q[0].getNumChildren()); |
172 |
4 |
Assert(vars.size() == terms.size()); |
173 |
4 |
return n.substitute(vars.begin(), vars.end(), terms.begin(), terms.end()); |
174 |
|
} |
175 |
|
|
176 |
|
Node QuantifiersRegistry::substituteInstConstants( |
177 |
|
Node n, Node q, const std::vector<Node>& terms) |
178 |
|
{ |
179 |
|
registerQuantifier(q); |
180 |
|
std::vector<Node>& consts = d_inst_constants.at(q); |
181 |
|
Assert(consts.size() == q[0].getNumChildren()); |
182 |
|
Assert(consts.size() == terms.size()); |
183 |
|
return n.substitute(consts.begin(), consts.end(), terms.begin(), terms.end()); |
184 |
|
} |
185 |
|
|
186 |
79009 |
QuantAttributes& QuantifiersRegistry::getQuantAttributes() |
187 |
|
{ |
188 |
79009 |
return d_quantAttr; |
189 |
|
} |
190 |
|
|
191 |
34699 |
QuantifiersBoundInference& QuantifiersRegistry::getQuantifiersBoundInference() |
192 |
|
{ |
193 |
34699 |
return d_quantBoundInf; |
194 |
|
} |
195 |
45128 |
QuantifiersPreprocess& QuantifiersRegistry::getPreprocess() |
196 |
|
{ |
197 |
45128 |
return d_quantPreproc; |
198 |
|
} |
199 |
|
|
200 |
34 |
Node QuantifiersRegistry::getNameForQuant(Node q) const |
201 |
|
{ |
202 |
68 |
Node name = d_quantAttr.getQuantName(q); |
203 |
34 |
if (!name.isNull()) |
204 |
|
{ |
205 |
10 |
return name; |
206 |
|
} |
207 |
24 |
return q; |
208 |
|
} |
209 |
|
|
210 |
34 |
bool QuantifiersRegistry::getNameForQuant(Node q, Node& name, bool req) const |
211 |
|
{ |
212 |
34 |
name = getNameForQuant(q); |
213 |
|
// if we have a name, or we did not require one |
214 |
34 |
return name != q || !req; |
215 |
|
} |
216 |
|
|
217 |
|
} // namespace quantifiers |
218 |
|
} // namespace theory |
219 |
31125 |
} // namespace cvc5 |