//must process assertions at preprocess so that quantified assertions are processed properly
void TheorySep::processAssertions( std::vector< Node >& assertions ) {
+ d_pp_nils.clear();
std::map< Node, bool > visited;
for( unsigned i=0; i<assertions.size(); i++ ){
processAssertion( assertions[i], visited );
void TheorySep::processAssertion( Node n, std::map< Node, bool >& visited ) {
if( visited.find( n )==visited.end() ){
visited[n] = true;
- if( n.getKind()==kind::SEP_PTO || n.getKind()==kind::SEP_STAR || n.getKind()==kind::SEP_WAND || n.getKind()==kind::SEP_EMP ){
+ if( n.getKind()==kind::SEP_NIL ){
+ if( std::find( d_pp_nils.begin(), d_pp_nils.end(), n )==d_pp_nils.end() ){
+ d_pp_nils.push_back( n );
+ }
+ }else if( n.getKind()==kind::SEP_PTO || n.getKind()==kind::SEP_STAR || n.getKind()==kind::SEP_WAND || n.getKind()==kind::SEP_EMP ){
//get the reference type (will compute d_type_references)
int card = 0;
TypeNode tn = getReferenceType( n, card );
void TheorySep::presolve() {
Trace("sep-pp") << "Presolving" << std::endl;
//TODO: cleanup if incremental?
+
+ //we must preregister all instances of sep.nil to ensure they are made equal
+ for( unsigned i=0; i<d_pp_nils.size(); i++ ){
+ std::map< TNode, bool > visited;
+ preRegisterTermRec( d_pp_nils[i], visited );
+ }
+ d_pp_nils.clear();
}
}
+bool TheorySep::needsCheckLastEffort() {
+ return hasFacts();
+}
+
Node TheorySep::getNextDecisionRequest() {
for( unsigned i=0; i<d_neg_guards.size(); i++ ){
Node g = d_neg_guards[i];
void TheoryEngine::finishInit() {
// initialize the quantifiers engine
d_quantEngine = new QuantifiersEngine(d_context, d_userContext, this);
+
+ //initialize the model
+ if( d_logicInfo.isQuantified() ) {
+ d_curr_model = d_quantEngine->getModel();
+ } else {
+ d_curr_model = new theory::TheoryModel(d_userContext, "DefaultModel", true);
+ d_aloc_curr_model = true;
+ }
if (d_logicInfo.isQuantified()) {
d_quantEngine->finishInit();
d_masterEENotify(*this),
d_quantEngine(NULL),
d_curr_model(NULL),
+ d_aloc_curr_model(false),
d_curr_model_builder(NULL),
d_ppCache(),
d_possiblePropagations(context),
}
// build model information if applicable
- d_curr_model = new theory::TheoryModel(userContext, "DefaultModel", true);
d_curr_model_builder = new theory::TheoryEngineModelBuilder(this);
smtStatisticsRegistry()->registerStat(&d_combineTheoriesTime);
}
delete d_curr_model_builder;
- delete d_curr_model;
+ if( d_aloc_curr_model ){
+ delete d_curr_model;
+ }
delete d_quantEngine;
// Must consult quantifiers theory for last call to ensure sat, or otherwise add a lemma
if( effort == Theory::EFFORT_FULL && ! d_inConflict && ! needCheck() ) {
- //calls to theories requiring the model go here
- //FIXME: this should not be theory-specific
- if(d_logicInfo.isTheoryEnabled(THEORY_SEP)) {
- Assert( d_theoryTable[THEORY_SEP]!=NULL );
- if( d_theoryTable[THEORY_SEP]->hasFacts() ){
- // must build model at this point
- d_curr_model_builder->buildModel(getModel(), false);
- d_theoryTable[THEORY_SEP]->check(Theory::EFFORT_LAST_CALL);
+ //checks for theories requiring the model go at last call
+ bool builtModel = false;
+ for (TheoryId theoryId = THEORY_FIRST; theoryId < THEORY_LAST; ++theoryId) {
+ if( theoryId!=THEORY_QUANTIFIERS ){
+ Theory* theory = d_theoryTable[theoryId];
+ if (theory && d_logicInfo.isTheoryEnabled(theoryId)) {
+ if( theory->needsCheckLastEffort() ){
+ if( !builtModel ){
+ builtModel = true;
+ d_curr_model_builder->buildModel(d_curr_model, false);
+ }
+ theory->check(Theory::EFFORT_LAST_CALL);
+ }
+ }
}
}
if( ! d_inConflict && ! needCheck() ){
if(d_logicInfo.isQuantified()) {
// quantifiers engine must pass effort last call check
d_quantEngine->check(Theory::EFFORT_LAST_CALL);
- // if returning incomplete or SAT, we have ensured that the model in the quantifiers engine has been built
+ // if returning incomplete or SAT, we have ensured that d_curr_model has been built with fullModel=true
} else if(options::produceModels()) {
// must build model at this point
- d_curr_model_builder->buildModel(getModel(), true);
+ d_curr_model_builder->buildModel(d_curr_model, true);
}
Trace("theory::assertions-model") << endl;
if (Trace.isOn("theory::assertions-model")) {
/* get model */
TheoryModel* TheoryEngine::getModel() {
- Debug("model") << "TheoryEngine::getModel()" << endl;
- if( d_logicInfo.isQuantified() ) {
- Debug("model") << "Get model from quantifiers engine." << endl;
- return d_quantEngine->getModel();
- } else {
- Debug("model") << "Get default model." << endl;
- return d_curr_model;
- }
+ return d_curr_model;
}
bool TheoryEngine::presolve() {
--- /dev/null
+(set-logic ALL_SUPPORTED)
+(set-info :status unsat)
+
+(declare-sort Loc 0)
+(declare-const loc0 Loc)
+
+(declare-datatypes () ((Node (node (data Int) (left Loc) (right Loc)))))
+
+(declare-const dv Int)
+(declare-const v Loc)
+
+(declare-const dl Int)
+(declare-const l Loc)
+(declare-const dr Int)
+(declare-const r Loc)
+
+(define-fun ten-tree0 ((x Loc) (d Int)) Bool
+(or (and (emp loc0) (= x (as sep.nil Loc))) (and (sep (pto x (node d l r)) (and (emp loc0) (= l (as sep.nil Loc))) (and (emp loc0) (= r (as sep.nil Loc)))) (= dl (- d 10)) (= dr (+ d 10)))))
+
+(declare-const dy Int)
+(declare-const y Loc)
+(declare-const dz Int)
+(declare-const z Loc)
+
+(define-fun ord-tree0 ((x Loc) (d Int)) Bool
+(or (and (emp loc0) (= x (as sep.nil Loc))) (and (sep (pto x (node d y z)) (and (emp loc0) (= y (as sep.nil Loc))) (and (emp loc0) (= z (as sep.nil Loc)))) (<= dy d) (<= d dz))))
+
+;------- f -------
+(assert (= y (as sep.nil Loc)))
+(assert (= z (as sep.nil Loc)))
+
+(assert (= dy dv))
+(assert (= dz (+ dv 10)))
+;-----------------
+
+(assert (not (= v (as sep.nil Loc))))
+
+(assert (ten-tree0 v dv))
+(assert (not (ord-tree0 v dv)))
+
+(check-sat)