}
-Node TheoryArrays::getNextDecisionRequest() {
+Node TheoryArrays::getNextDecisionRequest( unsigned& priority ) {
if(! d_decisionRequests.empty()) {
Node n = d_decisionRequests.front();
d_decisionRequests.pop();
+ priority = 2;
return n;
} else {
return Node::null();
private:
public:
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
void presolve();
void shutdown() { }
d_assertions[nlit] = n.getKind()!=NOT;
}
-Node BoundedIntegers::getNextDecisionRequest() {
+Node BoundedIntegers::getNextDecisionRequest( unsigned& priority ) {
Trace("bound-int-dec-debug") << "bi: Get next decision request?" << std::endl;
for( unsigned i=0; i<d_ranges.size(); i++) {
Node d = d_rms[d_ranges[i]]->getNextDecisionRequest();
i--;
}
}else{
+ priority = 1;
Trace("bound-int-dec") << "Bounded Integers : Decide " << d << std::endl;
return d;
}
void check( Theory::Effort e, unsigned quant_e );
void registerQuantifier( Node f );
void assertNode( Node n );
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
bool isBoundVar( Node q, Node v ) { return std::find( d_set[q].begin(), d_set[q].end(), v )!=d_set[q].end(); }
unsigned getBoundVarType( Node q, Node v );
unsigned getNumBoundVars( Node q ) { return d_set[q].size(); }
d_last_inst_si = false;
}
+CegInstantiation::~CegInstantiation(){
+ delete d_conj;
+}
+
bool CegInstantiation::needsCheck( Theory::Effort e ) {
return e>=Theory::EFFORT_LAST_CALL;
}
void CegInstantiation::assertNode( Node n ) {
}
-Node CegInstantiation::getNextDecisionRequest() {
+Node CegInstantiation::getNextDecisionRequest( unsigned& priority ) {
//enforce fairness
if( d_conj->isAssigned() ){
d_conj->initializeGuard( d_quantEngine );
bool value;
if( !d_quantEngine->getValuation().hasSatValue( req_dec[i], value ) ) {
Trace("cegqi-debug") << "CEGQI : Decide next on : " << req_dec[i] << "..." << std::endl;
+ priority = 0;
return req_dec[i];
}else{
Trace("cegqi-debug2") << "CEGQI : " << req_dec[i] << " already has value " << value << std::endl;
d_conj->d_curr_lit.set( d_conj->d_curr_lit.get() + 1 );
lit = d_conj->getLiteral( d_quantEngine, d_conj->d_curr_lit.get() );
Trace("cegqi-debug") << "CEGQI : Decide on next lit : " << lit << "..." << std::endl;
+ priority = 1;
return lit;
}
}else{
Trace("cegqi-debug") << "CEGQI : Decide on current lit : " << lit << "..." << std::endl;
+ priority = 1;
return lit;
}
}
Node getModelTerm( Node n );
public:
CegInstantiation( QuantifiersEngine * qe, context::Context* c );
+ ~CegInstantiation();
public:
bool needsCheck( Theory::Effort e );
unsigned needsModel( Theory::Effort e );
void preRegisterQuantifier( Node q );
void registerQuantifier( Node q );
void assertNode( Node n );
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
/** Identify this module (for debugging, dynamic configuration, etc..) */
std::string identify() const { return "CegInstantiation"; }
/** print solution for synthesis conjectures */
return Node::null();
}
-Node InstStrategyCbqi::getNextDecisionRequest(){
+Node InstStrategyCbqi::getNextDecisionRequest( unsigned& priority ){
std::map< Node, bool > proc;
for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
Node d = getNextDecisionRequestProc( q, proc );
if( !d.isNull() ){
+ priority = 0;
return d;
}
}
void preRegisterQuantifier( Node q );
void registerQuantifier( Node q );
/** get next decision request */
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
};
//generalized counterexample guided quantifier instantiation
virtual void registerQuantifier( Node q ) = 0;
virtual void assertNode( Node n ) {}
virtual void propagate( Theory::Effort level ){}
- virtual Node getNextDecisionRequest() { return TNode::null(); }
+ virtual Node getNextDecisionRequest( unsigned& priority ) { return TNode::null(); }
/** Identify this module (for debugging, dynamic configuration, etc..) */
virtual std::string identify() const = 0;
public:
getQuantifiersEngine()->check( e );
}
-Node TheoryQuantifiers::getNextDecisionRequest(){
- return getQuantifiersEngine()->getNextDecisionRequest();
+Node TheoryQuantifiers::getNextDecisionRequest( unsigned& priority ){
+ return getQuantifiersEngine()->getNextDecisionRequest( priority );
}
void TheoryQuantifiers::assertUniversal( Node n ){
void presolve();
void ppNotifyAssertions( std::vector< Node >& assertions );
void check(Effort e);
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
Node getValue(TNode n);
void collectModelInfo( TheoryModel* m, bool fullModel );
void shutdown() { }
}
}
-Node QuantifiersEngine::getNextDecisionRequest(){
+Node QuantifiersEngine::getNextDecisionRequest( unsigned& priority ){
+ unsigned min_priority;
+ Node dec;
for( unsigned i=0; i<d_modules.size(); i++ ){
- Node n = d_modules[i]->getNextDecisionRequest();
- if( !n.isNull() ){
- return n;
+ Node n = d_modules[i]->getNextDecisionRequest( priority );
+ if( !n.isNull() && ( dec.isNull() || priority<min_priority ) ){
+ dec = n;
+ min_priority = priority;
}
}
- return Node::null();
+ return dec;
}
quantifiers::TermDbSygus* QuantifiersEngine::getTermDatabaseSygus() {
/** propagate */
void propagate( Theory::Effort level );
/** get next decision request */
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
private:
/** reduceQuantifier, return true if reduced */
bool reduceQuantifier( Node q );
}else{
//this typically should not happen, should never happen for complete base theories
Trace("sep-process") << "*** repeated refinement lemma : " << lem << std::endl;
+ Trace("sep-warn") << "TheorySep : WARNING : repeated refinement lemma : " << lem << "!!!" << std::endl;
}
}
}else{
//must witness finite data points-to
for( std::map< TypeNode, Node >::iterator it = d_base_label.begin(); it != d_base_label.end(); ++it ){
TypeNode data_type = d_loc_to_data_type[it->first];
+ //if the data type is finite
if( data_type.isInterpretedFinite() ){
computeLabelModel( it->second );
Trace("sep-process-debug") << "Check heap data for " << it->first << " -> " << data_type << std::endl;
Node l = d_label_model[it->second].d_heap_locs_model[j][0];
Trace("sep-process-debug") << " location : " << l << std::endl;
if( d_pto_model[l].isNull() ){
- Node ll = d_tmodel[l];
- Assert( !ll.isNull() );
- Trace("sep-process") << "Must witness label : " << ll << ", data type is " << data_type << std::endl;
- Node dsk = NodeManager::currentNM()->mkSkolem( "dsk", data_type, "pto-data for implicit location" );
- // if location is in the heap, then something must point to it
- Node lem = NodeManager::currentNM()->mkNode( kind::IMPLIES, NodeManager::currentNM()->mkNode( kind::MEMBER, ll, it->second ),
- NodeManager::currentNM()->mkNode( kind::SEP_STAR,
- NodeManager::currentNM()->mkNode( kind::SEP_PTO, ll, dsk ),
- d_true ) );
- Trace("sep-lemma") << "Sep::Lemma : witness finite data-pto : " << lem << std::endl;
- d_out->lemma( lem );
- addedLemma = true;
+ needAddLemma = true;
+ Node ll;
+ std::map< Node, Node >::iterator itm = d_tmodel.find( l );
+ if( itm!=d_tmodel.end() ) {
+ ll = itm->second;
+ }else{
+ //try to assign arbitrary skolem?
+ }
+ if( !ll.isNull() ){
+ Trace("sep-process") << "Must witness label : " << ll << ", data type is " << data_type << std::endl;
+ Node dsk = NodeManager::currentNM()->mkSkolem( "dsk", data_type, "pto-data for implicit location" );
+ // if location is in the heap, then something must point to it
+ Node lem = NodeManager::currentNM()->mkNode( kind::IMPLIES, NodeManager::currentNM()->mkNode( kind::MEMBER, ll, it->second ),
+ NodeManager::currentNM()->mkNode( kind::SEP_STAR,
+ NodeManager::currentNM()->mkNode( kind::SEP_PTO, ll, dsk ),
+ d_true ) );
+ Trace("sep-lemma") << "Sep::Lemma : witness finite data-pto : " << lem << std::endl;
+ d_out->lemma( lem );
+ addedLemma = true;
+ }else{
+ //This should only happen if we are in an unbounded fragment
+ Trace("sep-warn") << "TheorySep : WARNING : no term corresponding to location " << l << " in heap!!!" << std::endl;
+ }
}else{
Trace("sep-process-debug") << " points-to data witness : " << d_pto_model[l] << std::endl;
}
}
}
if( !addedLemma && needAddLemma ){
- Trace("sep-process") << "WARNING : could not find sep refinement lemma!!!" << std::endl;
Assert( false );
d_out->setIncomplete();
}
return hasFacts();
}
-Node TheorySep::getNextDecisionRequest() {
+Node TheorySep::getNextDecisionRequest( unsigned& priority ) {
for( unsigned i=0; i<d_neg_guards.size(); i++ ){
Node g = d_neg_guards[i];
bool success = true;
Node cel = getQuantifiersEngine()->getTermDatabase()->getCounterexampleLiteral( q );
bool value;
if( d_valuation.hasSatValue( cel, value ) ){
+ Trace("sep-dec-debug") << "TheorySep::getNextDecisionRequest : dependent guard " << g << " depends on value for guard for quantified formula : " << value << std::endl;
success = value;
}else{
Trace("sep-dec-debug") << "TheorySep::getNextDecisionRequest : wait to decide on " << g << " until " << cel << " is set " << std::endl;
bool value;
if( !d_valuation.hasSatValue( g, value ) ) {
Trace("sep-dec") << "TheorySep::getNextDecisionRequest : " << g << " (" << i << "/" << d_neg_guards.size() << ")" << std::endl;
+ priority = 0;
return g;
}
}
private:
public:
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
void presolve();
void shutdown() { }
//// Finite Model Finding
-Node TheoryStrings::getNextDecisionRequest() {
+Node TheoryStrings::getNextDecisionRequest( unsigned& priority ) {
if( options::stringFMF() && !d_conflict ){
Node in_var_lsum = d_input_var_lsum.get();
//Trace("strings-fmf-debug") << "Strings::FMF: Assertion Level = " << d_valuation.getAssertionLevel() << std::endl;
}
Node lit = d_cardinality_lits[ decideCard ];
Trace("strings-fmf") << "Strings::FMF: Decide positive on " << lit << std::endl;
+ priority = 1;
return lit;
}
}
context::CDO< int > d_curr_cardinality;
public:
//for finite model finding
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
//ppRewrite
Node ppRewrite(TNode atom);
public:
/**
* Return a decision request, if the theory has one, or the NULL node
* otherwise.
+ * If returning non-null node, hould set priority to
+ * 0 if decision is necessary for model-soundness,
+ * 1 if decision is necessary for completeness,
+ * >1 otherwise.
*/
- virtual Node getNextDecisionRequest() { return Node(); }
+ virtual Node getNextDecisionRequest( unsigned& priority ) { return Node(); }
/**
* Statically learn from assertion "in," which has been asserted
Node TheoryEngine::getNextDecisionRequest() {
// Definition of the statement that is to be run by every theory
+ unsigned min_priority;
+ Node dec;
#ifdef CVC4_FOR_EACH_THEORY_STATEMENT
#undef CVC4_FOR_EACH_THEORY_STATEMENT
#endif
#define CVC4_FOR_EACH_THEORY_STATEMENT(THEORY) \
if (theory::TheoryTraits<THEORY>::hasGetNextDecisionRequest && d_logicInfo.isTheoryEnabled(THEORY)) { \
- Node n = theoryOf(THEORY)->getNextDecisionRequest(); \
- if(! n.isNull()) { \
- return n; \
+ unsigned priority; \
+ Node n = theoryOf(THEORY)->getNextDecisionRequest( priority ); \
+ if(! n.isNull() && ( dec.isNull() || priority<min_priority ) ) { \
+ dec = n; \
+ min_priority = priority; \
} \
}
// Request decision from each theory using the statement above
CVC4_FOR_EACH_THEORY;
- return TNode();
+ return dec;
}
bool TheoryEngine::properConflict(TNode conflict) const {
//}
}
-Node TheoryUF::getNextDecisionRequest(){
+Node TheoryUF::getNextDecisionRequest( unsigned& priority ){
if (d_thss != NULL && !d_conflict) {
- return d_thss->getNextDecisionRequest();
+ return d_thss->getNextDecisionRequest( priority );
}else{
return Node::null();
}
void computeCareGraph();
void propagate(Effort effort);
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
EqualityStatus getEqualityStatus(TNode a, TNode b);
}
/** get next decision request */
-Node StrongSolverTheoryUF::getNextDecisionRequest(){
+Node StrongSolverTheoryUF::getNextDecisionRequest( unsigned& priority ){
//request the combined cardinality as a decision literal, if not already asserted
if( options::ufssFairness() ){
int comCard = 0;
com_lit = d_com_card_literal.find( comCard )!=d_com_card_literal.end() ? d_com_card_literal[comCard] : Node::null();
if( !com_lit.isNull() && d_com_card_assertions.find( com_lit )==d_com_card_assertions.end() ){
Trace("uf-ss-dec") << "Decide on combined cardinality : " << com_lit << std::endl;
+ priority = 1;
return com_lit;
}
comCard++;
for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin(); it != d_rep_model.end(); ++it ){
Node n = it->second->getNextDecisionRequest();
if( !n.isNull() ){
+ priority = 1;
return n;
}
}
/** propagate */
void propagate( Theory::Effort level );
/** get next decision request */
- Node getNextDecisionRequest();
+ Node getNextDecisionRequest( unsigned& priority );
/** preregister a term */
void preRegisterTerm( TNode n );
/** notify restart */
dup-nemp.smt2 \
emp2-quant-unsat.smt2 \
dispose-1.smt2 \
- finite-witness-sat.smt2
+ finite-witness-sat.smt2 \
+ sep-fmf-priority.smt2
FAILING_TESTS =
--- /dev/null
+; COMMAND-LINE: --finite-model-find --quant-epr --no-check-models
+; EXPECT: sat
+(set-logic ALL_SUPPORTED)
+
+(declare-sort Loc 0)
+(declare-const l Loc)
+(declare-const x Loc)
+
+(assert (wand (pto x x) false))
+(assert (forall ((x Loc) (y Loc)) (not (pto x y))))
+
+(check-sat)