diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 1507ea3..3bdb1dd 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -1,9 +1,13 @@ package models.dataConstraintModel; +import java.util.AbstractMap; 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; @@ -201,8 +205,7 @@ return children[0] + ".equals(" + children[1] + ")"; } return "(" + children[0] + "==" + children[1] + ")"; - } - + } }, new Symbol.ICalculator() { @Override public Expression calculate(List args) { @@ -246,7 +249,6 @@ } return "(" + children[0] + "!=" + children[1] + ")"; } - }, new Symbol.ICalculator() { @Override public Expression calculate(List args) { @@ -467,13 +469,89 @@ } }); 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); + 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); - public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); - public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); + 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 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 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 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); + } + } + } + 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 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 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) { @@ -561,6 +639,42 @@ 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 args) { + if (args.get(0) instanceof Term) { + Term term = (Term) args.get(0); + Type type = term.getType(); + if (typeList.isAncestorOf(type)) { + Stack 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() { @Override public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) { @@ -650,26 +764,39 @@ 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); - public static final Symbol delete = new Symbol("delete", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); - public static final Symbol lookup = new Symbol("lookup", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); -// public static final Symbol lookup = new Symbol("lookup", 2, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { -// final int count[] = {0}; -// @Override -// public String generate(Type type, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) { -// String temp = "temp_get" + count[0]; -// String impl = childrenSideEffects[0] + childrenSideEffects[1]; -// impl += type.getInterfaceTypeName() + " " + temp + ";\n"; -// impl += "if (" + childrenImpl[0] + ".get(" + childrenImpl[1] + ") != null) {\n"; -// impl += "\t" + temp + " = " + childrenImpl[0] + ".get(" + childrenImpl[1] + ");\n"; -// impl += "} else {\n"; -// impl += "\t" + temp + " = " + getDefaultValue(type) + ";\n"; -// impl += "}"; -// sideEffect[0] = impl; -// count[0]++; -// return temp; -// } -// }); + 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 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> 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 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); @@ -710,6 +837,7 @@ 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}); @@ -792,6 +920,7 @@ addSymbol(tail); addSymbol(length); addSymbol(contains); + addSymbol(indexOf); addSymbol(get); addSymbol(set); addSymbol(cond);