1 /********************* */
4 ** Top contributors (to current version):
5 ** Tim King, Dejan Jovanovic, Clark Barrett
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2016 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.\endverbatim
12 ** \brief Base for theory interface.
14 ** Base for theory interface.
17 #include "theory/theory.h"
24 #include "base/cvc4_assert.h"
25 #include "smt/smt_statistics_registry.h"
26 #include "theory/substitutions.h"
27 #include "theory/quantifiers_engine.h"
35 /** Default value for the uninterpreted sorts is the UF theory */
36 TheoryId
Theory::s_uninterpretedSortOwner
= THEORY_UF
;
38 std::ostream
& operator<<(std::ostream
& os
, Theory::Effort level
){
40 case Theory::EFFORT_STANDARD
:
41 os
<< "EFFORT_STANDARD"; break;
42 case Theory::EFFORT_FULL
:
43 os
<< "EFFORT_FULL"; break;
44 case Theory::EFFORT_COMBINATION
:
45 os
<< "EFFORT_COMBINATION"; break;
46 case Theory::EFFORT_LAST_CALL
:
47 os
<< "EFFORT_LAST_CALL"; break;
52 }/* ostream& operator<<(ostream&, Theory::Effort) */
55 Theory::Theory(TheoryId id
, context::Context
* satContext
,
56 context::UserContext
* userContext
, OutputChannel
& out
,
57 Valuation valuation
, const LogicInfo
& logicInfo
,
58 std::string name
) throw()
60 , d_instanceName(name
)
61 , d_satContext(satContext
)
62 , d_userContext(userContext
)
63 , d_logicInfo(logicInfo
)
65 , d_factsHead(satContext
, 0)
66 , d_sharedTermsIndex(satContext
, 0)
69 , d_checkTime(getFullInstanceName() + "::checkTime")
70 , d_computeCareGraphTime(getFullInstanceName() + "::computeCareGraphTime")
71 , d_sharedTerms(satContext
)
73 , d_valuation(valuation
)
74 , d_proofsEnabled(false)
76 smtStatisticsRegistry()->registerStat(&d_checkTime
);
77 smtStatisticsRegistry()->registerStat(&d_computeCareGraphTime
);
81 smtStatisticsRegistry()->unregisterStat(&d_checkTime
);
82 smtStatisticsRegistry()->unregisterStat(&d_computeCareGraphTime
);
85 TheoryId
Theory::theoryOf(TheoryOfMode mode
, TNode node
) {
86 TheoryId tid
= THEORY_BUILTIN
;
88 case THEORY_OF_TYPE_BASED
:
89 // Constants, variables, 0-ary constructors
90 if (node
.isVar() || node
.isConst()) {
91 tid
= Theory::theoryOf(node
.getType());
92 } else if (node
.getKind() == kind::EQUAL
) {
93 // Equality is owned by the theory that owns the domain
94 tid
= Theory::theoryOf(node
[0].getType());
96 // Regular nodes are owned by the kind
97 tid
= kindToTheoryId(node
.getKind());
100 case THEORY_OF_TERM_BASED
:
103 if (Theory::theoryOf(node
.getType()) != theory::THEORY_BOOL
) {
104 // We treat the variables as uninterpreted
105 tid
= s_uninterpretedSortOwner
;
107 // Except for the Boolean ones, which we just ignore anyhow
108 tid
= theory::THEORY_BOOL
;
110 } else if (node
.isConst()) {
111 // Constants go to the theory of the type
112 tid
= Theory::theoryOf(node
.getType());
113 } else if (node
.getKind() == kind::EQUAL
) { // Equality
114 // If one of them is an ITE, it's irelevant, since they will get replaced out anyhow
115 if (node
[0].getKind() == kind::ITE
) {
116 tid
= Theory::theoryOf(node
[0].getType());
117 } else if (node
[1].getKind() == kind::ITE
) {
118 tid
= Theory::theoryOf(node
[1].getType());
122 TypeNode ltype
= l
.getType();
123 TypeNode rtype
= r
.getType();
124 if( ltype
!= rtype
){
125 tid
= Theory::theoryOf(l
.getType());
127 // If both sides belong to the same theory the choice is easy
128 TheoryId T1
= Theory::theoryOf(l
);
129 TheoryId T2
= Theory::theoryOf(r
);
133 TheoryId T3
= Theory::theoryOf(ltype
);
135 // * x*y = f(z) -> UF
137 // * f(x) = read(a, y) -> either UF or ARRAY
138 // at least one of the theories has to be parametric, i.e. theory of the type is different
139 // from the theory of the term
142 } else if (T2
== T3
) {
145 // If both are parametric, we take the smaller one (arbitrary)
146 tid
= T1
< T2
? T1
: T2
;
152 // Regular nodes are owned by the kind
153 tid
= kindToTheoryId(node
.getKind());
159 Trace("theory::internal") << "theoryOf(" << mode
<< ", " << node
<< ") -> " << tid
<< std::endl
;
163 void Theory::addSharedTermInternal(TNode n
) {
164 Debug("sharing") << "Theory::addSharedTerm<" << getId() << ">(" << n
<< ")" << endl
;
165 Debug("theory::assertions") << "Theory::addSharedTerm<" << getId() << ">(" << n
<< ")" << endl
;
166 d_sharedTerms
.push_back(n
);
170 void Theory::computeCareGraph() {
171 Debug("sharing") << "Theory::computeCareGraph<" << getId() << ">()" << endl
;
172 for (unsigned i
= 0; i
< d_sharedTerms
.size(); ++ i
) {
173 TNode a
= d_sharedTerms
[i
];
174 TypeNode aType
= a
.getType();
175 for (unsigned j
= i
+ 1; j
< d_sharedTerms
.size(); ++ j
) {
176 TNode b
= d_sharedTerms
[j
];
177 if (b
.getType() != aType
) {
178 // We don't care about the terms of different types
181 switch (d_valuation
.getEqualityStatus(a
, b
)) {
182 case EQUALITY_TRUE_AND_PROPAGATED
:
183 case EQUALITY_FALSE_AND_PROPAGATED
:
184 // If we know about it, we should have propagated it, so we can skip
195 void Theory::printFacts(std::ostream
& os
) const {
196 unsigned i
, n
= d_facts
.size();
197 for(i
= 0; i
< n
; i
++){
198 const Assertion
& a_i
= d_facts
[i
];
199 Node assertion
= a_i
;
200 os
<< d_id
<< '[' << i
<< ']' << " " << assertion
<< endl
;
204 void Theory::debugPrintFacts() const{
205 DebugChannel
.getStream() << "Theory::debugPrintFacts()" << endl
;
206 printFacts(DebugChannel
.getStream());
209 std::hash_set
<TNode
, TNodeHashFunction
> Theory::currentlySharedTerms() const{
210 std::hash_set
<TNode
, TNodeHashFunction
> currentlyShared
;
211 for (shared_terms_iterator i
= shared_terms_begin(),
212 i_end
= shared_terms_end(); i
!= i_end
; ++i
) {
213 currentlyShared
.insert (*i
);
215 return currentlyShared
;
219 void Theory::collectTerms(TNode n
, set
<Node
>& termSet
) const
221 if (termSet
.find(n
) != termSet
.end()) {
224 Trace("theory::collectTerms") << "Theory::collectTerms: adding " << n
<< endl
;
226 if (n
.getKind() == kind::NOT
|| n
.getKind() == kind::EQUAL
|| !isLeaf(n
)) {
227 for(TNode::iterator child_it
= n
.begin(); child_it
!= n
.end(); ++child_it
) {
228 collectTerms(*child_it
, termSet
);
234 void Theory::computeRelevantTerms(set
<Node
>& termSet
, bool includeShared
) const
236 // Collect all terms appearing in assertions
237 context::CDList
<Assertion
>::const_iterator assert_it
= facts_begin(), assert_it_end
= facts_end();
238 for (; assert_it
!= assert_it_end
; ++assert_it
) {
239 collectTerms(*assert_it
, termSet
);
242 if (!includeShared
) return;
244 // Add terms that are shared terms
245 context::CDList
<TNode
>::const_iterator shared_it
= shared_terms_begin(), shared_it_end
= shared_terms_end();
246 for (; shared_it
!= shared_it_end
; ++shared_it
) {
247 collectTerms(*shared_it
, termSet
);
252 Theory::PPAssertStatus
Theory::ppAssert(TNode in
,
253 SubstitutionMap
& outSubstitutions
)
255 if (in
.getKind() == kind::EQUAL
) {
256 // (and (= x t) phi) can be replaced by phi[x/t] if
257 // 1) x is a variable
258 // 2) x is not in the term t
259 // 3) x : T and t : S, then S <: T
260 if (in
[0].isVar() && !in
[1].hasSubterm(in
[0]) &&
261 (in
[1].getType()).isSubtypeOf(in
[0].getType()) ){
262 outSubstitutions
.addSubstitution(in
[0], in
[1]);
263 return PP_ASSERT_STATUS_SOLVED
;
265 if (in
[1].isVar() && !in
[0].hasSubterm(in
[1]) &&
266 (in
[0].getType()).isSubtypeOf(in
[1].getType())){
267 outSubstitutions
.addSubstitution(in
[1], in
[0]);
268 return PP_ASSERT_STATUS_SOLVED
;
270 if (in
[0].isConst() && in
[1].isConst()) {
271 if (in
[0] != in
[1]) {
272 return PP_ASSERT_STATUS_CONFLICT
;
277 return PP_ASSERT_STATUS_UNSOLVED
;
280 std::pair
<bool, Node
> Theory::entailmentCheck(
282 const EntailmentCheckParameters
* params
,
283 EntailmentCheckSideEffects
* out
) {
284 return make_pair(false, Node::null());
287 EntailmentCheckParameters::EntailmentCheckParameters(TheoryId tid
)
291 std::string
Theory::getFullInstanceName() const {
292 std::stringstream ss
;
293 ss
<< "theory<" << d_id
<< ">" << d_instanceName
;
297 EntailmentCheckParameters::~EntailmentCheckParameters(){}
299 TheoryId
EntailmentCheckParameters::getTheoryId() const {
303 EntailmentCheckSideEffects::EntailmentCheckSideEffects(TheoryId tid
)
307 TheoryId
EntailmentCheckSideEffects::getTheoryId() const {
311 EntailmentCheckSideEffects::~EntailmentCheckSideEffects() {
314 }/* CVC4::theory namespace */
315 }/* CVC4 namespace */