1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Mudathir Mohamed, Andres Noetzli |
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 |
|
* Implementation of sets term registry object. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "theory/sets/term_registry.h" |
17 |
|
|
18 |
|
#include "expr/emptyset.h" |
19 |
|
#include "expr/skolem_manager.h" |
20 |
|
|
21 |
|
using namespace std; |
22 |
|
using namespace cvc5::kind; |
23 |
|
|
24 |
|
namespace cvc5 { |
25 |
|
namespace theory { |
26 |
|
namespace sets { |
27 |
|
|
28 |
9917 |
TermRegistry::TermRegistry(Env& env, |
29 |
|
SolverState& state, |
30 |
|
InferenceManager& im, |
31 |
|
SkolemCache& skc, |
32 |
9917 |
ProofNodeManager* pnm) |
33 |
|
: EnvObj(env), |
34 |
|
d_im(im), |
35 |
|
d_skCache(skc), |
36 |
9917 |
d_proxy(userContext()), |
37 |
9917 |
d_proxy_to_term(userContext()), |
38 |
|
d_epg( |
39 |
1240 |
pnm ? new EagerProofGenerator(pnm, nullptr, "sets::TermRegistry::epg") |
40 |
30991 |
: nullptr) |
41 |
|
{ |
42 |
9917 |
} |
43 |
|
|
44 |
16451 |
Node TermRegistry::getProxy(Node n) |
45 |
|
{ |
46 |
16451 |
Kind nk = n.getKind(); |
47 |
16451 |
if (nk != EMPTYSET && nk != SINGLETON && nk != INTERSECTION && nk != SETMINUS |
48 |
3366 |
&& nk != UNION && nk != UNIVERSE_SET) |
49 |
|
{ |
50 |
1125 |
return n; |
51 |
|
} |
52 |
15326 |
NodeMap::const_iterator it = d_proxy.find(n); |
53 |
15326 |
if (it != d_proxy.end()) |
54 |
|
{ |
55 |
11464 |
return (*it).second; |
56 |
|
} |
57 |
3862 |
NodeManager* nm = NodeManager::currentNM(); |
58 |
3862 |
Node k = d_skCache.mkTypedSkolemCached( |
59 |
7724 |
n.getType(), n, SkolemCache::SK_PURIFY, "sp"); |
60 |
|
|
61 |
3862 |
d_proxy[n] = k; |
62 |
3862 |
d_proxy_to_term[k] = n; |
63 |
7724 |
Node eq = k.eqNode(n); |
64 |
3862 |
sendSimpleLemmaInternal(eq, InferenceId::SETS_PROXY); |
65 |
3862 |
if (nk == SINGLETON) |
66 |
|
{ |
67 |
3812 |
Node slem = nm->mkNode(MEMBER, n[0], k); |
68 |
1906 |
sendSimpleLemmaInternal(slem, InferenceId::SETS_PROXY_SINGLETON); |
69 |
|
} |
70 |
3862 |
return k; |
71 |
|
} |
72 |
|
|
73 |
8715 |
Node TermRegistry::getEmptySet(TypeNode tn) |
74 |
|
{ |
75 |
8715 |
std::map<TypeNode, Node>::iterator it = d_emptyset.find(tn); |
76 |
8715 |
if (it != d_emptyset.end()) |
77 |
|
{ |
78 |
8607 |
return it->second; |
79 |
|
} |
80 |
216 |
Node n = NodeManager::currentNM()->mkConst(EmptySet(tn)); |
81 |
108 |
d_emptyset[tn] = n; |
82 |
108 |
return n; |
83 |
|
} |
84 |
|
|
85 |
2929 |
Node TermRegistry::getUnivSet(TypeNode tn) |
86 |
|
{ |
87 |
2929 |
std::map<TypeNode, Node>::iterator it = d_univset.find(tn); |
88 |
2929 |
if (it != d_univset.end()) |
89 |
|
{ |
90 |
2791 |
return it->second; |
91 |
|
} |
92 |
138 |
NodeManager* nm = NodeManager::currentNM(); |
93 |
276 |
Node n = nm->mkNullaryOperator(tn, UNIVERSE_SET); |
94 |
152 |
for (it = d_univset.begin(); it != d_univset.end(); ++it) |
95 |
|
{ |
96 |
28 |
Node n1; |
97 |
28 |
Node n2; |
98 |
14 |
if (tn.isSubtypeOf(it->first)) |
99 |
|
{ |
100 |
|
n1 = n; |
101 |
|
n2 = it->second; |
102 |
|
} |
103 |
14 |
else if (it->first.isSubtypeOf(tn)) |
104 |
|
{ |
105 |
|
n1 = it->second; |
106 |
|
n2 = n; |
107 |
|
} |
108 |
14 |
if (!n1.isNull()) |
109 |
|
{ |
110 |
|
Node ulem = nm->mkNode(SUBSET, n1, n2); |
111 |
|
Trace("sets-lemma") << "Sets::Lemma : " << ulem << " by univ-type" |
112 |
|
<< std::endl; |
113 |
|
d_im.lemma(ulem, InferenceId::SETS_UNIV_TYPE); |
114 |
|
} |
115 |
|
} |
116 |
138 |
d_univset[tn] = n; |
117 |
138 |
return n; |
118 |
|
} |
119 |
|
|
120 |
|
Node TermRegistry::getTypeConstraintSkolem(Node n, TypeNode tn) |
121 |
|
{ |
122 |
|
std::map<TypeNode, Node>::iterator it = d_tc_skolem[n].find(tn); |
123 |
|
if (it == d_tc_skolem[n].end()) |
124 |
|
{ |
125 |
|
SkolemManager* sm = NodeManager::currentNM()->getSkolemManager(); |
126 |
|
Node k = sm->mkDummySkolem("tc_k", tn); |
127 |
|
d_tc_skolem[n][tn] = k; |
128 |
|
return k; |
129 |
|
} |
130 |
|
return it->second; |
131 |
|
} |
132 |
|
|
133 |
4348 |
void TermRegistry::debugPrintSet(Node s, const char* c) const |
134 |
|
{ |
135 |
4348 |
if (s.getNumChildren() == 0) |
136 |
|
{ |
137 |
3042 |
NodeMap::const_iterator it = d_proxy_to_term.find(s); |
138 |
3042 |
if (it != d_proxy_to_term.end()) |
139 |
|
{ |
140 |
850 |
debugPrintSet((*it).second, c); |
141 |
|
} |
142 |
|
else |
143 |
|
{ |
144 |
2192 |
Trace(c) << s; |
145 |
|
} |
146 |
|
} |
147 |
|
else |
148 |
|
{ |
149 |
1306 |
Trace(c) << "(" << s.getOperator(); |
150 |
3918 |
for (const Node& sc : s) |
151 |
|
{ |
152 |
2612 |
Trace(c) << " "; |
153 |
2612 |
debugPrintSet(sc, c); |
154 |
|
} |
155 |
1306 |
Trace(c) << ")"; |
156 |
|
} |
157 |
4348 |
} |
158 |
|
|
159 |
5768 |
void TermRegistry::sendSimpleLemmaInternal(Node n, InferenceId id) |
160 |
|
{ |
161 |
5768 |
Trace("sets-lemma") << "Sets::Lemma : " << n << " by " << id << std::endl; |
162 |
5768 |
if (d_epg.get() != nullptr) |
163 |
|
{ |
164 |
|
TrustNode teq = |
165 |
1388 |
d_epg->mkTrustNode(n, PfRule::MACRO_SR_PRED_INTRO, {}, {n}); |
166 |
694 |
d_im.trustedLemma(teq, id); |
167 |
|
} |
168 |
|
else |
169 |
|
{ |
170 |
5074 |
d_im.lemma(n, id); |
171 |
|
} |
172 |
5768 |
} |
173 |
|
|
174 |
|
} // namespace sets |
175 |
|
} // namespace theory |
176 |
29517 |
} // namespace cvc5 |