// formulas at preprocess time.
//
// We don't want to set this option when we are in logics that contain ALL.
- if (!logic.hasEverything() && logic.isTheoryEnabled(THEORY_STRINGS))
+ //
+ // We also must enable stringExp if reElimAgg is true, since this introduces
+ // bounded quantifiers during preprocessing.
+ if ((!logic.hasEverything() && logic.isTheoryEnabled(THEORY_STRINGS))
+ || opts.strings.regExpElimAgg)
{
// If the user explicitly set a logic that includes strings, but is not
// the generic "ALL" logic, then enable stringsExp.
#include "theory/strings/regexp_elim.h"
+#include "expr/bound_var_manager.h"
#include "options/strings_options.h"
#include "proof/proof_node_manager.h"
#include "theory/rewriter.h"
namespace theory {
namespace strings {
+/**
+ * Attributes used for constructing unique bound variables. The following
+ * attributes are used to construct (deterministic) bound variables for
+ * eliminations within eliminateConcat and eliminateStar respectively.
+ */
+struct ReElimConcatIndexAttributeId
+{
+};
+typedef expr::Attribute<ReElimConcatIndexAttributeId, Node>
+ ReElimConcatIndexAttribute;
+struct ReElimStarIndexAttributeId
+{
+};
+typedef expr::Attribute<ReElimStarIndexAttributeId, Node>
+ ReElimStarIndexAttribute;
+
RegExpElimination::RegExpElimination(bool isAgg,
ProofNodeManager* pnm,
context::Context* c)
Node RegExpElimination::eliminateConcat(Node atom, bool isAgg)
{
NodeManager* nm = NodeManager::currentNM();
+ BoundVarManager* bvm = nm->getBoundVarManager();
Node x = atom[0];
Node lenx = nm->mkNode(STRING_LENGTH, x);
Node re = atom[1];
}
// if the gap after this one is strict, we need a non-greedy find
// thus, we add a symbolic constant
- Node k = nm->mkBoundVar(nm->integerType());
+ Node cacheVal =
+ BoundVarManager::getCacheValue(atom, nm->mkConst(Rational(i)));
+ TypeNode intType = nm->integerType();
+ Node k =
+ bvm->mkBoundVar<ReElimConcatIndexAttribute>(cacheVal, intType);
non_greedy_find_vars.push_back(k);
prev_end = nm->mkNode(PLUS, prev_end, k);
}
}
else
{
- k = nm->mkBoundVar(nm->integerType());
+ Node cacheVal =
+ BoundVarManager::getCacheValue(atom, nm->mkConst(Rational(i)));
+ TypeNode intType = nm->integerType();
+ k = bvm->mkBoundVar<ReElimConcatIndexAttribute>(cacheVal, intType);
Node bound =
nm->mkNode(AND,
nm->mkNode(LEQ, zero, k),
// only aggressive rewrites below here
NodeManager* nm = NodeManager::currentNM();
+ BoundVarManager* bvm = nm->getBoundVarManager();
Node x = atom[0];
Node lenx = nm->mkNode(STRING_LENGTH, x);
Node re = atom[1];
}
bool lenOnePeriod = true;
std::vector<Node> char_constraints;
- Node index = nm->mkBoundVar(nm->integerType());
+ TypeNode intType = nm->integerType();
+ Node index = bvm->mkBoundVar<ReElimStarIndexAttribute>(atom, intType);
Node substr_ch =
nm->mkNode(STRING_SUBSTR, x, index, nm->mkConst(Rational(1)));
substr_ch = Rewriter::rewrite(substr_ch);