1 /********************* */
4 ** Original author: mdeters
5 ** Major contributors: ajreynol, dejan
6 ** Minor contributors (to current version): taking
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009-2012 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** information.\endverbatim
12 ** \brief Base for theory interface.
14 ** Base for theory interface.
17 #include "theory/theory.h"
18 #include "util/cvc4_assert.h"
19 #include "theory/quantifiers_engine.h"
20 #include "theory/quantifiers/instantiator_default.h"
29 /** Default value for the uninterpreted sorts is the UF theory */
30 TheoryId
Theory::s_uninterpretedSortOwner
= THEORY_UF
;
32 /** By default, we use the type based theoryOf */
33 TheoryOfMode
Theory::s_theoryOfMode
= THEORY_OF_TYPE_BASED
;
35 std::ostream
& operator<<(std::ostream
& os
, Theory::Effort level
){
37 case Theory::EFFORT_STANDARD
:
38 os
<< "EFFORT_STANDARD"; break;
39 case Theory::EFFORT_FULL
:
40 os
<< "EFFORT_FULL"; break;
41 case Theory::EFFORT_COMBINATION
:
42 os
<< "EFFORT_COMBINATION"; break;
43 case Theory::EFFORT_LAST_CALL
:
44 os
<< "EFFORT_LAST_CALL"; break;
49 }/* ostream& operator<<(ostream&, Theory::Effort) */
57 StatisticsRegistry::unregisterStat(&d_computeCareGraphTime
);
60 TheoryId
Theory::theoryOf(TheoryOfMode mode
, TNode node
) {
62 Trace("theory::internal") << "theoryOf(" << node
<< ")" << std::endl
;
65 case THEORY_OF_TYPE_BASED
:
66 // Constants, variables, 0-ary constructors
67 if (node
.isVar() || node
.isConst()) {
68 return theoryOf(node
.getType());
70 // Equality is owned by the theory that owns the domain
71 if (node
.getKind() == kind::EQUAL
) {
72 return theoryOf(node
[0].getType());
74 // Regular nodes are owned by the kind
75 return kindToTheoryId(node
.getKind());
77 case THEORY_OF_TERM_BASED
:
80 if (theoryOf(node
.getType()) != theory::THEORY_BOOL
) {
81 // We treat the varibables as uninterpreted
82 return s_uninterpretedSortOwner
;
84 // Except for the Boolean ones, which we just ignore anyhow
85 return theory::THEORY_BOOL
;
90 // Constants go to the theory of the type
91 return theoryOf(node
.getType());
94 if (node
.getKind() == kind::EQUAL
) {
95 // If one of them is an ITE, it's irelevant, since they will get replaced out anyhow
96 if (node
[0].getKind() == kind::ITE
) {
97 return theoryOf(node
[0].getType());
99 if (node
[1].getKind() == kind::ITE
) {
100 return theoryOf(node
[1].getType());
102 // If both sides belong to the same theory the choice is easy
103 TheoryId T1
= theoryOf(node
[0]);
104 TheoryId T2
= theoryOf(node
[1]);
108 TheoryId T3
= theoryOf(node
[0].getType());
110 // * x*y = f(z) -> UF
112 // * f(x) = read(a, y) -> either UF or ARRAY
113 // at least one of the theories has to be parametric, i.e. theory of the type is different
114 // from the theory of the term
121 // If both are parametric, we take the smaller one (arbitraty)
122 return T1
< T2
? T1
: T2
;
124 // Regular nodes are owned by the kind
125 return kindToTheoryId(node
.getKind());
132 void Theory::addSharedTermInternal(TNode n
) {
133 Debug("sharing") << "Theory::addSharedTerm<" << getId() << ">(" << n
<< ")" << endl
;
134 Debug("theory::assertions") << "Theory::addSharedTerm<" << getId() << ">(" << n
<< ")" << endl
;
135 d_sharedTerms
.push_back(n
);
139 void Theory::computeCareGraph() {
140 Debug("sharing") << "Theory::computeCareGraph<" << getId() << ">()" << endl
;
141 for (unsigned i
= 0; i
< d_sharedTerms
.size(); ++ i
) {
142 TNode a
= d_sharedTerms
[i
];
143 TypeNode aType
= a
.getType();
144 for (unsigned j
= i
+ 1; j
< d_sharedTerms
.size(); ++ j
) {
145 TNode b
= d_sharedTerms
[j
];
146 if (b
.getType() != aType
) {
147 // We don't care about the terms of different types
150 switch (d_valuation
.getEqualityStatus(a
, b
)) {
151 case EQUALITY_TRUE_AND_PROPAGATED
:
152 case EQUALITY_FALSE_AND_PROPAGATED
:
153 // If we know about it, we should have propagated it, so we can skip
164 void Theory::printFacts(std::ostream
& os
) const {
165 unsigned i
, n
= d_facts
.size();
166 for(i
= 0; i
< n
; i
++){
167 const Assertion
& a_i
= d_facts
[i
];
168 Node assertion
= a_i
;
169 os
<< d_id
<< '[' << i
<< ']' << " " << assertion
<< endl
;
173 void Theory::debugPrintFacts() const{
174 DebugChannel
.getStream() << "Theory::debugPrintFacts()" << endl
;
175 printFacts(DebugChannel
.getStream());
178 Instantiator::Instantiator(context::Context
* c
, QuantifiersEngine
* qe
, Theory
* th
) :
183 Instantiator::~Instantiator() {
186 void Instantiator::resetInstantiationRound(Theory::Effort effort
) {
187 for(int i
= 0; i
< (int) d_instStrategies
.size(); ++i
) {
188 if(isActiveStrategy(d_instStrategies
[i
])) {
189 d_instStrategies
[i
]->processResetInstantiationRound(effort
);
192 processResetInstantiationRound(effort
);
195 int Instantiator::doInstantiation(Node f
, Theory::Effort effort
, int e
) {
196 if( getQuantifierActive(f
) ) {
197 int status
= process(f
, effort
, e
);
198 if(d_instStrategies
.empty()) {
199 Debug("inst-engine-inst") << "There are no instantiation strategies allocated." << endl
;
201 for(int i
= 0; i
< (int) d_instStrategies
.size(); ++i
) {
202 if(isActiveStrategy(d_instStrategies
[i
])) {
203 Debug("inst-engine-inst") << d_instStrategies
[i
]->identify() << " process " << effort
<< endl
;
204 //call the instantiation strategy's process method
205 int s_status
= d_instStrategies
[i
]->process( f
, effort
, e
);
206 Debug("inst-engine-inst") << " -> status is " << s_status
<< endl
;
207 InstStrategy::updateStatus(status
, s_status
);
209 Debug("inst-engine-inst") << d_instStrategies
[i
]->identify() << " is not active." << endl
;
215 Debug("inst-engine-inst") << "We have no constraints from this quantifier." << endl
;
216 return InstStrategy::STATUS_SAT
;
220 //void Instantiator::doInstantiation(int effort) {
221 // d_status = InstStrategy::STATUS_SAT;
222 // for( int q = 0; q < d_quantEngine->getNumQuantifiers(); ++q ) {
223 // Node f = d_quantEngine->getQuantifier(q);
224 // if( d_quantEngine->getActive(f) && hasConstraintsFrom(f) ) {
225 // int d_quantStatus = process( f, effort );
226 // InstStrategy::updateStatus( d_status, d_quantStatus );
227 // for( int i = 0; i < (int)d_instStrategies.size(); ++i ) {
228 // if( isActiveStrategy( d_instStrategies[i] ) ) {
229 // Debug("inst-engine-inst") << d_instStrategies[i]->identify() << " process " << effort << endl;
230 // //call the instantiation strategy's process method
231 // d_quantStatus = d_instStrategies[i]->process( f, effort );
232 // Debug("inst-engine-inst") << " -> status is " << d_quantStatus << endl;
233 // InstStrategy::updateStatus( d_status, d_quantStatus );
240 std::hash_set
<TNode
, TNodeHashFunction
> Theory::currentlySharedTerms() const{
241 std::hash_set
<TNode
, TNodeHashFunction
> currentlyShared
;
242 for(shared_terms_iterator i
= shared_terms_begin(), i_end
= shared_terms_end(); i
!= i_end
; ++i
){
243 currentlyShared
.insert (*i
);
245 return currentlyShared
;
249 void Theory::collectTerms(TNode n
, set
<Node
>& termSet
)
251 if (termSet
.find(n
) != termSet
.end()) {
254 Trace("theory::collectTerms") << "Theory::collectTerms: adding " << n
<< endl
;
256 if (n
.getKind() == kind::NOT
|| n
.getKind() == kind::EQUAL
|| !isLeaf(n
)) {
257 for(TNode::iterator child_it
= n
.begin(); child_it
!= n
.end(); ++child_it
) {
258 collectTerms(*child_it
, termSet
);
264 void Theory::computeRelevantTerms(set
<Node
>& termSet
)
266 // Collect all terms appearing in assertions
267 context::CDList
<Assertion
>::const_iterator assert_it
= facts_begin(), assert_it_end
= facts_end();
268 for (; assert_it
!= assert_it_end
; ++assert_it
) {
269 collectTerms(*assert_it
, termSet
);
272 // Add terms that are shared terms
273 context::CDList
<TNode
>::const_iterator shared_it
= shared_terms_begin(), shared_it_end
= shared_terms_end();
274 for (; shared_it
!= shared_it_end
; ++shared_it
) {
275 collectTerms(*shared_it
, termSet
);
280 }/* CVC4::theory namespace */
281 }/* CVC4 namespace */