diff --git a/AlgebraicDataflowArchitectureModel/models/Search.model b/AlgebraicDataflowArchitectureModel/models/Search.model new file mode 100644 index 0000000..e401c34 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/Search.model @@ -0,0 +1,25 @@ +init { + accounts := {"001": {"name": "Alice", "age": 25, "address": "Kobe"}, + "002": {"name": "Bob", "age": 25, "address": "Osaka"}, + "003": {"name": "Carol", "age": 22, "address": "Kobe"}, + "004": {"name": "Dave", "age": 25, "address": "Kobe"} + } +} + +channel Signup { + out accounts(acDB:Map, signUp(aid:Str, name:Str, age:Int, address:Str)) = insert(acDB, aid, {"name": name, "age": age, "address": address}) +} + +channel ChangeName(aid:Str) { + out accounts.{aid}.name(n:Str, changeName(name:Str)) = name +} + +channel Query { + out query(q:Json, enterQuery(age:Int, address:Str)) = {"age": age, "address": address} +} + +channel SearchAccount { + in accounts(acDB:Map, searchAccount(acDB2, q2)) = acDB2 + in query(q:Json, searchAccount(acDB2, q2)) = q2 + out result(resultMap:Map, searchAccount(acDB2, q2)) = search(acDB2, q2) +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 4a498b1..18382a0 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -772,6 +772,90 @@ return null; } }); + public static final Symbol search = new Symbol("search", 2, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { + final int count[] = {0}; + @Override + public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) { + for (String s: childrenSideEffects) { + sideEffect[0] += s; + } + String temp = "temp_search" + count[0]; + String impl = ""; + impl += "Map " + temp + " = new HashMap<>();\n"; + impl += "for (String key: " + childrenImpl[0] + ".keySet()) {\n"; + impl += "\tboolean isMatch = true;\n"; + impl += "\tfor (String qKey: " + childrenImpl[1] + ".keySet()) {\n"; + impl += "\t\tMap value = " + childrenImpl[0] + ".get(key).getValue();\n"; + impl += "\t\tfor (String valKey: value.keySet()) {\n"; + impl += "\t\t\tif (valKey.equals(qKey)) {\n"; + impl += "\t\t\t\tif (value.get(valKey).equals(" + childrenImpl[1] + ".get(qKey))) {\n"; + impl += "\t\t\t\t\tisMatch = false;\n"; + impl += "\t\t\t\t}\n"; + impl += "\t\t\t\tbreak;\n"; + impl += "\t\t\t}\n"; + impl += "\t\t}\n"; + impl += "\t\tif (!isMatch) break;\n"; + impl += "\t}\n"; + impl += "\tif (isMatch) {\n"; + impl += "\t\t" + temp + ".put(key, " + childrenImpl[0] + ".get(key));\n"; + impl += "\t}\n"; + impl += "}\n"; + sideEffect[0] += impl; + + count[0]++; + return temp; + } + }, new Symbol.ICalculator() { + @Override + public Expression calculate(List args) { + if (args.size() != 2) + return null; + + Expression arg0 = args.get(0); + if (!(arg0 instanceof MapTerm)) { + return null; + } + MapTerm searchFrom = (MapTerm) arg0; + + Expression arg1 = args.get(1); + if (arg1 instanceof JsonTerm) { + JsonTerm queryTerm = (JsonTerm) arg1; + MapTerm result = new MapTerm(); + + for (String key: searchFrom.keySet()) { + boolean isMatch = true; + if (searchFrom.get(key) instanceof JsonTerm) { + JsonTerm value = (JsonTerm) searchFrom.get(key); + for (String qKey: queryTerm.keySet()) { + for (String valKey: value.keySet()) { + if (value.get(valKey) instanceof Constant) { + Constant valVal = (Constant) value.get(valKey); + if (!(valKey.equals(qKey))) { + continue; + } + if (queryTerm.get(qKey) instanceof Constant) { + Constant qVal = (Constant) queryTerm.get(qKey); + if (!(valVal.getValue().equals(qVal.getValue()))) { + isMatch = false; + } + } + break; + } + } + if (!isMatch) break; + } + if (isMatch) { + result.insert(key, value); + } + } else if (searchFrom.get(key) instanceof MapTerm) { + } else if (searchFrom.get(key) instanceof ListTerm) { + } + } + return result; + } + return null; + } + }); public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { final int count[] = {0}; @Override @@ -797,7 +881,7 @@ count[0]++; return temp; } - } + } return "new ArrayList<" + compType + ">()"; } }, true); @@ -809,7 +893,7 @@ @Override public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) { String temp = "temp_if" + count[0]; - String impl = ""; + String impl = ""; impl += type.getInterfaceTypeName() + " " + temp + ";\n"; if (childrenSideEffects[0] != null && childrenSideEffects[0].length() > 0) impl += childrenSideEffects[0]; @@ -888,8 +972,8 @@ 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()); + if (childEnt.getKey().getClass() == Constant.class) + mapTerm.insert((String) ((Constant) childEnt.getKey()).getValue(), childEnt.getValue()); } return mapTerm.get(key); } @@ -934,7 +1018,7 @@ 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}); @@ -959,13 +1043,14 @@ tail.setSignature(new Type[] {typeList, typeList}); contains.setSignature(new Type[] {typeBoolean, null, null}); indexOf.setSignature(new Type[] {typeInt, typeList, null}); + search.setSignature(new Type[] {typeMap, typeMap, typeJson}); 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.setSignature(new Type[] {typePair, null, null}); pair.setInverses(new Symbol[] {left, right}); left.setSignature(new Type[] {null, typePair}); right.setSignature(new Type[] {null, typePair}); @@ -1041,6 +1126,7 @@ addSymbol(tail); addSymbol(length); addSymbol(contains); + addSymbol(search); addSymbol(indexOf); addSymbol(get); addSymbol(set); @@ -1104,7 +1190,7 @@ do { hierarchy = resourcePath.getResourceHierarchy(); if (hierarchy != null && resourceHierarchies.get(hierarchy.toString()) == null) { - resourceHierarchies.put(hierarchy.toString(), hierarchy); + resourceHierarchies.put(hierarchy.toString(), hierarchy); } else { hierarchy = resourceHierarchies.get(hierarchy.toString()); resourcePath.setResourceHierarchy(hierarchy); @@ -1147,7 +1233,7 @@ public Collection getChannels() { return channels.values(); } - + public Channel getChannel(String channelName) { return channels.get(channelName); } @@ -1216,7 +1302,7 @@ } public boolean isPrimitiveType(Type type) { - if (type == typeInt + if (type == typeInt || type == typeLong || type == typeFloat || type == typeDouble diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java index 3998afa..8dba4c8 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java @@ -91,4 +91,17 @@ } return jsonStr + "}"; } + + public String toImplementation(String[] sideEffects) { + final int count[] = new int[]{0}; + String temp = "temp_json" + count[0]; + String impl = ""; + impl += "Map " + temp + " = new HashMap<>();\n"; + for (String key: keySet()) { + impl += temp + ".put(\"" + key + "\", " + get(key).toImplementation(sideEffects) + ");\n"; + } + sideEffects[0] += impl; + count[0]++; + return temp; + } }