diff --git a/AlgebraicDataflowArchitectureModel/models/GroupChat.model b/AlgebraicDataflowArchitectureModel/models/GroupChat.model index d8b0c42..f199175 100644 --- a/AlgebraicDataflowArchitectureModel/models/GroupChat.model +++ b/AlgebraicDataflowArchitectureModel/models/GroupChat.model @@ -19,9 +19,9 @@ } channel Notify(gid:Str) { - in groups.{gid}.messages(prevMesList, notify(id)) = mesList + in groups.{gid}.messages(prevMesList, notify(m)) = mesList for EachMember(mno:Int) { - ref groups.{gid}.members.{mno}(id:Str, notify(id)) - out accounts.{id}.notifications(prevNtMap:Map, notify(id)) = insert(prevNtMap, gid, true) + ref groups.{gid}.members.{mno}(m.{mno}:Str, notify(m)) + out accounts.{m.{mno}}.notifications(prevNtMap:Map, notify(m)) = insert(prevNtMap, gid, true) } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index e44c50c..858ecb4 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -962,7 +962,7 @@ 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, null, null}); + dotParam.setSignature(new Type[] {null, typeJson, null}); pi.setSignature(new Type[] {typeDouble}); E.setSignature(new Type[] {typeDouble}); sqrt.setSignature(new Type[] {typeDouble, typeDouble}); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonAccessor.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonAccessor.java index 26a4069..b6c4ad3 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonAccessor.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonAccessor.java @@ -38,7 +38,7 @@ public Expression reduce() { Expression reducedTerm = super.reduce(); if (reducedTerm instanceof Term) { - if (symbol.equals(DataConstraintModel.dot) && getChildren().size() >= 2) { + if ((symbol == DataConstraintModel.dot || symbol == DataConstraintModel.dotParam) && getChildren().size() >= 2) { // this term is `json.key`. Expression expJson = getChild(0); Expression expKey = getChild(1); @@ -54,18 +54,21 @@ if (json instanceof JsonTerm) { return ((JsonTerm) json).get(key); } - if (!json.getSymbol().equals(DataConstraintModel.addMember)) { - return new Constant(DataConstraintModel.null_); - } - if (json.getChild(1).equals(key)) { - Expression value = json.getChild(2); - if (value == null) { - return new Constant(DataConstraintModel.null_); + if (json.getSymbol().equals(DataConstraintModel.addMember) || json.getSymbol().equals(DataConstraintModel.set)) { + if (json.getChild(1).equals(key)) { + Expression value = json.getChild(2); + if (value == null) { + return new Constant(DataConstraintModel.null_); + } + return value; } - return value; + if (json.getChild(0) == null + || (json.getChild(0) instanceof Term && + (((Term) json.getChild(0)).getSymbol().equals(DataConstraintModel.null_)) + || ((Term) json.getChild(0)).getSymbol().equals(DataConstraintModel.nil))) return null; + return getValue((Term) json.getChild(0), key); } - if (json.getChild(0) == null || (json.getChild(0) instanceof Term && ((Term) json.getChild(0)).getSymbol().equals(DataConstraintModel.null_))) return null; - return getValue((Term) json.getChild(0), key); + return new Constant(DataConstraintModel.null_); } @Override @@ -75,7 +78,7 @@ int i = targetPos.removeHeadOrder(); Symbol[] inverseSymbols = symbol.getInverses(); if (i == 0) { - if (symbol.equals(DataConstraintModel.dot) && getChildren().size() >= 2) { + if (symbol == DataConstraintModel.dot && getChildren().size() >= 2) { // this term is `json.key`. Expression expJson = getChild(0); Expression expKey = getChild(1); @@ -112,7 +115,7 @@ LambdaAbstraction lambdaAbstraction = new LambdaAbstraction(var, jsonTerm); // v -> addMember(jsonTerm, key, v) inverseSymbols = new Symbol[] { lambdaAbstraction }; } - } else if (symbol.equals(DataConstraintModel.dotParam) && getChildren().size() >= 2) { + } else if (symbol == DataConstraintModel.dotParam && getChildren().size() >= 2) { // this term is `json.{param}`. Expression expListOrMap = getChild(0); Expression expKey = getChild(1); @@ -124,9 +127,9 @@ } Type keyType = null; if (expKey instanceof Variable) { - keyType = (JsonType) ((Variable) expKey).getType(); + keyType = ((Variable) expKey).getType(); } else if (expKey instanceof Term) { - keyType = (JsonType) ((Term) expKey).getType(); + keyType = ((Term) expKey).getType(); } if (jsonType != null && keyType != null) { if (DataConstraintModel.typeList.isAncestorOf(jsonType) || keyType.equals(DataConstraintModel.typeInt)) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferChannel.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferChannel.java index 5e408c5..9466c25 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferChannel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferChannel.java @@ -22,6 +22,7 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; +import parser.Parser; public class DataTransferChannel extends Channel { protected Set inputChannelMembers = null; @@ -620,12 +621,12 @@ public String toString() { String channelSource = ""; if (isNative()) { - channelSource += "native "; + channelSource += Parser.NATIVE + " "; } if (parent == null) { - channelSource += "channel " + getChannelName(); + channelSource += Parser.CHANNEL + " " + getChannelName(); } else { - channelSource += "sub " + getChannelName(); + channelSource += Parser.SUB_CHANNEL + " " + getChannelName(); } if (getSelectors().size() > 0) { channelSource += "("; @@ -638,13 +639,13 @@ } channelSource += " {\n"; for (ChannelMember inputMember: inputChannelMembers) { - channelSource += "\t in " + inputMember + "\n"; + channelSource += "\t " + Parser.IN + " " + inputMember + "\n"; } for (ChannelMember refMember: referenceChannelMembers) { - channelSource += "\t ref " + refMember + "\n"; + channelSource += "\t " + Parser.REF + " " + refMember + "\n"; } for (ChannelMember outputMember: outputChannelMembers) { - channelSource += "\t out " + outputMember + "\n"; + channelSource += "\t " + Parser.OUT + " " + outputMember + "\n"; } for (Channel childCh: getChildren()) { channelSource += childCh.toString(); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java index a1f0302..23dfafa 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java @@ -14,6 +14,7 @@ import models.algebra.Position; import models.algebra.Term; import models.algebra.UnificationFailed; +import models.algebra.Variable; import models.dataConstraintModel.Channel; import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.ResourcePath; @@ -39,8 +40,8 @@ private Map dependingParameters = new HashMap<>(); private Set outputResources = new HashSet<>(); private Set childEvents = new HashSet<>(); - private Map> channelSelectorToInputOrReferenceResourcePathParam = new HashMap<>(); - private Map> channelSelectorToOutputResourcePathParam = new HashMap<>(); + private Map>>> channelSelectorToInputOrReferenceResourcePathParam = new HashMap<>(); + private Map>>> channelSelectorToOutputResourcePathParam = new HashMap<>(); /** * Constructor for an input event channel @@ -60,13 +61,13 @@ // Extract the values of the channel selectors from the output resource. List channelSelectors = channel.getAllSelectors(); for (Selector sel: channelSelectors) { - int paramIdx = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); + Map.Entry> paramIdxAndPos = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); Resource ancestor = outputResource; int idx = outputResPath.getPathParams().size(); while (ancestor != null) { if (ancestor.getResourceHierarchy().getNumParameters() > 0) { idx--; - if (idx == paramIdx) break; + if (idx == paramIdxAndPos.getKey()) break; } ancestor = ancestor.getParent(); } @@ -92,14 +93,14 @@ List channelSelectors = channel.getAllSelectors(); for (Selector sel: channelSelectors) { if (inputResPath != null) { - Integer paramIdx = channelSelectorToInputOrReferenceResourcePathParam.get(sel).get(inputResPath); - if (paramIdx != null) { + Map.Entry> paramIdxAndPos = channelSelectorToInputOrReferenceResourcePathParam.get(sel).get(inputResPath); + if (paramIdxAndPos != null) { Resource ancestor = inputResource; int idx = inputResPath.getPathParams().size(); while (ancestor != null) { if (ancestor.getResourceHierarchy().getNumParameters() > 0) { idx--; - if (idx == paramIdx) break; + if (idx == paramIdxAndPos.getKey()) break; } ancestor = ancestor.getParent(); } @@ -137,37 +138,54 @@ private void connectChannelSelectorAndPathParameters() { List channelSelectors = channel.getAllSelectors(); for (Selector sel: channelSelectors) { - for (ResourcePath resPath: channel.getInputResources()) { - int paramIdx = resPath.getPathParams().indexOf(sel.getExpression()); - if (paramIdx >= 0) { - Map pathToIdx = channelSelectorToInputOrReferenceResourcePathParam.get(sel); - if (pathToIdx == null) { - pathToIdx = new HashMap<>(); - channelSelectorToInputOrReferenceResourcePathParam.put(sel, pathToIdx); + Set inputAndReferenceResPaths = new HashSet<>(channel.getInputResources()); + inputAndReferenceResPaths.addAll(channel.getReferenceResources()); + for (ResourcePath resPath: inputAndReferenceResPaths) { + for (int paramIdx = 0; paramIdx < resPath.getPathParams().size(); paramIdx++) { + Expression pathParam = resPath.getPathParams().get(paramIdx); + if (pathParam.contains(sel.getExpression())) { + for (Map.Entry posAndVar: pathParam.getVariables().entrySet()) { + Position p = posAndVar.getKey(); + Variable v = posAndVar.getValue(); + if (v.equals(sel.getExpression())) { + Map>> pathToIdxAndPos = channelSelectorToInputOrReferenceResourcePathParam.get(sel); + if (pathToIdxAndPos == null) { + pathToIdxAndPos = new HashMap<>(); + channelSelectorToInputOrReferenceResourcePathParam.put(sel, pathToIdxAndPos); + } + Map.Entry> idxAndPos = pathToIdxAndPos.get(resPath); + if (idxAndPos == null) { + idxAndPos = new AbstractMap.SimpleEntry<>(paramIdx, new HashSet<>()); + pathToIdxAndPos.put(resPath, idxAndPos); + } + idxAndPos.getValue().add(p); + } + } } - pathToIdx.put(resPath, paramIdx); - } - } - for (ResourcePath resPath: channel.getReferenceResources()) { - int paramIdx = resPath.getPathParams().indexOf(sel.getExpression()); - if (paramIdx >= 0) { - Map pathToIdx = channelSelectorToInputOrReferenceResourcePathParam.get(sel); - if (pathToIdx == null) { - pathToIdx = new HashMap<>(); - channelSelectorToInputOrReferenceResourcePathParam.put(sel, pathToIdx); - } - pathToIdx.put(resPath, paramIdx); } } for (ResourcePath resPath: channel.getOutputResources()) { - int paramIdx = resPath.getPathParams().indexOf(sel.getExpression()); - if (paramIdx >= 0) { - Map pathToIdx = channelSelectorToOutputResourcePathParam.get(sel); - if (pathToIdx == null) { - pathToIdx = new HashMap<>(); - channelSelectorToOutputResourcePathParam.put(sel, pathToIdx); + for (int paramIdx = 0; paramIdx < resPath.getPathParams().size(); paramIdx++) { + Expression pathParam = resPath.getPathParams().get(paramIdx); + if (pathParam.contains(sel.getExpression())) { + for (Map.Entry posAndVar: pathParam.getVariables().entrySet()) { + Position p = posAndVar.getKey(); + Variable v = posAndVar.getValue(); + if (v.equals(sel.getExpression())) { + Map>> pathToIdxAndPos = channelSelectorToOutputResourcePathParam.get(sel); + if (pathToIdxAndPos == null) { + pathToIdxAndPos = new HashMap<>(); + channelSelectorToOutputResourcePathParam.put(sel, pathToIdxAndPos); + } + Map.Entry> idxAndPos = pathToIdxAndPos.get(resPath); + if (idxAndPos == null) { + idxAndPos = new AbstractMap.SimpleEntry<>(paramIdx, new HashSet<>()); + pathToIdxAndPos.put(resPath, idxAndPos); + } + idxAndPos.getValue().add(p); + } + } } - pathToIdx.put(resPath, paramIdx); } } } @@ -488,21 +506,33 @@ ResourceIdentifier resId = ResourceIdentifier.createFrom(resPath); for (Map.Entry chParamEnt: channelSelectorAndValues) { Selector sel = chParamEnt.getKey(); - Map inputPathParamEnt = channelSelectorToInputOrReferenceResourcePathParam.get(sel); - if (inputPathParamEnt != null) { - Integer paramIdx = inputPathParamEnt.get(resPath); - if (paramIdx != null) { - resId.setPathParam(paramIdx, chParamEnt.getValue()); + Map>> inputPathToIdxAndPos = channelSelectorToInputOrReferenceResourcePathParam.get(sel); + if (inputPathToIdxAndPos != null) { + Map.Entry> pathParamEnt = inputPathToIdxAndPos.get(resPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Variable) { + resId.setPathParam(paramIdx, chParamEnt.getValue()); + } + } } } } for (Map.Entry chParamEnt: channelSelectorAndValues) { Selector sel = chParamEnt.getKey(); - Map outputPathParamEnt = channelSelectorToOutputResourcePathParam.get(sel); - if (outputPathParamEnt != null) { - Integer paramIdx = outputPathParamEnt.get(resPath); - if (paramIdx != null) { - resId.setPathParam(paramIdx, chParamEnt.getValue()); + Map>> outputPathToIdxAndPos = channelSelectorToOutputResourcePathParam.get(sel); + if (outputPathToIdxAndPos != null) { + Map.Entry> pathParamEnt = outputPathToIdxAndPos.get(resPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Variable) { + resId.setPathParam(paramIdx, chParamEnt.getValue()); + } + } } } } @@ -512,6 +542,40 @@ resId.setPathParam(paramIdx, (Constant) dependingParameters.get(var)); } } + for (Map.Entry chParamEnt: channelSelectorAndValues) { + Selector sel = chParamEnt.getKey(); + Map>> inputPathToIdxAndPos = channelSelectorToInputOrReferenceResourcePathParam.get(sel); + if (inputPathToIdxAndPos != null) { + Map.Entry> pathParamEnt = inputPathToIdxAndPos.get(resPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Term && sel.getExpression() instanceof Variable) { + pathParamExp = ((Term) pathParamExp).substitute((Variable) sel.getExpression(), chParamEnt.getValue()); + resId.setPathParam(paramIdx, ((Term) pathParamExp).reduce()); + } + } + } + } + } + for (Map.Entry chParamEnt: channelSelectorAndValues) { + Selector sel = chParamEnt.getKey(); + Map>> outputPathToIdxAndPos = channelSelectorToOutputResourcePathParam.get(sel); + if (outputPathToIdxAndPos != null) { + Map.Entry> pathParamEnt = outputPathToIdxAndPos.get(resPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Term && sel.getExpression() instanceof Variable) { + pathParamExp = ((Term) pathParamExp).substitute((Variable) sel.getExpression(), chParamEnt.getValue()); + resId.setPathParam(paramIdx, ((Term) pathParamExp).reduce()); + } + } + } + } + } return resId; } @@ -520,9 +584,15 @@ for (Map.Entry chParamEnt: channelSelectorAndValues) { Selector sel = chParamEnt.getKey(); if (channelSelectorToInputOrReferenceResourcePathParam.get(sel) != null) { - Integer paramIdx = channelSelectorToInputOrReferenceResourcePathParam.get(sel).get(inputResPath); - if (paramIdx != null) { - resId.setPathParam(paramIdx, chParamEnt.getValue()); + Map.Entry> pathParamEnt = channelSelectorToInputOrReferenceResourcePathParam.get(sel).get(inputResPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Variable) { + resId.setPathParam(paramIdx, chParamEnt.getValue()); + } + } } } } @@ -532,6 +602,22 @@ resId.setPathParam(paramIdx, (Constant) dependingParameters.get(var)); } } + for (Map.Entry chParamEnt: channelSelectorAndValues) { + Selector sel = chParamEnt.getKey(); + if (channelSelectorToInputOrReferenceResourcePathParam.get(sel) != null) { + Map.Entry> pathParamEnt = channelSelectorToInputOrReferenceResourcePathParam.get(sel).get(inputResPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Term && sel.getExpression() instanceof Variable) { + pathParamExp = ((Term) pathParamExp).substitute((Variable) sel.getExpression(), chParamEnt.getValue()); + resId.setPathParam(paramIdx, ((Term) pathParamExp).reduce()); + } + } + } + } + } return resId; } @@ -540,16 +626,38 @@ for (Map.Entry chParamEnt: channelSelectorAndValues) { Selector sel = chParamEnt.getKey(); if (channelSelectorToOutputResourcePathParam.get(sel) != null) { - Integer paramIdx = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); - if (paramIdx != null) { - resId.setPathParam(paramIdx, chParamEnt.getValue()); + Map.Entry> pathParamEnt = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Variable) { + resId.setPathParam(paramIdx, chParamEnt.getValue()); + } + } } } } for (Expression var: dependingParameters.keySet()) { int paramIdx = resId.getPathParams().indexOf(var); if (paramIdx >= 0) { - resId.setPathParam(paramIdx, (Constant) dependingParameters.get(var)); + resId.setPathParam(paramIdx, dependingParameters.get(var)); + } + } + for (Map.Entry chParamEnt: channelSelectorAndValues) { + Selector sel = chParamEnt.getKey(); + if (channelSelectorToOutputResourcePathParam.get(sel) != null) { + Map.Entry> pathParamEnt = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); + if (pathParamEnt != null) { + Integer paramIdx = pathParamEnt.getKey(); + if (paramIdx != null) { + Expression pathParamExp = resId.getPathParams().get(paramIdx); + if (pathParamExp instanceof Term && sel.getExpression() instanceof Variable) { + pathParamExp = ((Term) pathParamExp).substitute((Variable) sel.getExpression(), chParamEnt.getValue()); + resId.setPathParam(paramIdx, ((Term) pathParamExp).reduce()); + } + } + } } } return resId; diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java b/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java index 8987ee0..13b2c92 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java @@ -25,7 +25,7 @@ super(parentResId, exp, resourceHierarchy); } - public void setPathParam(int paramIdx, Constant param) { + public void setPathParam(int paramIdx, Expression param) { if (paramIdx < pathParams.size()) { pathParams.set(paramIdx, new AbstractMap.SimpleEntry<>(param, null)); if (parent != null) { @@ -130,7 +130,7 @@ return new ResourceIdentifier(parent, resPath.getLeafResourceName(), res); } } else { - return new ResourceIdentifier(parent, resPath.getLastParam(), res); + return new ResourceIdentifier(parent, (Expression) resPath.getLastParam().clone(), res); } }