F.NIL
.
+ * method returns {@link F#NIL}.
*
* @param astRules rules of the form position->y
or
* {position1->b, position2->d}
@@ -6078,6 +6078,28 @@ default IExpr replacePart(final IAST astRules, IExpr.COMPARE_TERNARY heads) {
return F.NIL;
}
+ /**
+ * All subexpressions whose positions matches the left-hand-side (lhs
) are replaced
+ * with the right-hand-side (rhs
). If no substitution matches, the method returns
+ * {@link F#NIL}.
+ *
+ * @param lhs the left-hand-side of the rule
+ * @param rhs the right-hand-side of the rule
+ * @param heads if TRUE
also replace the heads of expressions
+ * @return
+ */
+ default IExpr replacePart(final IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY heads) {
+ try {
+ return this.accept(new VisitorReplacePart(lhs, rhs, heads));
+ } catch (RuntimeException rex) {
+ Errors.rethrowsInterruptException(rex);
+ if (Config.SHOW_STACKTRACE) {
+ rex.printStackTrace();
+ }
+ }
+ return F.NIL;
+ }
+
/**
* Repeatedly replace all (sub-) expressions with the given unary function. If no substitution
* matches, the method returns this
.
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorReplacePart.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorReplacePart.java
index c5c0282838..68318e6a1c 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorReplacePart.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorReplacePart.java
@@ -27,7 +27,7 @@ public class VisitorReplacePart extends AbstractVisitor {
* 0
or 1
, depending if option Heads->True
is set or the
* 0
index position is used in the left-hand-side of a rule.
*/
- private int offset;
+ private int startOffset;
/**
* The current evaluation engine for this thread.
@@ -43,25 +43,50 @@ public class VisitorReplacePart extends AbstractVisitor {
public VisitorReplacePart(IAST rule, IExpr.COMPARE_TERNARY heads) {
super();
engine = EvalEngine.get();
+ startOffset = heads == IExpr.COMPARE_TERNARY.TRUE ? 0 : 1;
if (rule.isRuleAST()) {
rule = F.list(rule);
}
if (rule.isListOfRules()) {
IAST list = rule;
this.patternMatcherList = new ArrayList
+ * Note: the {@link #startOffset} is set to 0
if a position 0
is
+ * found.
+ *
+ * @param lhs
+ * @param rhs
+ * @param heads
+ */
+ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY heads) {
+ IExpr fromPositions = lhs;
try {
// try extracting an int[] array of expressions
if (fromPositions.isList()) {
@@ -76,11 +101,11 @@ private void initPatternMatcher(IAST rule, IExpr.COMPARE_TERNARY heads) {
throw ReturnException.RETURN_FALSE;
}
if (positions[k - 1] == 0) {
- offset = 0;
+ startOffset = 0;
}
}
IPatternMatcher evalPatternMatcher =
- engine.evalPatternMatcher(F.Sequence(positions), rule.arg2());
+ engine.evalPatternMatcher(F.Sequence(positions), rhs);
this.patternMatcherList.add(evalPatternMatcher);
}
} else {
@@ -93,34 +118,33 @@ private void initPatternMatcher(IAST rule, IExpr.COMPARE_TERNARY heads) {
throw ReturnException.RETURN_FALSE;
}
if (positions[j - 1] == 0) {
- offset = 0;
+ startOffset = 0;
}
}
IPatternMatcher evalPatternMatcher =
- engine.evalPatternMatcher(F.Sequence(positions), rule.arg2());
+ engine.evalPatternMatcher(F.Sequence(positions), rhs);
this.patternMatcherList.add(evalPatternMatcher);
}
}
} else {
- int[] positions = new int[] {rule.arg1().toIntDefault()};
+ int[] positions = new int[] {lhs.toIntDefault()};
if (positions[0] == Integer.MIN_VALUE) {
throw ReturnException.RETURN_FALSE;
}
if (positions[0] == 0) {
- offset = 0;
+ startOffset = 0;
}
- IPatternMatcher evalPatternMatcher =
- engine.evalPatternMatcher(F.Sequence(positions), rule.arg2());
+ IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(F.Sequence(positions), rhs);
this.patternMatcherList.add(evalPatternMatcher);
}
} catch (ReturnException rex) {
if (fromPositions.isList()) {
IAST list = ((IAST) fromPositions).apply(S.Sequence, 1);
- IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(list, rule.arg2());
+ IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(list, rhs);
this.patternMatcherList.add(evalPatternMatcher);
} else {
- IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(fromPositions, rule.arg2());
+ IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(fromPositions, rhs);
this.patternMatcherList.add(evalPatternMatcher);
}
}
@@ -128,7 +152,7 @@ private void initPatternMatcher(IAST rule, IExpr.COMPARE_TERNARY heads) {
private IExpr visitPatternIndexList(IAST ast, IASTAppendable positions) {
IASTAppendable result = F.NIL;
- for (int i = offset; i < ast.size(); i++) {
+ for (int i = startOffset; i < ast.size(); i++) {
final IInteger position = F.ZZ(i);
for (int j = 0; j < patternMatcherList.size(); j++) {
IPatternMatcher matcher = patternMatcherList.get(j);