1 /********************* */
2 /*! \file assertions.cpp
4 ** Top contributors (to current version):
5 ** Andrew Reynolds, Andres Noetzli, Haniel Barbosa
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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 The module for storing assertions for an SMT engine.
15 #include "smt/assertions.h"
17 #include "expr/node_algorithm.h"
18 #include "options/base_options.h"
19 #include "options/language.h"
20 #include "options/smt_options.h"
21 #include "proof/proof_manager.h"
22 #include "smt/smt_engine.h"
24 using namespace CVC4::theory
;
25 using namespace CVC4::kind
;
30 Assertions::Assertions(context::UserContext
* u
, AbstractValues
& absv
)
33 d_assertionList(nullptr),
34 d_globalNegation(false),
39 Assertions::~Assertions()
41 if (d_assertionList
!= nullptr)
43 d_assertionList
->deleteSelf();
47 void Assertions::finishInit()
49 // [MGD 10/20/2011] keep around in incremental mode, due to a
50 // cleanup ordering issue and Nodes/TNodes. If SAT is popped
51 // first, some user-context-dependent TNodes might still exist
53 if (options::produceAssertions() || options::incrementalSolving())
55 // In the case of incremental solving, we appear to need these to
56 // ensure the relevant Nodes remain live.
57 d_assertionList
= new (true) AssertionList(d_userContext
);
58 d_globalDefineFunRecLemmas
.reset(new std::vector
<Node
>());
62 void Assertions::clearCurrent()
65 d_assertions
.getIteSkolemMap().clear();
68 void Assertions::initializeCheckSat(const std::vector
<Node
>& assumptions
,
70 bool isEntailmentCheck
)
72 NodeManager
* nm
= NodeManager::currentNM();
73 // reset global negation
74 d_globalNegation
= false;
75 // clear the assumptions
76 d_assumptions
.clear();
77 if (isEntailmentCheck
)
79 size_t size
= assumptions
.size();
82 /* Assume: not (BIGAND assumptions) */
83 d_assumptions
.push_back(nm
->mkNode(AND
, assumptions
).notNode());
87 /* Assume: not expr */
88 d_assumptions
.push_back(assumptions
[0].notNode());
93 /* Assume: BIGAND assumptions */
94 d_assumptions
= assumptions
;
97 Result
r(Result::SAT_UNKNOWN
, Result::UNKNOWN_REASON
);
98 for (const Node
& e
: d_assumptions
)
100 // Substitute out any abstract values in ex.
101 Node n
= d_absValues
.substituteAbstractValues(e
);
102 // Ensure expr is type-checked at this point.
104 addFormula(n
, inUnsatCore
, true, true, false);
106 if (d_globalDefineFunRecLemmas
!= nullptr)
108 // Global definitions are asserted at check-sat-time because we have to
109 // make sure that they are always present (they are essentially level
111 for (const Node
& lemma
: *d_globalDefineFunRecLemmas
)
113 addFormula(lemma
, false, true, false, false);
118 void Assertions::assertFormula(const Node
& n
, bool inUnsatCore
)
121 bool maybeHasFv
= language::isInputLangSygus(options::inputLanguage());
122 addFormula(n
, inUnsatCore
, true, false, maybeHasFv
);
125 std::vector
<Node
>& Assertions::getAssumptions() { return d_assumptions
; }
126 bool Assertions::isGlobalNegated() const { return d_globalNegation
; }
127 void Assertions::flipGlobalNegated() { d_globalNegation
= !d_globalNegation
; }
129 preprocessing::AssertionPipeline
& Assertions::getAssertionPipeline()
134 context::CDList
<Node
>* Assertions::getAssertionList()
136 return d_assertionList
;
139 void Assertions::addFormula(
140 TNode n
, bool inUnsatCore
, bool inInput
, bool isAssumption
, bool maybeHasFv
)
142 // add to assertion list if it exists
143 if (d_assertionList
!= nullptr)
145 d_assertionList
->push_back(n
);
147 if (n
.isConst() && n
.getConst
<bool>())
149 // true, nothing to do
153 Trace("smt") << "SmtEnginePrivate::addFormula(" << n
154 << "), inUnsatCore = " << inUnsatCore
155 << ", inInput = " << inInput
156 << ", isAssumption = " << isAssumption
<< std::endl
;
158 // Ensure that it does not contain free variables
161 if (expr::hasFreeVar(n
))
163 std::stringstream se
;
164 se
<< "Cannot process assertion with free variable.";
165 if (language::isInputLangSygus(options::inputLanguage()))
167 // Common misuse of SyGuS is to use top-level assert instead of
168 // constraint when defining the synthesis conjecture.
169 se
<< " Perhaps you meant `constraint` instead of `assert`?";
171 throw ModalException(se
.str().c_str());
175 // Give it to proof manager
176 if (options::unsatCores())
179 { // n is an input assertion
180 if (inUnsatCore
|| options::unsatCores() || options::dumpUnsatCores()
181 || options::checkUnsatCores())
183 ProofManager::currentPM()->addCoreAssertion(n
.toExpr());
188 // n is the result of an unknown preprocessing step, add it to dependency
190 ProofManager::currentPM()->addDependence(n
, Node::null());
194 // Add the normalized formula to the queue
195 d_assertions
.push_back(n
, isAssumption
, true);
198 void Assertions::addDefineFunRecDefinition(Node n
, bool global
)
200 n
= d_absValues
.substituteAbstractValues(n
);
201 if (d_assertionList
!= nullptr)
203 d_assertionList
->push_back(n
);
205 if (global
&& d_globalDefineFunRecLemmas
!= nullptr)
207 // Global definitions are asserted at check-sat-time because we have to
208 // make sure that they are always present
209 Assert(!language::isInputLangSygus(options::inputLanguage()));
210 d_globalDefineFunRecLemmas
->emplace_back(n
);
214 bool maybeHasFv
= language::isInputLangSygus(options::inputLanguage());
215 addFormula(n
, false, true, false, maybeHasFv
);
219 void Assertions::ensureBoolean(const Node
& n
)
221 TypeNode type
= n
.getType(options::typeChecking());
222 if (!type
.isBoolean())
224 std::stringstream ss
;
225 ss
<< "Expected Boolean type\n"
226 << "The assertion : " << n
<< "\n"
227 << "Its type : " << type
;
228 throw TypeCheckingException(n
.toExpr(), ss
.str());
232 void Assertions::setProofGenerator(smt::PreprocessProofGenerator
* pppg
)
234 d_assertions
.setProofGenerator(pppg
);
237 bool Assertions::isProofEnabled() const
239 return d_assertions
.isProofEnabled();