From: ajreynol Date: Fri, 23 Jan 2015 19:40:57 +0000 (+0100) Subject: Refactor sygus arg nf. Minor improvements. X-Git-Tag: cvc5-1.0.0~6426 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e1e393dff082ad115ba198c32990235fb991eb13;p=cvc5.git Refactor sygus arg nf. Minor improvements. --- diff --git a/src/theory/datatypes/datatypes_sygus.cpp b/src/theory/datatypes/datatypes_sygus.cpp index b68206b48..c7b3e69c4 100644 --- a/src/theory/datatypes/datatypes_sygus.cpp +++ b/src/theory/datatypes/datatypes_sygus.cpp @@ -109,7 +109,6 @@ void SygusSplit::getSygusSplits( Node n, const Datatype& dt, std::vector< Node > int sIndex = -1; Node arg1; Kind parentKind = UNDEFINED_KIND; - bool isPComm = false; TypeNode tnnp; if( n.getKind()==APPLY_SELECTOR_TOTAL ){ Node op = n.getOperator(); @@ -125,8 +124,6 @@ void SygusSplit::getSygusSplits( Node n, const Datatype& dt, std::vector< Node > //relationships between arguments if( isKindArg( tnnp, csIndex ) ){ - parentKind = d_arg_kind[tnnp][csIndex]; - isPComm = isComm( parentKind ); if( sIndex==1 ){ //if commutative, normalize based on term ordering (the constructor index of left arg must be less than or equal to the right arg) Trace("sygus-split-debug") << "Commutative operator : " << parentKind << std::endl; @@ -154,58 +151,24 @@ void SygusSplit::getSygusSplits( Node n, const Datatype& dt, std::vector< Node > } if( addSplit ){ Node test = DatatypesRewriter::mkTester( n, i, dt ); - if( options::sygusNormalFormArg() ){ - //strengthen first argument - if( !arg1.isNull() ){ - //arguments that can be removed - std::map< int, bool > rem_arg; - if( isComm( parentKind ) ){ - for( unsigned j=0; ji ){ - //based on commutativity - // use term ordering : constructor index of first argument is not greater than constructor index of second argument - rem_arg[j] = true; - }else{ - if( parentKind!=UNDEFINED_KIND && dt[i].getNumArgs()==0 && dt[j].getNumArgs()==0 ){ - Node nr = NodeManager::currentNM()->mkNode( parentKind, dt[j].getSygusOp(), dt[i].getSygusOp() ); - Node nrr = Rewriter::rewrite( nr ); - Trace("sygus-split-debug") << " Test constant args : " << nr << " rewrites to " << nrr << std::endl; - //based on rewriting - // if rewriting the two arguments gives an operator that is in the parent syntax, remove the redundancy - if( hasOp( tnnp, nrr ) ){ - Trace("sygus-nf") << "* Sygus norm : simplify based on rewrite " << nr << " -> " << nrr << std::endl; - rem_arg[j] = true; - } - } - } - } - } - } - - if( !rem_arg.empty() ){ - std::vector< Node > lem_c; - for( unsigned j=0; jmkNode( OR, lem_c ); - Trace("sygus-str") << "...strengthen corresponding first argument of " << test << " : " << argStr << std::endl; - test = NodeManager::currentNM()->mkNode( AND, test, argStr ); - } + + //check if we can strengthen the first argument + if( !arg1.isNull() ){ + std::map< int, std::vector< int > >::iterator it = d_sygus_pc_arg_pos[tnn][csIndex].find( i ); + if( it!=d_sygus_pc_arg_pos[tnn][csIndex].end() ){ + Assert( !it->second.empty() ); + std::vector< Node > lem_c; + for( unsigned j=0; jsecond.size(); j++ ){ + lem_c.push_back( DatatypesRewriter::mkTester( arg1, it->second[j], dt ) ); } + Node argStr = lem_c.size()==1 ? lem_c[0] : NodeManager::currentNM()->mkNode( OR, lem_c ); + Trace("sygus-str") << "...strengthen corresponding first argument of " << test << " : " << argStr << std::endl; + test = NodeManager::currentNM()->mkNode( AND, test, argStr ); } } - if( !test.isNull() ){ - d_splits[n].push_back( test ); - Trace("sygus-split-debug2") << "SUCCESS" << std::endl; - Trace("sygus-split") << "Disjunct #" << d_splits[n].size() << " : " << test << std::endl; - } + d_splits[n].push_back( test ); + Trace("sygus-split-debug2") << "SUCCESS" << std::endl; + Trace("sygus-split") << "Disjunct #" << d_splits[n].size() << " : " << test << std::endl; }else{ Trace("sygus-split-debug2") << "redundant argument" << std::endl; } @@ -314,6 +277,67 @@ void SygusSplit::registerSygusTypeConstructorArg( TypeNode tnn, const Datatype& } d_sygus_pc_nred[tnn][csIndex][sIndex].push_back( addSplit ); } + //also compute argument relationships + if( options::sygusNormalFormArg() ){ + if( isKindArg( tnnp, csIndex ) && pdt[csIndex].getNumArgs()==2 ){ + int osIndex = sIndex==0 ? 1 : 0; + if( isArgDatatype( pdt[csIndex], osIndex, dt ) ){ + registerSygusTypeConstructorArg( tnn, dt, tnnp, pdt, csIndex, osIndex ); + if( sIndex==0 ){ + Assert( d_sygus_pc_nred[tnn][csIndex].find( sIndex )!=d_sygus_pc_nred[tnn][csIndex].end() ); + Assert( d_sygus_pc_nred[tnn][csIndex].find( osIndex )!=d_sygus_pc_nred[tnn][csIndex].end() ); + + Kind parentKind = d_arg_kind[tnnp][csIndex]; + bool isPComm = isComm( parentKind ); + for( unsigned i=0; i rem_arg; + if( isComm( parentKind ) ){ + for( unsigned j=0; ji ){ + //based on commutativity + // use term ordering : constructor index of first argument is not greater than constructor index of second argument + rem_arg[j] = true; + }else{ + if( parentKind!=UNDEFINED_KIND && dt[i].getNumArgs()==0 && dt[j].getNumArgs()==0 ){ + Node nr = NodeManager::currentNM()->mkNode( parentKind, dt[j].getSygusOp(), dt[i].getSygusOp() ); + Node nrr = Rewriter::rewrite( nr ); + Trace("sygus-split-debug") << " Test constant args : " << nr << " rewrites to " << nrr << std::endl; + //based on rewriting + // if rewriting the two arguments gives an operator that is in the parent syntax, remove the redundancy + if( hasOp( tnnp, nrr ) ){ + Trace("sygus-nf") << "* Sygus norm : simplify based on rewrite " << nr << " -> " << nrr << std::endl; + rem_arg[j] = true; + } + } + } + } + } + } + if( !rem_arg.empty() ){ + d_sygus_pc_arg_pos[tnn][csIndex][i].clear(); + Trace("sygus-split-debug") << "Possibilities for first argument of " << parentKind << ", when second argument is " << dt[i].getName() << " : " << std::endl; + for( unsigned j=0; j > d_splits; std::map< TypeNode, std::vector< bool > > d_sygus_nred; std::map< TypeNode, std::map< int, std::map< int, std::vector< bool > > > > d_sygus_pc_nred; + std::map< TypeNode, std::map< int, std::map< int, std::vector< int > > > > d_sygus_pc_arg_pos; //information for builtin types std::map< TypeNode, std::map< int, Node > > d_type_value; std::map< TypeNode, Node > d_type_max_value;