summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/cvc4cpp.cpp173
-rw-r--r--src/api/cvc4cpp.h51
-rw-r--r--src/api/cvc4cppkind.h26
-rw-r--r--src/expr/expr_manager_template.cpp27
-rw-r--r--src/theory/strings/theory_strings_rewriter.cpp16
-rw-r--r--src/util/regexp.h16
6 files changed, 212 insertions, 97 deletions
diff --git a/src/api/cvc4cpp.cpp b/src/api/cvc4cpp.cpp
index 123613797..ddb17c3a7 100644
--- a/src/api/cvc4cpp.cpp
+++ b/src/api/cvc4cpp.cpp
@@ -1444,6 +1444,14 @@ DatatypeSelector::DatatypeSelector(const CVC4::DatatypeConstructorArg& stor)
DatatypeSelector::~DatatypeSelector() {}
+bool DatatypeSelector::isResolved() const { return d_stor->isResolved(); }
+
+OpTerm DatatypeSelector::getSelectorTerm() const
+{
+ CVC4_API_CHECK(isResolved()) << "Expected resolved datatype selector.";
+ return d_stor->getSelector();
+}
+
std::string DatatypeSelector::toString() const
{
std::stringstream ss;
@@ -1478,10 +1486,10 @@ DatatypeConstructor::~DatatypeConstructor() {}
bool DatatypeConstructor::isResolved() const { return d_ctor->isResolved(); }
-Term DatatypeConstructor::getConstructorTerm() const
+OpTerm DatatypeConstructor::getConstructorTerm() const
{
CVC4_API_CHECK(isResolved()) << "Expected resolved datatype constructor.";
- return Term(d_ctor->getConstructor());
+ return OpTerm(d_ctor->getConstructor());
}
DatatypeSelector DatatypeConstructor::operator[](const std::string& name) const
@@ -1498,7 +1506,7 @@ DatatypeSelector DatatypeConstructor::getSelector(const std::string& name) const
return (*d_ctor)[name];
}
-Term DatatypeConstructor::getSelectorTerm(const std::string& name) const
+OpTerm DatatypeConstructor::getSelectorTerm(const std::string& name) const
{
// CHECK: cons with name exists?
// CHECK: is resolved?
@@ -1627,7 +1635,7 @@ DatatypeConstructor Datatype::getConstructor(const std::string& name) const
return (*d_dtype)[name];
}
-Term Datatype::getConstructorTerm(const std::string& name) const
+OpTerm Datatype::getConstructorTerm(const std::string& name) const
{
// CHECK: cons with name exists?
// CHECK: is resolved?
@@ -2451,40 +2459,41 @@ void Solver::checkMkTerm(Kind kind, uint32_t nchildren) const
<< "Only operator-style terms are created with mkTerm(), "
"to create variables and constants see mkVar(), mkBoundVar(), "
"and mkConst().";
- if (nchildren)
- {
- const uint32_t n =
- nchildren - (mk == CVC4::kind::metakind::PARAMETERIZED ? 1 : 0);
- CVC4_API_KIND_CHECK_EXPECTED(n >= minArity(kind) && n <= maxArity(kind),
- kind)
- << "Terms with kind " << kindToString(kind) << " must have at least "
- << minArity(kind) << " children and at most " << maxArity(kind)
- << " children (the one under construction has " << n << ")";
- }
+ CVC4_API_KIND_CHECK_EXPECTED(
+ nchildren >= minArity(kind) && nchildren <= maxArity(kind), kind)
+ << "Terms with kind " << kindToString(kind) << " must have at least "
+ << minArity(kind) << " children and at most " << maxArity(kind)
+ << " children (the one under construction has " << nchildren << ")";
}
-void Solver::checkMkOpTerm(OpTerm opTerm, uint32_t nchildren) const
+void Solver::checkMkOpTerm(Kind kind, OpTerm opTerm, uint32_t nchildren) const
{
- const Kind kind = opTerm.getKind();
Assert(isDefinedIntKind(extToIntKind(kind)));
const CVC4::Kind int_kind = extToIntKind(kind);
- const CVC4::Kind int_op_kind =
+ const CVC4::Kind int_op_kind = opTerm.d_expr->getKind();
+ const CVC4::Kind int_op_to_kind =
NodeManager::operatorToKind(opTerm.d_expr->getNode());
- CVC4_API_ARG_CHECK_EXPECTED(int_kind == kind::BUILTIN
- || CVC4::kind::metaKindOf(int_op_kind)
- == kind::metakind::PARAMETERIZED,
- opTerm)
+ CVC4_API_ARG_CHECK_EXPECTED(
+ int_kind == int_op_to_kind
+ || (kind == APPLY_CONSTRUCTOR
+ && int_op_to_kind == CVC4::Kind::UNDEFINED_KIND)
+ || (kind == APPLY_SELECTOR
+ && int_op_to_kind == CVC4::Kind::UNDEFINED_KIND)
+ || (kind == APPLY_UF && int_op_to_kind == CVC4::Kind::UNDEFINED_KIND),
+ kind)
+ << "kind that matches kind associated with given operator term";
+ CVC4_API_ARG_CHECK_EXPECTED(
+ int_op_kind == CVC4::kind::BUILTIN
+ || CVC4::kind::metaKindOf(int_kind) == kind::metakind::PARAMETERIZED,
+ opTerm)
<< "This term constructor is for parameterized kinds only";
- if (nchildren)
- {
- uint32_t min_arity = ExprManager::minArity(int_op_kind);
- uint32_t max_arity = ExprManager::maxArity(int_op_kind);
- CVC4_API_KIND_CHECK_EXPECTED(
- nchildren >= min_arity && nchildren <= max_arity, kind)
- << "Terms with kind " << kindToString(kind) << " must have at least "
- << min_arity << " children and at most " << max_arity
- << " children (the one under construction has " << nchildren << ")";
- }
+ uint32_t min_arity = ExprManager::minArity(int_kind);
+ uint32_t max_arity = ExprManager::maxArity(int_kind);
+ CVC4_API_KIND_CHECK_EXPECTED(nchildren >= min_arity && nchildren <= max_arity,
+ kind)
+ << "Terms with kind " << kindToString(kind) << " must have at least "
+ << min_arity << " children and at most " << max_arity
+ << " children (the one under construction has " << nchildren << ")";
}
Term Solver::mkTerm(Kind kind) const
@@ -2611,13 +2620,30 @@ Term Solver::mkTerm(Kind kind, const std::vector<Term>& children) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, Term child) const
+Term Solver::mkTerm(Kind kind, OpTerm opTerm) const
+{
+ try
+ {
+ checkMkOpTerm(kind, opTerm, 0);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(int_kind, *opTerm.d_expr);
+ (void)res.d_expr->getType(true); /* kick off type checking */
+ return res;
+ }
+ catch (const CVC4::TypeCheckingException& e)
+ {
+ throw CVC4ApiException(e.getMessage());
+ }
+}
+
+Term Solver::mkTerm(Kind kind, OpTerm opTerm, Term child) const
{
try
{
CVC4_API_ARG_CHECK_EXPECTED(!child.isNull(), child) << "non-null term";
- checkMkOpTerm(opTerm, 1);
- Term res = d_exprMgr->mkExpr(*opTerm.d_expr, *child.d_expr);
+ checkMkOpTerm(kind, opTerm, 1);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(int_kind, *opTerm.d_expr, *child.d_expr);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2627,15 +2653,16 @@ Term Solver::mkTerm(OpTerm opTerm, Term child) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2) const
+Term Solver::mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2) const
{
try
{
CVC4_API_ARG_CHECK_EXPECTED(!child1.isNull(), child1) << "non-null term";
CVC4_API_ARG_CHECK_EXPECTED(!child2.isNull(), child2) << "non-null term";
- checkMkOpTerm(opTerm, 2);
- Term res =
- d_exprMgr->mkExpr(*opTerm.d_expr, *child1.d_expr, *child2.d_expr);
+ checkMkOpTerm(kind, opTerm, 2);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(
+ int_kind, *opTerm.d_expr, *child1.d_expr, *child2.d_expr);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2645,16 +2672,21 @@ Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2, Term child3) const
+Term Solver::mkTerm(
+ Kind kind, OpTerm opTerm, Term child1, Term child2, Term child3) const
{
try
{
CVC4_API_ARG_CHECK_EXPECTED(!child1.isNull(), child1) << "non-null term";
CVC4_API_ARG_CHECK_EXPECTED(!child2.isNull(), child2) << "non-null term";
CVC4_API_ARG_CHECK_EXPECTED(!child3.isNull(), child3) << "non-null term";
- checkMkOpTerm(opTerm, 3);
- Term res = d_exprMgr->mkExpr(
- *opTerm.d_expr, *child1.d_expr, *child2.d_expr, *child3.d_expr);
+ checkMkOpTerm(kind, opTerm, 3);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(int_kind,
+ *opTerm.d_expr,
+ *child1.d_expr,
+ *child2.d_expr,
+ *child3.d_expr);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2664,7 +2696,9 @@ Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2, Term child3) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, const std::vector<Term>& children) const
+Term Solver::mkTerm(Kind kind,
+ OpTerm opTerm,
+ const std::vector<Term>& children) const
{
try
{
@@ -2674,9 +2708,10 @@ Term Solver::mkTerm(OpTerm opTerm, const std::vector<Term>& children) const
!children[i].isNull(), "parameter term", children[i], i)
<< "non-null term";
}
- checkMkOpTerm(opTerm, children.size());
+ checkMkOpTerm(kind, opTerm, children.size());
+ const CVC4::Kind int_kind = extToIntKind(kind);
std::vector<Expr> echildren = termVectorToExprs(children);
- Term res = d_exprMgr->mkExpr(*opTerm.d_expr, echildren);
+ Term res = d_exprMgr->mkExpr(int_kind, *opTerm.d_expr, echildren);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2691,16 +2726,26 @@ Term Solver::mkTuple(const std::vector<Sort>& sorts,
{
CVC4_API_CHECK(sorts.size() == terms.size())
<< "Expected the same number of sorts and elements";
- std::vector<Term> args;
- for (size_t i = 0, size = sorts.size(); i < size; i++)
+ try
{
- args.push_back(ensureTermSort(terms[i], sorts[i]));
- }
+ std::vector<CVC4::Expr> args;
+ for (size_t i = 0, size = sorts.size(); i < size; i++)
+ {
+ args.push_back(*(ensureTermSort(terms[i], sorts[i])).d_expr);
+ }
- Sort s = mkTupleSort(sorts);
- Datatype dt = s.getDatatype();
- args.insert(args.begin(), dt[0].getConstructorTerm());
- return mkTerm(APPLY_CONSTRUCTOR, args);
+ Sort s = mkTupleSort(sorts);
+ Datatype dt = s.getDatatype();
+ Term res = d_exprMgr->mkExpr(extToIntKind(APPLY_CONSTRUCTOR),
+ *dt[0].getConstructorTerm().d_expr,
+ args);
+ (void)res.d_expr->getType(true); /* kick off type checking */
+ return res;
+ }
+ catch (const CVC4::TypeCheckingException& e)
+ {
+ throw CVC4ApiException(e.getMessage());
+ }
}
std::vector<Expr> Solver::termVectorToExprs(
@@ -3458,28 +3503,32 @@ void Solver::setOption(const std::string& option,
}
}
-Term Solver::ensureTermSort(const Term& t, const Sort& s) const
+Term Solver::ensureTermSort(const Term& term, const Sort& sort) const
{
- CVC4_API_CHECK(t.getSort() == s || (t.getSort().isInteger() && s.isReal()))
+ CVC4_API_CHECK(term.getSort() == sort
+ || (term.getSort().isInteger() && sort.isReal()))
<< "Expected conversion from Int to Real";
- if (t.getSort() == s)
+ Sort t = term.getSort();
+ if (term.getSort() == sort)
{
- return t;
+ return term;
}
// Integers are reals, too
- Assert(t.getSort().isReal());
- Term res = t;
- if (t.getSort().isInteger())
+ Assert(t.isReal());
+ Term res = term;
+ if (t.isInteger())
{
// Must cast to Real to ensure correct type is passed to parametric type
// constructors. We do this cast using division with 1. This has the
// advantage wrt using TO_REAL since (constant) division is always included
// in the theory.
- res = mkTerm(DIVISION, *t.d_expr, mkReal(1));
+ res = Term(d_exprMgr->mkExpr(extToIntKind(DIVISION),
+ *res.d_expr,
+ d_exprMgr->mkConst(CVC4::Rational(1))));
}
- Assert(res.getSort() == s);
+ Assert(res.getSort() == sort);
return res;
}
diff --git a/src/api/cvc4cpp.h b/src/api/cvc4cpp.h
index a06f2e415..b8da070fc 100644
--- a/src/api/cvc4cpp.h
+++ b/src/api/cvc4cpp.h
@@ -1100,6 +1100,17 @@ class CVC4_PUBLIC DatatypeSelector
~DatatypeSelector();
/**
+ * @return true if this datatype selector has been resolved.
+ */
+ bool isResolved() const;
+
+ /**
+ * Get the selector operator of this datatype selector.
+ * @return the selector operator
+ */
+ OpTerm getSelectorTerm() const;
+
+ /**
* @return a string representation of this datatype selector
*/
std::string toString() const;
@@ -1154,7 +1165,7 @@ class CVC4_PUBLIC DatatypeConstructor
* Get the constructor operator of this datatype constructor.
* @return the constructor operator
*/
- Term getConstructorTerm() const;
+ OpTerm getConstructorTerm() const;
/**
* Get the datatype selector with the given name.
@@ -1173,7 +1184,7 @@ class CVC4_PUBLIC DatatypeConstructor
* @param name the name of the datatype selector
* @return a term representing the datatype selector with the given name
*/
- Term getSelectorTerm(const std::string& name) const;
+ OpTerm getSelectorTerm(const std::string& name) const;
/**
* @return a string representation of this datatype constructor
@@ -1320,7 +1331,7 @@ class CVC4_PUBLIC Datatype
* similarly-named constructors, the
* first is returned.
*/
- Term getConstructorTerm(const std::string& name) const;
+ OpTerm getConstructorTerm(const std::string& name) const;
/** Get the number of constructors for this Datatype. */
size_t getNumConstructors() const;
@@ -1725,43 +1736,59 @@ class CVC4_PUBLIC Solver
Term mkTerm(Kind kind, const std::vector<Term>& children) const;
/**
- * Create unary term from a given operator term.
+ * Create nullary term of given kind from a given operator term.
+ * Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
+ * @param the operator term
+ * @return the Term
+ */
+ Term mkTerm(Kind kind, OpTerm opTerm) const;
+
+ /**
+ * Create unary term of given kind from a given operator term.
* Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
* @param the operator term
* @child the child of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, Term child) const;
+ Term mkTerm(Kind kind, OpTerm opTerm, Term child) const;
/**
- * Create binary term from a given operator term.
+ * Create binary term of given kind from a given operator term.
+ * @param kind the kind of the term
* Create operator terms with mkOpTerm().
* @param the operator term
* @child1 the first child of the term
* @child2 the second child of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, Term child1, Term child2) const;
+ Term mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2) const;
/**
- * Create ternary term from a given operator term.
+ * Create ternary term of given kind from a given operator term.
* Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
* @param the operator term
* @child1 the first child of the term
* @child2 the second child of the term
* @child3 the third child of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, Term child1, Term child2, Term child3) const;
+ Term mkTerm(
+ Kind kind, OpTerm opTerm, Term child1, Term child2, Term child3) const;
/**
- * Create n-ary term from a given operator term.
+ * Create n-ary term of given kind from a given operator term.
* Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
* @param the operator term
* @children the children of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, const std::vector<Term>& children) const;
+ Term mkTerm(Kind kind,
+ OpTerm opTerm,
+ const std::vector<Term>& children) const;
/**
* Create a tuple term. Terms are automatically converted if sorts are
@@ -2485,7 +2512,7 @@ class CVC4_PUBLIC Solver
/* Helper to convert a vector of sorts to internal types. */
std::vector<Expr> termVectorToExprs(const std::vector<Term>& vector) const;
/* Helper to check for API misuse in mkTerm functions. */
- void checkMkOpTerm(OpTerm opTerm, uint32_t nchildren) const;
+ void checkMkOpTerm(Kind kind, OpTerm opTerm, uint32_t nchildren) const;
/* Helper to check for API misuse in mkOpTerm functions. */
void checkMkTerm(Kind kind, uint32_t nchildren) const;
/* Helper for mk-functions that call d_exprMgr->mkConst(). */
diff --git a/src/api/cvc4cppkind.h b/src/api/cvc4cppkind.h
index a7f6926bb..4e69ddfe1 100644
--- a/src/api/cvc4cppkind.h
+++ b/src/api/cvc4cppkind.h
@@ -1649,30 +1649,32 @@ enum CVC4_PUBLIC Kind : int32_t
/**
* Constructor application.
* Paramters: n > 0
- * -[1]: Constructor
+ * -[1]: Constructor (operator term)
* -[2]..[n]: Parameters to the constructor
* Create with:
- * mkTerm(Kind kind)
- * mkTerm(Kind kind, Term child)
- * mkTerm(Kind kind, Term child1, Term child2)
- * mkTerm(Kind kind, Term child1, Term child2, Term child3)
- * mkTerm(Kind kind, const std::vector<Term>& children)
+ * mkTerm(Kind kind, OpTerm opTerm)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2, Term child3)
+ * mkTerm(Kind kind, OpTerm opTerm, const std::vector<Term>& children)
*/
- APPLY_SELECTOR,
+ APPLY_CONSTRUCTOR,
/**
* Datatype selector application.
* Parameters: 1
- * -[1]: Datatype term (undefined if mis-applied)
+ * -[1]: Selector (operator term)
+ * -[2]: Datatype term (undefined if mis-applied)
* Create with:
- * mkTerm(Kind kind, Term child)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child)
*/
- APPLY_CONSTRUCTOR,
+ APPLY_SELECTOR,
/**
* Datatype selector application.
* Parameters: 1
- * -[1]: Datatype term (defined rigidly if mis-applied)
+ * -[1]: Selector (operator term)
+ * -[2]: Datatype term (defined rigidly if mis-applied)
* Create with:
- * mkTerm(Kind kind, Term child)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child)
*/
APPLY_SELECTOR_TOTAL,
/**
diff --git a/src/expr/expr_manager_template.cpp b/src/expr/expr_manager_template.cpp
index e6b89b498..d0d36508f 100644
--- a/src/expr/expr_manager_template.cpp
+++ b/src/expr/expr_manager_template.cpp
@@ -301,21 +301,30 @@ Expr ExprManager::mkExpr(Kind kind, Expr child1, Expr child2, Expr child3,
}
}
-Expr ExprManager::mkExpr(Kind kind, const std::vector<Expr>& children) {
+Expr ExprManager::mkExpr(Kind kind, const std::vector<Expr>& children)
+{
+ const size_t nchildren = children.size();
const kind::MetaKind mk = kind::metaKindOf(kind);
- const unsigned n = children.size() - (mk == kind::metakind::PARAMETERIZED ? 1 : 0);
PrettyCheckArgument(
- mk == kind::metakind::PARAMETERIZED ||
- mk == kind::metakind::OPERATOR, kind,
+ mk == kind::metakind::PARAMETERIZED || mk == kind::metakind::OPERATOR,
+ kind,
"Only operator-style expressions are made with mkExpr(); "
"to make variables and constants, see mkVar(), mkBoundVar(), "
"and mkConst().");
PrettyCheckArgument(
- n >= minArity(kind) && n <= maxArity(kind), kind,
- "Exprs with kind %s must have at least %u children and "
- "at most %u children (the one under construction has %u)",
- kind::kindToString(kind).c_str(),
- minArity(kind), maxArity(kind), n);
+ mk != kind::metakind::PARAMETERIZED || nchildren > 0,
+ kind,
+ "Terms with kind %s must have an operator expression as first argument",
+ kind::kindToString(kind).c_str());
+ const size_t n = nchildren - (mk == kind::metakind::PARAMETERIZED ? 1 : 0);
+ PrettyCheckArgument(n >= minArity(kind) && n <= maxArity(kind),
+ kind,
+ "Exprs with kind %s must have at least %u children and "
+ "at most %u children (the one under construction has %u)",
+ kind::kindToString(kind).c_str(),
+ minArity(kind),
+ maxArity(kind),
+ n);
NodeManagerScope nms(d_nodeManager);
diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp
index 3ec38e306..60084d535 100644
--- a/src/theory/strings/theory_strings_rewriter.cpp
+++ b/src/theory/strings/theory_strings_rewriter.cpp
@@ -2049,8 +2049,7 @@ Node TheoryStringsRewriter::rewriteContains( Node node ) {
if( node[0][i].isConst() ){
CVC4::String s = node[0][i].getConst<String>();
// if no overlap, we can split into disjunction
- if (t.find(s) == std::string::npos && s.overlap(t) == 0
- && t.overlap(s) == 0)
+ if (s.noOverlapWith(t))
{
std::vector<Node> nc0;
getConcat(node[0], nc0);
@@ -2076,6 +2075,19 @@ Node TheoryStringsRewriter::rewriteContains( Node node ) {
}
else if (node[0].getKind() == kind::STRING_STRREPL)
{
+ if (node[1].isConst() && node[0][1].isConst() && node[0][2].isConst())
+ {
+ String c = node[1].getConst<String>();
+ if (c.noOverlapWith(node[0][1].getConst<String>())
+ && c.noOverlapWith(node[0][2].getConst<String>()))
+ {
+ // (str.contains (str.replace x c1 c2) c3) ---> (str.contains x c3)
+ // if there is no overlap between c1 and c3 and none between c2 and c3
+ Node ret = nm->mkNode(STRING_STRCTN, node[0][0], node[1]);
+ return returnRewrite(node, ret, "ctn-repl-cnsts-to-ctn");
+ }
+ }
+
if (node[0][0] == node[0][2])
{
// (str.contains (str.replace x y x) y) ---> (str.contains x y)
diff --git a/src/util/regexp.h b/src/util/regexp.h
index 2ab6b659c..1588b5174 100644
--- a/src/util/regexp.h
+++ b/src/util/regexp.h
@@ -149,6 +149,22 @@ class CVC4_PUBLIC String {
String prefix(std::size_t i) const { return substr(0, i); }
String suffix(std::size_t i) const { return substr(size() - i, i); }
+
+ /**
+ * Checks if there is any overlap between this string and another string. This
+ * corresponds to checking whether one string contains the other and wether a
+ * substring of one is a prefix of the other and vice-versa.
+ *
+ * @param y The other string
+ * @return True if there is an overlap, false otherwise
+ */
+ bool noOverlapWith(const String& y) const
+ {
+ return y.find(*this) == std::string::npos
+ && this->find(y) == std::string::npos && this->overlap(y) == 0
+ && y.overlap(*this) == 0;
+ }
+
/** string overlap
*
* if overlap returns m>0,
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback