Skip to content

Commit

Permalink
Improve ReplacePart
Browse files Browse the repository at this point in the history
  • Loading branch information
axkr committed Dec 7, 2024
1 parent 1f3864c commit 67d90ff
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6211,25 +6211,27 @@ public IExpr evaluate(IAST ast, int argSize, IExpr[] option, EvalEngine engine,
// Note: Rubi uses this kind of rule:
return result.replacePart(lhs, rhs, heads).orElse(result);
}

if (ast.arg2().isRuleAST()) {
return ast.arg1().replacePart((IAST) ast.arg2(), heads).orElse(ast.arg1());
IAST ruleAST = (IAST) ast.arg2();
return ast.arg1().replacePart(ruleAST.arg1(), ruleAST.arg2(), heads).orElse(ast.arg1());
}

if (ast.arg2().isList()) {
IAST listAST = (IAST) ast.arg2();
if (ast.arg2().isListOfRules()) {
IExpr expr = result.replacePart((IAST) ast.arg2(), heads);
IExpr expr = result.replacePart(listAST, heads);
if (expr.isPresent()) {
result = expr;
}
return result;
}
for (IExpr subList : (IAST) ast.arg2()) {
for (IExpr subList : listAST) {
IExpr expr = result.replacePart(F.Rule(subList, ast.arg2()), heads);
if (expr.isPresent()) {
result = expr;
}
}
// return result.replacePart(F.Rule(ast.arg3(), ast.arg2()), heads).orElse(result);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.matheclipse.core.visit;

import java.util.ArrayList;
import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.eval.exception.ReturnException;
import org.matheclipse.core.expression.F;
Expand All @@ -21,8 +20,9 @@ public class VisitorReplacePart extends AbstractVisitor {
* A list of pattern matchers which should be matched against, for every possible position of an
* {@link IAST} structure.
*/
private ArrayList<IPatternMatcher> patternMatcherList;
private IPatternMatcher[] patternMatcherList;

private int listLength;
/**
* <code>0</code> or <code>1</code>, depending if option <code>Heads->True</code> is set or the
* <code>0</code> index position is used in the left-hand-side of a rule.
Expand All @@ -49,7 +49,7 @@ public VisitorReplacePart(IAST rule, IExpr.COMPARE_TERNARY heads) {
}
if (rule.isListOfRules()) {
IAST list = rule;
this.patternMatcherList = new ArrayList<IPatternMatcher>(list.argSize() + 3);
this.patternMatcherList = new IPatternMatcher[list.argSize()];

for (int i = 1; i < list.size(); i++) {
rule = (IAST) list.get(i);
Expand All @@ -66,7 +66,11 @@ public VisitorReplacePart(IAST rule, IExpr.COMPARE_TERNARY heads) {
public VisitorReplacePart(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY heads) {
super();
engine = EvalEngine.get();
this.patternMatcherList = new ArrayList<IPatternMatcher>(1);
if (lhs.isList()) {
this.patternMatcherList = new IPatternMatcher[lhs.argSize()];
} else {
this.patternMatcherList = new IPatternMatcher[1];
}
startOffset = heads == IExpr.COMPARE_TERNARY.TRUE ? 0 : 1;
initPatternMatcher(lhs, rhs, heads);
if (heads == COMPARE_TERNARY.FALSE) {
Expand Down Expand Up @@ -106,7 +110,7 @@ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY head
}
IPatternMatcher evalPatternMatcher =
engine.evalPatternMatcher(F.Sequence(positions), rhs);
this.patternMatcherList.add(evalPatternMatcher);
this.patternMatcherList[listLength++] = evalPatternMatcher;
}
} else {
if (list.argSize() > 0) {
Expand All @@ -123,7 +127,7 @@ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY head
}
IPatternMatcher evalPatternMatcher =
engine.evalPatternMatcher(F.Sequence(positions), rhs);
this.patternMatcherList.add(evalPatternMatcher);
this.patternMatcherList[listLength++] = evalPatternMatcher;
}
}
} else {
Expand All @@ -135,17 +139,17 @@ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY head
startOffset = 0;
}
IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(F.Sequence(positions), rhs);
this.patternMatcherList.add(evalPatternMatcher);
this.patternMatcherList[listLength++] = evalPatternMatcher;

}
} catch (ReturnException rex) {
if (fromPositions.isList()) {
IAST list = ((IAST) fromPositions).apply(S.Sequence, 1);
IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(list, rhs);
this.patternMatcherList.add(evalPatternMatcher);
this.patternMatcherList[listLength++] = evalPatternMatcher;
} else {
IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(fromPositions, rhs);
this.patternMatcherList.add(evalPatternMatcher);
this.patternMatcherList[listLength++] = evalPatternMatcher;
}
}
}
Expand All @@ -154,8 +158,11 @@ private IExpr visitPatternIndexList(IAST ast, IASTAppendable positions) {
IASTAppendable result = F.NIL;
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);
for (int j = 0; j < listLength; j++) {
IPatternMatcher matcher = patternMatcherList[j];
if (matcher == null) {
continue;
}
IASTAppendable positionsToMatch = positions.copyAppendable();
positionsToMatch.append(position);

Expand Down Expand Up @@ -251,8 +258,11 @@ private IASTAppendable patternIndexRecursive(IPatternMatcher matcher, IAST ast,
@Override
public IExpr visit(IASTMutable ast) {
IASTAppendable positionsToMatch = F.ast(S.Sequence);
for (int j = 0; j < patternMatcherList.size(); j++) {
IPatternMatcher matcher = patternMatcherList.get(j);
for (int j = 0; j < listLength; j++) {
IPatternMatcher matcher = patternMatcherList[j];
if (matcher == null) {
continue;
}
IExpr lhs = matcher.getLHS();
if (lhs.isAST(S.Sequence, 1)) {
// empty sequence matches with complete expression
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,9 @@ public void testReplacePartPattern() {

@Test
public void testReplacePartIntegerPositions() {
check("ReplacePart({a, b, c}, {{1}, {2}} -> t)", //
"{t,t,c}");

check("ReplacePart({4,-1},-x,2)", //
"{4,-x}");
check("ReplacePart({4,{1,3,7,11,19}},tt,{2,5})", //
Expand Down

0 comments on commit 67d90ff

Please sign in to comment.