}
}
if( options::dtStcInduction() ){
+ //leads to unfairness FIXME
if( !options::dtForceAssignment.wasSetByUser() ){
options::dtForceAssignment.set( true );
}
d_equalityEngine.addFunctionKind(kind::APPLY_UF);
d_true = NodeManager::currentNM()->mkConst( true );
+ d_dtfCounter = 0;
}
TheoryDatatypes::~TheoryDatatypes() {
}
}
}
-
- if( !needSplit && options::dtForceAssignment() ){
+ //d_dtfCounter++;
+ if( !needSplit && options::dtForceAssignment() && d_dtfCounter%2==0 ){
//for the sake of termination, we must choose the constructor of a ground term
//NEED GUARENTEE: groundTerm should not contain any subterms of the same type
// TODO: this is probably not good enough, actually need fair enumeration strategy
context::CDList<TNode> d_consTerms;
/** All the selector terms that the theory has seen */
context::CDList<TNode> d_selTerms;
+ /** counter for forcing assignments (ensures fairness) */
+ unsigned d_dtfCounter;
private:
/** assert fact */
void assertFact( Node fact, Node exp );
Trace("sg-rel-term") << std::endl;\r
\r
for( unsigned r=0; r<2; r++ ){\r
- Trace("sg-gen-tg-eqc") << "...from equivalence classes (" << r << ") : ";\r
+ Trace("sg-rel-term-debug") << "...from equivalence classes (" << r << ") : ";\r
int index = d_ccand_eqc[r].size()-1;\r
for( unsigned j=0; j<d_ccand_eqc[r][index].size(); j++ ){\r
- Trace("sg-gen-tg-eqc") << "e" << d_em[d_ccand_eqc[r][index][j]] << " ";\r
+ Trace("sg-rel-term-debug") << "e" << d_em[d_ccand_eqc[r][index][j]] << " ";\r
}\r
- Trace("sg-gen-tg-eqc") << std::endl;\r
+ Trace("sg-rel-term-debug") << std::endl;\r
}\r
TypeNode tnn = nn.getType();\r
Trace("sg-gen-tg-debug") << "...term is " << nn << std::endl;\r
int index = d_ccand_eqc[1].size()-1;\r
for( unsigned j=0; j<d_ccand_eqc[1][index].size(); j++ ){\r
TNode r = d_ccand_eqc[1][index][j];\r
- Trace("sg-gen-tg-eqc") << " Matches for e" << d_em[r] << ", which is ground term " << d_ground_eqc_map[r] << ":" << std::endl;\r
+ Trace("sg-rel-term-debug") << " Matches for e" << d_em[r] << ", which is ground term " << d_ground_eqc_map[r] << ":" << std::endl;\r
std::map< TypeNode, std::map< unsigned, TNode > > subs;\r
std::map< TNode, bool > rev_subs;\r
//only get ground terms\r
unsigned tindex = typ_to_subs_index[it->first];\r
for( std::map< unsigned, TNode >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
if( !firstTime ){\r
- Trace("sg-gen-tg-eqc") << ", ";\r
+ Trace("sg-rel-term-debug") << ", ";\r
}else{\r
firstTime = false;\r
- Trace("sg-gen-tg-eqc") << " ";\r
+ Trace("sg-rel-term-debug") << " ";\r
}\r
- Trace("sg-gen-tg-eqc") << it->first << ":x" << it2->first << " -> " << it2->second;\r
+ Trace("sg-rel-term-debug") << it->first << ":x" << it2->first << " -> " << it2->second;\r
Assert( tindex+it2->first<gsubs_terms.size() );\r
gsubs_terms[tindex+it2->first] = it2->second;\r
}\r
}\r
- Trace("sg-gen-tg-eqc") << std::endl;\r
+ Trace("sg-rel-term-debug") << std::endl;\r
d_rel_pattern_subs_index[nn].addSubstitution( r, gsubs_vars, gsubs_terms );\r
}\r
}\r
std::map< TNode, bool > rev_subs;\r
unsigned mode;\r
if( r==0 ){\r
- mode = optReqDistinctVarPatterns() ? 1 : 0;\r
+ mode = optReqDistinctVarPatterns() ? ( 1 << 0 ) : 0;\r
+ mode = mode | (1 << 2 );\r
}else{\r
- mode = (optFilterConfirmation() && optFilterConfirmationOnlyGround() ) ? 2 : 0;\r
+ mode = (optFilterConfirmation() && optFilterConfirmationOnlyGround() ) ? ( 1 << 1 ) : 0;\r
}\r
d_tg_alloc[0].resetMatching( this, d_ccand_eqc[r][i-1][j], mode );\r
if( d_tg_alloc[0].getNextMatch( this, d_ccand_eqc[r][i-1][j], subs, rev_subs ) ){\r
d_match_children_end.clear();\r
d_match_mode = mode;\r
//if this term generalizes, it must generalize a non-ground term\r
- if( mode<2 && s->isGroundEqc( eqc ) && d_status==5 ){\r
- d_match_status = -1;\r
- }\r
+ //if( (d_match_mode & ( 1 << 2 ))!=0 && s->isGroundEqc( eqc ) && d_status==5 ){\r
+ // d_match_status = -1;\r
+ //}\r
}\r
\r
bool TermGenerator::getNextMatch( ConjectureGenerator * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs ) {\r
//a variable\r
if( d_match_status==0 ){\r
d_match_status++;\r
- if( d_match_mode>=2 ){\r
+ if( (d_match_mode & ( 1 << 1 ))!=0 ){\r
//only ground terms\r
if( !s->isGroundEqc( eqc ) ){\r
return false;\r
}\r
+ }else if( (d_match_mode & ( 1 << 2 ))!=0 ){\r
+ //only non-ground terms\r
+ //if( s->isGroundEqc( eqc ) ){\r
+ // return false;\r
+ //}\r
}\r
- if( d_match_mode%2==1 ){\r
+ //store the match : restricted if match_mode.0 = 1\r
+ if( (d_match_mode & ( 1 << 0 ))!=0 ){\r
std::map< TNode, bool >::iterator it = rev_subs.find( eqc );\r
if( it==rev_subs.end() ){\r
rev_subs[eqc] = true;\r
}else{\r
//clean up\r
subs[d_typ].erase( d_status_num );\r
- if( d_match_mode%2==1 ){\r
+ if( (d_match_mode & ( 1 << 0 ))!=0 ){\r
rev_subs.erase( eqc );\r
}\r
return false;\r
//match status\r
int d_match_status;\r
int d_match_status_child_num;\r
- //match mode\r
- //1 : different variables must have different matches\r
- //2 : variables must map to ground terms\r
- //3 : both 1 and 2\r
+ //match mode bits\r
+ //0 : different variables must have different matches\r
+ //1 : variables must map to ground terms\r
+ //2 : variables must map to non-ground terms\r
unsigned d_match_mode;\r
//children\r
std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children;\r
return isGeneralization( patg, pat, subs );\r
}\r
bool isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs );\r
-\r
public: //for property enumeration\r
//process this candidate conjecture\r
void processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth );\r
# forall y. P( c, y )
option varElimQuant /--disable-var-elim-quant bool :default true
disable simple variable elimination for quantified formulas
-option dtVarExpandQuant --dt-var-exp-quant bool :default false
+option dtVarExpandQuant --dt-var-exp-quant bool :default true
expand datatype variables bound to one constructor in quantifiers
option simpleIteLiftQuant /--disable-ite-lift-quant bool :default true
//try to make a matches making the body false\r
Trace("qcf-check-debug") << "Get next match..." << std::endl;\r
while( qi->d_mg->getNextMatch( this, qi ) ){\r
- Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
- qi->debugPrintMatch("qcf-check");\r
- Trace("qcf-check") << std::endl;\r
+ Trace("qcf-inst") << "*** Produced match at effort " << e << " : " << std::endl;\r
+ qi->debugPrintMatch("qcf-inst");\r
+ Trace("qcf-inst") << std::endl;\r
std::vector< int > assigned;\r
if( !qi->isMatchSpurious( this ) ){\r
if( qi->completeMatch( this, assigned ) ){\r
++(d_statistics.d_prop_inst);\r
}\r
}else{\r
- Trace("qcf-check") << " ... Failed to add instantiation" << std::endl;\r
+ Trace("qcf-inst") << " ... Failed to add instantiation" << std::endl;\r
//Assert( false );\r
}\r
}\r
qi->revertMatch( assigned );\r
d_tempCache.clear();\r
}else{\r
- Trace("qcf-check") << " ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
+ Trace("qcf-inst") << " ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
}\r
}else{\r
- Trace("qcf-check") << " ... Spurious instantiation (match is inconsistent)" << std::endl;\r
+ Trace("qcf-inst") << " ... Spurious instantiation (match is inconsistent)" << std::endl;\r
}\r
}\r
if( d_conflict ){\r
for( std::map< Node, bool >::iterator it = qpr.d_phase_reqs.begin(); it != qpr.d_phase_reqs.end(); ++it ){
//Notice() << " " << it->first << " -> " << ( it->second ? "true" : "false" ) << std::endl;
if( it->first.getKind()==EQUAL ){
- if( it->second ){
+ if( it->second && options::varElimQuant() ){
for( int i=0; i<2; i++ ){
int j = i==0 ? 1 : 0;
std::vector< Node >::iterator ita = std::find( args.begin(), args.end(), it->first[i] );
}
}
}
- /*
- else if( options::dtVarExpandQuant() && it->first.getKind()==APPLY_TESTER && it->first[0].getKind()==BOUND_VARIABLE ){
- if( it->second ){
+ else if( it->first.getKind()==APPLY_TESTER ){
+ if( options::dtVarExpandQuant() && it->second && it->first[0].getKind()==BOUND_VARIABLE ){
Trace("dt-var-expand") << "Expand datatype variable based on : " << it->first << std::endl;
std::vector< Node >::iterator ita = std::find( args.begin(), args.end(), it->first[0] );
+ if( ita!=args.end() ){
+ vars.push_back( it->first[0] );
+ Expr testerExpr = it->first.getOperator().toExpr();
+ int index = Datatype::indexOf( testerExpr );
+ const Datatype& dt = Datatype::datatypeOf(testerExpr);
+ const DatatypeConstructor& c = dt[index];
+ std::vector< Node > newChildren;
+ newChildren.push_back( Node::fromExpr( c.getConstructor() ) );
+ std::vector< Node > newVars;
+ for( unsigned j=0; j<c.getNumArgs(); j++ ){
+ TypeNode tn = TypeNode::fromType( c[j].getSelector().getType() );
+ tn = tn[1];
+ Node v = NodeManager::currentNM()->mkBoundVar( tn );
+ newChildren.push_back( v );
+ newVars.push_back( v );
+ }
+ subs.push_back( NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, newChildren ) );
+ Trace("dt-var-expand") << "...apply substitution " << subs[0] << "/" << vars[0] << std::endl;
+ args.erase( ita );
+ args.insert( args.end(), newVars.begin(), newVars.end() );
+ }
}
}
- */
}
if( !vars.empty() ){
Trace("var-elim-quant") << "VE " << vars.size() << "/" << args.size() << std::endl;
}else if( computeOption==COMPUTE_PRENEX ){
return options::prenexQuant() && !options::aggressiveMiniscopeQuant();
}else if( computeOption==COMPUTE_VAR_ELIMINATION ){
- return options::varElimQuant();
+ return options::varElimQuant() || options::dtVarExpandQuant();
}else if( computeOption==COMPUTE_CNF ){
return false;//return options::cnfQuant() ; FIXME
}else if( computeOption==COMPUTE_SPLIT ){
(set-logic ALL_SUPPORTED)
; COMMAND-LINE: --incremental
; EXPECT: unknown
-; EXPECT: unknown
+; EXPECT: unsat
; EXPECT: unknown
(declare-datatypes () ((OptInt0 (Some (value0 Int)) (None))))
(declare-datatypes () ((List0 (Cons (head0 Int) (tail0 List0)) (Nil))))