Skip to content

Commit 67d90ff

Browse files
committed
Improve ReplacePart
1 parent 1f3864c commit 67d90ff

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/ListFunctions.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6211,25 +6211,27 @@ public IExpr evaluate(IAST ast, int argSize, IExpr[] option, EvalEngine engine,
62116211
// Note: Rubi uses this kind of rule:
62126212
return result.replacePart(lhs, rhs, heads).orElse(result);
62136213
}
6214+
62146215
if (ast.arg2().isRuleAST()) {
6215-
return ast.arg1().replacePart((IAST) ast.arg2(), heads).orElse(ast.arg1());
6216+
IAST ruleAST = (IAST) ast.arg2();
6217+
return ast.arg1().replacePart(ruleAST.arg1(), ruleAST.arg2(), heads).orElse(ast.arg1());
62166218
}
62176219

62186220
if (ast.arg2().isList()) {
6221+
IAST listAST = (IAST) ast.arg2();
62196222
if (ast.arg2().isListOfRules()) {
6220-
IExpr expr = result.replacePart((IAST) ast.arg2(), heads);
6223+
IExpr expr = result.replacePart(listAST, heads);
62216224
if (expr.isPresent()) {
62226225
result = expr;
62236226
}
62246227
return result;
62256228
}
6226-
for (IExpr subList : (IAST) ast.arg2()) {
6229+
for (IExpr subList : listAST) {
62276230
IExpr expr = result.replacePart(F.Rule(subList, ast.arg2()), heads);
62286231
if (expr.isPresent()) {
62296232
result = expr;
62306233
}
62316234
}
6232-
// return result.replacePart(F.Rule(ast.arg3(), ast.arg2()), heads).orElse(result);
62336235
}
62346236
return result;
62356237
}

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorReplacePart.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.matheclipse.core.visit;
22

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

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

5454
for (int i = 1; i < list.size(); i++) {
5555
rule = (IAST) list.get(i);
@@ -66,7 +66,11 @@ public VisitorReplacePart(IAST rule, IExpr.COMPARE_TERNARY heads) {
6666
public VisitorReplacePart(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY heads) {
6767
super();
6868
engine = EvalEngine.get();
69-
this.patternMatcherList = new ArrayList<IPatternMatcher>(1);
69+
if (lhs.isList()) {
70+
this.patternMatcherList = new IPatternMatcher[lhs.argSize()];
71+
} else {
72+
this.patternMatcherList = new IPatternMatcher[1];
73+
}
7074
startOffset = heads == IExpr.COMPARE_TERNARY.TRUE ? 0 : 1;
7175
initPatternMatcher(lhs, rhs, heads);
7276
if (heads == COMPARE_TERNARY.FALSE) {
@@ -106,7 +110,7 @@ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY head
106110
}
107111
IPatternMatcher evalPatternMatcher =
108112
engine.evalPatternMatcher(F.Sequence(positions), rhs);
109-
this.patternMatcherList.add(evalPatternMatcher);
113+
this.patternMatcherList[listLength++] = evalPatternMatcher;
110114
}
111115
} else {
112116
if (list.argSize() > 0) {
@@ -123,7 +127,7 @@ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY head
123127
}
124128
IPatternMatcher evalPatternMatcher =
125129
engine.evalPatternMatcher(F.Sequence(positions), rhs);
126-
this.patternMatcherList.add(evalPatternMatcher);
130+
this.patternMatcherList[listLength++] = evalPatternMatcher;
127131
}
128132
}
129133
} else {
@@ -135,17 +139,17 @@ private void initPatternMatcher(IExpr lhs, IExpr rhs, IExpr.COMPARE_TERNARY head
135139
startOffset = 0;
136140
}
137141
IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(F.Sequence(positions), rhs);
138-
this.patternMatcherList.add(evalPatternMatcher);
142+
this.patternMatcherList[listLength++] = evalPatternMatcher;
139143

140144
}
141145
} catch (ReturnException rex) {
142146
if (fromPositions.isList()) {
143147
IAST list = ((IAST) fromPositions).apply(S.Sequence, 1);
144148
IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(list, rhs);
145-
this.patternMatcherList.add(evalPatternMatcher);
149+
this.patternMatcherList[listLength++] = evalPatternMatcher;
146150
} else {
147151
IPatternMatcher evalPatternMatcher = engine.evalPatternMatcher(fromPositions, rhs);
148-
this.patternMatcherList.add(evalPatternMatcher);
152+
this.patternMatcherList[listLength++] = evalPatternMatcher;
149153
}
150154
}
151155
}
@@ -154,8 +158,11 @@ private IExpr visitPatternIndexList(IAST ast, IASTAppendable positions) {
154158
IASTAppendable result = F.NIL;
155159
for (int i = startOffset; i < ast.size(); i++) {
156160
final IInteger position = F.ZZ(i);
157-
for (int j = 0; j < patternMatcherList.size(); j++) {
158-
IPatternMatcher matcher = patternMatcherList.get(j);
161+
for (int j = 0; j < listLength; j++) {
162+
IPatternMatcher matcher = patternMatcherList[j];
163+
if (matcher == null) {
164+
continue;
165+
}
159166
IASTAppendable positionsToMatch = positions.copyAppendable();
160167
positionsToMatch.append(position);
161168

@@ -251,8 +258,11 @@ private IASTAppendable patternIndexRecursive(IPatternMatcher matcher, IAST ast,
251258
@Override
252259
public IExpr visit(IASTMutable ast) {
253260
IASTAppendable positionsToMatch = F.ast(S.Sequence);
254-
for (int j = 0; j < patternMatcherList.size(); j++) {
255-
IPatternMatcher matcher = patternMatcherList.get(j);
261+
for (int j = 0; j < listLength; j++) {
262+
IPatternMatcher matcher = patternMatcherList[j];
263+
if (matcher == null) {
264+
continue;
265+
}
256266
IExpr lhs = matcher.getLHS();
257267
if (lhs.isAST(S.Sequence, 1)) {
258268
// empty sequence matches with complete expression

symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/PatternsTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,9 @@ public void testReplacePartPattern() {
997997

998998
@Test
999999
public void testReplacePartIntegerPositions() {
1000+
check("ReplacePart({a, b, c}, {{1}, {2}} -> t)", //
1001+
"{t,t,c}");
1002+
10001003
check("ReplacePart({4,-1},-x,2)", //
10011004
"{4,-x}");
10021005
check("ReplacePart({4,{1,3,7,11,19}},tt,{2,5})", //

0 commit comments

Comments
 (0)