1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Mathias Preiner |
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 |
|
* Relevant domain class. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H |
19 |
|
#define CVC5__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H |
20 |
|
|
21 |
|
#include "theory/quantifiers/first_order_model.h" |
22 |
|
#include "theory/quantifiers/quant_util.h" |
23 |
|
|
24 |
|
namespace cvc5 { |
25 |
|
namespace theory { |
26 |
|
namespace quantifiers { |
27 |
|
|
28 |
|
class QuantifiersState; |
29 |
|
class QuantifiersRegistry; |
30 |
|
class TermRegistry; |
31 |
|
|
32 |
|
/** Relevant Domain |
33 |
|
* |
34 |
|
* This class computes the relevant domain of |
35 |
|
* functions and quantified formulas based on |
36 |
|
* techniques from "Complete Instantiation for Quantified |
37 |
|
* Formulas in SMT" by Ge et al., CAV 2009. |
38 |
|
* |
39 |
|
* Calling compute() will compute a representation |
40 |
|
* of relevant domain information, which be accessed |
41 |
|
* by getRDomain(...) calls. It is intended to be called |
42 |
|
* at full effort check, after we have initialized |
43 |
|
* the term database. |
44 |
|
*/ |
45 |
|
class RelevantDomain : public QuantifiersUtil |
46 |
|
{ |
47 |
|
public: |
48 |
|
RelevantDomain(Env& env, |
49 |
|
QuantifiersState& qs, |
50 |
|
QuantifiersRegistry& qr, |
51 |
|
TermRegistry& tr); |
52 |
|
virtual ~RelevantDomain(); |
53 |
|
/** Reset. */ |
54 |
|
bool reset(Theory::Effort e) override; |
55 |
|
/** Register the quantified formula q */ |
56 |
|
void registerQuantifier(Node q) override; |
57 |
|
/** identify */ |
58 |
419 |
std::string identify() const override { return "RelevantDomain"; } |
59 |
|
/** Compute the relevant domain */ |
60 |
|
void compute(); |
61 |
|
/** Relevant domain representation. |
62 |
|
* |
63 |
|
* This data structure is inspired by the paper |
64 |
|
* "Complete Instantiation for Quantified Formulas in SMT" by |
65 |
|
* Ge et al., CAV 2009. |
66 |
|
* Notice that relevant domains may be equated to one another, |
67 |
|
* for example, if the quantified formula forall x. P( x, x ) |
68 |
|
* exists in the current context, then the relevant domain of |
69 |
|
* arguments 1 and 2 of P are equated. |
70 |
|
*/ |
71 |
1459 |
class RDomain |
72 |
|
{ |
73 |
|
public: |
74 |
1459 |
RDomain() : d_parent( NULL ) {} |
75 |
|
/** the set of terms in this relevant domain */ |
76 |
|
std::vector< Node > d_terms; |
77 |
|
/** reset this object */ |
78 |
2877 |
void reset() |
79 |
|
{ |
80 |
2877 |
d_parent = NULL; |
81 |
2877 |
d_terms.clear(); |
82 |
2877 |
} |
83 |
|
/** merge this with r |
84 |
|
* This sets d_parent of this to r and |
85 |
|
* copies the terms of this to r. |
86 |
|
*/ |
87 |
|
void merge( RDomain * r ); |
88 |
|
/** add term to the relevant domain */ |
89 |
|
void addTerm( Node t ); |
90 |
|
/** get the parent of this */ |
91 |
|
RDomain * getParent(); |
92 |
|
/** remove redundant terms for d_terms, removes |
93 |
|
* duplicates modulo equality. |
94 |
|
*/ |
95 |
|
void removeRedundantTerms(QuantifiersState& qs); |
96 |
|
/** is n in this relevant domain? */ |
97 |
|
bool hasTerm( Node n ) { return std::find( d_terms.begin(), d_terms.end(), n )!=d_terms.end(); } |
98 |
|
|
99 |
|
private: |
100 |
|
/** the parent of this relevant domain */ |
101 |
|
RDomain* d_parent; |
102 |
|
}; |
103 |
|
/** get the relevant domain |
104 |
|
* |
105 |
|
* Gets object representing the relevant domain of the i^th argument of n. |
106 |
|
* |
107 |
|
* If getParent is true, we return the representative |
108 |
|
* of the equivalence class of relevant domain objects, |
109 |
|
* which is computed as a union find (see RDomain::d_parent). |
110 |
|
*/ |
111 |
|
RDomain* getRDomain(Node n, size_t i, bool getParent = true); |
112 |
|
|
113 |
|
private: |
114 |
|
/** the relevant domains for each quantified formula and function, |
115 |
|
* for each variable # and argument #. |
116 |
|
*/ |
117 |
|
std::map<Node, std::map<size_t, RDomain*> > d_rel_doms; |
118 |
|
/** Reference to the quantifiers state object */ |
119 |
|
QuantifiersState& d_qs; |
120 |
|
/** Reference to the quantifiers registry */ |
121 |
|
QuantifiersRegistry& d_qreg; |
122 |
|
/** Reference to the term registry */ |
123 |
|
TermRegistry& d_treg; |
124 |
|
/** have we computed the relevant domain on this full effort check? */ |
125 |
|
bool d_is_computed; |
126 |
|
/** relevant domain literal |
127 |
|
* Caches the effect of literals on the relevant domain. |
128 |
|
*/ |
129 |
|
class RDomainLit { |
130 |
|
public: |
131 |
132 |
RDomainLit() : d_merge(false){ |
132 |
132 |
d_rd[0] = NULL; |
133 |
132 |
d_rd[1] = NULL; |
134 |
132 |
} |
135 |
132 |
~RDomainLit(){} |
136 |
|
/** whether this literal forces the merge of two relevant domains */ |
137 |
|
bool d_merge; |
138 |
|
/** the relevant domains that are merged as a result |
139 |
|
* of this literal |
140 |
|
*/ |
141 |
|
RDomain * d_rd[2]; |
142 |
|
/** the terms that are added to |
143 |
|
* the relevant domain as a result of this literal |
144 |
|
*/ |
145 |
|
std::vector< Node > d_val; |
146 |
|
}; |
147 |
|
/** Cache of the effect of literals on the relevant domain */ |
148 |
|
std::map< bool, std::map< bool, std::map< Node, RDomainLit > > > d_rel_dom_lit; |
149 |
|
/** Compute the relevant domain for quantified formula q. */ |
150 |
|
void computeRelevantDomain(Node q); |
151 |
|
/** Compute the relevant domain for a subformula n of q, |
152 |
|
* whose polarity is given by hasPol/pol. |
153 |
|
*/ |
154 |
|
void computeRelevantDomainNode(Node q, Node n, bool hasPol, bool pol); |
155 |
|
/** Compute the relevant domain when the term n |
156 |
|
* is in a position to be included in relevant domain rf. |
157 |
|
*/ |
158 |
|
void computeRelevantDomainOpCh(RDomain* rf, Node n); |
159 |
|
/** compute relevant domain for literal. |
160 |
|
* |
161 |
|
* Updates the relevant domains based on a literal n in quantified |
162 |
|
* formula q whose polarity is given by hasPol/pol. |
163 |
|
*/ |
164 |
|
void computeRelevantDomainLit( Node q, bool hasPol, bool pol, Node n ); |
165 |
|
};/* class RelevantDomain */ |
166 |
|
|
167 |
|
} // namespace quantifiers |
168 |
|
} // namespace theory |
169 |
|
} // namespace cvc5 |
170 |
|
|
171 |
|
#endif /* CVC5__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H */ |