return getFreeVariables(n, fvs, false);
}
+struct HasClosureTag
+{
+};
+struct HasClosureComputedTag
+{
+};
+/** Attribute true for expressions with closures in them */
+typedef expr::Attribute<HasClosureTag, bool> HasClosureAttr;
+typedef expr::Attribute<HasClosureComputedTag, bool> HasClosureComputedAttr;
+
+bool hasClosure(Node n)
+{
+ if (!n.getAttribute(HasClosureComputedAttr()))
+ {
+ bool hasC = false;
+ if (n.isClosure())
+ {
+ hasC = true;
+ }
+ else
+ {
+ for (auto i = n.begin(); i != n.end() && !hasC; ++i)
+ {
+ hasC = hasClosure(*i);
+ }
+ }
+ if (!hasC && n.hasOperator())
+ {
+ hasC = hasClosure(n.getOperator());
+ }
+ n.setAttribute(HasClosureAttr(), hasC);
+ n.setAttribute(HasClosureComputedAttr(), true);
+ return hasC;
+ }
+ return n.getAttribute(HasClosureAttr());
+}
+
bool getFreeVariables(TNode n,
std::unordered_set<Node, NodeHashFunction>& fvs,
bool computeFv)
*/
bool hasFreeVar(TNode n);
+/**
+ * Returns true iff the node n contains a closure, that is, a node
+ * whose kind is FORALL, EXISTS, CHOICE, LAMBDA, or any other closure currently
+ * supported.
+ * @param n The node under investigation
+ * @return true iff this node contains a closure.
+ */
+bool hasClosure(Node n);
+
/**
* Get the free variables in n, that is, the subterms of n of kind
* BOUND_VARIABLE that are not bound in n, adds these to fvs.
#include "theory/bv/theory_bv_rewriter.h"
#include "theory/logic_info.h"
#include "theory/quantifiers/fun_def_process.h"
-#include "theory/quantifiers/quantifiers_rewriter.h"
#include "theory/quantifiers/single_inv_partition.h"
#include "theory/quantifiers/sygus/sygus_abduct.h"
#include "theory/quantifiers/sygus/synth_engine.h"
// this is necessary until preprocessing passes explicitly record how they rewrite quantified formulas
if( hardFailure && !n.isConst() && n.getKind() != kind::LAMBDA ){
Notice() << "SmtEngine::checkModel(): -- relax check model wrt quantified formulas..." << endl;
- AlwaysAssert(quantifiers::QuantifiersRewriter::containsQuantifiers(n));
+ AlwaysAssert(expr::hasClosure(n));
Warning() << "Warning : SmtEngine::checkModel(): cannot check simplified assertion : " << n << endl;
continue;
}
void CegInstantiator::presolve( Node q ) {
//at preregister time, add proxy of obvious instantiations up front, which helps learning during preprocessing
//only if no nested quantifiers
- if( !QuantifiersRewriter::containsQuantifiers( q[1] ) ){
+ if (!expr::hasClosure(q[1]))
+ {
std::vector< Node > ps_vars;
std::map< Node, std::vector< Node > > teq;
for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
Trace("cbqi-nqe") << " " << ceq << std::endl;
Trace("cbqi-nqe") << " " << d_nested_qe[ceq] << std::endl;
//should not contain quantifiers
- Assert(!QuantifiersRewriter::containsQuantifiers(d_nested_qe[ceq]));
+ Assert(!expr::hasClosure(d_nested_qe[ceq]));
}
Assert(d_quantEngine->getTermUtil()->d_inst_constants[q].size()
== inst_terms.size());
if( itv!=visited[tindex].end() ){
return itv->second;
}
- if( containsQuantifiers( n ) ){
+ if (expr::hasClosure(n))
+ {
Node ret = n;
if (topLevel
&& options::prenexQuant() == options::PrenexQuantMode::DISJ_NORMAL
return rn;
}
-struct ContainsQuantAttributeId {};
-typedef expr::Attribute<ContainsQuantAttributeId, uint64_t> ContainsQuantAttribute;
-
-// check if the given node contains a universal quantifier
-bool QuantifiersRewriter::containsQuantifiers( Node n ){
- if( n.hasAttribute(ContainsQuantAttribute()) ){
- return n.getAttribute(ContainsQuantAttribute())==1;
- }else if( n.getKind() == kind::FORALL ){
- return true;
- }else{
- bool cq = false;
- for( unsigned i = 0; i < n.getNumChildren(); ++i ){
- if( containsQuantifiers( n[i] ) ){
- cq = true;
- break;
- }
- }
- ContainsQuantAttribute cqa;
- n.setAttribute(cqa, cq ? 1 : 0);
- return cq;
- }
-}
bool QuantifiersRewriter::isPrenexNormalForm( Node n ) {
if( n.getKind()==FORALL ){
return n[1].getKind()!=FORALL && isPrenexNormalForm( n[1] );
}else if( n.getKind()==NOT ){
return n[0].getKind()!=NOT && isPrenexNormalForm( n[0] );
}else{
- return !containsQuantifiers( n );
+ return !expr::hasClosure(n);
}
}
}else{
//check if it contains a quantifier as a subterm
//if so, we will write this node
- if( containsQuantifiers( n ) ){
+ if (expr::hasClosure(n))
+ {
if( ( n.getKind()==kind::ITE && n.getType().isBoolean() ) || ( n.getKind()==kind::EQUAL && n[0].getType().isBoolean() ) ){
if( options::preSkolemQuantAgg() ){
Node nn;
static Node preSkolemizeQuantifiers(Node n, bool polarity, std::vector< TypeNode >& fvTypes, std::vector<TNode>& fvs);
public:
static Node rewriteRewriteRule( Node r );
- static bool containsQuantifiers( Node n );
static bool isPrenexNormalForm( Node n );
/** preprocess
*