diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java index dcdba9f..047f906 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java @@ -1,5 +1,7 @@ package models.algebra; +import java.util.List; + public class Symbol { protected String name; protected String implName; @@ -10,6 +12,7 @@ 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; @@ -66,6 +69,37 @@ } } + public Symbol(String name, int arity, ICalculator calculator) { + this.name = name; + this.arity = arity; + this.calculator = calculator; + } + + public Symbol(String name, int arity, Type operatorType, ICalculator calculator) { + this.name = name; + this.arity = arity; + this.operatorType = operatorType; + this.calculator = calculator; + } + + public Symbol(String name, int arity, Type operatorType, IImplGenerator generator, ICalculator calculator) { + this.name = 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; } @@ -171,6 +205,17 @@ } return null; } + + public boolean isCalculatable() { + return (calculator != null); + } + + public Constant calculate(List args) { + if (calculator != null) { + return calculator.calculate(args); + } + return null; + } public boolean equals(Object another) { if (!(another instanceof Symbol)) return false; @@ -232,4 +277,8 @@ */ public String generate(models.algebra.Type type, models.algebra.Type[] childrenTypes, String children[], String[] childrenSideEffects, String[] sideEffect); } + + public interface ICalculator { + public Constant calculate(List args); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index 52d000e..b326caa 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -149,6 +149,18 @@ } 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(); + } + if (!(child instanceof Constant)) { + return this; + } + newChildren.add((Constant) child); + } + return symbol.calculate(newChildren); } else { // Calculate inverse map List newChildren = new ArrayList<>(); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index f72c44a..3f8a50e 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.List; +import models.algebra.Constant; import models.algebra.Expression; import models.algebra.LambdaAbstraction; import models.algebra.Symbol; @@ -36,11 +37,90 @@ public static final Type typePairDouble = new Type("Pair", "Pair", "Pair", typePair); public static final Type typeMap = new Type("Map", "HashMap<>", "Map"); public static final JsonType typeJson = new JsonType("Json", "HashMap<>", "Map"); - public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX); - public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX); - public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX); - public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX); - public static final Symbol minus = new Symbol(Parser.MINUS, 1); + public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + String arg0 = args.get(0).getSymbol().toString(); + String arg1 = args.get(1).getSymbol().toString(); + if (args.get(0).getType().equals(typeDouble) || args.get(1).getType().equals(typeDouble)) { + return new Constant(Double.toString(Double.parseDouble(arg0) + Double.parseDouble(arg1)), typeDouble); + } else if (args.get(0).getType().equals(typeFloat) || args.get(1).getType().equals(typeFloat)) { + return new Constant(Float.toString(Float.parseFloat(arg0) + Float.parseFloat(arg1)), typeFloat); + } else if (args.get(0).getType().equals(typeLong) || args.get(1).getType().equals(typeLong)) { + return new Constant(Long.toString(Long.parseLong(arg0) + Long.parseLong(arg1)), typeLong); + } else if (args.get(0).getType().equals(typeInt) || args.get(1).getType().equals(typeInt)) { + return new Constant(Integer.toString(Integer.parseInt(arg0) + Integer.parseInt(arg1)), typeInt); + } + return new Constant(Integer.toString(Integer.parseInt(arg0) + Integer.parseInt(arg1))); + } + }); + public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + String arg0 = args.get(0).getSymbol().toString(); + String arg1 = args.get(1).getSymbol().toString(); + if (args.get(0).getType().equals(typeDouble) || args.get(1).getType().equals(typeDouble)) { + return new Constant(Double.toString(Double.parseDouble(arg0) * Double.parseDouble(arg1)), typeDouble); + } else if (args.get(0).getType().equals(typeFloat) || args.get(1).getType().equals(typeFloat)) { + return new Constant(Float.toString(Float.parseFloat(arg0) * Float.parseFloat(arg1)), typeFloat); + } else if (args.get(0).getType().equals(typeLong) || args.get(1).getType().equals(typeLong)) { + return new Constant(Long.toString(Long.parseLong(arg0) * Long.parseLong(arg1)), typeLong); + } else if (args.get(0).getType().equals(typeInt) || args.get(1).getType().equals(typeInt)) { + return new Constant(Integer.toString(Integer.parseInt(arg0) * Integer.parseInt(arg1)), typeInt); + } + return new Constant(Integer.toString(Integer.parseInt(arg0) * Integer.parseInt(arg1))); + } + }); + public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + String arg0 = args.get(0).getSymbol().toString(); + String arg1 = args.get(1).getSymbol().toString(); + if (args.get(0).getType().equals(typeDouble) || args.get(1).getType().equals(typeDouble)) { + return new Constant(Double.toString(Double.parseDouble(arg0) - Double.parseDouble(arg1)), typeDouble); + } else if (args.get(0).getType().equals(typeFloat) || args.get(1).getType().equals(typeFloat)) { + return new Constant(Float.toString(Float.parseFloat(arg0) - Float.parseFloat(arg1)), typeFloat); + } else if (args.get(0).getType().equals(typeLong) || args.get(1).getType().equals(typeLong)) { + return new Constant(Long.toString(Long.parseLong(arg0) - Long.parseLong(arg1)), typeLong); + } else if (args.get(0).getType().equals(typeInt) || args.get(1).getType().equals(typeInt)) { + return new Constant(Integer.toString(Integer.parseInt(arg0) - Integer.parseInt(arg1)), typeInt); + } + return new Constant(Integer.toString(Integer.parseInt(arg0) - Integer.parseInt(arg1))); + } + }); + public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + String arg0 = args.get(0).getSymbol().toString(); + String arg1 = args.get(1).getSymbol().toString(); + if (args.get(0).getType().equals(typeDouble) || args.get(1).getType().equals(typeDouble)) { + return new Constant(Double.toString(Double.parseDouble(arg0) / Double.parseDouble(arg1)), typeDouble); + } else if (args.get(0).getType().equals(typeFloat) || args.get(1).getType().equals(typeFloat)) { + return new Constant(Float.toString(Float.parseFloat(arg0) / Float.parseFloat(arg1)), typeFloat); + } else if (args.get(0).getType().equals(typeLong) || args.get(1).getType().equals(typeLong)) { + return new Constant(Long.toString(Long.parseLong(arg0) / Long.parseLong(arg1)), typeLong); + } else if (args.get(0).getType().equals(typeInt) || args.get(1).getType().equals(typeInt)) { + return new Constant(Integer.toString(Integer.parseInt(arg0) / Integer.parseInt(arg1)), typeInt); + } + return new Constant(Integer.toString(Integer.parseInt(arg0) / Integer.parseInt(arg1))); + } + }); + public static final Symbol minus = new Symbol(Parser.MINUS, 1, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + String arg = args.get(0).getSymbol().toString(); + if (args.get(0).getType().equals(typeDouble)) { + return new Constant(Double.toString(-Double.parseDouble(arg)), typeDouble); + } else if (args.get(0).getType().equals(typeFloat)) { + return new Constant(Float.toString(-Float.parseFloat(arg)), typeFloat); + } else if (args.get(0).getType().equals(typeLong)) { + return new Constant(Long.toString(-Long.parseLong(arg)), typeLong); + } else if (args.get(0).getType().equals(typeInt)) { + return new Constant(Integer.toString(-Integer.parseInt(arg)), typeInt); + } + return new Constant(Integer.toString(-Integer.parseInt(arg))); + } + }); public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "($x,$y)->$x.add(0, $y)", Symbol.Type.LAMBDA_WITH_SIDE_EFFECT, new int[] {1, 0}); public static final Symbol append = new Symbol("append", 2, Symbol.Type.PREFIX, "add", Symbol.Type.METHOD_WITH_SIDE_EFFECT); public static final Symbol remove = new Symbol("remove", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); @@ -108,10 +188,32 @@ count[0]++; return temp; } + }, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + if (args.get(0).getSymbol().equals(true_)) { + return args.get(1); + } else if (args.get(0).getSymbol().equals(false_)) { + return args.get(2); + } + return null; + } }); - public static final Symbol mod = new Symbol("mod", 2, Symbol.Type.PREFIX, "%", Symbol.Type.INFIX); + public static final Symbol mod = new Symbol("mod", 2, Symbol.Type.PREFIX, "%", Symbol.Type.INFIX, new Symbol.ICalculator() { + @Override + public Constant calculate(List args) { + String arg0 = args.get(0).getSymbol().toString(); + String arg1 = args.get(1).getSymbol().toString(); + if (args.get(0).getType().equals(typeLong) || args.get(1).getType().equals(typeLong)) { + return new Constant(Long.toString(Long.parseLong(arg0) % Long.parseLong(arg1)), typeLong); + } else if (args.get(0).getType().equals(typeInt) || args.get(1).getType().equals(typeInt)) { + return new Constant(Integer.toString(Integer.parseInt(arg0) % Integer.parseInt(arg1)), typeInt); + } + return new Constant(Integer.toString(Integer.parseInt(arg0) % Integer.parseInt(arg1))); + } + }); public static final Symbol eq = new Symbol("eq", 2, Symbol.Type.PREFIX, "==", Symbol.Type.INFIX); public static final Symbol neq = new Symbol("neq", 2, Symbol.Type.PREFIX, "!=", Symbol.Type.INFIX); public static final Symbol gt = new Symbol("gt", 2, Symbol.Type.PREFIX, ">", Symbol.Type.INFIX); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 4adf78d..494ac79 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -147,6 +147,9 @@ } } } else { + if (resStateValue instanceof Term) { + resStateValue = ((Term) resStateValue).reduce(); + } if (resStateValue instanceof Constant) { Resource res = getResource(resourceIdentifier); ResourceState state = null;