package models.dataConstraintModel;
import java.util.AbstractMap;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.LambdaAbstraction;
import models.algebra.Symbol;
import models.algebra.Term;
import models.algebra.Type;
import models.algebra.Variable;
import parser.Parser;
public class DataConstraintModel {
protected List<ResourcePath> resourcePaths = null;
protected HashMap<String, ResourceHierarchy> resourceHierarchies = null;
protected HashMap<String, Channel> channels = null;
protected HashMap<String, Channel> inputChannels = null;
protected HashMap<String, Type> types = null;
protected HashMap<String, Symbol> symbols = null;
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;
}
};
public static final Type typeList = new Type("List", "ArrayList", "List");
public static final Type typeListInt = new Type("List", "ArrayList<>", "List<Integer>", typeList);
public static final Type typeListStr = new Type("List", "ArrayList<>", "List<String>", typeList);
public static final Type typeTuple = new Type("Tuple", "AbstractMap.SimpleEntry", "Map.Entry");
public static final Type typePair = new Type("Pair", "Pair", "Pair");
public static final Type typePairInt = new Type("Pair", "Pair<Integer>", "Pair<Integer>", typePair);
public static final Type typePairStr = new Type("Pair", "Pair<String>", "Pair<String>", typePair);
public static final Type typePairDouble = new Type("Pair", "Pair<Double>", "Pair<Double>", typePair);
public static final Type typeMap = new Type("Map", "HashMap<>", "Map");
public static final JsonType typeJson = new JsonType("Json", "HashMap<>", "Map<String, Object>");
public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) + Double.parseDouble(sArg1)), typeDouble);
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
return new Constant(Float.toString(Float.parseFloat(sArg0) + Float.parseFloat(sArg1)), typeFloat);
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
return new Constant(Long.toString(Long.parseLong(sArg0) + Long.parseLong(sArg1)), typeLong);
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
return new Constant(Integer.toString(Integer.parseInt(sArg0) + Integer.parseInt(sArg1)), typeInt);
} else if (arg0.getType().equals(typeString) || arg1.getType().equals(typeString)) {
return new Constant((String) arg0.getValue() + (String) arg1.getValue(), typeString);
}
}
if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) + Double.parseDouble(sArg1)), typeDouble);
} else {
return new Constant(Integer.toString(Integer.parseInt(sArg0) + Integer.parseInt(sArg1)), typeInt);
}
}
});
public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) * Double.parseDouble(sArg1)), typeDouble);
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
return new Constant(Float.toString(Float.parseFloat(sArg0) * Float.parseFloat(sArg1)), typeFloat);
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
return new Constant(Long.toString(Long.parseLong(sArg0) * Long.parseLong(sArg1)), typeLong);
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
return new Constant(Integer.toString(Integer.parseInt(sArg0) * Integer.parseInt(sArg1)), typeInt);
}
}
if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) * Double.parseDouble(sArg1)), typeDouble);
} else {
return new Constant(Integer.toString(Integer.parseInt(sArg0) * Integer.parseInt(sArg1)), typeInt);
}
}
});
public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) - Double.parseDouble(sArg1)), typeDouble);
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
return new Constant(Float.toString(Float.parseFloat(sArg0) - Float.parseFloat(sArg1)), typeFloat);
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
return new Constant(Long.toString(Long.parseLong(sArg0) - Long.parseLong(sArg1)), typeLong);
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
return new Constant(Integer.toString(Integer.parseInt(sArg0) - Integer.parseInt(sArg1)), typeInt);
}
}
if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) - Double.parseDouble(sArg1)), typeDouble);
} else {
return new Constant(Integer.toString(Integer.parseInt(sArg0) - Integer.parseInt(sArg1)), typeInt);
}
}
});
public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) / Double.parseDouble(sArg1)), typeDouble);
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
return new Constant(Float.toString(Float.parseFloat(sArg0) / Float.parseFloat(sArg1)), typeFloat);
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
return new Constant(Long.toString(Long.parseLong(sArg0) / Long.parseLong(sArg1)), typeLong);
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
return new Constant(Integer.toString(Integer.parseInt(sArg0) / Integer.parseInt(sArg1)), typeInt);
}
}
if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
return new Constant(Double.toString(Double.parseDouble(sArg0) / Double.parseDouble(sArg1)), typeDouble);
} else {
return new Constant(Integer.toString(Integer.parseInt(sArg0) / Integer.parseInt(sArg1)), 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<Expression> 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(typeLong) || arg1.getType().equals(typeLong)) {
return new Constant(Long.toString(Long.parseLong(sArg0) % Long.parseLong(sArg1)), typeLong);
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
return new Constant(Integer.toString(Integer.parseInt(sArg0) % Integer.parseInt(sArg1)), 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<Expression> 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(typeDouble)) {
return new Constant(Double.toString(-Double.parseDouble(sArg)), typeDouble);
} else if (arg.getType().equals(typeFloat)) {
return new Constant(Float.toString(-Float.parseFloat(sArg)), typeFloat);
} else if (arg.getType().equals(typeLong)) {
return new Constant(Long.toString(-Long.parseLong(sArg)), typeLong);
} else if (arg.getType().equals(typeInt)) {
return new Constant(Integer.toString(-Integer.parseInt(sArg)), typeInt);
}
}
if (sArg.contains(Parser.DOT)) {
return new Constant(Double.toString(-Double.parseDouble(sArg)), typeDouble);
} else {
return new Constant(Integer.toString(-Integer.parseInt(sArg)), 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(typeString)
&& childrenTypes[1] != null && childrenTypes[1].equals(typeString)) {
return children[0] + ".equals(" + children[1] + ")";
}
return "(" + children[0] + "==" + children[1] + ")";
}
}, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
result = (Double.parseDouble(sArg0) == Double.parseDouble(sArg1));
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
result = (Float.parseFloat(sArg0) == Float.parseFloat(sArg1));
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
result = (Long.parseLong(sArg0) == Long.parseLong(sArg1));
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
result = (Integer.parseInt(sArg0) == Integer.parseInt(sArg1));
} else if (arg0.getType().equals(typeString) || arg1.getType().equals(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(typeString)
&& childrenTypes[1] != null && childrenTypes[1].equals(typeString)) {
return "!" + children[0] + ".equals(" + children[1] + ")";
}
return "(" + children[0] + "!=" + children[1] + ")";
}
}, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
result = (Double.parseDouble(sArg0) != Double.parseDouble(sArg1));
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
result = (Float.parseFloat(sArg0) != Float.parseFloat(sArg1));
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
result = (Long.parseLong(sArg0) != Long.parseLong(sArg1));
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) {
result = (Integer.parseInt(sArg0) != Integer.parseInt(sArg1));
} else if (arg0.getType().equals(typeString) || arg1.getType().equals(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<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
result = (Double.parseDouble(sArg0) > Double.parseDouble(sArg1));
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
result = (Float.parseFloat(sArg0) > Float.parseFloat(sArg1));
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
result = (Long.parseLong(sArg0) > Long.parseLong(sArg1));
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(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<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
result = (Double.parseDouble(sArg0) < Double.parseDouble(sArg1));
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
result = (Float.parseFloat(sArg0) < Float.parseFloat(sArg1));
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
result = (Long.parseLong(sArg0) < Long.parseLong(sArg1));
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(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<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
result = (Double.parseDouble(sArg0) >= Double.parseDouble(sArg1));
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
result = (Float.parseFloat(sArg0) >= Float.parseFloat(sArg1));
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
result = (Long.parseLong(sArg0) >= Long.parseLong(sArg1));
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(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<Expression> 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(typeDouble) || arg1.getType().equals(typeDouble)) {
result = (Double.parseDouble(sArg0) <= Double.parseDouble(sArg1));
} else if (arg0.getType().equals(typeFloat) || arg1.getType().equals(typeFloat)) {
result = (Float.parseFloat(sArg0) <= Float.parseFloat(sArg1));
} else if (arg0.getType().equals(typeLong) || arg1.getType().equals(typeLong)) {
result = (Long.parseLong(sArg0) <= Long.parseLong(sArg1));
} else if (arg0.getType().equals(typeInt) || arg1.getType().equals(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<Expression> 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(typeBoolean) || arg1.getType().equals(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<Expression> 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(typeBoolean) || arg1.getType().equals(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<Expression> 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(typeBoolean)) {
result = !Boolean.parseBoolean(sArg0);
}
if (result) {
return new Constant(true_);
} else {
return new Constant(false_);
}
}
});
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); // Don't calculate here (Calculated in simulator).
public static final Symbol remove = new Symbol("remove", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator).
public static final Symbol head = new Symbol("head", 1, Symbol.Type.PREFIX, "($x)->$x.get(0)", Symbol.Type.LAMBDA);
public static final Symbol tail = new Symbol("tail", 1, Symbol.Type.PREFIX, "($x)->$x.subList(1, $x.size())", Symbol.Type.LAMBDA);
public static final Symbol length = new Symbol("length", 1, Symbol.Type.PREFIX, "($x)->$x.size()", Symbol.Type.LAMBDA, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (args.get(0).getClass() == Constant.class && ((Constant) args.get(0)).getSymbol().equals(nil)) {
return new Constant("0", typeInt);
}
if (args.get(0) instanceof Term) {
Term term = (Term) args.get(0);
Type type = term.getType();
if (typeList.isAncestorOf(type)) {
int len = 0;
while (term.getSymbol().equals(DataConstraintModel.append)) {
len++;
term = (Term) term.getChild(0);
}
if (term instanceof ListTerm) {
len += ((ListTerm) term).getChildren().size();
return new Constant(Integer.toString(len), typeInt);
}
} else if (typeMap.isAncestorOf(type)) {
HashSet<String> keySet = new HashSet<>();
while (term.getSymbol().equals(DataConstraintModel.insert)) {
if (term.getChild(1).getClass() == Constant.class) {
keySet.add((String) ((Constant) term.getChild(1)).getValue());
}
term = (Term) term.getChild(0);
}
if (term instanceof MapTerm) {
keySet.addAll(((MapTerm) term).keySet());
return new Constant(Integer.toString(keySet.size()), typeInt);
}
} else if (typeJson.isAncestorOf(type)) {
HashSet<String> keySet = new HashSet<>();
while (term.getSymbol().equals(DataConstraintModel.addMember)) {
if (term.getChild(1).getClass() == Constant.class) {
keySet.add((String) ((Constant) term.getChild(1)).getValue());
}
term = (Term) term.getChild(0);
}
if (term instanceof JsonTerm) {
keySet.addAll(((JsonTerm) term).keySet());
return new Constant(Integer.toString(keySet.size()), typeInt);
}
} else if (typeString.isAncestorOf(type)) {
int len = 0;
ArrayDeque<Term> strTerms = new ArrayDeque<>();
strTerms.add(term);
while (strTerms.size() > 0) {
term = strTerms.poll();
type = term.getType();
if (term.getSymbol().equals(DataConstraintModel.add)) {
strTerms.add((Term) term.getChild(0));
strTerms.add((Term) term.getChild(1));
} else if (term instanceof Constant && typeString.isAncestorOf(type)) {
len += ((String) ((Constant) term).getValue()).length();
}
}
return new Constant(Integer.toString(len), typeInt);
}
}
return null;
}
});
public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (args.get(1).getClass() == Constant.class && ((Constant) args.get(1)).getType().equals(typeInt)) {
int idx = Integer.parseInt(((Constant) args.get(1)).toString());
if (args.get(0) instanceof Term) {
Term term = (Term) args.get(0);
Type type = term.getType();
if (typeList.isAncestorOf(type)) {
Stack<Expression> appendedChldren = new Stack<>();
while (term.getSymbol().equals(DataConstraintModel.append)) {
if (!(term.getChild(0) instanceof Term)) {
return null;
}
appendedChldren.push(term.getChild(1));
term = (Term) term.getChild(0);
}
if (term instanceof ListTerm) {
ListTerm listTerm = (ListTerm) term.clone();
for (Expression child: appendedChldren) {
listTerm.append(child);
}
return listTerm.get(idx);
}
}
}
}
return null;
}
});
public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator).
public static final Symbol contains = new Symbol("contains", 2, Symbol.Type.PREFIX, new Symbol.IImplGenerator() {
@Override
public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) {
for (String s: childrenSideEffects) {
sideEffect[0] += s;
}
if (childrenTypes[0] != null && (typeMap.isAncestorOf(childrenTypes[0]) || typeJson.isAncestorOf(childrenTypes[0]))) {
return childrenImpl[0] + "." + "containsKey(" + childrenImpl[1] + ")";
}
return childrenImpl[0] + "." + "contains(" + childrenImpl[1] + ")";
}
}, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (args.get(0).getClass() == Constant.class && ((Constant) args.get(0)).getSymbol().equals(nil)) {
return new Constant(false_);
}
if (args.get(0) instanceof Term) {
Term term = (Term) args.get(0);
Type type = term.getType();
if (typeList.isAncestorOf(type)) {
while (term.getSymbol().equals(DataConstraintModel.append)) {
if (term.getChild(1).equals(args.get(1))) {
return new Constant(true_);
}
if (!(term.getChild(0) instanceof Term)) {
return new Constant(false_);
}
term = (Term) term.getChild(0);
}
if (term instanceof ListTerm) {
for (Expression element: term.getChildren()) {
if (element.equals(args.get(1))) {
return new Constant(true_);
}
}
return new Constant(false_);
}
} else if (typeMap.isAncestorOf(type)) {
while (term.getSymbol().equals(DataConstraintModel.insert)) {
if (term.getChild(1).equals(args.get(1))) {
return new Constant(true_);
}
if (!(term.getChild(0) instanceof Term)) {
return new Constant(false_);
}
term = (Term) term.getChild(0);
}
if (term instanceof MapTerm) {
String key;
if (args.get(1) instanceof Constant) {
key = (String) ((Constant) args.get(1)).getValue();
} else {
key = args.get(1).toString();
}
if (((MapTerm) term).keySet().contains(key)) {
return new Constant(true_);
}
return new Constant(false_);
}
} else if (typeJson.isAncestorOf(type)) {
while (term.getSymbol().equals(DataConstraintModel.addMember)) {
if (term.getChild(1).equals(args.get(1))) {
return new Constant(true_);
}
if (!(term.getChild(0) instanceof Term)) {
return new Constant(false_);
}
term = (Term) term.getChild(0);
}
if (term instanceof JsonTerm) {
String key;
if (args.get(1) instanceof Constant) {
key = (String) ((Constant) args.get(1)).getValue();
} else {
key = args.get(1).toString();
}
if (((JsonTerm) term).keySet().contains(key)) {
return new Constant(true_);
}
return new Constant(false_);
}
}
}
return null;
}
});
public static final Symbol indexOf = new Symbol("indexOf", 2, Symbol.Type.PREFIX, "indexOf", Symbol.Type.METHOD, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (args.get(0) instanceof Term) {
Term term = (Term) args.get(0);
Type type = term.getType();
if (typeList.isAncestorOf(type)) {
Stack<Expression> appendedChldren = new Stack<>();
while (term.getSymbol().equals(DataConstraintModel.append)) {
if (!(term.getChild(0) instanceof Term)) {
return null;
}
appendedChldren.push(term.getChild(1));
term = (Term) term.getChild(0);
}
if (term instanceof ListTerm) {
int idx = 0;
ListTerm listTerm = (ListTerm) term;
for (Expression child: listTerm.getChildren()) {
if (child.equals(args.get(1))) {
return new Constant(Integer.toString(idx), typeInt);
}
idx++;
}
for (Expression child: appendedChldren) {
if (child.equals(args.get(1))) {
return new Constant(Integer.toString(idx), typeInt);
}
idx++;
}
}
}
}
return null;
}
});
public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, new Symbol.IImplGenerator() {
final int count[] = {0};
@Override
public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) {
String compType = "";
if (type != null) {
String interfaceType = type.getInterfaceTypeName();
if (interfaceType.contains("<")) {
compType = interfaceType.substring(interfaceType.indexOf("<") + 1, interfaceType.lastIndexOf(">"));
}
String implType = type.getImplementationTypeName();
if (implType.indexOf('<') >= 0) {
implType = implType.substring(0, implType.indexOf('<'));
}
if (sideEffect == null) {
return "new " + implType + "<>()";
} else {
String temp = "temp_nil" + count[0];
if (sideEffect[0] == null) {
sideEffect[0] = "";
}
sideEffect[0] += interfaceType + " " + temp + " = " + "new " + implType + "<" + compType + ">();\n";
count[0]++;
return temp;
}
}
return "new ArrayList<" + compType + ">()";
}
}, true);
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 cond = new Symbol("if", 3, Symbol.Type.PREFIX, new Symbol.IImplGenerator() {
final int count[] = {0};
@Override
public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) {
String temp = "temp_if" + count[0];
String impl = "";
impl += type.getInterfaceTypeName() + " " + temp + ";\n";
if (childrenSideEffects[0] != null && childrenSideEffects[0].length() > 0) impl += childrenSideEffects[0];
impl += "if (" + childrenImpl[0] + ") {\n";
if (childrenSideEffects[1] != null && childrenSideEffects[1].length() > 0) impl += "\t" + childrenSideEffects[1];
impl += "\t" + temp + " = " + childrenImpl[1] + ";\n";
impl += "} else {\n";
if (childrenSideEffects[2] != null && childrenSideEffects[2].length() > 0) impl += "\t" + childrenSideEffects[2];
impl += "\t" + temp + " = " + childrenImpl[2] + ";\n";
impl += "}\n";
sideEffect[0] += impl;
count[0]++;
return temp;
}
}, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (!(args.get(0).getClass() == Constant.class)) return null;
if (((Constant) args.get(0)).getSymbol().equals(true_)) {
return args.get(1);
} else if (((Constant) args.get(0)).getSymbol().equals(false_)) {
return args.get(2);
}
return null;
}
});
public static final Symbol pair = new Symbol("pair", -1, Symbol.Type.PREFIX, new Symbol.IImplGenerator() {
@Override
public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) {
for (String s: childrenSideEffects) {
sideEffect[0] += s;
}
String impl = "new Pair<>(" + childrenImpl[0] + "," + childrenImpl[1] + ")";
return impl;
}
});
public static final Symbol tuple = new Symbol("tuple", -1, Symbol.Type.PREFIX, new Symbol.IImplGenerator() {
@Override
public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) {
for (String s: childrenSideEffects) {
sideEffect[0] += s;
}
String impl = "new AbstractMap.SimpleEntry<>(" + childrenImpl[0] + "$x)";
for (int i = 1; i < childrenImpl.length - 1; i++) {
impl = impl.replace("$x", ", new AbstractMap.SimpleEntry<>(" + childrenImpl[i] + "$x)");
}
impl = impl.replace("$x", ", " + childrenImpl[childrenImpl.length - 1]);
return impl;
}
});
public static final Symbol fst = new Symbol("fst", 1, Symbol.Type.PREFIX, "getKey", Symbol.Type.METHOD);
public static final Symbol snd = new Symbol("snd", 1, Symbol.Type.PREFIX, "getValue", Symbol.Type.METHOD);
public static final Symbol left = new Symbol("left", 1, Symbol.Type.PREFIX, "getLeft", Symbol.Type.METHOD);
public static final Symbol right = new Symbol("right", 1, Symbol.Type.PREFIX, "getRight", Symbol.Type.METHOD);
public static final Symbol insert = new Symbol("insert", 3, Symbol.Type.PREFIX, "put", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator).
public static final Symbol delete = new Symbol("delete", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator).
public static final Symbol lookup = new Symbol("lookup", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (args.get(1).getClass() == Constant.class && ((Constant) args.get(1)).getType().equals(typeString)) {
String key = (String) ((Constant) args.get(1)).getValue();
if (args.get(0) instanceof Term) {
Term term = (Term) args.get(0);
Type type = term.getType();
if (typeMap.isAncestorOf(type)) {
Stack<Map.Entry<Expression, Expression>> appendedChldren = new Stack<>();
while (term.getSymbol().equals(DataConstraintModel.insert)) {
if (!(term.getChild(0) instanceof Term)) {
return null;
}
appendedChldren.push(new AbstractMap.SimpleEntry<>(term.getChild(0), term.getChild(1)));
term = (Term) term.getChild(0);
}
if (term instanceof MapTerm) {
MapTerm mapTerm = (MapTerm) term.clone();
for (Map.Entry<Expression, Expression> childEnt: appendedChldren) {
if (childEnt.getKey().getClass() == Constant.class)
mapTerm.insert((String) ((Constant) childEnt.getKey()).getValue(), childEnt.getValue());
}
return mapTerm.get(key);
}
}
}
}
return null;
}
});
public static final Symbol addMember = new Symbol("addMember", 3, Symbol.Type.PREFIX, "put", Symbol.Type.METHOD_WITH_SIDE_EFFECT);
public static final Symbol dot = new Symbol(Parser.DOT, 2, Symbol.Type.INFIX, "get", Symbol.Type.METHOD);
public static final Symbol dotParam = new Symbol(Parser.DOT, 2, Symbol.Type.INFIX, "get", Symbol.Type.METHOD);
public static final Symbol pi = new Symbol("PI", 0, Symbol.Type.PREFIX, "Math.PI", Symbol.Type.PREFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
return new Constant(Double.toString(Math.PI), typeDouble);
}});
public static final Symbol E = new Symbol("E", 0, Symbol.Type.PREFIX, "Math.E", Symbol.Type.PREFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
return new Constant(Double.toString(Math.E), typeDouble);
}});
public static final Symbol sqrt = new Symbol("sqrt", 1, Symbol.Type.PREFIX, "Math.sqrt", Symbol.Type.PREFIX, new Symbol.ICalculator() {
@Override
public Expression calculate(List<Expression> args) {
if (args.get(0).getClass() == Constant.class) {
if (((Constant) args.get(0)).getType().equals(typeDouble)) {
return new Constant(Double.toString(Math.sqrt(Double.parseDouble((String) ((Constant) args.get(0)).getValue()))), typeDouble);
} else if (((Constant) args.get(0)).getType().equals(typeFloat)) {
return new Constant(Float.toString((float) Math.sqrt(Float.parseFloat((String) ((Constant) args.get(0)).getValue()))), typeFloat);
}
}
return null;
}});
public static final Symbol sin = new Symbol("sin", 1, Symbol.Type.PREFIX, "Math.sin", Symbol.Type.PREFIX);
public static final Symbol cos = new Symbol("cos", 1, Symbol.Type.PREFIX, "Math.cos", Symbol.Type.PREFIX);
public static final Symbol tan = new Symbol("tan", 1, Symbol.Type.PREFIX, "Math.tan", Symbol.Type.PREFIX);
public static final Symbol asin = new Symbol("asin", 1, Symbol.Type.PREFIX, "Math.asin", Symbol.Type.PREFIX);
public static final Symbol acos = new Symbol("acos", 1, Symbol.Type.PREFIX, "Math.acos", Symbol.Type.PREFIX);
public static final Symbol atan = new Symbol("atan", 1, Symbol.Type.PREFIX, "Math.atan", Symbol.Type.PREFIX);
public static final Symbol pow = new Symbol("pow", 2, Symbol.Type.PREFIX, "Math.pow", Symbol.Type.PREFIX);
public static final Symbol exp = new Symbol("exp", 1, Symbol.Type.PREFIX, "Math.exp", Symbol.Type.PREFIX);
public static final Symbol log = new Symbol("log", 1, Symbol.Type.PREFIX, "Math.log", Symbol.Type.PREFIX);
public static final Symbol abs = new Symbol("abs", 1, Symbol.Type.PREFIX, "Math.abs", Symbol.Type.PREFIX);
static {
add.setInverses(new Symbol[] {sub, sub});
mul.setInverses(new Symbol[] {div, div});
sub.setInverses(new Symbol[] {add});
div.setInverses(new Symbol[] {mul});
minus.setInverses(new Symbol[] {minus});
mod.setSignature(new Type[] {typeInt, null, null});
eq.setSignature(new Type[] {typeBoolean, null, null});
neq.setSignature(new Type[] {typeBoolean, null, null});
gt.setSignature(new Type[] {typeBoolean, null, null});
lt.setSignature(new Type[] {typeBoolean, null, null});
ge.setSignature(new Type[] {typeBoolean, null, null});
le.setSignature(new Type[] {typeBoolean, null, null});
and.setSignature(new Type[] {typeBoolean, typeBoolean, typeBoolean});
or.setSignature(new Type[] {typeBoolean, typeBoolean, typeBoolean});
neg.setSignature(new Type[] {typeBoolean, typeBoolean});
cons.setInverses(new Symbol[] {head, tail});
cons.setSignature(new Type[] {typeList, null, typeList});
append.setSignature(new Type[] {typeList, typeList, null});
remove.setSignature(new Type[] {typeList, typeList, typeInt});
head.setSignature(new Type[] {null, typeList});
tail.setSignature(new Type[] {typeList, typeList});
contains.setSignature(new Type[] {typeBoolean, null, null});
indexOf.setSignature(new Type[] {typeInt, typeList, null});
length.setSignature(new Type[] {typeInt, null});
get.setSignature(new Type[] {null, typeList, typeInt});
set.setSignature(new Type[] {typeList, typeList, typeInt, null});
null_.setSignature(new Type[] {null});
true_.setSignature(new Type[] {typeBoolean});
false_.setSignature(new Type[] {typeBoolean});
pair.setSignature(new Type[] {typePair,null,null});
pair.setInverses(new Symbol[] {left, right});
left.setSignature(new Type[] {null, typePair});
right.setSignature(new Type[] {null, typePair});
tuple.setSignature(new Type[] {typeTuple, null, null});
tuple.setInverses(new Symbol[] {fst, snd});
fst.setSignature(new Type[] {null, typeTuple});
fst.setInverses(new Symbol[] {new LambdaAbstraction(new Variable("x"), new Term(tuple, new Expression[] {new Variable("x"), new Variable("y")}))});
snd.setSignature(new Type[] {null, typeTuple});
snd.setInverses(new Symbol[] {new LambdaAbstraction(new Variable("y"), new Term(tuple, new Expression[] {new Variable("x"), new Variable("y")}))});
insert.setSignature(new Type[] {typeMap, typeMap, null, null});
delete.setSignature(new Type[] {typeMap, typeMap, null});
lookup.setSignature(new Type[] {null, typeMap, null});
addMember.setSignature(new Type[] {typeJson, typeJson, typeString, null});
dot.setSignature(new Type[] {null, typeJson, typeString});
dotParam.setSignature(new Type[] {null, typeJson, null});
pi.setSignature(new Type[] {typeDouble});
E.setSignature(new Type[] {typeDouble});
sqrt.setSignature(new Type[] {typeDouble, typeDouble});
sin.setSignature(new Type[] {typeDouble, typeDouble});
cos.setSignature(new Type[] {typeDouble, typeDouble});
tan.setSignature(new Type[] {typeDouble, typeDouble});
asin.setSignature(new Type[] {typeDouble, typeDouble});
asin.setInverses(new Symbol[] {sin});
acos.setSignature(new Type[] {typeDouble, typeDouble});
acos.setInverses(new Symbol[] {cos});
atan.setSignature(new Type[] {typeDouble, typeDouble});
atan.setInverses(new Symbol[] {tan});
pow.setSignature(new Type[] {typeDouble, typeDouble, typeDouble});
exp.setSignature(new Type[] {typeDouble, typeDouble});
exp.setInverses(new Symbol[] {log});
log.setSignature(new Type[] {typeDouble, typeDouble});
log.setInverses(new Symbol[] {exp});
abs.setSignature(new Type[] {typeDouble, typeDouble});
}
public DataConstraintModel() {
resourcePaths = new ArrayList<>();
resourceHierarchies = new HashMap<>();
channels = new HashMap<>();
inputChannels = new HashMap<>();
types = new HashMap<>();
addType(typeInt);
addType(typeLong);
addType(typeFloat);
addType(typeDouble);
addType(typeBoolean);
addType(typeString);
addType(typeList);
addType(typePair);
addType(typeTuple);
addType(typeMap);
addType(typeJson);
symbols = new HashMap<>();
addSymbol(add);
addSymbol(mul);
addSymbol(sub);
addSymbol(div);
addSymbol(minus);
addSymbol(mod);
addSymbol(eq);
addSymbol(neq);
addSymbol(gt);
addSymbol(lt);
addSymbol(ge);
addSymbol(le);
addSymbol(and);
addSymbol(or);
addSymbol(neg);
addSymbol(cons);
addSymbol(append);
addSymbol(remove);
addSymbol(head);
addSymbol(tail);
addSymbol(length);
addSymbol(contains);
addSymbol(indexOf);
addSymbol(get);
addSymbol(set);
addSymbol(cond);
addSymbol(nil);
addSymbol(null_);
addSymbol(true_);
addSymbol(false_);
addSymbol(pair);
addSymbol(left);
addSymbol(right);
addSymbol(tuple);
addSymbol(fst);
addSymbol(snd);
addSymbol(insert);
addSymbol(delete);
addSymbol(lookup);
addSymbol(addMember);
addSymbol(dot);
addSymbol(dotParam);
addSymbol(pi);
addSymbol(E);
addSymbol(sqrt);
addSymbol(sin);
addSymbol(cos);
addSymbol(tan);
addSymbol(asin);
addSymbol(acos);
addSymbol(atan);
addSymbol(pow);
addSymbol(exp);
addSymbol(log);
addSymbol(abs);
}
public Collection<ResourceHierarchy> getResourceHierarchies() {
return resourceHierarchies.values();
}
public ResourceHierarchy getResourceHierarchy(String hierarchy) {
return resourceHierarchies.get(hierarchy);
}
public ResourceHierarchy getOrPutResourceHierarchy(ResourceHierarchy resourceHierarchy) {
String hierarchy = resourceHierarchy.toString();
if (resourceHierarchies.get(hierarchy) != null) {
return resourceHierarchies.get(hierarchy);
}
resourceHierarchies.put(hierarchy, resourceHierarchy);
return resourceHierarchy;
}
public List<ResourcePath> getResourcePaths() {
return resourcePaths;
}
public void addResourcePath(ResourcePath resourcePath) {
resourcePaths.add(resourcePath);
ResourceHierarchy childHierarchy = null;
ResourceHierarchy hierarchy = null;
do {
hierarchy = resourcePath.getResourceHierarchy();
if (hierarchy != null && resourceHierarchies.get(hierarchy.toString()) == null) {
resourceHierarchies.put(hierarchy.toString(), hierarchy);
} else {
hierarchy = resourceHierarchies.get(hierarchy.toString());
resourcePath.setResourceHierarchy(hierarchy);
if (childHierarchy != null) {
childHierarchy.setParent(hierarchy);
}
}
resourcePath = resourcePath.getParent();
childHierarchy = hierarchy;
} while (resourcePath != null);
}
public void setResourcePaths(List<ResourcePath> resourcePaths) {
this.resourcePaths = resourcePaths;
}
public ResourcePath getResourcePath(String path) {
for (ResourcePath resourcePath: resourcePaths) {
if (resourcePath.toString().equals(path)) return resourcePath;
}
return null;
}
public void removeResourcePath(String path) {
ResourcePath resourcePath = getResourcePath(path);
if (resourcePath == null) return;
resourcePaths.remove(resourcePath);
removeResourcePath(resourcePath);
}
public void removeResourcePath(ResourcePath resourcePath) {
for (Channel ch: channels.values()) {
ch.removeChannelMember(resourcePath);
}
for (Channel ch: inputChannels.values()) {
ch.removeChannelMember(resourcePath);
}
}
public Collection<Channel> getChannels() {
return channels.values();
}
public Channel getChannel(String channelName) {
return channels.get(channelName);
}
public void setChannels(HashMap<String, Channel> channels) {
this.channels = channels;
}
public void addChannel(Channel channel) {
channels.put(channel.getChannelName(), channel);
}
public void removeChannel(String channelName) {
channels.remove(channelName);
}
public Collection<Channel> getInputChannels() {
return inputChannels.values();
}
public Channel getInputChannel(String channelName) {
return inputChannels.get(channelName);
}
public void setInputChannels(HashMap<String, Channel> inputChannels) {
this.inputChannels = inputChannels;
}
public void addInputChannel(Channel inputChannel) {
inputChannels.put(inputChannel.getChannelName(), inputChannel);
}
public void removeInputChannel(String inputChannelName) {
inputChannels.remove(inputChannelName);
}
public void addType(Type type) {
types.put(type.getTypeName(), type);
}
public Type getType(String name) {
return types.get(name);
}
public void addSymbol(Symbol symbol) {
symbols.put(symbol.getName(), symbol);
}
public Symbol getSymbol(String name) {
return symbols.get(name);
}
public static String getWrapperType(Type type) {
if (type == typeInt) {
return "Integer";
} else if (type == typeLong) {
return "Long";
} else if (type == typeFloat) {
return "Float";
} else if (type == typeDouble) {
return "Double";
} else if (type == typeBoolean) {
return "Boolean";
}
return null;
}
public boolean isPrimitiveType(Type type) {
if (type == typeInt
|| type == typeLong
|| type == typeFloat
|| type == typeDouble
|| type == typeBoolean) {
return true;
}
return false;
}
public static boolean isListType(Type type) {
return typeList.isAncestorOf(type);
}
public static String getDefaultValue(Type type) {
if (type == typeInt) {
return "0";
} else if (type == typeLong) {
return "0L";
} else if (type == typeFloat) {
return "0.0f";
} else if (type == typeDouble) {
return "0.0";
} else if (type == typeBoolean) {
return "false";
} else if (type == typeString) {
return "\"\"";
}
return "new " + type.getImplementationTypeName() + "()";
}
public static Expression getDefaultValueExpression(Type type) {
if (type == typeInt) {
return new Constant("0", typeInt);
} else if (type == typeLong) {
return new Constant("0L", typeLong);
} else if (type == typeFloat) {
return new Constant("0.0f", typeFloat);
} else if (type == typeDouble) {
return new Constant("0.0", typeDouble);
} else if (type == typeBoolean) {
return new Constant(false_);
} else if (type == typeString) {
return new Constant("", typeString);
} else if (type.isAncestorOf(typeList)) {
return new ListTerm();
} else if (type.isAncestorOf(typeMap)) {
return new MapTerm();
} else if (type.isAncestorOf(typeJson)) {
return new JsonTerm();
}
return null;
}
@Override
public String toString() {
String out = "";
for (Channel channel: inputChannels.values()) {
out += channel.toString();
}
for (Channel channel: channels.values()) {
out += channel.toString();
}
return out;
}
public String getSourceText() {
String out = "";
String init = "";
for (ResourceHierarchy resource: resourceHierarchies.values()) {
String initializer = resource.getInitText();
if (initializer != null) {
init += resource.toString() + " := " + initializer + "\n";
}
}
if (init.length() > 0) {
out += "init {\n" + init + "}\n";
}
for (Channel channel: inputChannels.values()) {
out += channel.getSourceText();
}
for (Channel channel: channels.values()) {
out += channel.getSourceText();
}
return out;
}
}