1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Paul Meng, 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 |
|
* Model extended classes. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__FIRST_ORDER_MODEL_H |
19 |
|
#define CVC5__FIRST_ORDER_MODEL_H |
20 |
|
|
21 |
|
#include "context/cdlist.h" |
22 |
|
#include "theory/quantifiers/equality_query.h" |
23 |
|
#include "theory/theory_model.h" |
24 |
|
#include "theory/uf/theory_uf_model.h" |
25 |
|
|
26 |
|
namespace cvc5 { |
27 |
|
namespace theory { |
28 |
|
|
29 |
|
class TheoryModel; |
30 |
|
class RepSet; |
31 |
|
|
32 |
|
namespace quantifiers { |
33 |
|
|
34 |
|
class QuantifiersState; |
35 |
|
class TermRegistry; |
36 |
|
class QuantifiersRegistry; |
37 |
|
|
38 |
|
// TODO (#1301) : document and refactor this class |
39 |
|
class FirstOrderModel |
40 |
|
{ |
41 |
|
public: |
42 |
|
FirstOrderModel(QuantifiersState& qs, |
43 |
|
QuantifiersRegistry& qr, |
44 |
|
TermRegistry& tr); |
45 |
17578 |
virtual ~FirstOrderModel() {} |
46 |
|
|
47 |
|
/** finish init */ |
48 |
|
void finishInit(TheoryModel* m); |
49 |
|
//---------------------------------- access functions for underlying model |
50 |
|
/** Get value in the underlying theory model */ |
51 |
|
Node getValue(TNode n) const; |
52 |
|
/** does the equality engine of this model have term a? */ |
53 |
|
bool hasTerm(TNode a); |
54 |
|
/** get the representative of a in the equality engine of this model */ |
55 |
|
Node getRepresentative(TNode a); |
56 |
|
/** are a and b equal in the equality engine of this model? */ |
57 |
|
bool areEqual(TNode a, TNode b); |
58 |
|
/** are a and b disequal in the equality engine of this model? */ |
59 |
|
bool areDisequal(TNode a, TNode b); |
60 |
|
/** get the equality engine for this model */ |
61 |
|
eq::EqualityEngine* getEqualityEngine(); |
62 |
|
/** get the representative set object */ |
63 |
|
const RepSet* getRepSet() const; |
64 |
|
/** get the representative set object */ |
65 |
|
RepSet* getRepSetPtr(); |
66 |
|
/** get the entire theory model */ |
67 |
|
TheoryModel* getTheoryModel(); |
68 |
|
//---------------------------------- end access functions for underlying model |
69 |
|
/** get internal representative |
70 |
|
* |
71 |
|
* Choose a term that is equivalent to a in the current context that is the |
72 |
|
* best term for instantiating the index^th variable of quantified formula q. |
73 |
|
* If no legal term can be found, we return null. This can occur if: |
74 |
|
* - a's type is not a subtype of the type of the index^th variable of q, |
75 |
|
* - a is in an equivalent class with all terms that are restricted not to |
76 |
|
* appear in instantiations of q, e.g. INST_CONSTANT terms for counterexample |
77 |
|
* guided instantiation. |
78 |
|
*/ |
79 |
|
Node getInternalRepresentative(Node a, Node q, size_t index); |
80 |
|
|
81 |
|
/** assert quantifier */ |
82 |
|
void assertQuantifier( Node n ); |
83 |
|
/** get number of asserted quantifiers */ |
84 |
|
size_t getNumAssertedQuantifiers() const; |
85 |
|
/** get asserted quantifier */ |
86 |
|
Node getAssertedQuantifier( unsigned i, bool ordered = false ); |
87 |
|
/** initialize model for term */ |
88 |
|
void initializeModelForTerm( Node n, std::map< Node, bool >& visited ); |
89 |
|
// initialize the model |
90 |
|
void initialize(); |
91 |
|
/** get variable id */ |
92 |
54550 |
int getVariableId(TNode q, TNode n) { |
93 |
54550 |
return d_quant_var_id.find( q )!=d_quant_var_id.end() ? d_quant_var_id[q][n] : -1; |
94 |
|
} |
95 |
|
/** do we need to do any work? */ |
96 |
|
bool checkNeeded(); |
97 |
|
/** reset round */ |
98 |
|
void reset_round(); |
99 |
|
/** mark quantified formula relevant */ |
100 |
|
void markRelevant( Node q ); |
101 |
|
/** set quantified formula active/inactive |
102 |
|
* |
103 |
|
* This indicates that quantified formula is "inactive", that is, it need |
104 |
|
* not be considered during this instantiation round. |
105 |
|
* |
106 |
|
* A quantified formula may be set inactive if for instance: |
107 |
|
* - It is entailed by other quantified formulas, or |
108 |
|
* - All of its instances are known to be true in the current model. |
109 |
|
* |
110 |
|
* This method should be called after a call to FirstOrderModel::reset_round, |
111 |
|
* and before calls to QuantifiersModule check calls. A common place to call |
112 |
|
* this method is during QuantifiersModule reset_round calls. |
113 |
|
*/ |
114 |
|
void setQuantifierActive( TNode q, bool active ); |
115 |
|
/** is quantified formula active? |
116 |
|
* |
117 |
|
* Returns false if there has been a call to setQuantifierActive( q, false ) |
118 |
|
* during this instantiation round. |
119 |
|
*/ |
120 |
|
bool isQuantifierActive(TNode q) const; |
121 |
|
/** is quantified formula asserted */ |
122 |
|
bool isQuantifierAsserted(TNode q) const; |
123 |
|
/** get model basis term */ |
124 |
|
Node getModelBasisTerm(TypeNode tn); |
125 |
|
/** is model basis term */ |
126 |
|
bool isModelBasisTerm(Node n); |
127 |
|
/** get model basis term for op */ |
128 |
|
Node getModelBasisOpTerm(Node op); |
129 |
|
/** get model basis */ |
130 |
|
Node getModelBasis(Node q, Node n); |
131 |
|
/** get model basis arg */ |
132 |
|
unsigned getModelBasisArg(Node n); |
133 |
|
/** get some domain element */ |
134 |
|
Node getSomeDomainElement(TypeNode tn); |
135 |
|
/** initialize representative set for type |
136 |
|
* |
137 |
|
* This ensures that TheoryModel::d_rep_set |
138 |
|
* is initialized for type tn. In particular: |
139 |
|
* (1) If tn is an uninitialized (unconstrained) |
140 |
|
* uninterpreted sort, then we interpret it |
141 |
|
* as a set of size one, |
142 |
|
* (2) If tn is a "small" enumerable finite type, |
143 |
|
* then we ensure that all its values are in |
144 |
|
* TheoryModel::d_rep_set. |
145 |
|
* |
146 |
|
* Returns true if the initialization was complete, |
147 |
|
* in that the set for tn in TheoryModel::d_rep_set |
148 |
|
* has all representatives of type tn. |
149 |
|
*/ |
150 |
|
bool initializeRepresentativesForType(TypeNode tn); |
151 |
|
/** |
152 |
|
* Has the term been marked as a model basis term? |
153 |
|
*/ |
154 |
|
static bool isModelBasis(TNode n); |
155 |
|
/** Get the equality query */ |
156 |
|
EqualityQuery* getEqualityQuery(); |
157 |
|
|
158 |
|
protected: |
159 |
|
/** Pointer to the underyling theory model */ |
160 |
|
TheoryModel* d_model; |
161 |
|
/** The quantifiers registry */ |
162 |
|
QuantifiersRegistry& d_qreg; |
163 |
|
/** Reference to the term registry */ |
164 |
|
TermRegistry& d_treg; |
165 |
|
/** equality query class */ |
166 |
|
EqualityQuery d_eq_query; |
167 |
|
/** list of quantifiers asserted in the current context */ |
168 |
|
context::CDList<Node> d_forall_asserts; |
169 |
|
/** |
170 |
|
* The (ordered) list of quantified formulas marked as relevant using |
171 |
|
* markRelevant, where the quantified formula q in the most recent |
172 |
|
* call to markRelevant comes last in the list. |
173 |
|
*/ |
174 |
|
std::vector<Node> d_forall_rlv_vec; |
175 |
|
/** The last quantified formula marked as relevant, if one exists. */ |
176 |
|
Node d_last_forall_rlv; |
177 |
|
/** |
178 |
|
* The list of asserted quantified formulas, ordered by relevance. |
179 |
|
* Relevance is a dynamic partial ordering where q1 < q2 if there has been |
180 |
|
* a call to markRelevant( q1 ) after the last call to markRelevant( q2 ) |
181 |
|
* (or no call to markRelevant( q2 ) has been made). |
182 |
|
* |
183 |
|
* This list is used primarily as an optimization for conflict-based |
184 |
|
* instantiation so that quantifed formulas that have been instantiated |
185 |
|
* most recently are processed first, since these are (statistically) more |
186 |
|
* likely to have conflicting instantiations. |
187 |
|
*/ |
188 |
|
std::vector<Node> d_forall_rlv_assert; |
189 |
|
/** |
190 |
|
* Whether the above list has been computed. This flag is updated during |
191 |
|
* reset_round and is valid within a full effort check. |
192 |
|
*/ |
193 |
|
bool d_forallRlvComputed; |
194 |
|
/** get variable id */ |
195 |
|
std::map<Node, std::map<Node, int> > d_quant_var_id; |
196 |
|
/** process initialize model for term */ |
197 |
|
virtual void processInitializeModelForTerm(Node n) {} |
198 |
|
/** process initialize quantifier */ |
199 |
9947 |
virtual void processInitializeQuantifier(Node q) {} |
200 |
|
/** process initialize */ |
201 |
|
virtual void processInitialize(bool ispre) {} |
202 |
|
|
203 |
|
private: |
204 |
|
// list of inactive quantified formulas |
205 |
|
std::map<TNode, bool> d_quant_active; |
206 |
|
/** map from types to model basis terms */ |
207 |
|
std::map<TypeNode, Node> d_model_basis_term; |
208 |
|
/** map from ops to model basis terms */ |
209 |
|
std::map<Node, Node> d_model_basis_op_term; |
210 |
|
/** map from instantiation terms to their model basis equivalent */ |
211 |
|
std::map<Node, Node> d_model_basis_body; |
212 |
|
/** map from universal quantifiers to model basis terms */ |
213 |
|
std::map<Node, std::vector<Node> > d_model_basis_terms; |
214 |
|
/** compute model basis arg */ |
215 |
|
void computeModelBasisArgAttribute(Node n); |
216 |
|
};/* class FirstOrderModel */ |
217 |
|
|
218 |
|
} // namespace quantifiers |
219 |
|
} // namespace theory |
220 |
|
} // namespace cvc5 |
221 |
|
|
222 |
|
#endif /* CVC5__FIRST_ORDER_MODEL_H */ |