diff --git a/pom.xml b/pom.xml
index 64d94ac..feb78c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,12 +28,6 @@
-
- com.nitta-lab
- dtram
- 1.0
-
-
diff --git a/src/main/java/Main.java b/src/main/java/Main.java
index 1738ff9..b692f74 100644
--- a/src/main/java/Main.java
+++ b/src/main/java/Main.java
@@ -1,325 +1,33 @@
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
-import inference.rewrite.Position;
-import inference.rewrite.ResourceTree;
-import inference.rewrite.RewriteInferenceSystem;
-import lombok.SneakyThrows;
+import constants.Types;
+import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.Type;
-import models.dataConstraintModel.DataConstraintModel;
-import models.dataFlowModel.DataTransferModel;
-import models.formulas.EquationFormula;
-import models.formulas.Then;
-import models.terms.DependencyTerm;
-import models.terms.PrimedTerm;
-import models.terms.Resource;
-import parser.Parser;
-import parser.Parser.TokenStream;
+import models.algebra.Variable;
public class Main {
- static TokenStream stream = new Parser.TokenStream();
- static Parser parser = new Parser(stream);
- static DataTransferModel model = new DataTransferModel();
-
- static Type INT = DataConstraintModel.typeInt;
+ static Type INT = Types.typeInt;
public static void main(String[] args) {
-// sandbox4();
-// System.out.println("=================================================================");
-// System.out.println("=================================================================");
-// System.out.println("=================================================================");
-// sandbox5();
- sandbox9();
- }
-
- static void sandbox1() {
- Resource A = new Resource("A", INT, 1);
- Resource B = new Resource("B", INT, 1);
- Resource C = new Resource("C", INT, 1);
- Resource D = new Resource("D", INT, 1);
- Resource E = new Resource("E", INT, 1);
- Resource F = new Resource("F", INT, 1);
- Resource G = new Resource("G", INT, 1);
- DependencyTerm t1 = new DependencyTerm(A, B, C, D, E);
- DependencyTerm t2 = new DependencyTerm(t1, F, G);
- System.out.println(t2);
- ResourceTree rt = new ResourceTree(t2);
- System.out.println(rt);
- rt.debug(new Position(List.of(0)));
- }
-
- static void sandbox2() {
- Resource A = new Resource("A", INT, 1);
- Resource B = new Resource("B", INT, 1);
- Resource C = new Resource("C", INT, 1);
- Resource D = new Resource("D", INT, 1);
- Resource E = new Resource("E", INT, 1);
- Resource F = new Resource("F", INT, 1);
- Resource G = new Resource("G", INT, 1);
- Resource H = new Resource("H", INT, 1);
- Resource I = new Resource("I", INT, 1);
- Resource J = new Resource("J", INT, 1);
- Resource K = new Resource("K", INT, 1);
- Resource L = new Resource("L", INT, 1);
- Resource M = new Resource("M", INT, 1);
- Resource N = new Resource("N", INT, 1);
- Resource O = new Resource("O", INT, 1);
- Resource P = new Resource("P", INT, 1);
- Resource Q = new Resource("Q", INT, 1);
-
- DependencyTerm t1 = new DependencyTerm(A, B, C, D, E);
- DependencyTerm t2 = new DependencyTerm(G, H, I, J, K);
- DependencyTerm t3 = new DependencyTerm(M, N, O, P, Q);
- DependencyTerm t4 = new DependencyTerm(t1, F, t2, L, t3);
- System.out.println(t4);
- ResourceTree rt = new ResourceTree(t4);
- System.out.println(rt);
- rt.debug(new Position());
- rt.debugAllPath();
-
- }
-
- static void sandbox3() {
- Resource A = new Resource("A", INT, 1);
- Resource B = new Resource("B", INT, 1);
- Resource C = new Resource("C", INT, 1);
- Resource D = new Resource("D", INT, 1);
- Resource x = new Resource("x", INT, 0);
- Resource y = new Resource("y", INT, 1);
- DependencyTerm t1 = new DependencyTerm(A, B, C);
- DependencyTerm t2 = new DependencyTerm(B, C, D);
- EquationFormula f1 = new EquationFormula(t1, x);
- EquationFormula f2 = new EquationFormula(y, t2);
- RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(f1, f2), null);
- ris.inference();
-
- }
-
- static void sandbox4() {
- Resource uadd = new Resource("uadd", INT, 1);
- Resource add = new Resource("add", INT, 1);
- Resource cid = new Resource("cid", INT, 1);
- Resource org = new Resource("org", INT, 1);
- Resource uid = new Resource("uid", INT, 1);
- Resource x = new Resource("x", INT, 0);
- Resource y = new Resource("y", INT, 0);
- DependencyTerm t1 = new DependencyTerm(add, cid, org);
- DependencyTerm t2 = new DependencyTerm(org, uid, x);
- DependencyTerm t3 = new DependencyTerm(uadd, uid, x);
- DependencyTerm t4 = new DependencyTerm(add, cid, y);
- EquationFormula f1 = new EquationFormula(uadd, t1);
- EquationFormula f2 = new EquationFormula(t2, y);
- EquationFormula f3 = new EquationFormula(t3, t4);
-
-
- RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(f1, f2), f3);
- ris.debug();
- ris.inference();
-
- }
-
- static void sandbox5() {
- Resource uadd = new Resource("uadd", INT, 1);
- Resource add = new Resource("add", INT, 1);
- Resource cid = new Resource("cid", INT, 1);
- Resource org = new Resource("org", INT, 1);
- Resource uid = new Resource("uid", INT, 1);
- Resource x = new Resource("x", INT, 0);
- Resource y = new Resource("y", INT, 0);
- Resource z = new Resource("z", INT, 0);
- DependencyTerm t1 = new DependencyTerm(add, cid, org);
- DependencyTerm t2 = new DependencyTerm(add, cid, x);
- DependencyTerm t3 = new DependencyTerm(org, uid, z);
- DependencyTerm t4 = new DependencyTerm(uadd, uid, z);
-
- EquationFormula f1 = new EquationFormula(uadd, t1);
- EquationFormula f2 = new EquationFormula(t2, y);
- EquationFormula f3 = new EquationFormula(t3, x);
- EquationFormula f4 = new EquationFormula(t4, y);
- Then f5 = new Then(f3, f4);
-
- RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(f1, f2), f5);
- ris.debug();
- ris.inference();
-
- }
-
- static void sandbox6() {
- Resource add = new Resource("add", INT, 1);
- Resource cid = new Resource("cid", INT, 1);
- Resource org = new Resource("org", INT, 1);
- Resource uid = new Resource("uid", INT, 1);
- Resource x = new Resource("x", INT, 0);
- Resource y = new Resource("y", INT, 0);
- Resource z = new Resource("z", INT, 0);
-
- DependencyTerm t1 = new DependencyTerm(add, cid, x);
- DependencyTerm t2 = new DependencyTerm(cid, uid, z);
- DependencyTerm t3 = new DependencyTerm(add, cid, t2);
- EquationFormula f1 = new EquationFormula(t1, y);
- EquationFormula f2 = new EquationFormula(t2, x);
- EquationFormula f3 = new EquationFormula(t3, y);
- Then f4 = new Then(f2, f3);
- RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(f1), f4);
- ris.inference();
-
+ sandbox();
}
- static void sandbox7() {
- Resource A = new Resource("A", INT, 1);
- Resource B = new Resource("B", INT, 1);
- Resource C = new Resource("C", INT, 1);
- Resource D = new Resource("D", INT, 1);
- Resource E = new Resource("E", INT, 1);
- Resource F = new Resource("F", INT, 1);
- Resource G = new Resource("G", INT, 1);
- Resource H = new Resource("H", INT, 1);
- Resource I = new Resource("I", INT, 1);
- Resource J = new Resource("J", INT, 1);
- Resource K = new Resource("K", INT, 1);
- Resource L = new Resource("L", INT, 1);
- Resource M = new Resource("M", INT, 1);
- Resource N = new Resource("N", INT, 1);
- Resource O = new Resource("O", INT, 1);
+ static void sandbox() {
+ Expression tmp = utils.ExpressionUitls.parse("x");
+ System.out.println(tmp);
+ tmp = utils.ExpressionUitls.parse("(x + 5) * 3");
+ Map nums = new HashMap<>();
+ int a = utils.ExpressionUitls.getCoefficientAndConstantsFromExpression(tmp, nums, 1);
+ System.out.println(tmp);
+ System.out.println(a);
+ System.out.println(nums);
- DependencyTerm t1 = new DependencyTerm(A, B, C);
- DependencyTerm t2 = new DependencyTerm(I, J, K);
- DependencyTerm t3 = new DependencyTerm(M, N, O);
- DependencyTerm t4 = new DependencyTerm(E, F, G, H, t2);
- DependencyTerm t5 = new DependencyTerm(t1, D, t4, L, t3);
-
- ResourceTree rt = new ResourceTree(t5);
-// System.out.println(rt);
- rt.debug(new Position(List.of(0)));
+ int b = utils.ExpressionUitls.getConstantValue(new Constant("3"));
+ System.out.println(b);
}
- static void sandbox8() {
- Resource A = new Resource("A", INT, 1);
- Resource B = new Resource("B", INT, 1);
- Resource C = new Resource("C", INT, 1);
- DependencyTerm te = new DependencyTerm(A, B, C);
- EquationFormula eq1 = new EquationFormula(A, te);
- RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(eq1), eq1);
- ris.inference();
- }
-
- static void sandbox9() {
- Resource totalAmount = new Resource("totalAmount", INT, 1);
- Resource quantity = new Resource("quantity", INT, 1);
- Resource unitPrice = new Resource("unitPrice", INT, 1);
- Resource productId = new Resource("productID", INT, 1);
- Resource productName = new Resource("productName", INT, 1);
- Resource soledProductId = new Resource("soledProductId", INT, 1);
- PrimedTerm totalAmountP = new PrimedTerm(totalAmount);
- PrimedTerm quantityP = new PrimedTerm(quantity);
- PrimedTerm unitPriceP = new PrimedTerm(unitPrice);
- PrimedTerm productIdP = new PrimedTerm(productId);
- PrimedTerm productNameP = new PrimedTerm(productName);
- PrimedTerm soledProductIdP = new PrimedTerm(soledProductId);
- Resource a = new Resource("a", INT, 0);
- Resource b = new Resource("b", INT, 0);
- Resource c = new Resource("c", INT, 0);
- Resource d = new Resource("d", INT, 0);
- Resource e = new Resource("e", INT, 0);
- Resource salesId = new Resource("salesId", INT, 1);
- PrimedTerm salesIdP = new PrimedTerm(salesId);
- Resource mul = new Resource("mul", INT, 1);
- Resource mul1= new Resource("mul1", INT, 1);
- Resource mul2 = new Resource("mul2", INT, 1);
-
- // reference1
- DependencyTerm te1 = new DependencyTerm(unitPrice, productId, soledProductId);
- DependencyTerm te2 = new DependencyTerm(mul, mul1, quantity, mul2, te1);
- EquationFormula eq1 = new EquationFormula(totalAmount, te2);
-
- //reference2
- DependencyTerm te3 = new DependencyTerm(unitPriceP, productIdP, soledProductIdP);
- DependencyTerm te4 = new DependencyTerm(mul, mul1, quantityP, mul2, te3);
- EquationFormula eq2 = new EquationFormula(totalAmountP, te4);
-
- //input1
- DependencyTerm te5 = new DependencyTerm(soledProductIdP, salesIdP, a);
- EquationFormula eq3 = new EquationFormula(te5, b);
-
- //input2
- DependencyTerm te6 = new DependencyTerm(quantityP, salesIdP, a);
- EquationFormula eq4 = new EquationFormula(te6, c);
-
- //input3, 4, 5
- EquationFormula eq5 = new EquationFormula(productIdP, productId);
- EquationFormula eq6 = new EquationFormula(productNameP, productName);
- EquationFormula eq7 = new EquationFormula(unitPriceP, unitPrice);
-
- // value copy
- DependencyTerm te7 = new DependencyTerm(totalAmountP, salesIdP, a);
- DependencyTerm te8 = new DependencyTerm(unitPriceP, productIdP, b);
- DependencyTerm te9 = new DependencyTerm(mul, mul1, c, mul2, te8);
- EquationFormula eq8 = new EquationFormula(te7, te9);
-
-
- //----------------------change value-------------------
- //input6
- DependencyTerm te10 = new DependencyTerm(unitPriceP, productIdP, d);
- EquationFormula eq9 = new EquationFormula(te10, e);
-
- //input7, 8, 9, 10
- EquationFormula eq10 = new EquationFormula(productNameP, productName);
- EquationFormula eq11 = new EquationFormula(salesIdP, salesId);
- EquationFormula eq12 = new EquationFormula(soledProductIdP, soledProductId);
- EquationFormula eq13 = new EquationFormula(quantityP, quantity);
-
- //value copy
- EquationFormula eq14 = new EquationFormula(totalAmountP, totalAmount);
-
- //value copy conclusion
- DependencyTerm te11 = new DependencyTerm(totalAmountP, salesIdP, a);
- DependencyTerm te12 = new DependencyTerm(totalAmount, salesId, a);
- EquationFormula eq15 = new EquationFormula(te11, te12);
-// RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(eq3, eq4, eq5, eq6, eq7, eq8, eq9, eq10, eq11, eq12, eq13, eq14), eq15);
-// RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(), List.of(), List.of(eq3, eq4, eq5, eq6, eq7, eq8, eq9, eq10, eq11, eq12, eq13, eq14), eq15);
-
- //value copy new sales
-// RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(eq3, eq4, eq5, eq6, eq7, eq8), eq15);
-
- //value copy change value
- RewriteInferenceSystem ris = new RewriteInferenceSystem(List.of(eq9, eq10, eq11, eq12, eq13, eq14), eq15);
- ris.debug();
- ris.inference();
-//
- System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
- System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
- System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
-
- //reference conclusion
- DependencyTerm te13 = new DependencyTerm(soledProductId, salesId, a);
- EquationFormula eq16 = new EquationFormula(d, te13);
- Then th1 = new Then(eq16, eq15);
-
-
-// RewriteInferenceSystem ris2 = new RewriteInferenceSystem(List.of(eq3, eq4, eq5, eq6, eq7, eq1, eq9, eq10, eq11, eq12, eq13, eq2), th1);
-// RewriteInferenceSystem ris2 = new RewriteInferenceSystem(List.of(eq1, eq2), List.of(), List.of(eq3, eq4, eq5, eq6, eq7,eq9, eq10, eq11, eq12, eq13), th1);
-
- //reference new sales
-// RewriteInferenceSystem ris2 = new RewriteInferenceSystem(List.of(eq1, eq2, eq3, eq4, eq5, eq6, eq7), th1);
-
- //reference change value
- RewriteInferenceSystem ris2 = new RewriteInferenceSystem(List.of(eq1, eq2, eq9, eq10, eq11, eq12, eq13), th1);
-
- ris2.debug();
- ris2.inference();
-
- }
-
-
-
-
- @SneakyThrows
- static Expression parse(String expr) {
- stream.addLine(expr);
- return parser.parseTerm(stream, model);
- }
-
-
}
diff --git a/src/main/java/constants/Symbols.java b/src/main/java/constants/Symbols.java
new file mode 100644
index 0000000..b2dba87
--- /dev/null
+++ b/src/main/java/constants/Symbols.java
@@ -0,0 +1,513 @@
+package constants;
+
+import java.util.List;
+
+import models.algebra.Constant;
+import models.algebra.Expression;
+import models.algebra.Symbol;
+import models.algebra.Type;
+import parser.Parser;
+
+public class Symbols {
+
+ public static final Symbol null_ = new Symbol("null", 0, Symbol.Type.PREFIX, "null", Symbol.Type.PREFIX);
+ public static final Symbol true_ = new Symbol("true", 0, Symbol.Type.PREFIX, "true", Symbol.Type.PREFIX);
+ public static final Symbol false_ = new Symbol("false", 0, Symbol.Type.PREFIX, "false", Symbol.Type.PREFIX);
+
+ public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ if (arg0.getType() != null && arg1.getType() != null) {
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) + Double.parseDouble(sArg1)), Types.typeDouble);
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ return new Constant(Float.toString(Float.parseFloat(sArg0) + Float.parseFloat(sArg1)), Types.typeFloat);
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ return new Constant(Long.toString(Long.parseLong(sArg0) + Long.parseLong(sArg1)), Types.typeLong);
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) + Integer.parseInt(sArg1)), Types.typeInt);
+ } else if (arg0.getType().equals(Types.typeString) || arg1.getType().equals(Types.typeString)) {
+ return new Constant((String) arg0.getValue() + (String) arg1.getValue(), Types.typeString);
+ }
+ }
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) + Double.parseDouble(sArg1)), Types.typeDouble);
+ } else {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) + Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ });
+ public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ if (arg0.getType() != null && arg1.getType() != null) {
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) * Double.parseDouble(sArg1)), Types.typeDouble);
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ return new Constant(Float.toString(Float.parseFloat(sArg0) * Float.parseFloat(sArg1)), Types.typeFloat);
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ return new Constant(Long.toString(Long.parseLong(sArg0) * Long.parseLong(sArg1)), Types.typeLong);
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) * Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) * Double.parseDouble(sArg1)), Types.typeDouble);
+ } else {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) * Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ });
+ public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ if (arg0.getType() != null && arg1.getType() != null) {
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) - Double.parseDouble(sArg1)), Types.typeDouble);
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ return new Constant(Float.toString(Float.parseFloat(sArg0) - Float.parseFloat(sArg1)), Types.typeFloat);
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ return new Constant(Long.toString(Long.parseLong(sArg0) - Long.parseLong(sArg1)), Types.typeLong);
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) - Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) - Double.parseDouble(sArg1)), Types.typeDouble);
+ } else {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) - Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ });
+ public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ if (arg0.getType() != null && arg1.getType() != null) {
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) / Double.parseDouble(sArg1)), Types.typeDouble);
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ return new Constant(Float.toString(Float.parseFloat(sArg0) / Float.parseFloat(sArg1)), Types.typeFloat);
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ return new Constant(Long.toString(Long.parseLong(sArg0) / Long.parseLong(sArg1)), Types.typeLong);
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) / Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ return new Constant(Double.toString(Double.parseDouble(sArg0) / Double.parseDouble(sArg1)), Types.typeDouble);
+ } else {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) / Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ });
+ public static final Symbol mod = new Symbol(Parser.MOD, 2, Symbol.Type.INFIX, "%", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ if (arg0.getType() != null && arg1.getType() != null) {
+ if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ return new Constant(Long.toString(Long.parseLong(sArg0) % Long.parseLong(sArg1)), Types.typeLong);
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) % Integer.parseInt(sArg1)), Types.typeInt);
+ }
+ }
+ return new Constant(Integer.toString(Integer.parseInt(sArg0) % Integer.parseInt(sArg1)));
+ }
+ });
+ public static final Symbol minus = new Symbol(Parser.MINUS, 1, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg = (Constant) args.get(0);
+ String sArg = arg.getSymbol().toString();
+ if (arg.getType() != null) {
+ if (arg.getType().equals(Types.typeDouble)) {
+ return new Constant(Double.toString(-Double.parseDouble(sArg)), Types.typeDouble);
+ } else if (arg.getType().equals(Types.typeFloat)) {
+ return new Constant(Float.toString(-Float.parseFloat(sArg)), Types.typeFloat);
+ } else if (arg.getType().equals(Types.typeLong)) {
+ return new Constant(Long.toString(-Long.parseLong(sArg)), Types.typeLong);
+ } else if (arg.getType().equals(Types.typeInt)) {
+ return new Constant(Integer.toString(-Integer.parseInt(sArg)), Types.typeInt);
+ }
+ }
+ if (sArg.contains(Parser.DOT)) {
+ return new Constant(Double.toString(-Double.parseDouble(sArg)), Types.typeDouble);
+ } else {
+ return new Constant(Integer.toString(-Integer.parseInt(sArg)), Types.typeInt);
+ }
+ }
+ });
+ public static final Symbol eq = new Symbol(Parser.EQ, 2, Symbol.Type.INFIX, new Symbol.IImplGenerator() {
+ @Override
+ public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) {
+ for (String s: childrenSideEffects) {
+ sideEffect[0] += s;
+ }
+ if (childrenTypes[0] != null && childrenTypes[0].equals(Types.typeString)
+ && childrenTypes[1] != null && childrenTypes[1].equals(Types.typeString)) {
+ return children[0] + ".equals(" + children[1] + ")";
+ }
+ return "(" + children[0] + "==" + children[1] + ")";
+ }
+ }, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) {
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ result = Double.parseDouble(sArg0) == Double.parseDouble(sArg1);
+ } else {
+ result = Integer.parseInt(sArg0) == Integer.parseInt(sArg1);
+ }
+ }
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ result = (Double.parseDouble(sArg0) == Double.parseDouble(sArg1));
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ result = (Float.parseFloat(sArg0) == Float.parseFloat(sArg1));
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ result = (Long.parseLong(sArg0) == Long.parseLong(sArg1));
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ result = (Integer.parseInt(sArg0) == Integer.parseInt(sArg1));
+ } else if (arg0.getType().equals(Types.typeString) || arg1.getType().equals(Types.typeString)) {
+ result = sArg0.toString().equals(sArg1.toString());
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol neq = new Symbol(Parser.NEQ, 2, Symbol.Type.INFIX, new Symbol.IImplGenerator() {
+ @Override
+ public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) {
+ for (String s: childrenSideEffects) {
+ sideEffect[0] += s;
+ }
+ if (childrenTypes[0] != null && childrenTypes[0].equals(Types.typeString)
+ && childrenTypes[1] != null && childrenTypes[1].equals(Types.typeString)) {
+ return "!" + children[0] + ".equals(" + children[1] + ")";
+ }
+ return "(" + children[0] + "!=" + children[1] + ")";
+ }
+ }, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) {
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ result = Double.parseDouble(sArg0) != Double.parseDouble(sArg1);
+ } else {
+ result = Integer.parseInt(sArg0) != Integer.parseInt(sArg1);
+ }
+ }
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ result = (Double.parseDouble(sArg0) != Double.parseDouble(sArg1));
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ result = (Float.parseFloat(sArg0) != Float.parseFloat(sArg1));
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ result = (Long.parseLong(sArg0) != Long.parseLong(sArg1));
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ result = (Integer.parseInt(sArg0) != Integer.parseInt(sArg1));
+ } else if (arg0.getType().equals(Types.typeString) || arg1.getType().equals(Types.typeString)) {
+ result = !(sArg0.toString().equals(sArg1.toString()));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol gt = new Symbol(Parser.GT, 2, Symbol.Type.INFIX, ">", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) {
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ result = Double.parseDouble(sArg0) > Double.parseDouble(sArg1);
+ } else {
+ result = Integer.parseInt(sArg0) > Integer.parseInt(sArg1);
+ }
+ }
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ result = (Double.parseDouble(sArg0) > Double.parseDouble(sArg1));
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ result = (Float.parseFloat(sArg0) > Float.parseFloat(sArg1));
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ result = (Long.parseLong(sArg0) > Long.parseLong(sArg1));
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ result = (Integer.parseInt(sArg0) > Integer.parseInt(sArg1));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol lt = new Symbol(Parser.LT, 2, Symbol.Type.INFIX, "<", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) {
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ result = Double.parseDouble(sArg0) < Double.parseDouble(sArg1);
+ } else {
+ result = Integer.parseInt(sArg0) < Integer.parseInt(sArg1);
+ }
+ }
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ result = (Double.parseDouble(sArg0) < Double.parseDouble(sArg1));
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ result = (Float.parseFloat(sArg0) < Float.parseFloat(sArg1));
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ result = (Long.parseLong(sArg0) < Long.parseLong(sArg1));
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ result = (Integer.parseInt(sArg0) < Integer.parseInt(sArg1));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol ge = new Symbol(Parser.GE, 2, Symbol.Type.INFIX, ">=", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) {
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ result = Double.parseDouble(sArg0) >= Double.parseDouble(sArg1);
+ } else {
+ result = Integer.parseInt(sArg0) >= Integer.parseInt(sArg1);
+ }
+ }
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ result = (Double.parseDouble(sArg0) >= Double.parseDouble(sArg1));
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ result = (Float.parseFloat(sArg0) >= Float.parseFloat(sArg1));
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ result = (Long.parseLong(sArg0) >= Long.parseLong(sArg1));
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ result = (Integer.parseInt(sArg0) >= Integer.parseInt(sArg1));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol le = new Symbol(Parser.LE, 2, Symbol.Type.INFIX, "<=", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) {
+ if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
+ result = Double.parseDouble(sArg0) <= Double.parseDouble(sArg1);
+ } else {
+ result = Integer.parseInt(sArg0) <= Integer.parseInt(sArg1);
+ }
+ }
+ if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
+ result = (Double.parseDouble(sArg0) <= Double.parseDouble(sArg1));
+ } else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
+ result = (Float.parseFloat(sArg0) <= Float.parseFloat(sArg1));
+ } else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
+ result = (Long.parseLong(sArg0) <= Long.parseLong(sArg1));
+ } else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
+ result = (Integer.parseInt(sArg0) <= Integer.parseInt(sArg1));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol and = new Symbol(Parser.AND, 2, Symbol.Type.INFIX, "&&", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) return null;
+ if (arg0.getType().equals(Types.typeBoolean) || arg1.getType().equals(Types.typeBoolean)) {
+ result = (Boolean.parseBoolean(sArg0) && Boolean.parseBoolean(sArg1));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol or = new Symbol(Parser.OR, 2, Symbol.Type.INFIX, "||", Symbol.Type.INFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ if (!(args.get(1).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ Constant arg1 = (Constant) args.get(1);
+ String sArg0 = arg0.getSymbol().toString();
+ String sArg1 = arg1.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null || arg1.getType() == null) return null;
+ if (arg0.getType().equals(Types.typeBoolean) || arg1.getType().equals(Types.typeBoolean)) {
+ result = (Boolean.parseBoolean(sArg0) || Boolean.parseBoolean(sArg1));
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+ public static final Symbol neg = new Symbol(Parser.NEG, 1, Symbol.Type.PREFIX, "!", Symbol.Type.PREFIX, new Symbol.ICalculator() {
+ @Override
+ public Expression calculate(List args) {
+ if (!(args.get(0).getClass() == Constant.class)) {
+ return null;
+ }
+ Constant arg0 = (Constant) args.get(0);
+ String sArg0 = arg0.getSymbol().toString();
+ boolean result = false;
+ if (arg0.getType() == null) return null;
+ if (arg0.getType().equals(Types.typeBoolean)) {
+ result = !Boolean.parseBoolean(sArg0);
+ }
+ if (result) {
+ return new Constant(true_);
+ } else {
+ return new Constant(false_);
+ }
+ }
+ });
+
+}
diff --git a/src/main/java/constants/Types.java b/src/main/java/constants/Types.java
new file mode 100644
index 0000000..ccaa4fe
--- /dev/null
+++ b/src/main/java/constants/Types.java
@@ -0,0 +1,27 @@
+package constants;
+import models.algebra.Type;
+import parser.Parser;
+
+public class Types {
+
+ public static final Type typeInt = new Type("Int", "int");
+ public static final Type typeLong = new Type("Long", "long", typeInt);
+ public static final Type typeFloat = new Type("Float", "float", typeInt);
+ public static final Type typeDouble = new Type("Double", "double", typeFloat);
+ public static final Type typeBoolean = new Type("Bool", "boolean");
+ public static final Type typeString = new Type("Str", "String") {
+ public String valueToRepresentation(Object value) {
+ if (value instanceof String) {
+ return Parser.DOUBLE_QUOT + (String) value + Parser.DOUBLE_QUOT;
+ }
+ return value.toString();
+ }
+ public Object representationToValue(String representation) {
+ if (representation.startsWith(Parser.DOUBLE_QUOT) && representation.endsWith(Parser.DOUBLE_QUOT)) {
+ return representation.substring(1, representation.length() - 1);
+ }
+ return representation;
+ }
+ };
+
+}
diff --git a/src/main/java/models/algebra/Constant.java b/src/main/java/models/algebra/Constant.java
new file mode 100644
index 0000000..2e55f0a
--- /dev/null
+++ b/src/main/java/models/algebra/Constant.java
@@ -0,0 +1,51 @@
+package models.algebra;
+
+import java.util.ArrayList;
+
+public class Constant extends Term {
+
+ public Constant(String value) {
+ super(new Symbol(value, 0), new ArrayList());
+ }
+
+ public Constant(String value, Type type) {
+ super(new Symbol((type == null ? value: type.valueToRepresentation(value)), 0), new ArrayList());
+ symbol.setSignature(new Type[] {type});
+ }
+
+ public Constant(Symbol symbol) {
+ super(symbol);
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (!(another instanceof Constant)) return false;
+ return symbol.equals(((Constant) another).symbol);
+ }
+
+ @Override
+ public Object clone() {
+ Constant c = new Constant(symbol);
+ c.setType(type);
+ return c;
+ }
+
+ public String toString() {
+ return symbol.getName();
+ }
+
+ public Object getValue() {
+ if (getType() != null) {
+ return getType().representationToValue(symbol.getName());
+ }
+ return symbol.getName();
+ }
+
+ public String toImplementation(String[] sideEffects) {
+ if (symbol.isImplGenerative()) {
+ String exp = symbol.generate(getType(), new Type[] {}, new String[] {}, new String[] {}, sideEffects);
+ return exp;
+ }
+ return symbol.getImplName();
+ }
+}
diff --git a/src/main/java/models/algebra/Expression.java b/src/main/java/models/algebra/Expression.java
new file mode 100644
index 0000000..ba4ce79
--- /dev/null
+++ b/src/main/java/models/algebra/Expression.java
@@ -0,0 +1,36 @@
+package models.algebra;
+
+import java.util.HashMap;
+
+public abstract class Expression implements Cloneable {
+ public abstract Expression getSubTerm(Position pos);
+ /**
+ * Get the unification between this expression and another expression.
+ * @param another another expression
+ * @return unified expression
+ */
+ public abstract Expression unify(Expression another);
+ /**
+ * Get the inverse map to obtain a sub-term of a given output value back from the output value itself.
+ * @param outputValue an output value (usually a term)
+ * @param targetPos a position in outputValue
+ * @return inverse map
+ */
+ public abstract Expression getInverseMap(Expression outputValue, Position targetPos);
+ public abstract boolean contains(Expression exp);
+ public abstract Object clone();
+ public abstract HashMap getSubTerms(Class clazz);
+
+ public HashMap getVariables() {
+ return getSubTerms(Variable.class);
+ }
+
+ /**
+ * Get the implementation of this expression.
+ * @param sideEffects an array with an optional implementation that should be written before the evaluation of this expression
+ * @return the implementation to represent the value of this expression
+ */
+ public String toImplementation(String[] sideEffects) {
+ return toString();
+ }
+}
diff --git a/src/main/java/models/algebra/Field.java b/src/main/java/models/algebra/Field.java
new file mode 100644
index 0000000..b82f0fa
--- /dev/null
+++ b/src/main/java/models/algebra/Field.java
@@ -0,0 +1,46 @@
+package models.algebra;
+
+import java.util.ArrayList;
+
+/**
+ * A field in the implementation (regarded as a constant in the algebraic system)
+ * @author Nitta
+ *
+ */
+public class Field extends Constant {
+
+ public Field(String name) {
+ super(name);
+ }
+
+ public Field(String name, Type type) {
+ super(name);
+ symbol.setSignature(new Type[] {type});
+ }
+
+ public Field(Symbol symbol) {
+ super(symbol);
+ }
+
+ public Type getType() {
+ if (symbol.getSignature() != null && symbol.getSignature().length >= 1) {
+ return symbol.getSignature()[0];
+ }
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (!(another instanceof Field)) return false;
+ return symbol.equals(((Field) another).symbol);
+ }
+
+ @Override
+ public Object clone() {
+ return new Field(symbol);
+ }
+
+ public String toImplementation(String[] sideEffects) {
+ return "this." + super.toImplementation(sideEffects);
+ }
+}
diff --git a/src/main/java/models/algebra/FutureWorkException.java b/src/main/java/models/algebra/FutureWorkException.java
new file mode 100644
index 0000000..0dad4bb
--- /dev/null
+++ b/src/main/java/models/algebra/FutureWorkException.java
@@ -0,0 +1,5 @@
+package models.algebra;
+
+public class FutureWorkException extends Exception {
+
+}
diff --git a/src/main/java/models/algebra/InvalidMessage.java b/src/main/java/models/algebra/InvalidMessage.java
new file mode 100644
index 0000000..de909e5
--- /dev/null
+++ b/src/main/java/models/algebra/InvalidMessage.java
@@ -0,0 +1,5 @@
+package models.algebra;
+
+public class InvalidMessage extends Exception {
+
+}
diff --git a/src/main/java/models/algebra/LambdaAbstraction.java b/src/main/java/models/algebra/LambdaAbstraction.java
new file mode 100644
index 0000000..9898224
--- /dev/null
+++ b/src/main/java/models/algebra/LambdaAbstraction.java
@@ -0,0 +1,30 @@
+package models.algebra;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LambdaAbstraction extends Symbol {
+ private List variables = null;
+ private Term term = null;
+
+ public LambdaAbstraction(Variable variable, Term term) {
+ super("($" + variable.getName() + ")->" + term.toString(), 1, Type.LAMBDA);
+ this.variables = new ArrayList<>();
+ this.variables.add(variable);
+ this.term = term;
+ }
+
+ public LambdaAbstraction(List variables, Term term) {
+ super("($" + variables + ")->" + term.toString(), variables.size(), Type.LAMBDA);
+ this.variables = variables;
+ this.term = term;
+ }
+
+ public List getVariables() {
+ return variables;
+ }
+
+ public Term getTerm() {
+ return term;
+ }
+}
diff --git a/src/main/java/models/algebra/Parameter.java b/src/main/java/models/algebra/Parameter.java
new file mode 100644
index 0000000..5403bc1
--- /dev/null
+++ b/src/main/java/models/algebra/Parameter.java
@@ -0,0 +1,40 @@
+package models.algebra;
+
+/**
+ * A parameter in the implementation (regarded as a constant in the algebraic system)
+ * @author Nitta
+ *
+ */
+public class Parameter extends Constant {
+
+ public Parameter(String name) {
+ super(name);
+ }
+
+ public Parameter(String name, Type type) {
+ super(name);
+ symbol.setSignature(new Type[] {type});
+ }
+
+ public Parameter(Symbol symbol) {
+ super(symbol);
+ }
+
+ public Type getType() {
+ if (symbol.getSignature() != null && symbol.getSignature().length >= 1) {
+ return symbol.getSignature()[0];
+ }
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (!(another instanceof Parameter)) return false;
+ return symbol.equals(((Parameter) another).symbol);
+ }
+
+ @Override
+ public Object clone() {
+ return new Parameter(symbol);
+ }
+}
diff --git a/src/main/java/models/algebra/ParameterizedIdentifierIsFutureWork.java b/src/main/java/models/algebra/ParameterizedIdentifierIsFutureWork.java
new file mode 100644
index 0000000..3a58863
--- /dev/null
+++ b/src/main/java/models/algebra/ParameterizedIdentifierIsFutureWork.java
@@ -0,0 +1,5 @@
+package models.algebra;
+
+public class ParameterizedIdentifierIsFutureWork extends FutureWorkException {
+
+}
diff --git a/src/main/java/models/algebra/Position.java b/src/main/java/models/algebra/Position.java
new file mode 100644
index 0000000..243e274
--- /dev/null
+++ b/src/main/java/models/algebra/Position.java
@@ -0,0 +1,52 @@
+package models.algebra;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Position implements Cloneable {
+ private ArrayList orders = new ArrayList();
+
+ public Position() {
+ }
+
+ public Position(ArrayList orders) {
+ this.orders = orders;
+ }
+
+ public void addHeadOrder(int order) {
+ orders.add(0, order);
+ }
+
+ public int removeHeadOrder() {
+ return orders.remove(0);
+ }
+
+ public List getOrders() {
+ return orders;
+ }
+
+ public boolean isEmpty() {
+ return (orders == null || orders.size() == 0);
+ }
+
+ public boolean isAncestorOf(Position another) {
+ if (another.orders.size() < this.orders.size()) return false;
+ for (int i = 0; i < orders.size(); i++) {
+ if (this.orders.get(i) != another.orders.get(i)) return false;
+ }
+ return true;
+ }
+
+ public Object clone() {
+ return new Position((ArrayList) orders.clone());
+ }
+
+ public boolean equals(Object another) {
+ if (!(another instanceof Position)) return false;
+ return orders.equals(((Position) another).orders);
+ }
+
+ public int hashCode() {
+ return orders.hashCode();
+ }
+}
diff --git a/src/main/java/models/algebra/Symbol.java b/src/main/java/models/algebra/Symbol.java
new file mode 100644
index 0000000..6d6ac02
--- /dev/null
+++ b/src/main/java/models/algebra/Symbol.java
@@ -0,0 +1,295 @@
+package models.algebra;
+
+import java.util.List;
+
+public class Symbol {
+ protected String name;
+ protected String implName;
+ protected int arity = 0; // -1: variable number
+ protected Type operatorType = Type.PREFIX;
+ protected Type implOperatorType = Type.PREFIX;
+ protected Symbol[] inverses = null;
+ protected models.algebra.Type[] signature = null;
+ protected int[] implParamOrder = null;
+ protected IImplGenerator generator = null;
+ protected ICalculator calculator = null;
+
+ public Symbol(String name) {
+ this.name = name;
+ this.implName = name;
+ this.arity = 0;
+ }
+
+ public Symbol(String name, int arity) {
+ this.name = name;
+ this.implName = name;
+ this.arity = arity;
+ }
+
+ public Symbol(String name, int arity, Type operatorType) {
+ this(name, arity);
+ this.operatorType = operatorType;
+ this.implOperatorType = operatorType;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, String implName, Type implOperatorType) {
+ this.name = name;
+ this.implName = implName;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.implOperatorType = implOperatorType;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, String implName, Type implOperatorType, int[] implParamOrder) {
+ this.name = name;
+ this.implName = implName;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.implOperatorType = implOperatorType;
+ this.implParamOrder = implParamOrder;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, IImplGenerator generator) {
+ this.name = name;
+ this.implName = name;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.generator = generator;
+ this.implOperatorType = Type.GENERATIVE;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, IImplGenerator generator, boolean bSideEffect) {
+ this.name = name;
+ this.implName = name;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.generator = generator;
+ if (!bSideEffect) {
+ this.implOperatorType = Type.GENERATIVE;
+ } else {
+ this.implOperatorType = Type.GENERATIVE_WITH_SIDE_EFFECT;
+ }
+ }
+
+ public Symbol(String name, int arity, ICalculator calculator) {
+ this.name = name;
+ this.implName = name;
+ this.arity = arity;
+ this.calculator = calculator;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, ICalculator calculator) {
+ this.name = name;
+ this.implName = name;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.implOperatorType = operatorType;
+ this.calculator = calculator;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, IImplGenerator generator, ICalculator calculator) {
+ this.name = name;
+ this.implName = name;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.generator = generator;
+ this.implOperatorType = Type.GENERATIVE;
+ this.calculator = calculator;
+ }
+
+ public Symbol(String name, int arity, Type operatorType, String implName, Type implOperatorType, ICalculator calculator) {
+ this.name = name;
+ this.implName = implName;
+ this.arity = arity;
+ this.operatorType = operatorType;
+ this.implOperatorType = implOperatorType;
+ this.calculator = calculator;
+ }
+
+ public void setArity(int arity) {
+ this.arity = arity;
+ }
+
+ public int getArity() {
+ return arity;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void changeName(String name) {
+ this.name = name;
+ this.implName = name;
+ }
+
+ public Type getOperatorType() {
+ return operatorType;
+ }
+
+ public boolean isInfix() {
+ return (operatorType == Type.INFIX);
+ }
+
+ public boolean isMethod() {
+ return (operatorType == Type.METHOD || operatorType == Type.METHOD_WITH_SIDE_EFFECT);
+ }
+
+ public boolean isLambda() {
+ return (operatorType == Type.LAMBDA);
+ }
+
+ public Symbol[] getInverses() {
+ return inverses;
+ }
+
+ public void setInverses(Symbol[] inverses) {
+ this.inverses = inverses;
+ }
+
+ public models.algebra.Type[] getSignature() {
+ return signature;
+ }
+
+ public void setSignature(models.algebra.Type[] signature) {
+ this.signature = signature;
+ }
+
+ public String getImplName() {
+ return implName;
+ }
+
+ public void setImplName(String implName) {
+ this.implName = implName;
+ }
+
+ public Type getImplOperatorType() {
+ return implOperatorType;
+ }
+
+ public boolean isImplInfix() {
+ return (implOperatorType == Type.INFIX);
+ }
+
+ public boolean isImplMethod() {
+ return (implOperatorType == Type.METHOD || implOperatorType == Type.METHOD_WITH_SIDE_EFFECT);
+ }
+
+ public boolean isImplLambda() {
+ return (implOperatorType == Type.LAMBDA || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT);
+ }
+
+ public boolean isImplGenerative() {
+ return (implOperatorType == Type.GENERATIVE || implOperatorType == Type.GENERATIVE_WITH_SIDE_EFFECT);
+ }
+
+ public boolean isImplWithSideEffect() {
+ return (implOperatorType == Type.METHOD_WITH_SIDE_EFFECT
+ || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT
+ || implOperatorType == Type.GENERATIVE_WITH_SIDE_EFFECT);
+ }
+
+ public void setImplOperatorType(Type implOperatorType) {
+ this.implOperatorType = implOperatorType;
+ }
+
+ public int[] getImplParamOrder() {
+ return implParamOrder;
+ }
+
+ public void setGenerator(IImplGenerator generator) {
+ this.generator = generator;
+ }
+
+ /**
+ * Generate the implementation of this symbol
+ * @param type the type of this symbol
+ * @param childrenTypes
+ * @param childrenImpl the implementations of the children
+ * @param childrenSideEffects (input) an array of the side effects of the children
+ * @param sideEffect (output) an array of the side effect of this symbol
+ * @return the implementation
+ */
+ public String generate(models.algebra.Type type, models.algebra.Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) {
+ if (generator != null) {
+ return generator.generate(type, childrenTypes, childrenImpl, childrenSideEffects, sideEffect);
+ }
+ return null;
+ }
+
+ public boolean isCalculatable() {
+ return (calculator != null);
+ }
+
+ public Expression calculate(List args) {
+ if (calculator != null) {
+ return calculator.calculate(args);
+ }
+ return null;
+ }
+
+ public boolean equals(Object another) {
+ if (!(another instanceof Symbol)) return false;
+ return name.equals(((Symbol) another).name) && arity == ((Symbol) another).arity;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public String toImplementation() {
+ return implName;
+ }
+
+ public enum Type {
+ PREFIX,
+ INFIX,
+ METHOD,
+ METHOD_WITH_SIDE_EFFECT,
+ LAMBDA,
+ LAMBDA_WITH_SIDE_EFFECT,
+ GENERATIVE,
+ GENERATIVE_WITH_SIDE_EFFECT
+ }
+
+ public Memento createMemento() {
+ return new Memento(implName, implOperatorType);
+ }
+
+ public void setMemento(Memento memento) {
+ this.implName = memento.implName;
+ this.implOperatorType = memento.implOperatorType;
+ }
+
+ public static class Memento {
+ private String implName;
+ private Type implOperatorType = Type.PREFIX;
+
+ public Memento(String implName, Type implOperatorType) {
+ this.implName = implName;
+ this.implOperatorType = implOperatorType;
+ }
+ }
+
+ public interface IImplGenerator {
+ /**
+ * Generate the implementation
+ * @param type the type of this expression
+ * @param childrenTypes
+ * @param children the implementations of the children
+ * @param childrenSideEffects (input) an array of the side effects of the children
+ * @param sideEffect (output) an array of the side effect of this generator
+ * @return the generated implementation
+ */
+ public String generate(models.algebra.Type type, models.algebra.Type[] childrenTypes, String children[], String[] childrenSideEffects, String[] sideEffect);
+ }
+
+ public interface ICalculator {
+ public Expression calculate(List args);
+ }
+}
diff --git a/src/main/java/models/algebra/Term.java b/src/main/java/models/algebra/Term.java
new file mode 100644
index 0000000..06c906c
--- /dev/null
+++ b/src/main/java/models/algebra/Term.java
@@ -0,0 +1,448 @@
+package models.algebra;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+public class Term extends Expression {
+ protected Symbol symbol = null;
+ protected List children = new ArrayList<>();
+ protected Type type = null;
+
+ public Term(Symbol symbol) {
+ super();
+ this.symbol = symbol;
+ }
+
+ public Term(Symbol symbol, List children) {
+ super();
+ this.symbol = symbol;
+ this.children = children;
+ }
+
+ public Term(Symbol symbol, Expression[] children) {
+ super();
+ this.symbol = symbol;
+ this.children = new ArrayList<>(Arrays.asList(children));
+ }
+
+ public Symbol getSymbol() {
+ return symbol;
+ }
+
+ public int getArity() {
+ return symbol.getArity();
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public Type getType() {
+ if (type == null) {
+ if (symbol.getSignature() == null) return null;
+ return symbol.getSignature()[0];
+ }
+ return type;
+ }
+
+ public boolean addChild(Expression child) {
+ if (getArity() != -1 && children.size() >= getArity()) return false;
+ children.add(child);
+ return true;
+ }
+
+ public boolean setChild(int n, Expression child) {
+ if (getArity() != -1 && n >= getArity()) return false;
+ children.set(n, child);
+ return true;
+ }
+
+ public void addChild(Expression child, boolean bForced) {
+ if (!bForced && getArity() != -1 && children.size() >= getArity()) return;
+ children.add(child);
+ }
+
+ public void addChild(int n, Expression child, boolean bForced) {
+ if (!bForced && getArity() != -1 && children.size() >= getArity()) return;
+ children.add(n, child);
+ }
+
+ public Expression getChild(int n) {
+ return children.get(n);
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public HashMap getSubTerms(Class clazz) {
+ HashMap subTerms = new HashMap<>();
+ Class thisClass = this.getClass();
+ while (thisClass != null) {
+ if (clazz == thisClass) {
+ subTerms.put(new Position(), (T) this);
+ break;
+ }
+ thisClass = thisClass.getSuperclass();
+ }
+ for (int i = 0; i < children.size(); i++) {
+ if (children.get(i) != null) {
+ HashMap terms = children.get(i).getSubTerms(clazz);
+ for (Entry term: terms.entrySet()) {
+ Position pos = term.getKey();
+ pos.addHeadOrder(i);
+ subTerms.put(pos, term.getValue());
+ }
+ }
+ }
+ return subTerms;
+ }
+
+ public Expression getSubTerm(Position pos) {
+ if (pos.isEmpty()) return this;
+ pos = (Position) pos.clone();
+ int i = pos.removeHeadOrder();
+ if (i >= children.size()) return null;
+ if (children.get(i) == null) return null;
+ return children.get(i).getSubTerm(pos);
+ }
+
+ public Term substitute(Variable variable, Expression value) {
+ Term newTerm = (Term) this.clone();
+ HashMap variables = getVariables();
+ for (Entry varEnt: variables.entrySet()) {
+ if (varEnt.getValue().equals(variable)) {
+ newTerm.replaceSubTerm(varEnt.getKey(), value);
+ }
+ }
+ return newTerm;
+ }
+
+ public void replaceSubTerm(Position pos, Expression newSubTerm) {
+ if (pos.isEmpty()) return;
+ pos = (Position) pos.clone();
+ int i = pos.removeHeadOrder();
+ if (pos.isEmpty()) {
+ children.set(i, newSubTerm);
+ } else {
+ if (!(children.get(i) instanceof Term)) return;
+ ((Term) children.get(i)).replaceSubTerm(pos, newSubTerm);
+ }
+ }
+
+ @Override
+ public Expression unify(Expression another) {
+ if (another instanceof Variable) return (Expression) this.clone();
+ if (this instanceof Constant) return (Expression) this.clone();
+ if (another instanceof Constant) return (Expression) another.clone();
+ if (another instanceof Term) {
+ Term anotherTerm = (Term) another;
+ if (!symbol.equals(anotherTerm.symbol)) return null;
+ if (children.size() != anotherTerm.children.size()) return null;
+ Term unifiedTerm = new Term(symbol);
+ for (int i = 0; i < children.size(); i++) {
+ if (children.get(i) != null) {
+ unifiedTerm.addChild(children.get(i).unify(anotherTerm.children.get(i)));
+ } else {
+ unifiedTerm.addChild(anotherTerm.children.get(i));
+ }
+ }
+ return unifiedTerm;
+ } else {
+ return null;
+ }
+ }
+
+ public Expression reduce() {
+ if (symbol.isLambda()) {
+ // Lambda beta-reduction
+ LambdaAbstraction newSymbol = ((LambdaAbstraction) symbol);
+ Term newTerm = newSymbol.getTerm();
+ List newVariables = newSymbol.getVariables();
+ List newChildren = children;
+ while (newVariables.size() > 0 && newChildren.size() > 0) {
+ newTerm = newTerm.substitute(newVariables.get(0), newChildren.get(0));
+ newVariables = newVariables.subList(1, newVariables.size());
+ newChildren = newChildren.subList(1, newChildren.size());
+ newSymbol = new LambdaAbstraction(newVariables, newTerm);
+ }
+ if (newSymbol.arity == 0 && newChildren.size() == 0) {
+ return newTerm;
+ } else {
+ return new Term(newSymbol, newChildren);
+ }
+ } else if (symbol.isCalculatable()) {
+ List newChildren = new ArrayList<>();
+ for (Expression child: children) {
+ if (child instanceof Term) {
+ child = ((Term) child).reduce();
+ }
+ newChildren.add(child);
+ }
+ Expression newTerm = symbol.calculate(newChildren);
+ if (newTerm == null) return this;
+ return newTerm;
+ } else {
+ // Calculate inverse map
+ List newChildren = new ArrayList<>();
+ boolean bReduced = false;
+ for (Expression child: children) {
+ if (child instanceof Term && !(child instanceof Constant)) {
+ Expression newChild = ((Term) (child)).reduce();
+ if (newChild != child) {
+ bReduced = true;
+ child = newChild;
+ }
+ }
+ newChildren.add(child);
+ }
+ if (symbol.arity == 1 && newChildren.size() == 1) {
+ Expression child = newChildren.get(0);
+ if (child instanceof Term && !(child instanceof Constant)) {
+ Symbol childSymbol = ((Term) child).getSymbol();
+ if (childSymbol.getInverses() != null) {
+ for (int i = 0; i < childSymbol.getInverses().length; i++) {
+ if (symbol.equals(childSymbol.getInverses()[i])) {
+ return ((Term) child).getChild(i);
+ }
+ }
+ }
+ }
+ }
+ if (!bReduced) return this;
+ Term newTerm = (Term) this.clone();
+ newTerm.children = newChildren;
+ return newTerm;
+ }
+ }
+
+ @Override
+ public Expression getInverseMap(Expression outputValue, Position targetPos) {
+ if (targetPos.isEmpty()) return outputValue;
+ targetPos = (Position) targetPos.clone();
+ int i = targetPos.removeHeadOrder();
+ Symbol[] inverseSymbols = symbol.getInverses();
+ if (inverseSymbols == null || i >= inverseSymbols.length || inverseSymbols[i] == null) return null;
+ Term inverseMap = new Term(inverseSymbols[i]);
+ inverseMap.addChild(outputValue);
+ for (int n = 0; n < inverseSymbols[i].getArity(); n++) {
+ if (n != i) {
+ inverseMap.addChild(children.get(n));
+ }
+ }
+ return children.get(i).getInverseMap(inverseMap, targetPos);
+ }
+
+ @Override
+ public boolean contains(Expression exp) {
+ if (equals(exp)) return true;
+ for (Expression e: children) {
+ if (e.contains(exp)) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (!(another instanceof Term)) return false;
+ if (this == another) return true;
+ Term anotherTerm = (Term) another;
+ if (!symbol.equals(anotherTerm.symbol)) return false;
+ if (children.size() != anotherTerm.children.size()) return false;
+ if (type != anotherTerm.type) return false;
+ for (int i = 0; i < children.size(); i++) {
+ Expression e = children.get(i);
+ Expression e2 = anotherTerm.children.get(i);
+ if (!e.equals(e2)) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return symbol.hashCode();
+ }
+
+
+ @Override
+ public Object clone() {
+ Term newTerm = new Term(symbol);
+ for (Expression e: children) {
+ if (e != null) {
+ newTerm.addChild((Expression) e.clone());
+ } else {
+ newTerm.addChild(null);
+ }
+ }
+ newTerm.type = type;
+ return newTerm;
+ }
+
+ public String toString() {
+ if (getArity() == 2 && symbol.isInfix()) {
+ return "(" + children.get(0) + symbol.toString() + children.get(1) + ")";
+ }
+ if ((getArity() >= 1 || getArity() == -1) && symbol.isMethod()) {
+ String exp = children.get(0).toString() + "." + symbol.toString() + "(";
+ String delimiter = "";
+ for (int i = 1; i < children.size(); i++) {
+ Expression e = children.get(i);
+ exp += (delimiter + e.toString());
+ delimiter = ",";
+ }
+ return exp + ")";
+ } else {
+ String exp = symbol.toString() + "(";
+ String delimiter = "";
+ for (Expression e: children) {
+ if (e != null) {
+ exp += (delimiter + e.toString());
+ } else {
+ exp += (delimiter + "null");
+ }
+ delimiter = ",";
+ }
+ return exp + ")";
+ }
+ }
+
+
+ public String toImplementation(String[] sideEffects) {
+ int[] implParamOrder = symbol.getImplParamOrder();
+ if (symbol.isImplLambda()) {
+ String[] components = symbol.getImplName().split("->");
+ String component0 = components[0].replace("(", "").replace(")", "");
+ String[] params = component0.split(",");
+ String exp = components[1];
+ String receiver = "";
+ if (implParamOrder == null) {
+ receiver = children.get(0).toImplementation(sideEffects);
+ exp = exp.replace(params[0], receiver);
+ for (int i = 1; i < params.length; i++) {
+ exp = exp.replace(params[i], children.get(i).toImplementation(sideEffects));
+ }
+ } else {
+ receiver = children.get(implParamOrder[0]).toImplementation(sideEffects);
+ exp = exp.replace(params[0], receiver);
+ for (int i = 1; i < params.length; i++) {
+ exp = exp.replace(params[i], children.get(implParamOrder[i]).toImplementation(sideEffects));
+ }
+ }
+ if (symbol.isImplWithSideEffect()) {
+ sideEffects[0] = sideEffects[0] + exp + ";\n";
+ exp = receiver;
+ }
+ return exp;
+ }
+ if (symbol.isImplGenerative()) {
+ Type childrenTypes[] = new Type[children.size()];
+ String childrenImpl[] = new String[children.size()];
+ String childrenSideEffects[] = new String[children.size()];
+ if (implParamOrder == null) {
+ for (int i = 0; i < children.size(); i++) {
+ Expression child = children.get(i);
+ if (child instanceof Variable) {
+ childrenTypes[i] = ((Variable) child).getType();
+ } else if (child instanceof Term) {
+ childrenTypes[i] = ((Term) child).getType();
+ }
+ String childSideEffect[] = new String[] {""};
+ childrenImpl[i] = child.toImplementation(childSideEffect);
+ childrenSideEffects[i] = childSideEffect[0];
+ }
+ String exp = symbol.generate(getType(), childrenTypes, childrenImpl, childrenSideEffects, sideEffects);
+ if (symbol.isImplWithSideEffect()) {
+ sideEffects[0] = sideEffects[0] + exp;
+ exp = childrenImpl[0]; // the value of this term
+ }
+ return exp;
+ } else {
+ for (int i = 0; i < children.size(); i++) {
+ Expression child = children.get(implParamOrder[i]);
+ if (child instanceof Variable) {
+ childrenTypes[i] = ((Variable) child).getType();
+ } else if (child instanceof Term) {
+ childrenTypes[i] = ((Term) child).getType();
+ }
+ String childSideEffect[] = new String[] {""};
+ childrenImpl[i] = child.toImplementation(childSideEffect);
+ childrenSideEffects[i] = childSideEffect[0];
+ }
+ String exp = symbol.generate(getType(), childrenTypes, childrenImpl, childrenSideEffects, sideEffects);
+ if (symbol.isImplWithSideEffect()) {
+ sideEffects[0] = sideEffects[0] + exp;
+ exp = childrenImpl[0]; // the value of this term
+ }
+ return exp;
+ }
+ }
+ if (getArity() == 2 && symbol.isImplInfix()) {
+ if (implParamOrder == null) {
+ return "(" + children.get(0).toImplementation(sideEffects) + symbol.toImplementation() + children.get(1).toImplementation(sideEffects) + ")";
+ } else {
+ return "(" + children.get(implParamOrder[0]).toImplementation(sideEffects) + symbol.toImplementation() + children.get(implParamOrder[1]).toImplementation(sideEffects) + ")";
+ }
+ }
+ if ((getArity() >= 1 || getArity() == -1) && symbol.isImplMethod()) {
+ if (implParamOrder == null) {
+ String exp = null;
+ String receiver = "";
+ if (children.size() > 0 && children.get(0) != null) {
+ receiver = children.get(0).toImplementation(sideEffects);
+ exp = receiver + "." + symbol.toImplementation() + "(";
+ } else {
+ exp = symbol.toImplementation() + "(";
+ }
+ String delimiter = "";
+ for (int i = 1; i < children.size(); i++) {
+ Expression e = children.get(i);
+ exp += (delimiter + e.toImplementation(sideEffects));
+ delimiter = ",";
+ }
+ exp += ")";
+ if (symbol.isImplWithSideEffect()) {
+ sideEffects[0] = sideEffects[0] + exp + ";\n";
+ exp = receiver;
+ }
+ return exp;
+ } else {
+ String receiver = children.get(implParamOrder[0]).toImplementation(sideEffects);
+ String exp = receiver + "." + symbol.toImplementation() + "(";
+ String delimiter = "";
+ for (int i = 1; i < children.size(); i++) {
+ Expression e = children.get(implParamOrder[i]);
+ exp += (delimiter + e.toImplementation(sideEffects));
+ delimiter = ",";
+ }
+ exp += ")";
+ if (symbol.isImplWithSideEffect()) {
+ sideEffects[0] = sideEffects[0] + exp + ";\n";
+ exp = receiver;
+ }
+ return exp;
+ }
+ } else {
+ if (implParamOrder == null) {
+ String exp = symbol.toImplementation() + "(";
+ String delimiter = "";
+ for (Expression e: children) {
+ exp += (delimiter + e.toImplementation(sideEffects));
+ delimiter = ",";
+ }
+ return exp + ")";
+ } else {
+ String exp = symbol.toImplementation() + "(";
+ String delimiter = "";
+ for (int i = 0; i < children.size(); i++) {
+ Expression e = children.get(implParamOrder[i]);
+ exp += (delimiter + e.toImplementation(sideEffects));
+ delimiter = ",";
+ }
+ return exp + ")";
+ }
+ }
+ }
+}
diff --git a/src/main/java/models/algebra/Type.java b/src/main/java/models/algebra/Type.java
new file mode 100644
index 0000000..207cb6c
--- /dev/null
+++ b/src/main/java/models/algebra/Type.java
@@ -0,0 +1,124 @@
+package models.algebra;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Type {
+ private String typeName;
+ private String implementationTypeName;
+ private String interfaceTypeName;
+ private List parentTypes = new ArrayList<>();
+
+ public Type(String typeName, String implementationTypeName) {
+ this.typeName = typeName;
+ this.implementationTypeName = implementationTypeName;
+ this.interfaceTypeName = implementationTypeName;
+ }
+
+ public Type(String typeName, String implementationTypeName, String interfaceTypeName) {
+ this.typeName = typeName;
+ this.implementationTypeName = implementationTypeName;
+ this.interfaceTypeName = interfaceTypeName;
+ }
+
+ public Type(String typeName, String implementationTypeName, Type parentType) {
+ this.typeName = typeName;
+ this.implementationTypeName = implementationTypeName;
+ this.interfaceTypeName = implementationTypeName;
+ this.parentTypes.add(parentType);
+ }
+
+ public Type(String typeName, String implementationTypeName, String interfaceTypeName, Type parentType) {
+ this.typeName = typeName;
+ this.implementationTypeName = implementationTypeName;
+ this.interfaceTypeName = interfaceTypeName;
+ this.parentTypes.add(parentType);
+ }
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public void setTypeName(String typeName) {
+ this.typeName = typeName;
+ }
+
+ public String getImplementationTypeName() {
+ return implementationTypeName;
+ }
+
+ public void setImplementationTypeName(String implementastionTypeName) {
+ this.implementationTypeName = implementastionTypeName;
+ }
+
+ public String getInterfaceTypeName() {
+ return interfaceTypeName;
+ }
+
+ public void setInterfaceTypeName(String interfaceTypeName) {
+ this.interfaceTypeName = interfaceTypeName;
+ }
+
+ public List getParentTypes() {
+ return parentTypes;
+ }
+
+ public void addParentType(Type parentType) {
+ parentTypes.add(parentType);
+ }
+
+ public void replaceParentType(Type oldParentType, Type newParentType) {
+ parentTypes.set(parentTypes.indexOf(oldParentType), newParentType);
+ }
+
+ public boolean isAncestorOf(Type another) {
+ if (this.equals(another)) return true;
+ if (another == null || another.getParentTypes() == null) return false;
+ for (Type anothersParentType: another.getParentTypes()) {
+ if (isAncestorOf(anothersParentType)) return true;
+ }
+ return false;
+ }
+
+ public String valueToRepresentation(Object value) {
+ if (value instanceof String) return (String) value;
+ return value.toString();
+ }
+
+ public Object representationToValue(String representation) {
+ return representation;
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ if (another == null) return false;
+ if (!(another instanceof Type)) return false;
+ if (!typeName.equals(((Type) another).typeName)) return false;
+ if (!implementationTypeName.equals(((Type) another).implementationTypeName)) return false;
+ if (!interfaceTypeName.equals(((Type) another).interfaceTypeName)) return false;
+ return true;
+ }
+
+ public Memento createMemento() {
+ return new Memento(implementationTypeName, interfaceTypeName, parentTypes);
+ }
+
+ public void setMemento(Memento memento) {
+ this.implementationTypeName = memento.implementationTypeName;
+ this.interfaceTypeName = memento.interfaceTypeName;
+ this.parentTypes = memento.parentTypes;
+ }
+
+ public static class Memento {
+ private String implementationTypeName;
+ private String interfaceTypeName;
+ private List parentTypes;
+
+ public Memento(String implementationTypeName, String interfaceTypeName, List parentTypes) {
+ this.implementationTypeName = implementationTypeName;
+ this.interfaceTypeName = interfaceTypeName;
+ this.parentTypes = parentTypes;
+ }
+ }
+}
diff --git a/src/main/java/models/algebra/UnificationFailed.java b/src/main/java/models/algebra/UnificationFailed.java
new file mode 100644
index 0000000..46e06a7
--- /dev/null
+++ b/src/main/java/models/algebra/UnificationFailed.java
@@ -0,0 +1,5 @@
+package models.algebra;
+
+public class UnificationFailed extends Exception {
+
+}
diff --git a/src/main/java/models/algebra/ValueUndefined.java b/src/main/java/models/algebra/ValueUndefined.java
new file mode 100644
index 0000000..61dab0e
--- /dev/null
+++ b/src/main/java/models/algebra/ValueUndefined.java
@@ -0,0 +1,5 @@
+package models.algebra;
+
+public class ValueUndefined extends Exception {
+
+}
diff --git a/src/main/java/models/algebra/Variable.java b/src/main/java/models/algebra/Variable.java
new file mode 100644
index 0000000..a3161a9
--- /dev/null
+++ b/src/main/java/models/algebra/Variable.java
@@ -0,0 +1,87 @@
+package models.algebra;
+
+import java.util.HashMap;
+
+public class Variable extends Expression {
+ private String name;
+ private Type type = null;
+
+ public Variable(String name) {
+ super();
+ this.name = name;
+ }
+
+ public Variable(String name, Type type) {
+ super();
+ this.name = name;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public HashMap getSubTerms(Class clazz) {
+ HashMap subTerms = new HashMap<>();
+ if (clazz == this.getClass()) {
+ subTerms.put(new Position(), (T) this);
+ }
+ return subTerms;
+ }
+
+ @Override
+ public Expression getSubTerm(Position pos) {
+ if (pos.isEmpty()) return this;
+ return null;
+ }
+
+ @Override
+ public Expression unify(Expression another) {
+ return (Expression) another.clone();
+ }
+
+ @Override
+ public Expression getInverseMap(Expression outputValue, Position targetPos) {
+ if (targetPos.isEmpty()) return outputValue;
+ return null;
+ }
+
+ @Override
+ public boolean contains(Expression exp) {
+ return equals(exp);
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (!(another instanceof Variable)) return false;
+ return name.equals(((Variable) another).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public Object clone() {
+ return new Variable(name, type);
+ }
+
+ public String toString() {
+ if (type == null) return name;
+ return name + ":" + type.getTypeName();
+ }
+
+ public String toImplementation(String[] sideEffects) {
+ return name;
+ }
+}
diff --git a/src/main/java/parser/Parser.java b/src/main/java/parser/Parser.java
new file mode 100644
index 0000000..aa61b9c
--- /dev/null
+++ b/src/main/java/parser/Parser.java
@@ -0,0 +1,429 @@
+package parser;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import constants.Symbols;
+import constants.Types;
+import models.algebra.Constant;
+import models.algebra.Expression;
+import models.algebra.Symbol;
+import models.algebra.Term;
+import models.algebra.Variable;
+import parser.exceptions.ExpectedDoubleQuotation;
+import parser.exceptions.ExpectedRightBracket;
+
+public class Parser {
+ protected TokenStream stream;
+
+ public static final String LEFT_BRACKET = "(";
+ public static final String RIGHT_BRACKET = ")";
+ public static final String LEFT_BRACKET_REGX = "\\(";
+ public static final String RIGHT_BRACKET_REGX = "\\)";
+ public static final String ADD = "+";
+ public static final String MUL = "*";
+ public static final String SUB = "-";
+ public static final String DIV = "/";
+ public static final String MOD = "%";
+ public static final String MINUS = "-";
+ public static final String EQ = "==";
+ public static final String NEQ = "!=";
+ public static final String GT = ">";
+ public static final String LT = "<";
+ public static final String GE = ">=";
+ public static final String LE = "<=";
+ public static final String AND = "&&";
+ public static final String OR = "||";
+ public static final String NEG = "!";
+ public static final String ADD_REGX = "\\+";
+ public static final String MUL_REGX = "\\*";
+ public static final String SUB_REGX = "\\-";
+ public static final String DIV_REGX = "/";
+ public static final String OR_REGX = "\\|\\|";
+ public static final String EQUALS = "=";
+ public static final String ASSIGNMENT = "=";
+ public static final String COMMA = ",";
+ public static final String COLON = ":";
+ public static final String DOT = ".";
+ public static final String DOT_REGX = "\\.";
+ public static final String DOUBLE_QUOT = "\"";
+
+ public Parser(final TokenStream stream) {
+ this.stream = stream;
+ }
+
+ public Parser(final BufferedReader reader) {
+ this.stream = new TokenStream();
+ try {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ stream.addLine(line);
+ }
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Expression parseTerm(TokenStream stream) throws ExpectedRightBracket, ExpectedDoubleQuotation {
+ ArrayList expressions = new ArrayList<>();
+ ArrayList operators = new ArrayList<>();
+ String operator = null;
+ for (;;) {
+ String leftBracketOrMinusOrNeg = stream.next();
+ if (leftBracketOrMinusOrNeg.equals(LEFT_BRACKET)) {
+ Expression exp = parseTerm(stream);
+ String rightBracket = stream.next();
+ if (!rightBracket.equals(RIGHT_BRACKET)) throw new ExpectedRightBracket(stream.getLine());
+ expressions.add(exp);
+ } else {
+ Symbol minusOrNeg = null;
+ String symbolName = null;
+ if (leftBracketOrMinusOrNeg.equals(MINUS)) {
+ minusOrNeg = Symbols.minus; // not sub
+ symbolName = stream.next();
+ } else if (leftBracketOrMinusOrNeg.equals(NEG)) {
+ minusOrNeg = Symbols.neg;
+ symbolName = stream.next();
+ } else if (leftBracketOrMinusOrNeg.equals(DOUBLE_QUOT)) {
+ symbolName = DOUBLE_QUOT + stream.next() + DOUBLE_QUOT;
+ String doubleQuot = stream.next();
+ if (!doubleQuot.equals(DOUBLE_QUOT)) throw new ExpectedDoubleQuotation(stream.getLine());
+ } else {
+ symbolName = leftBracketOrMinusOrNeg;
+ }
+ Expression exp = null;
+ if (Character.isDigit(symbolName.charAt(0))) {
+ // maybe a numerical value
+ if (stream.checkNext() != null && stream.checkNext().equals(DOT)) {
+ // Because tokens are separated by a DOT.
+ stream.next();
+ symbolName += DOT + stream.next(); // decimal fraction
+ }
+ Double d = Double.parseDouble(symbolName);
+ // a numerical value
+ if (symbolName.contains(DOT)) {
+ exp = new Constant(symbolName, Types.typeDouble);
+ } else {
+ exp = new Constant(symbolName, Types.typeInt);
+ }
+ } else if (symbolName.startsWith(DOUBLE_QUOT) && symbolName.endsWith(DOUBLE_QUOT)) {
+ // a string value
+ exp = new Constant(symbolName.substring(1, symbolName.length() - 1), Types.typeString);
+ } else {
+ // a variable
+ exp = parseVariable(stream, symbolName);
+ }
+
+ if (minusOrNeg != null) {
+ Term minusOrNegTerm = new Term(minusOrNeg);
+ minusOrNegTerm.addChild(exp);
+ expressions.add(minusOrNegTerm);
+ } else {
+ expressions.add(exp);
+ }
+ }
+ operator = stream.checkNext();
+ if (operator == null) {
+ break;
+ } else if (operator.equals(ADD)) {
+ operators.add(Symbols.add);
+ stream.next();
+ } else if (operator.equals(MUL)) {
+ operators.add(Symbols.mul);
+ stream.next();
+ } else if (operator.equals(SUB)) {
+ operators.add(Symbols.sub); // not minus
+ stream.next();
+ } else if (operator.equals(DIV)) {
+ operators.add(Symbols.div);
+ stream.next();
+ } else if (operator.equals(MOD)) {
+ operators.add(Symbols.mod);
+ stream.next();
+ } else if (operator.equals(EQ)) {
+ operators.add(Symbols.eq);
+ stream.next();
+ } else if (operator.equals(NEQ)) {
+ operators.add(Symbols.neq);
+ stream.next();
+ } else if (operator.equals(GT)) {
+ operators.add(Symbols.gt);
+ stream.next();
+ } else if (operator.equals(LT)) {
+ operators.add(Symbols.lt);
+ stream.next();
+ } else if (operator.equals(GE)) {
+ operators.add(Symbols.ge);
+ stream.next();
+ } else if (operator.equals(LE)) {
+ operators.add(Symbols.le);
+ stream.next();
+// } else if (operator.equals(AND)) {
+// operators.add(Symbols.and);
+// stream.next();
+// } else if (operator.equals(OR)) {
+// operators.add(Symbols.or);
+// stream.next();
+ } else {
+ break;
+ }
+ }
+ if (expressions.size() == 1) {
+ // no arithmetic operators
+ return expressions.get(0);
+ }
+ ArrayList monomials = new ArrayList<>();
+ ArrayList addSubs = new ArrayList<>();
+ Expression first = expressions.get(0);
+ int i = 1;
+ Term rootTerm = null;
+ for (Symbol op: operators) {
+ Expression second = expressions.get(i);
+ if (op.getName().equals(MUL) || op.getName().equals(DIV) || op.getName().equals(MOD)) {
+ // higher priority than add and sub
+ Term term = new Term(op);
+ term.addChild(first);
+ term.addChild(second);
+ first = term;
+ } else if (op.getName().equals(EQ) || op.getName().equals(NEQ) || op.getName().equals(GT) || op.getName().equals(LT)
+ || op.getName().equals(GE) || op.getName().equals(LE) || op.getName().equals(AND) || op.getName().equals(OR)) {
+ // lower priority than add and sub
+ if (first != null) monomials.add(first);
+ Expression firstMonomial = monomials.get(0);
+ int j = 1;
+ for (Symbol op2: addSubs) {
+ Expression secondMonomial = monomials.get(j);
+ Term term = new Term(op2);
+ term.addChild(firstMonomial);
+ term.addChild(secondMonomial);
+ firstMonomial = term;
+ j++;
+ }
+ if (rootTerm == null) {
+ rootTerm = new Term(op);
+ rootTerm.addChild(firstMonomial);
+ } else {
+ rootTerm.addChild(firstMonomial);
+ firstMonomial = rootTerm;
+ rootTerm = new Term(op);
+ rootTerm.addChild(firstMonomial);
+ }
+ monomials.clear();
+ addSubs.clear();
+ first = second;
+ } else {
+ // add or sub ==> new monomial
+ monomials.add(first);
+ addSubs.add(op);
+ first = second;
+ }
+ i++;
+ }
+ if (first != null) monomials.add(first);
+ Expression firstMonomial = monomials.get(0);
+ i = 1;
+ for (Symbol op: addSubs) {
+ Expression secondMonomial = monomials.get(i);
+ Term term = new Term(op);
+ term.addChild(firstMonomial);
+ term.addChild(secondMonomial);
+ firstMonomial = term;
+ i++;
+ }
+ if (rootTerm == null) {
+ return firstMonomial;
+ } else {
+ rootTerm.addChild(firstMonomial);
+ return rootTerm;
+ }
+ }
+
+ public Variable parseVariable(TokenStream stream, String symbolName) {
+ return new Variable(symbolName);
+ }
+
+
+ protected Boolean doesMatchToKeyword(final String token, final String specificTokenName) {
+ if(token == null) return false;
+ if(specificTokenName == null) return false;
+ return token.equals(specificTokenName);
+ }
+
+ public static class TokenStream {
+ private ArrayList> tokens = new ArrayList<>();
+ private ArrayList lines = new ArrayList<>();
+ private int line = 0;
+ private int n = 0;
+
+ public TokenStream() {
+ line = 0;
+ n = 0;
+ }
+
+ public void addLine(String line) {
+ lines.add(line);
+ line = line.trim();
+ ArrayList tokenList = splitByDoubleQuotation(line);
+ tokenList = splitBy(tokenList, ADD, ADD_REGX);
+ tokenList = splitBy(tokenList, MUL, MUL_REGX);
+ tokenList = splitBy(tokenList, SUB, SUB_REGX);
+ tokenList = splitBy(tokenList, DIV, DIV_REGX);
+ tokenList = splitBy(tokenList, MOD, MOD);
+ tokenList = splitBy(tokenList, EQ, EQ);
+ tokenList = splitBy(tokenList, NEQ, NEQ);
+ tokenList = splitBy(tokenList, GE, GE);
+ tokenList = splitBy(tokenList, LE, LE);
+ tokenList = splitBy(tokenList, GT, GT);
+ tokenList = splitBy(tokenList, LT, LT);
+ tokenList = splitBy(tokenList, AND, AND);
+ tokenList = splitBy(tokenList, OR, OR_REGX);
+ tokenList = splitBy(tokenList, NEG, NEG);
+ tokenList = splitBy(tokenList, DOT, DOT_REGX);
+ tokenList = splitBy(tokenList, COMMA, COMMA);
+ tokenList = splitBy(tokenList, COLON, COLON);
+ tokenList = splitBy(tokenList, LEFT_BRACKET, LEFT_BRACKET_REGX);
+ tokenList = splitBy(tokenList, RIGHT_BRACKET, RIGHT_BRACKET_REGX);
+ tokenList = splitBy(tokenList, EQUALS, EQUALS);
+ tokens.add(tokenList);
+ }
+
+ private ArrayList splitBy(final List tokens, final String delimiter, final String delimiterRegx) {
+ ArrayList newTokens = new ArrayList<>();
+ for (Token token: tokens) {
+ if (token.isAtomic()) {
+ newTokens.add(token);
+ } else {
+ String[] splitTokens = token.split(delimiterRegx);
+ boolean fFirstToken = true;
+ for (String t: splitTokens) {
+ if (!fFirstToken) {
+ newTokens.add(new Token(delimiter, true));
+ }
+ if (t.length() > 0) {
+ newTokens.add(new Token(t));
+ }
+ fFirstToken = false;
+ }
+ while (token.endsWith(delimiter)) {
+ newTokens.add(new Token(delimiter, true));
+ token = token.substring(0, token.length() - 1);
+ }
+ }
+ }
+ return newTokens;
+ }
+
+ private ArrayList splitByDoubleQuotation(String line) {
+ ArrayList newTokens = new ArrayList<>();
+ String[] tokens = line.split(DOUBLE_QUOT);
+ boolean fFirstToken = true;
+ for (int i = 0; i < tokens.length; i++) {
+ String token = tokens[i];
+ if (!fFirstToken) {
+ newTokens.add(new Token(DOUBLE_QUOT, true));
+ }
+ if (!fFirstToken || token.length() > 0) {
+ if (i % 2 == 0) {
+ for (String t: token.split("[ \t]")) {
+ newTokens.add(new Token(t));
+ }
+ } else {
+ // string literal
+ newTokens.add(new Token(token, true));
+ }
+ }
+ fFirstToken = false;
+ }
+ if (line.endsWith(DOUBLE_QUOT)) {
+ newTokens.add(new Token(DOUBLE_QUOT, true));
+ }
+ return newTokens;
+ }
+
+ public String next() {
+ if (line >= tokens.size()) return null;
+ while (n >= tokens.get(line).size()) {
+ line++;
+ n = 0;
+ if (line >= tokens.size()) return null;
+ }
+ String token = tokens.get(line).get(n).getTokenStr();
+ n++;
+ return token;
+ }
+
+ public String checkNext() {
+ if (line >= tokens.size()) return null;
+ while (n >= tokens.get(line).size()) {
+ line++;
+ n = 0;
+ if (line >= tokens.size()) return null;
+ }
+ return tokens.get(line).get(n).getTokenStr();
+ }
+
+ public boolean hasNext() {
+ if (line >= tokens.size()) return false;
+ while (n >= tokens.get(line).size()) {
+ line++;
+ n = 0;
+ if (line >= tokens.size()) return false;
+ }
+ return true;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public String getSourceText(int from, int to) {
+ String text = "";
+ for (int l = from; l <= to; l++) {
+ text += lines.get(l) + "\n";
+ }
+ return text;
+ }
+ }
+
+ public static class Token {
+ String token;
+ boolean isAtomic = false;
+
+ public Token(String token) {
+ this.token = token;
+ }
+
+ public Token(String token, boolean isAtomic) {
+ this.token = token;
+ this.isAtomic = isAtomic;
+ }
+
+ public String getTokenStr() {
+ return token;
+ }
+
+ public boolean isAtomic() {
+ return isAtomic;
+ }
+
+ public String[] split(String delimiterRegx) {
+ return token.split(delimiterRegx);
+ }
+
+ public boolean endsWith(String delimiter) {
+ return token.endsWith(delimiter);
+ }
+
+ public int length() {
+ return token.length();
+ }
+
+ public Token substring(int beginIdx, int endIdx) {
+ return new Token(token.substring(beginIdx, endIdx));
+ }
+ }
+}
diff --git a/src/main/java/parser/exceptions/ExpectedDoubleQuotation.java b/src/main/java/parser/exceptions/ExpectedDoubleQuotation.java
new file mode 100644
index 0000000..434bec3
--- /dev/null
+++ b/src/main/java/parser/exceptions/ExpectedDoubleQuotation.java
@@ -0,0 +1,8 @@
+package parser.exceptions;
+
+public class ExpectedDoubleQuotation extends ParseException {
+
+ public ExpectedDoubleQuotation(int line) {
+ super(line);
+ }
+}
diff --git a/src/main/java/parser/exceptions/ExpectedRightBracket.java b/src/main/java/parser/exceptions/ExpectedRightBracket.java
new file mode 100644
index 0000000..6d99d81
--- /dev/null
+++ b/src/main/java/parser/exceptions/ExpectedRightBracket.java
@@ -0,0 +1,9 @@
+package parser.exceptions;
+
+public class ExpectedRightBracket extends ParseException {
+
+ public ExpectedRightBracket(int line) {
+ super(line);
+ }
+
+}
diff --git a/src/main/java/parser/exceptions/ParseException.java b/src/main/java/parser/exceptions/ParseException.java
new file mode 100644
index 0000000..b28550d
--- /dev/null
+++ b/src/main/java/parser/exceptions/ParseException.java
@@ -0,0 +1,10 @@
+package parser.exceptions;
+
+public class ParseException extends RuntimeException {
+ protected int line;
+
+ public ParseException(int line) {
+ super("at line " + (line + 1));
+ this.line = line;
+ }
+}
diff --git a/src/main/java/utils/ExpressionUitls.java b/src/main/java/utils/ExpressionUitls.java
index c6313a4..d223bcf 100644
--- a/src/main/java/utils/ExpressionUitls.java
+++ b/src/main/java/utils/ExpressionUitls.java
@@ -2,20 +2,15 @@
import java.util.Map;
+import constants.Symbols;
import exceptions.NonLinearExpressionException;
import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.Symbol;
import models.algebra.Term;
import models.algebra.Variable;
-import models.dataConstraintModel.DataConstraintModel;
-import models.dataFlowModel.DataTransferModel;
import parser.Parser;
import parser.Parser.TokenStream;
-import parser.exceptions.ExpectedColon;
-import parser.exceptions.ExpectedDoubleQuotation;
-import parser.exceptions.ExpectedRightBracket;
-import parser.exceptions.WrongJsonExpression;
public class ExpressionUitls {
@@ -30,17 +25,17 @@
}
Term term = (Term) expression;
Symbol symbol = term.getSymbol();
- if(symbol.equals(DataConstraintModel.add)) {
+ if(symbol.equals(Symbols.add)) {
Expression c1 = term.getChild(0);
Expression c2 = term.getChild(1);
res += getCoefficientAndConstantsFromExpression(c1, coefficients, curWeight);
res += getCoefficientAndConstantsFromExpression(c2, coefficients, curWeight);
- } else if(symbol.equals(DataConstraintModel.sub)) {
+ } else if(symbol.equals(Symbols.sub)) {
Expression c1 = term.getChild(0);
Expression c2 = term.getChild(1);
res += getCoefficientAndConstantsFromExpression(c1, coefficients, curWeight);
res += getCoefficientAndConstantsFromExpression(c2, coefficients, -curWeight);
- } else if(symbol.equals(DataConstraintModel.mul)) {
+ } else if(symbol.equals(Symbols.mul)) {
Expression c1 = term.getChild(0);
Expression c2 = term.getChild(1);
if(c1.getVariables().size() == 0 && c2.getVariables().size() == 0) {
@@ -61,7 +56,7 @@
} else {
throw new NonLinearExpressionException("Order expression must be linear expression.");
}
- } else if(symbol.equals(DataConstraintModel.minus)) {
+ } else if(symbol.equals(Symbols.minus)) {
Expression c1 = term.getChild(0);
res += getCoefficientAndConstantsFromExpression(c1, coefficients, -curWeight);
} else {
@@ -77,16 +72,10 @@
private static TokenStream stream = new Parser.TokenStream();
private static Parser parser = new Parser(stream);
- private static DataTransferModel model = new DataTransferModel();
public static Expression parse(String expr) {
stream.addLine(expr);
- try {
- return parser.parseTerm(stream, model);
- } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) {
- e.printStackTrace();
- return null;
- }
+ return parser.parseTerm(stream);
}
}
diff --git a/src/test/java/utils/Utils.java b/src/test/java/utils/Utils.java
index fcf7adc..95ed96f 100644
--- a/src/test/java/utils/Utils.java
+++ b/src/test/java/utils/Utils.java
@@ -1,32 +1,21 @@
package utils;
+import constants.Types;
import models.algebra.Expression;
import models.algebra.Type;
-import models.dataConstraintModel.DataConstraintModel;
-import models.dataFlowModel.DataTransferModel;
import parser.Parser;
import parser.Parser.TokenStream;
-import parser.exceptions.ExpectedColon;
-import parser.exceptions.ExpectedDoubleQuotation;
-import parser.exceptions.ExpectedRightBracket;
-import parser.exceptions.WrongJsonExpression;
public class Utils {
- public static Type INT = DataConstraintModel.typeInt;
+ public static Type INT = Types.typeInt;
private static TokenStream stream = new Parser.TokenStream();
private static Parser parser = new Parser(stream);
- private static DataTransferModel model = new DataTransferModel();
public static Expression parse(String expr) {
stream.addLine(expr);
- try {
- return parser.parseTerm(stream, model);
- } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) {
- e.printStackTrace();
- return null;
- }
+ return parser.parseTerm(stream);
}
}