}
}
-Node CegConjectureSingleInv::getSolution( QuantifiersEngine * qe, TypeNode stn, unsigned i, Node varList ){
+Node CegConjectureSingleInv::getSolution( QuantifiersEngine * qe, unsigned i, TypeNode stn, int& reconstructed ){
Assert( !d_lemmas_produced.empty() );
Node s = constructSolution( i, 0 );
+ const Datatype& dt = ((DatatypeType)(stn).toType()).getDatatype();
+ Node varList = Node::fromExpr( dt.getSygusVarList() );
//TODO : not in grammar
Node prog = d_quant[0][i];
Node prog_app = d_single_inv_app_map[prog];
d_orig_solution = s;
Trace("cegqi-si-debug-sol") << "Solution (pre-rewrite): " << d_orig_solution << std::endl;
s = pullITEs( s );
+ //s = flattenITEs( s );
//do standard rewriting
s = Rewriter::rewrite( s );
s = Rewriter::rewrite( s );
Trace("cegqi-si-debug-sol") << "Solution (post-rewrite): " << s << std::endl;
d_solution = s;
- if( options::cegqiSingleInvReconstruct() ){
+ if( options::cegqiSingleInvReconstruct() && !stn.isNull() ){
collectReconstructNodes( qe->getTermDatabaseSygus(), d_solution, stn, Node::null(), TypeNode::null(), false );
std::vector< TypeNode > rcons_tn;
for( std::map< TypeNode, std::map< Node, bool > >::iterator it = d_rcons_to_process.begin(); it != d_rcons_to_process.end(); ++it ){
Assert( !it->second.empty() );
rcons_tn.push_back( it->first );
}
- /*
bool success;
unsigned index = 0;
do {
if( it->second.empty() ){
to_erase.push_back( it->first );
}else{
- Node n = qe->getTermDatabase()->getEnumerateType( it->first, index );
-
+ Node ns = qe->getTermDatabase()->getEnumerateTerm( it->first, index );
+ Node nb = qe->getTermDatabaseSygus()->sygusToBuiltin( ns, it->first );
+ Node nr = Rewriter::rewrite( nb );//qe->getTermDatabaseSygus()->getNormalized( it->first, nb, false, false );
+ if( it->second.find( nr )!=it->second.end() ){
+ Trace("cegqi-si-rcons") << "...reconstructed " << ns << " for term " << nr << std::endl;
+ d_reconstructed[nr][it->first] = ns;
+ d_reconstructed_op[nr][it->first] = false;
+ setReconstructed( nr, it->first );
+ }
success = false;
}
}
for( unsigned i=0; i<to_erase.size(); i++ ){
+ Trace("cegqi-si-rcons") << "......reconstructed all terms for type " << to_erase[i] << std::endl;
d_rcons_to_process.erase( to_erase[i] );
}
index++;
+ if( index%100==0 ){
+ Trace("cegqi-si-rcons-debug") << "Tried " << index << " for each type." << std::endl;
+ }
+ if( success ){
+ reconstructed = 1;
+ }
}while( !success );
- */
+ }else{
+ reconstructed = 0;
}
if( Trace.isOn("cegqi-si-debug-sol") ){
//debug solution
}
}
+Node CegConjectureSingleInv::flattenITEs( Node n, bool rec ) {
+ if( n.getKind()==ITE ){
+ Trace("csi-simp-debug") << "Flatten ITE : " << n << std::endl;
+ Node ret;
+ Node n0 = rec ? flattenITEs( n[0] ) : n[0];
+ Node n1 = rec ? flattenITEs( n[1] ) : n[1];
+ Node n2 = rec ? flattenITEs( n[2] ) : n[2];
+ if( n0.getKind()==NOT ){
+ ret = NodeManager::currentNM()->mkNode( ITE, n0[0], n2, n1 );
+ }else if( n0.getKind()==AND || n0.getKind()==OR ){
+ std::vector< Node > children;
+ for( unsigned i=1; i<n0.getNumChildren(); i++ ){
+ children.push_back( n0[i] );
+ }
+ Node rem = children.size()==1 ? children[0] : NodeManager::currentNM()->mkNode( n0.getKind(), children );
+ Node ret;
+ if( n0.getKind()==AND ){
+ ret = NodeManager::currentNM()->mkNode( ITE, rem, NodeManager::currentNM()->mkNode( n0[0], n1, n2 ), n2 );
+ }else{
+ ret = NodeManager::currentNM()->mkNode( ITE, rem, n1, NodeManager::currentNM()->mkNode( n0[0], n1, n2 ) );
+ }
+ }else{
+ if( n0.getKind()==ITE ){
+ n0 = NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, n0, n1 ),
+ NodeManager::currentNM()->mkNode( AND, n0.negate(), n2 ) );
+ }else if( n0.getKind()==IFF ){
+ n0 = NodeManager::currentNM()->mkNode( OR, NodeManager::currentNM()->mkNode( AND, n0, n1 ),
+ NodeManager::currentNM()->mkNode( AND, n0.negate(), n1.negate() ) );
+ }else{
+ return NodeManager::currentNM()->mkNode( ITE, n0, n1, n2 );
+ }
+ ret = NodeManager::currentNM()->mkNode( ITE, n0, n1, n2 );
+ }
+ return flattenITEs( ret, false );
+ }else{
+ if( n.getNumChildren()>0 ){
+ std::vector< Node > children;
+ bool childChanged = false;
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ Node nc = flattenITEs( n[i] );
+ children.push_back( nc );
+ childChanged = childChanged || nc!=n[i];
+ }
+ if( !childChanged ){
+ return n;
+ }else{
+ return NodeManager::currentNM()->mkNode( n.getKind(), children );
+ }
+ }else{
+ return n;
+ }
+ }
+}
+
// assign is from literals to booleans
// union_find is from args to values
void CegConjectureSingleInv::collectReconstructNodes( TermDbSygus * tds, Node t, TypeNode stn, Node parent, TypeNode pstn, bool ignoreBoolean ) {
if( ignoreBoolean && t.getType().isBoolean() ){
- if( t.getKind()==OR || t.getKind()==AND || t.getKind()==IFF || t.getKind()==ITE ){
+ if( t.getKind()==OR || t.getKind()==AND || t.getKind()==IFF || t.getKind()==ITE || t.getKind()==NOT ){ //FIXME
for( unsigned i=0; i<t.getNumChildren(); i++ ){
collectReconstructNodes( tds, t[i], stn, parent, pstn, ignoreBoolean );
}
collectReconstructNodes( tds, t[i], stnc, t, stn, ignB );
}
d_reconstructed[t][stn] = Node::fromExpr( dt[arg].getSygusOp() );
+ d_reconstructed_op[t][stn] = true;
processed = true;
}else{
Trace("cegqi-si-rcons-debug") << " Type has kind " << t.getKind() << ", but argument mismatch, with parent " << parent << std::endl;
Trace("cegqi-si-rcons") << "...Reconstruction needed for " << t << " sygus type " << dt.getName() << " with parent " << parent << std::endl;
}else{
d_reconstructed[t][stn] = Node::fromExpr( dt[carg].getSygusOp() );
+ d_reconstructed_op[t][stn] = false;
processed = true;
Trace("cegqi-si-rcons-debug") << " Type has constant." << std::endl;
}
TypeNode stnc;
for( std::map< TypeNode, bool >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
stnc = it2->first;
- d_rcons_graph[ro][it->first][stnc][t].erase( it2->first );
+ d_rcons_graph[ro][it->first][stnc][t].erase( stn );
if( d_rcons_graph[ro][it->first][stnc][t].empty() ){
d_rcons_graph[ro][it->first][stnc].erase( t );
+ }else{
+ Trace("cegqi-si-rcons-debug") << " " << ( r==0 ? "child" : "parent" ) << " " << it->first << " now has " << d_rcons_graph[ro][it->first][stnc][t].size() << std::endl;
}
}
if( d_rcons_graph[ro][it->first][stnc].empty() ){
}
}
+Node CegConjectureSingleInv::getReconstructedSolution( TypeNode stn, Node t ) {
+ std::map< TypeNode, Node >::iterator it = d_reconstructed[t].find( stn );
+ if( it!=d_reconstructed[t].end() ){
+ if( d_reconstructed_op[t][stn] ){
+ std::vector< Node > children;
+ children.push_back( it->second );
+ for( unsigned i=0; i<t.getNumChildren(); i++ ){
+ Node nc = getReconstructedSolution( stn, t[i] );
+ children.push_back( nc );
+ }
+ return NodeManager::currentNM()->mkNode( APPLY_CONSTRUCTOR, children );
+ }else{
+ return it->second;
+ }
+ }else{
+ Trace("cegqi-si-rcons-debug") << "*** error : missing reconstruction for " << t << std::endl;
+ Assert( false );
+ return Node::null();
+ }
+}
+
}
\ No newline at end of file
//check
void check( QuantifiersEngine * qe, std::vector< Node >& lems );
//get solution
- Node getSolution( QuantifiersEngine * qe, TypeNode stn, unsigned i, Node varList );
+ Node getSolution( QuantifiersEngine * qe, unsigned i, TypeNode stn, int& reconstructed );
//solution simplification
void debugTermSize( Node sol, int& t_size, int& num_ite );
Node pullITEs( Node n );
bool pullITECondition( Node root, Node n, std::vector< Node >& conj, Node& t, Node& rem, int depth );
+ Node flattenITEs( Node n, bool rec = true );
Node simplifySolution( QuantifiersEngine * qe, Node sol, std::map< Node, bool >& assign,
std::vector< Node >& vars, std::vector< Node >& subs, std::vector< Node >& args, int status );
bool getAssign( QuantifiersEngine * qe, bool pol, Node n, std::map< Node, bool >& assign, std::vector< Node >& new_assign,
private:
std::map< Node, std::vector< TypeNode > > d_rcons_processed;
std::map< Node, std::map< TypeNode, Node > > d_reconstructed;
+ std::map< Node, std::map< TypeNode, bool > > d_reconstructed_op;
std::map< Node, std::map< TypeNode, std::map< Node, std::map< TypeNode, bool > > > > d_rcons_graph[2];
std::map< TypeNode, std::map< Node, bool > > d_rcons_to_process;
// term t with sygus type st
void collectReconstructNodes( TermDbSygus * tds, Node t, TypeNode stn, Node parent, TypeNode pstn, bool ignoreBoolean );
// set reconstructed
void setReconstructed( Node t, TypeNode stn );
+ // get solution
+ Node getReconstructedSolution( TypeNode stn, Node t );
};
}
}
}
+Node TermDbSygus::sygusToBuiltin( Node n, TypeNode tn ) {
+ std::map< Node, Node >::iterator it = d_sygus_to_builtin[tn].find( n );
+ if( it==d_sygus_to_builtin[tn].end() ){
+ Assert( n.getKind()==APPLY_CONSTRUCTOR );
+ const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
+ unsigned i = Datatype::indexOf( n.getOperator().toExpr() );
+ Assert( n.getNumChildren()==dt[i].getNumArgs() );
+ std::map< TypeNode, int > var_count;
+ std::map< int, Node > pre;
+ for( unsigned j=0; j<n.getNumChildren(); j++ ){
+ pre[j] = sygusToBuiltin( n[j], getArgType( dt[i], j ) );
+ }
+ Node ret = mkGeneric( dt, i, var_count, pre );
+ d_sygus_to_builtin[tn][n] = ret;
+ return ret;
+ }else{
+ return it->second;
+ }
+}
+
Node TermDbSygus::getSygusNormalized( Node n, std::map< TypeNode, int >& var_count, std::map< Node, Node >& subs ) {
return n;
if( n.getKind()==SKOLEM ){
}
}
-Node TermDbSygus::getNormalized( TypeNode t, Node prog, bool do_pre_norm ) {
+Node TermDbSygus::getNormalized( TypeNode t, Node prog, bool do_pre_norm, bool do_post_norm ) {
if( do_pre_norm ){
std::map< TypeNode, int > var_count;
std::map< Node, Node > subs;
if( itn==d_normalized[t].end() ){
Node progr = Node::fromExpr( smt::currentSmtEngine()->expandDefinitions( prog.toExpr() ) );
progr = Rewriter::rewrite( progr );
- std::map< TypeNode, int > var_count;
- std::map< Node, Node > subs;
- progr = getSygusNormalized( progr, var_count, subs );
+ if( do_post_norm ){
+ std::map< TypeNode, int > var_count;
+ std::map< Node, Node > subs;
+ progr = getSygusNormalized( progr, var_count, subs );
+ }
Trace("sygus-sym-break2") << "...rewrites to " << progr << std::endl;
d_normalized[t][prog] = progr;
return progr;