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 |
9917 |
QuantifiersRegistry::QuantifiersRegistry(Env& env) |
27 |
|
: QuantifiersUtil(env), |
28 |
|
d_quantAttr(), |
29 |
9917 |
d_quantBoundInf(options::fmfTypeCompletionThresh(), |
30 |
9917 |
options::finiteModelFind()), |
31 |
29751 |
d_quantPreproc(env) |
32 |
|
{ |
33 |
9917 |
} |
34 |
|
|
35 |
76420 |
void QuantifiersRegistry::registerQuantifier(Node q) |
36 |
|
{ |
37 |
76420 |
if (d_inst_constants.find(q) != d_inst_constants.end()) |
38 |
|
{ |
39 |
51337 |
return; |
40 |
|
} |
41 |
25083 |
NodeManager* nm = NodeManager::currentNM(); |
42 |
50166 |
Debug("quantifiers-engine") |
43 |
25083 |
<< "Instantiation constants for " << q << " : " << std::endl; |
44 |
84294 |
for (size_t i = 0, nvars = q[0].getNumChildren(); i < nvars; i++) |
45 |
|
{ |
46 |
59211 |
d_vars[q].push_back(q[0][i]); |
47 |
|
// make instantiation constants |
48 |
118422 |
Node ic = nm->mkInstConstant(q[0][i].getType()); |
49 |
59211 |
d_inst_constants_map[ic] = q; |
50 |
59211 |
d_inst_constants[q].push_back(ic); |
51 |
59211 |
Debug("quantifiers-engine") << " " << ic << std::endl; |
52 |
|
// set the var number attribute |
53 |
|
InstVarNumAttribute ivna; |
54 |
59211 |
ic.setAttribute(ivna, i); |
55 |
|
InstConstantAttribute ica; |
56 |
59211 |
ic.setAttribute(ica, q); |
57 |
|
} |
58 |
|
// compute attributes |
59 |
25083 |
d_quantAttr.computeAttributes(q); |
60 |
|
} |
61 |
|
|
62 |
28089 |
bool QuantifiersRegistry::reset(Theory::Effort e) { return true; } |
63 |
|
|
64 |
28089 |
std::string QuantifiersRegistry::identify() const |
65 |
|
{ |
66 |
28089 |
return "QuantifiersRegistry"; |
67 |
|
} |
68 |
|
|
69 |
500700 |
QuantifiersModule* QuantifiersRegistry::getOwner(Node q) const |
70 |
|
{ |
71 |
500700 |
std::map<Node, QuantifiersModule*>::const_iterator it = d_owner.find(q); |
72 |
500700 |
if (it == d_owner.end()) |
73 |
|
{ |
74 |
447735 |
return nullptr; |
75 |
|
} |
76 |
52965 |
return it->second; |
77 |
|
} |
78 |
|
|
79 |
2895 |
void QuantifiersRegistry::setOwner(Node q, |
80 |
|
QuantifiersModule* m, |
81 |
|
int32_t priority) |
82 |
|
{ |
83 |
2895 |
QuantifiersModule* mo = getOwner(q); |
84 |
2895 |
if (mo == m) |
85 |
|
{ |
86 |
|
return; |
87 |
|
} |
88 |
2895 |
if (mo != nullptr) |
89 |
|
{ |
90 |
4 |
if (priority <= d_owner_priority[q]) |
91 |
|
{ |
92 |
8 |
Trace("quant-warn") << "WARNING: setting owner of " << q << " to " |
93 |
8 |
<< (m ? m->identify() : "null") |
94 |
8 |
<< ", but already has owner " << mo->identify() |
95 |
4 |
<< " with higher priority!" << std::endl; |
96 |
4 |
return; |
97 |
|
} |
98 |
|
} |
99 |
2891 |
d_owner[q] = m; |
100 |
2891 |
d_owner_priority[q] = priority; |
101 |
|
} |
102 |
|
|
103 |
445097 |
bool QuantifiersRegistry::hasOwnership(Node q, QuantifiersModule* m) const |
104 |
|
{ |
105 |
445097 |
QuantifiersModule* mo = getOwner(q); |
106 |
445097 |
return mo == m || mo == nullptr; |
107 |
|
} |
108 |
|
|
109 |
62862 |
Node QuantifiersRegistry::getInstantiationConstant(Node q, size_t i) const |
110 |
|
{ |
111 |
|
std::map<Node, std::vector<Node> >::const_iterator it = |
112 |
62862 |
d_inst_constants.find(q); |
113 |
62862 |
if (it != d_inst_constants.end()) |
114 |
|
{ |
115 |
62862 |
return it->second[i]; |
116 |
|
} |
117 |
|
return Node::null(); |
118 |
|
} |
119 |
|
|
120 |
26697 |
size_t QuantifiersRegistry::getNumInstantiationConstants(Node q) const |
121 |
|
{ |
122 |
|
std::map<Node, std::vector<Node> >::const_iterator it = |
123 |
26697 |
d_inst_constants.find(q); |
124 |
26697 |
if (it != d_inst_constants.end()) |
125 |
|
{ |
126 |
26697 |
return it->second.size(); |
127 |
|
} |
128 |
|
return 0; |
129 |
|
} |
130 |
|
|
131 |
160398 |
Node QuantifiersRegistry::getInstConstantBody(Node q) |
132 |
|
{ |
133 |
160398 |
std::map<Node, Node>::const_iterator it = d_inst_const_body.find(q); |
134 |
160398 |
if (it == d_inst_const_body.end()) |
135 |
|
{ |
136 |
46862 |
Node n = substituteBoundVariablesToInstConstants(q[1], q); |
137 |
23431 |
d_inst_const_body[q] = n; |
138 |
23431 |
return n; |
139 |
|
} |
140 |
136967 |
return it->second; |
141 |
|
} |
142 |
|
|
143 |
32705 |
Node QuantifiersRegistry::substituteBoundVariablesToInstConstants(Node n, |
144 |
|
Node q) |
145 |
|
{ |
146 |
32705 |
registerQuantifier(q); |
147 |
32705 |
return n.substitute(d_vars[q].begin(), |
148 |
32705 |
d_vars[q].end(), |
149 |
32705 |
d_inst_constants[q].begin(), |
150 |
130820 |
d_inst_constants[q].end()); |
151 |
|
} |
152 |
|
|
153 |
18626 |
Node QuantifiersRegistry::substituteInstConstantsToBoundVariables(Node n, |
154 |
|
Node q) |
155 |
|
{ |
156 |
18626 |
registerQuantifier(q); |
157 |
18626 |
return n.substitute(d_inst_constants[q].begin(), |
158 |
18626 |
d_inst_constants[q].end(), |
159 |
18626 |
d_vars[q].begin(), |
160 |
74504 |
d_vars[q].end()); |
161 |
|
} |
162 |
|
|
163 |
16 |
Node QuantifiersRegistry::substituteBoundVariables(Node n, |
164 |
|
Node q, |
165 |
|
std::vector<Node>& terms) |
166 |
|
{ |
167 |
16 |
registerQuantifier(q); |
168 |
16 |
Assert(d_vars[q].size() == terms.size()); |
169 |
|
return n.substitute( |
170 |
16 |
d_vars[q].begin(), d_vars[q].end(), terms.begin(), terms.end()); |
171 |
|
} |
172 |
|
|
173 |
|
Node QuantifiersRegistry::substituteInstConstants(Node n, |
174 |
|
Node q, |
175 |
|
std::vector<Node>& terms) |
176 |
|
{ |
177 |
|
registerQuantifier(q); |
178 |
|
Assert(d_inst_constants[q].size() == terms.size()); |
179 |
|
return n.substitute(d_inst_constants[q].begin(), |
180 |
|
d_inst_constants[q].end(), |
181 |
|
terms.begin(), |
182 |
|
terms.end()); |
183 |
|
} |
184 |
|
|
185 |
79992 |
QuantAttributes& QuantifiersRegistry::getQuantAttributes() |
186 |
|
{ |
187 |
79992 |
return d_quantAttr; |
188 |
|
} |
189 |
|
|
190 |
28725 |
QuantifiersBoundInference& QuantifiersRegistry::getQuantifiersBoundInference() |
191 |
|
{ |
192 |
28725 |
return d_quantBoundInf; |
193 |
|
} |
194 |
39025 |
QuantifiersPreprocess& QuantifiersRegistry::getPreprocess() |
195 |
|
{ |
196 |
39025 |
return d_quantPreproc; |
197 |
|
} |
198 |
|
|
199 |
34 |
Node QuantifiersRegistry::getNameForQuant(Node q) const |
200 |
|
{ |
201 |
68 |
Node name = d_quantAttr.getQuantName(q); |
202 |
34 |
if (!name.isNull()) |
203 |
|
{ |
204 |
10 |
return name; |
205 |
|
} |
206 |
24 |
return q; |
207 |
|
} |
208 |
|
|
209 |
34 |
bool QuantifiersRegistry::getNameForQuant(Node q, Node& name, bool req) const |
210 |
|
{ |
211 |
34 |
name = getNameForQuant(q); |
212 |
|
// if we have a name, or we did not require one |
213 |
34 |
return name != q || !req; |
214 |
|
} |
215 |
|
|
216 |
|
} // namespace quantifiers |
217 |
|
} // namespace theory |
218 |
29514 |
} // namespace cvc5 |