1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Mudathir Mohamed |
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 |
|
* An extension of the theory sets for handling cardinality constraints. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__THEORY__SETS__CARDINALITY_EXTENSION_H |
19 |
|
#define CVC5__THEORY__SETS__CARDINALITY_EXTENSION_H |
20 |
|
|
21 |
|
#include "context/cdhashset.h" |
22 |
|
#include "context/context.h" |
23 |
|
#include "theory/sets/inference_manager.h" |
24 |
|
#include "theory/sets/solver_state.h" |
25 |
|
#include "theory/sets/term_registry.h" |
26 |
|
#include "theory/type_set.h" |
27 |
|
#include "theory/uf/equality_engine.h" |
28 |
|
|
29 |
|
namespace cvc5 { |
30 |
|
namespace theory { |
31 |
|
namespace sets { |
32 |
|
|
33 |
|
/** |
34 |
|
* This class implements a variant of the procedure from Bansal et al, IJCAR |
35 |
|
* 2016. It is used during a full effort check in the following way: |
36 |
|
* reset(); { registerTerm(n,lemmas); | n in CardTerms } check(); |
37 |
|
* where CardTerms is the set of all applications of CARD in the current |
38 |
|
* context. |
39 |
|
* |
40 |
|
* The remaining public methods are used during model construction, i.e. |
41 |
|
* the collectModelInfo method of the theory of sets. |
42 |
|
* |
43 |
|
* The procedure from Bansal et al IJCAR 2016 introduces the notion of a |
44 |
|
* "cardinality graph", where the nodes of this graph are sets and (directed) |
45 |
|
* edges connect sets to their Venn regions wrt to other sets. For example, |
46 |
|
* if (A \ B) is a term in the current context, then the node A is |
47 |
|
* connected via an edge to child (A \ B). The node (A ^ B) is a child |
48 |
|
* of both A and B. The notion of a cardinality graph is loosely followed |
49 |
|
* in the procedure implemented by this class. |
50 |
|
* |
51 |
|
* The main difference wrt Bansal et al IJCAR 2016 is that the nodes of the |
52 |
|
* cardinality graph considered by this class are not arbitrary set terms, but |
53 |
|
* are instead representatives of equivalence classes. For more details, see |
54 |
|
* documentation of the inference schemas in the private methods of this class. |
55 |
|
* |
56 |
|
* This variant of the procedure takes inspiration from the procedure |
57 |
|
* for word equations in Liang et al, CAV 2014. In that procedure, "normal |
58 |
|
* forms" are generated for String terms by recursively expanding |
59 |
|
* concatentations modulo equality. This procedure similarly maintains |
60 |
|
* normal forms, where the normal form for Set terms is a set of (equivalence |
61 |
|
* class representatives of) Venn regions that do not contain the empty set. |
62 |
|
*/ |
63 |
|
class CardinalityExtension |
64 |
|
{ |
65 |
|
typedef context::CDHashSet<Node> NodeSet; |
66 |
|
|
67 |
|
public: |
68 |
|
/** |
69 |
|
* Constructs a new instance of the cardinality solver w.r.t. the provided |
70 |
|
* contexts. |
71 |
|
*/ |
72 |
|
CardinalityExtension(SolverState& s, |
73 |
|
InferenceManager& im, |
74 |
|
TermRegistry& treg); |
75 |
|
|
76 |
9923 |
~CardinalityExtension() {} |
77 |
|
/** reset |
78 |
|
* |
79 |
|
* Called at the beginning of a full effort check. This resets the data |
80 |
|
* structures used by this class during a full effort check. |
81 |
|
*/ |
82 |
|
void reset(); |
83 |
|
/** register term |
84 |
|
* |
85 |
|
* Register that the term n exists in the current context, where n is an |
86 |
|
* application of CARD. |
87 |
|
*/ |
88 |
|
void registerTerm(Node n); |
89 |
|
/** check |
90 |
|
* |
91 |
|
* Invoke a full effort check of the cardinality solver. At a high level, |
92 |
|
* this asserts inferences via the inference manager object d_im. If no |
93 |
|
* inferences are made, then the current set of assertions is satisfied |
94 |
|
* with respect to constraints involving set cardinality. |
95 |
|
* |
96 |
|
* This method applies various inference schemas in succession until an |
97 |
|
* inference is made. These inference schemas are given in the private |
98 |
|
* methods of this class (e.g. checkMinCard, checkCardBuildGraph, etc.). |
99 |
|
*/ |
100 |
|
void check(); |
101 |
|
/** Is model value basic? |
102 |
|
* |
103 |
|
* This returns true if equivalence class eqc is a "leaf" in the cardinality |
104 |
|
* graph. |
105 |
|
*/ |
106 |
|
bool isModelValueBasic(Node eqc); |
107 |
|
/** get model elements |
108 |
|
* |
109 |
|
* This method updates els so that it is the set of elements that occur in |
110 |
|
* an equivalence class (whose representative is eqc) in the model we are |
111 |
|
* building. Notice that els may already have elements in it (from explicit |
112 |
|
* memberships from the base set solver for leaf nodes of the cardinality |
113 |
|
* graph). This method is used during the collectModelInfo method of theory |
114 |
|
* of sets. |
115 |
|
* |
116 |
|
* The argument v is the Valuation utility of the theory of sets, which is |
117 |
|
* used by this method to query the value assigned to cardinality terms by |
118 |
|
* the theory of arithmetic. |
119 |
|
* |
120 |
|
* The argument mvals maps set equivalence classes to their model values. |
121 |
|
* Due to our model construction algorithm, it can be assumed that all |
122 |
|
* sets in the normal form of eqc occur in the domain of mvals by the order |
123 |
|
* in which sets are assigned. |
124 |
|
*/ |
125 |
|
void mkModelValueElementsFor(Valuation& v, |
126 |
|
Node eqc, |
127 |
|
std::vector<Node>& els, |
128 |
|
const std::map<Node, Node>& mvals, |
129 |
|
TheoryModel* model); |
130 |
|
/** get ordered sets equivalence classes |
131 |
|
* |
132 |
|
* Get the ordered set of equivalence classes computed by this class. This |
133 |
|
* ordering ensures the invariant mentioned above mkModelValueElementsFor. |
134 |
|
* |
135 |
|
* This ordering ensures that all children of a node in the cardinality |
136 |
|
* graph computed by this class occur before it in this list. |
137 |
|
*/ |
138 |
81 |
const std::vector<Node>& getOrderedSetsEqClasses() { return d_oSetEqc; } |
139 |
|
|
140 |
|
/** |
141 |
|
* get the slack elements generated for each finite type. This function is |
142 |
|
* called by TheorySetsPrivate::collectModelInfo to ask the TheoryModel to |
143 |
|
* exclude these slack elements from the members in all sets of that type. |
144 |
|
*/ |
145 |
71 |
const std::map<TypeNode, std::vector<TNode> >& getFiniteTypeSlackElements() |
146 |
|
const |
147 |
|
{ |
148 |
71 |
return d_finite_type_slack_elements; |
149 |
|
} |
150 |
|
/** |
151 |
|
* get non-slack members in all sets of the given finite type. This function |
152 |
|
* is called by TheorySetsPrivate::collectModelInfo to specify the exclusion |
153 |
|
* sets for TheoryModel |
154 |
|
*/ |
155 |
|
const std::vector<Node>& getFiniteTypeMembers(TypeNode typeNode); |
156 |
|
|
157 |
|
private: |
158 |
|
/** constants */ |
159 |
|
Node d_true; |
160 |
|
Node d_zero; |
161 |
|
/** the empty vector */ |
162 |
|
std::vector<Node> d_emp_exp; |
163 |
|
/** Reference to the state object for the theory of sets */ |
164 |
|
SolverState& d_state; |
165 |
|
/** Reference to the inference manager for the theory of sets */ |
166 |
|
InferenceManager& d_im; |
167 |
|
/** Reference to the term registry */ |
168 |
|
TermRegistry& d_treg; |
169 |
|
/** register cardinality term |
170 |
|
* |
171 |
|
* This method adds lemmas corresponding to the definition of |
172 |
|
* the cardinality of set term n. For example, if n is A^B (denoting set |
173 |
|
* intersection as ^), then we consider the lemmas card(A^B)>=0, |
174 |
|
* card(A) = card(A\B) + card(A^B) and card(B) = card(B\A) + card(A^B). |
175 |
|
* |
176 |
|
* The exact form of this lemma is modified such that proxy variables are |
177 |
|
* introduced for set terms as needed (see SolverState::getProxy). |
178 |
|
*/ |
179 |
|
void registerCardinalityTerm(Node n); |
180 |
|
/** check register |
181 |
|
* |
182 |
|
* This ensures that all (non-redundant, relevant) non-variable set terms in |
183 |
|
* the current context have been passed to registerCardinalityTerm. In other |
184 |
|
* words, this ensures that the cardinality graph for these terms can be |
185 |
|
* constructed since the cardinality relationships for these terms have been |
186 |
|
* elaborated as lemmas. |
187 |
|
* |
188 |
|
* Notice a term is redundant in a context if it is congruent to another |
189 |
|
* term that is already in the context; it is not relevant if no cardinality |
190 |
|
* constraints exist for its type. |
191 |
|
*/ |
192 |
|
void checkRegister(); |
193 |
|
/** check minimum cardinality |
194 |
|
* |
195 |
|
* This adds lemmas to the argument of the method of the form |
196 |
|
* distinct(x1,...,xn) ^ member(x1,S) ^ ... ^ member(xn,S) => card(S) >= n |
197 |
|
* This lemma enforces the rules GUESS_LOWER_BOUND and PROPAGATE_MIN_SIZE |
198 |
|
* from Bansal et. al IJCAR 2016. |
199 |
|
* |
200 |
|
* Notice that member(x1,S) is implied to hold in the current context. This |
201 |
|
* means that it may be the case that member(x,T) ^ T = S are asserted |
202 |
|
* literals. Furthermore, x1, ..., xn reside in distinct equivalence classes |
203 |
|
* but are not necessarily entailed to be distinct. |
204 |
|
*/ |
205 |
|
void checkMinCard(); |
206 |
|
/** check cardinality cycles |
207 |
|
* |
208 |
|
* The purpose of this inference schema is to construct two data structures: |
209 |
|
* |
210 |
|
* (1) d_card_parent, which maps set terms (A op B) for op in { \, ^ } to |
211 |
|
* equivalence class representatives of their "parents", where: |
212 |
|
* parent( A ^ B ) = A, B |
213 |
|
* parent( A \ B ) = A |
214 |
|
* Additionally, (A union B) is a parent of all three of the above sets |
215 |
|
* if it exists as a term in the current context. As exceptions, |
216 |
|
* if A op B = A, then A is not a parent of A ^ B and similarly for B. |
217 |
|
* If A ^ B is empty, then it has no parents. |
218 |
|
* |
219 |
|
* We say the cardinality graph induced by the current set of equalities |
220 |
|
* is an (irreflexive, acyclic) graph whose nodes are equivalence classes and |
221 |
|
* which contains a (directed) edge r1 to r2 if there exists a term t2 in r2 |
222 |
|
* that has some parent t1 in r1. |
223 |
|
* |
224 |
|
* (2) d_oSetEqc, an ordered set of equivalence classes whose types are set. |
225 |
|
* These equivalence classes have the property that if r1 is a descendant |
226 |
|
* of r2 in the cardinality graph, then r1 must come before r2 in d_oSetEqc. |
227 |
|
* |
228 |
|
* This inference schema may make various inferences while building these |
229 |
|
* two data structures if the current equality arrangement of sets is not |
230 |
|
* as expected. For example, it will infer equalities between sets based on |
231 |
|
* the emptiness and equalities of sets in adjacent children in the |
232 |
|
* cardinality graph, to give some examples: |
233 |
|
* (A \ B = empty) => A = A ^ B |
234 |
|
* A^B = B => B \ A = empty |
235 |
|
* A union B = A ^ B => A \ B = empty AND B \ A = empty |
236 |
|
* and so on. |
237 |
|
* |
238 |
|
* It will also recognize when a cycle occurs in the cardinality graph, in |
239 |
|
* which case an equality chain between sets can be inferred. For an example, |
240 |
|
* see checkCardCyclesRec below. |
241 |
|
* |
242 |
|
* This method is inspired by the checkCycles inference schema in the theory |
243 |
|
* of strings. |
244 |
|
*/ |
245 |
|
void checkCardCycles(); |
246 |
|
/** |
247 |
|
* Helper function for above. Called when wish to process equivalence class |
248 |
|
* eqc. |
249 |
|
* |
250 |
|
* Argument curr contains the equivalence classes we are currently processing, |
251 |
|
* which are descendants of eqc in the cardinality graph, where eqc is the |
252 |
|
* representative of some equivalence class. |
253 |
|
* |
254 |
|
* Argument exp contains an explanation of why the chain of children curr |
255 |
|
* are descedants of . For example, say we are in context with equivalence |
256 |
|
* classes: |
257 |
|
* { A, B, C^D }, { D, B ^ C, A ^ E } |
258 |
|
* We may recursively call this method via the following steps: |
259 |
|
* eqc = D, curr = {}, exp = {} |
260 |
|
* eqc = A, curr = { D }, exp = { D = B^C } |
261 |
|
* eqc = A, curr = { D, A }, exp = { D = B^C, A = C^D } |
262 |
|
* after which we discover a cycle in the cardinality graph. We infer |
263 |
|
* that A must be equal to D, where exp is an explanation of the cycle. |
264 |
|
*/ |
265 |
|
void checkCardCyclesRec(Node eqc, |
266 |
|
std::vector<Node>& curr, |
267 |
|
std::vector<Node>& exp); |
268 |
|
/** check normal forms |
269 |
|
* |
270 |
|
* This method attempts to assign "normal forms" to all set equivalence |
271 |
|
* classes whose types have cardinality constraints. Normal forms are |
272 |
|
* defined recursively. |
273 |
|
* |
274 |
|
* A "normal form" of an equivalence class [r] (where [r] denotes the |
275 |
|
* equivalence class whose representative is r) is a set of representatives |
276 |
|
* U = { r1, ..., rn }. If there exists at least one set in [r] that has a |
277 |
|
* "flat form", then all sets in the equivalence class have flat form U. |
278 |
|
* If no set in U has a flat form, then U = { r } if r does not contain |
279 |
|
* the empty set, and {} otherwise. Notice that the choice of representative |
280 |
|
* r is determined by the equality engine. |
281 |
|
* |
282 |
|
* A "flat form" of a set term T is the union of the normal forms of the |
283 |
|
* equivalence classes that contain sets whose parent is T. |
284 |
|
* |
285 |
|
* In terms of the cardinality graph, the "flat form" of term t is the set |
286 |
|
* of leaves of t that are descendants of it in the cardinality graph induced |
287 |
|
* by the current set of assertions. Notice a flat form is only defined if t |
288 |
|
* has children. If all terms in an equivalence class E with flat forms have |
289 |
|
* the same flat form, then E is added as a node to the cardinality graph with |
290 |
|
* edges connecting to all equivalence classes with terms that have a parent |
291 |
|
* in E. |
292 |
|
* |
293 |
|
* In the following inference schema, the argument intro_sets is updated to |
294 |
|
* contain the set of new set terms that the procedure is requesting to |
295 |
|
* introduce for the purpose of forcing the flat forms of two equivalent sets |
296 |
|
* to become identical. If any equivalence class cannot be assigned a normal |
297 |
|
* form, then the resulting intro_sets is guaranteed to be non-empty. |
298 |
|
* |
299 |
|
* As an example, say we have a context with equivalence classes: |
300 |
|
* {A, D}, {C, A^B}, {E, C^D}, {C\D}, {D\C}, {A\B}, {empty, B\A}, |
301 |
|
* where assume the first term in each set is its representative. An ordered |
302 |
|
* list d_oSetEqc for this context: |
303 |
|
* A, C, E, C\D, D\C, A\B, empty, ... |
304 |
|
* The normal form of {empty, B\A} is {}, since it contains the empty set. |
305 |
|
* The normal forms for each of the singleton equivalence classes are |
306 |
|
* themselves. |
307 |
|
* The flat form of each of E and C^D does not exist, hence the normal form |
308 |
|
* of {E, C^D} is {E}. |
309 |
|
* The flat form of C is {E, C\D}, noting that C^D and C\D are terms whose |
310 |
|
* parent is C, hence {E, C\D} is the normal form for class {C, A^B}. |
311 |
|
* The flat form of A is {E, C\D, A\B} and the flat form of D is {E, D\C}. |
312 |
|
* Hence, no normal form can be assigned to class {A, D}. Instead this method |
313 |
|
* will e.g. add (C\D)^E to intro_sets, which will force the solver |
314 |
|
* to explore a model where the Venn regions (C\D)^E (C\D)\E and E\(C\D) are |
315 |
|
* considered while constructing flat forms. Splitting on whether these sets |
316 |
|
* are empty will eventually lead to a model where the flat forms of A and D |
317 |
|
* are the same. |
318 |
|
*/ |
319 |
|
void checkNormalForms(std::vector<Node>& intro_sets); |
320 |
|
/** |
321 |
|
* Called for each equivalence class, in order of d_oSetEqc, by the above |
322 |
|
* function. |
323 |
|
*/ |
324 |
|
void checkNormalForm(Node eqc, std::vector<Node>& intro_sets); |
325 |
|
|
326 |
|
/** |
327 |
|
* Add cardinality lemmas for the univset of each type with cardinality terms. |
328 |
|
* The lemmas are explained below. |
329 |
|
*/ |
330 |
|
void checkCardinalityExtended(); |
331 |
|
/** |
332 |
|
* This function adds the following lemmas for type t for each S |
333 |
|
* where S is a (representative) set term of type t, and for each negative |
334 |
|
* member x not in S: |
335 |
|
* 1- (=> true (<= (card (as univset t)) n) where n is the |
336 |
|
* cardinality of t, which may be symbolic |
337 |
|
* 2- (=> true (subset S (as univset t)) where S is a set |
338 |
|
* term of type t |
339 |
|
* 3- (=> (not (member negativeMember S))) (member |
340 |
|
* negativeMember (as univset t))) |
341 |
|
*/ |
342 |
|
void checkCardinalityExtended(TypeNode& t); |
343 |
|
|
344 |
|
/** element types of sets for which cardinality is enabled */ |
345 |
|
std::map<TypeNode, bool> d_t_card_enabled; |
346 |
|
/** |
347 |
|
* This maps equivalence classes r to an application of cardinality of the |
348 |
|
* form card( t ), where t = r holds in the current context. |
349 |
|
*/ |
350 |
|
std::map<Node, Node> d_eqc_to_card_term; |
351 |
|
/** |
352 |
|
* User-context-dependent set of set terms for which we have called |
353 |
|
* registerCardinalityTerm on. |
354 |
|
*/ |
355 |
|
NodeSet d_card_processed; |
356 |
|
/** The ordered set of equivalence classes, see checkCardCycles. */ |
357 |
|
std::vector<Node> d_oSetEqc; |
358 |
|
/** |
359 |
|
* This maps set terms to the set of representatives of their "parent" sets, |
360 |
|
* see checkCardCycles. Parents are stored as a pair of the form |
361 |
|
* (r, t) |
362 |
|
* where t is the parent term and r is the representative of equivalence |
363 |
|
* class of t. |
364 |
|
*/ |
365 |
|
std::map<Node, std::vector<std::pair<Node, Node>>> d_cardParent; |
366 |
|
/** |
367 |
|
* Maps equivalence classes + set terms in that equivalence class to their |
368 |
|
* "flat form" (see checkNormalForms). |
369 |
|
*/ |
370 |
|
std::map<Node, std::map<Node, std::vector<Node> > > d_ff; |
371 |
|
/** Maps equivalence classes to their "normal form" (see checkNormalForms). */ |
372 |
|
std::map<Node, std::vector<Node> > d_nf; |
373 |
|
/** The local base node map |
374 |
|
* |
375 |
|
* This maps set terms to the "local base node" of its cardinality graph. |
376 |
|
* The local base node of S is the intersection node that is either S itself |
377 |
|
* or is adjacent to S in the cardinality graph. This maps |
378 |
|
* |
379 |
|
* For example, the ( A ^ B ) is the local base of each of the sets (A \ B), |
380 |
|
* ( A ^ B ), and (B \ A). |
381 |
|
*/ |
382 |
|
std::map<Node, Node> d_localBase; |
383 |
|
|
384 |
|
/** |
385 |
|
* a map to store proxy nodes for the universe sets |
386 |
|
*/ |
387 |
|
std::map<Node, Node> d_univProxy; |
388 |
|
|
389 |
|
/** |
390 |
|
* collect the elements in all sets of finite types in model, and |
391 |
|
* store them in the field d_finite_type_elements |
392 |
|
*/ |
393 |
|
void collectFiniteTypeSetElements(TheoryModel* model); |
394 |
|
/** |
395 |
|
* a map to store the non-slack elements encountered so far in all finite |
396 |
|
* types |
397 |
|
*/ |
398 |
|
std::map<TypeNode, std::vector<Node> > d_finite_type_elements; |
399 |
|
/** |
400 |
|
* a map to store slack elements in all finite types |
401 |
|
*/ |
402 |
|
std::map<TypeNode, std::vector<TNode> > d_finite_type_slack_elements; |
403 |
|
/** This boolean determines whether we already collected finite type constants |
404 |
|
* present in the current model. |
405 |
|
* Default value is false |
406 |
|
*/ |
407 |
|
bool d_finite_type_constants_processed; |
408 |
|
|
409 |
|
/* |
410 |
|
* a map that stores skolem nodes n that satisfies the constraint |
411 |
|
* (<= (card t) n) where t is an infinite type |
412 |
|
*/ |
413 |
|
std::map<TypeNode, Node> d_infiniteTypeUnivCardSkolems; |
414 |
|
|
415 |
|
}; /* class CardinalityExtension */ |
416 |
|
|
417 |
|
} // namespace sets |
418 |
|
} // namespace theory |
419 |
|
} // namespace cvc5 |
420 |
|
|
421 |
|
#endif |