Skip to content

Commit ff8ea4c

Browse files
committed
minus fix
1 parent 19e809d commit ff8ea4c

File tree

4 files changed

+151
-51
lines changed

4 files changed

+151
-51
lines changed

src/main/java/io/polypen/Polynomial.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public Polynomial multiply(Polynomial other) {
4646
public Polynomial multiply(int factor) {
4747
List<Integer> newCoefficients = new ArrayList<>(coefficients.size());
4848
for (Integer coefficient : coefficients) {
49-
newCoefficients.add(coefficient * (factor));
49+
newCoefficients.add(coefficient * factor);
5050
}
5151
return new Polynomial(newCoefficients);
5252
}

src/main/java/io/polypen/parse/Macro.java

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package io.polypen.parse;
22

3+
import io.polypen.parse.Parser.BindingMinusExpr;
34
import io.polypen.parse.Parser.Expr;
45
import io.polypen.parse.Parser.ListExpr;
6+
import io.polypen.parse.Parser.MinusExpr;
57
import io.polypen.parse.Parser.MultExpr;
68
import io.polypen.parse.Parser.MultListExpr;
79
import io.polypen.parse.Parser.NumberExpr;
10+
import io.polypen.parse.Parser.PlusExpr;
811
import io.polypen.parse.Parser.PlusListExpr;
912
import io.polypen.parse.Parser.VarExp;
1013

@@ -13,19 +16,54 @@
1316

1417
public class Macro {
1518

19+
static Expr minusMacro(Expr exprs) {
20+
if (exprs.size() == 1) {
21+
return exprs;
22+
}
23+
Expr old = null;
24+
Expr previous = null;
25+
List<Expr> result = new ArrayList<>(exprs.size());
26+
for (Expr expr : exprs.getExprs()) {
27+
if (previous instanceof MinusExpr) {
28+
if (needsPlusInsert(old)) {
29+
result.add(Parser.PLUS);
30+
}
31+
result.add(BindingMinusExpr.of(minusMacro(expr)));
32+
} else {
33+
if (!(expr instanceof MinusExpr)) {
34+
result.add(minusMacro(expr));
35+
}
36+
}
37+
old = previous;
38+
previous = expr;
39+
}
40+
return new ListExpr(result);
41+
}
42+
43+
private static boolean needsPlusInsert(Expr prev) {
44+
if (prev == null) {
45+
return false;
46+
}
47+
return switch (prev) {
48+
case PlusExpr ignored -> false;
49+
case MultExpr ignored -> false;
50+
default -> true;
51+
};
52+
}
53+
1654
static Expr applyStarMacro(List<Expr> exprs) {
1755
if (exprs.size() == 1) {
1856
return expandRecursively(exprs.getFirst());
1957
}
20-
List<Expr> exprsCopy = new ArrayList<>(exprs.size());
21-
List<Expr> region = new ArrayList<>(exprs.size());
58+
PlusListExpr exprsCopy = PlusListExpr.create(exprs.size());
59+
MultListExpr region = MultListExpr.create(exprs.size());
2260
Expr previous = null;
2361
for (Expr expr : exprs) {
2462
if (isStrongBind(previous) && (isStrongBind(expr) || !region.isEmpty())) {
2563
region.add(previous);
2664
} else {
2765
if (!region.isEmpty()) {
28-
exprsCopy.add(new MultListExpr(new ArrayList<>(region)));
66+
exprsCopy.add(region.copy());
2967
region.clear();
3068
}
3169
if (previous != null) {
@@ -36,15 +74,15 @@ static Expr applyStarMacro(List<Expr> exprs) {
3674
}
3775
if (exprsCopy.isEmpty()) {
3876
region.add(expandRecursively(previous));
39-
return new MultListExpr(region);
77+
return region;
4078
}
4179
if (region.isEmpty()) {
4280
exprsCopy.add(expandRecursively(previous));
4381
} else {
4482
region.add(expandRecursively(previous));
45-
exprsCopy.add(new MultListExpr(region));
83+
exprsCopy.add(region);
4684
}
47-
return new PlusListExpr(exprsCopy);
85+
return exprsCopy;
4886
}
4987

5088
private static Expr expandRecursively(Expr expr) {
@@ -53,6 +91,7 @@ private static Expr expandRecursively(Expr expr) {
5391
}
5492
return switch (expr) {
5593
case ListExpr x -> applyStarMacro(x.value());
94+
case BindingMinusExpr x -> BindingMinusExpr.of(applyStarMacro(List.of(x.expr())));
5695
default -> expr;
5796
};
5897
}
@@ -68,6 +107,7 @@ public static boolean isStrongBind(Expr expr) {
68107
case MultExpr ignored -> true;
69108
case NumberExpr ignored -> true;
70109
case VarExp ignored -> true;
110+
case BindingMinusExpr ignored -> true;
71111
default -> false;
72112
};
73113
}

src/main/java/io/polypen/parse/Parser.java

Lines changed: 88 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.io.PushbackReader;
1010
import java.util.ArrayList;
1111
import java.util.List;
12+
import java.util.stream.IntStream;
1213

1314
public final class Parser {
1415

@@ -111,7 +112,7 @@ public static ListExpr parse(String s) {
111112
}
112113
}
113114

114-
public sealed interface Expr permits PlusExpr, MinusExpr, MultExpr, ListExpr, NumberExpr, VarExp, PlusListExpr, MultListExpr {
115+
public sealed interface Expr permits PlusExpr, MinusExpr, MultExpr, ListExpr, NumberExpr, VarExp, PlusListExpr, MultListExpr, BindingMinusExpr {
115116
int size();
116117

117118
Expr getFirst();
@@ -127,17 +128,17 @@ public String toString() {
127128

128129
@Override
129130
public int size() {
130-
return 0;
131+
return 1;
131132
}
132133

133134
@Override
134135
public Expr getFirst() {
135-
return null;
136+
return this;
136137
}
137138

138139
@Override
139140
public List<Expr> getExprs() {
140-
return List.of();
141+
return List.of(this);
141142
}
142143
}
143144

@@ -151,17 +152,17 @@ public String toString() {
151152

152153
@Override
153154
public int size() {
154-
return 0;
155+
return 1;
155156
}
156157

157158
@Override
158159
public Expr getFirst() {
159-
return null;
160+
return this;
160161
}
161162

162163
@Override
163164
public List<Expr> getExprs() {
164-
return List.of();
165+
return List.of(this);
165166
}
166167
}
167168

@@ -175,69 +176,72 @@ public String toString() {
175176

176177
@Override
177178
public int size() {
178-
return 0;
179+
return 1;
179180
}
180181

181182
@Override
182183
public Expr getFirst() {
183-
return null;
184+
return this;
184185
}
185186

186187
@Override
187188
public List<Expr> getExprs() {
188-
return List.of();
189+
return List.of(this);
189190
}
190191
}
191192

192193
public static final Expr MULT = new MultExpr();
193194

194195
public static Polynomial eval(Expr expr) {
195-
Expr exprs = Macro.applyStarMacro(expr.getExprs());
196+
List<Expr> expanded = Macro.minusMacro(expr).getExprs();
197+
Expr exprs = Macro.applyStarMacro(expanded);
198+
return _eval(exprs);
199+
}
200+
201+
private static Polynomial _eval(Expr exprs) {
196202
return switch (exprs) {
197203
case PlusListExpr listExpr -> {
198204
if (listExpr.value.size() == 1) {
199-
yield eval(listExpr.value().getFirst());
205+
yield _eval(listExpr.value().getFirst());
200206
}
201207
if (exprs.size() == 1) {
202-
yield eval(exprs.getFirst());
208+
yield _eval(exprs.getFirst());
203209
}
204210
Polynomial result = Polynomial.ZERO;
205-
int sign = 1;
206211
for (Expr exp : exprs.getExprs()) {
207212
if (isMinus(exp)) {
208-
sign = -1;
209213
continue;
210214
}
211215
if (isPlus(exp)) {
212-
sign = 1;
213216
continue;
214217
}
215-
Polynomial p = eval(exp);
216-
result = result.add(p.multiply(sign));
218+
Polynomial p = _eval(exp);
219+
result = result.add(p);
217220
}
218221
yield result;
219222
}
220223
case MultListExpr listExpr -> {
221224
if (listExpr.value.size() == 1) {
222-
yield eval(listExpr.value().getFirst());
225+
yield _eval(listExpr.value().getFirst());
223226
}
224227
if (exprs.size() == 1) {
225-
yield eval(exprs.getFirst());
228+
yield _eval(exprs.getFirst());
226229
}
227230
Polynomial result;
228231
result = Polynomial.ONE;
229232
for (Expr exp : exprs.getExprs()) {
230233
if (isOperator(exp)) {
231234
continue;
232235
}
233-
Polynomial p = eval(exp);
236+
Polynomial p = _eval(exp);
234237
result = result.multiply(p);
235238
}
236239
yield result;
237240
}
238241
case NumberExpr numberExpr -> new Monomial(numberExpr.value, 0).polynomial();
239242
case VarExp varExp -> new Monomial(1, varExp.exp).polynomial();
240-
default -> throw new IllegalStateException(expr.toString());
243+
case BindingMinusExpr minEx -> _eval(minEx.expr).multiply(-1);
244+
default -> throw new IllegalStateException(exprs.toString());
241245
};
242246
}
243247

@@ -258,20 +262,36 @@ private static boolean isMinus(Expr expr) {
258262
return expr instanceof MinusExpr;
259263
}
260264

261-
private static boolean hasPlus(Expr exprs) {
262-
for (Expr expr : exprs.getExprs()) {
263-
if (expr instanceof PlusExpr || expr instanceof MinusExpr) {
264-
return true;
265-
}
265+
public record MultListExpr(List<Expr> value) implements Expr {
266+
public static MultListExpr create(int capacity) {
267+
return new MultListExpr(new ArrayList<>(capacity));
266268
}
267-
return false;
268-
}
269269

270-
public record MultListExpr(List<Expr> value) implements Expr {
271270
public static MultListExpr of(Expr... value) {
272271
return new MultListExpr(List.of(value));
273272
}
274273

274+
public static MultListExpr of(int... value) {
275+
List<Expr> list = IntStream.of(value).mapToObj(NumberExpr::of).map(s -> (Expr) s).toList();
276+
return new MultListExpr(list);
277+
}
278+
279+
public void add(Expr expr) {
280+
addIfNotOperator(value, expr);
281+
}
282+
283+
public MultListExpr copy() {
284+
return new MultListExpr(List.copyOf(value));
285+
}
286+
287+
public void clear() {
288+
value.clear();
289+
}
290+
291+
public boolean isEmpty() {
292+
return value.isEmpty();
293+
}
294+
275295
@Override
276296
public int size() {
277297
return value().size();
@@ -288,11 +308,49 @@ public List<Expr> getExprs() {
288308
}
289309
}
290310

311+
private static void addIfNotOperator(List<Expr> exprs, Expr expr) {
312+
if (!isOperator(expr)) {
313+
exprs.add(expr);
314+
}
315+
}
316+
317+
public record BindingMinusExpr(Expr expr) implements Expr {
318+
public static BindingMinusExpr of(Expr expr) {
319+
return new BindingMinusExpr(expr);
320+
}
321+
322+
@Override
323+
public int size() {
324+
return 1;
325+
}
326+
327+
@Override
328+
public Expr getFirst() {
329+
return expr;
330+
}
331+
332+
@Override
333+
public List<Expr> getExprs() {
334+
return List.of(expr);
335+
}
336+
}
337+
291338
public record PlusListExpr(List<Expr> value) implements Expr {
339+
public static PlusListExpr create(int capacity) {
340+
return new PlusListExpr(new ArrayList<>(capacity));
341+
}
342+
292343
public static PlusListExpr of(Expr... value) {
293344
return new PlusListExpr(List.of(value));
294345
}
295346

347+
public void add(Expr expr) {
348+
addIfNotOperator(value, expr);
349+
}
350+
351+
public boolean isEmpty() {
352+
return value.isEmpty();
353+
}
296354

297355
@Override
298356
public int size() {

0 commit comments

Comments
 (0)