diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java index 46bc39a..476c942 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java @@ -75,6 +75,7 @@ protected int minimumWidth = DEFAULT_MIN_WIDTH; protected int minimumHeight = DEFAULT_MIN_HEIGHT; + private SimulatorWindow window; private Object editingCell; private EventObject trigger; private JComboBox comboBox; @@ -84,8 +85,8 @@ private Editor editor; private boolean bReflectingArchitectureModel = false; - public InputEventCellEditor(mxGraphComponent graphComponent, Simulator simulator, Editor editor) { - this.graphComponent = graphComponent; + public InputEventCellEditor(SimulatorWindow window, mxGraphComponent graphComponent, Simulator simulator, Editor editor) { this.graphComponent = graphComponent; + this.window = window; this.simulator = simulator; this.editor = editor; } @@ -109,26 +110,8 @@ ArrayList eventMessages = new ArrayList<>();//messageList ResourcePath eventResPath = null; - for(Channel ch : simulator.getModel().getInputChannels()) {//all channel - if(((DataTransferChannel)ch).getInputResources().size()== 0) {//ioch Or normalch - for(ChannelMember out: ((DataTransferChannel)ch).getOutputChannelMembers()) { - ResourcePath resPath = out.getResource(); - if(resId.isInstanceOf(resPath)) {//account.uid == acounts.123 - eventResPath = resPath; - eventChs.add(((DataTransferChannel)ch)); - String message = null; - Expression mesExp = out.getStateTransition().getMessageExpression();//sync(a,b) - eventMessages.add(mesExp); - if(mesExp instanceof Term) { - message = ((Term) mesExp).getSymbol().toString();//sync - }else if(mesExp instanceof Variable) { - message = ((Variable) mesExp).getName();//x,y,z.. - } - messages.add(message);//pulldown - - } - } - } + for (Channel ch: simulator.getModel().getInputChannels()) {//all channel + eventResPath = getSelectableMessages(ch, resId, eventChs, messages, eventMessages, eventResPath); } if(messages.isEmpty()) { @@ -140,7 +123,7 @@ JPanel eventChoice = new JPanel(); eventChoice.add(event);//FirstEventChoice - int ret = JOptionPane.showConfirmDialog(null, eventChoice, "Event Choice", JOptionPane.OK_CANCEL_OPTION); + int ret = JOptionPane.showConfirmDialog(window, eventChoice, "Event Choice", JOptionPane.OK_CANCEL_OPTION); if (ret == JOptionPane.OK_OPTION) { JPanel inputEvent = new JPanel(); @@ -157,22 +140,22 @@ JTextArea textArea = new JTextArea(eventMessages.get(eventNum).toString(), 10, 30);//EventInput inputEvent.add(textArea); - int approve = JOptionPane.showConfirmDialog(null, inputEvent, "Event Code", JOptionPane.OK_CANCEL_OPTION); + int approve = JOptionPane.showConfirmDialog(window, inputEvent, "Event Code", JOptionPane.OK_CANCEL_OPTION); if (approve == JOptionPane.OK_OPTION) { try { - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - stream.addLine(textArea.getText()); - Expression eventMessage = parser.parseTerm(stream,simulator.getModel()); - - Event newEvent = new Event(eventChs.get(eventNum), eventMessage, eventResPath, simulator.getCurState().getResource(resId)); - simulator.transition(newEvent); - -// SimulationLayout layout = new SimulationLayout(simulator.getCurState()); -// layout.constructSimulateGraph(graph, simulator); - - graphComponent.setCellEditor(new InputEventCellEditor(graphComponent, simulator, this.editor)); + TokenStream stream = new Parser.TokenStream(); + Parser parser = new Parser(stream); + stream.addLine(textArea.getText()); + Expression eventMessage = parser.parseTerm(stream,simulator.getModel()); + + Event newEvent = new Event(eventChs.get(eventNum), eventMessage, eventResPath, simulator.getCurState().getResource(resId)); + simulator.transition(newEvent); + +// SimulationLayout layout = new SimulationLayout(simulator.getCurState()); +// layout.constructSimulateGraph(graph, simulator); + + graphComponent.setCellEditor(new InputEventCellEditor(window, graphComponent, simulator, this.editor)); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { @@ -180,8 +163,6 @@ } } } - //resource - return; } mxCellState state = graphComponent.getGraph().getView().getState(cell); @@ -203,7 +184,34 @@ } } } - + + private ResourcePath getSelectableMessages(Channel ch, ResourceIdentifier resId, + ArrayList eventChs, ArrayList messages, ArrayList eventMessages, + ResourcePath eventResPath) { + if (((DataTransferChannel)ch).getInputResources().size() == 0) {//ioch Or normalch + for (ChannelMember out: ((DataTransferChannel)ch).getOutputChannelMembers()) { + ResourcePath resPath = out.getResource(); + if (!out.isOutside() && resId.isInstanceOf(resPath)) {//account.uid == acounts.123 + eventResPath = resPath; + eventChs.add(((DataTransferChannel)ch)); + String message = null; + Expression mesExp = out.getStateTransition().getMessageExpression();//sync(a,b) + eventMessages.add(mesExp); + if (mesExp instanceof Term) { + message = ((Term) mesExp).getSymbol().toString();//sync + } else if(mesExp instanceof Variable) { + message = ((Variable) mesExp).getName();//x,y,z.. + } + messages.add(message);//pulldown + } + } + for (Channel childCh: ch.getChildren()) { + eventResPath = getSelectableMessages(childCh, resId, eventChs, messages, eventMessages, eventResPath); + } + } + return eventResPath; + } + // private mxGraph constructNextSimulateGraph(Set simulateRes, DataTransferModel model,DataFlowGraph dataFlowGraph, mxGraph nextGraph) { // bReflectingArchitectureModel = true; // ((mxGraphModel) nextGraph.getModel()).clear(); diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java index 6dfb078..adfd10f 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java @@ -131,8 +131,8 @@ simulator = new Simulator(model); SimulationLayout layout = new SimulationLayout(simulator.getCurState()); layout.constructSimulateGraph(graph, simulator); - graphComponent.setCellEditor(new InputEventCellEditor(graphComponent, simulator, this.editor)); - simulator.addSystemReceiver(this); + graphComponent.setCellEditor(new InputEventCellEditor(this, graphComponent, simulator, this.editor)); + simulator.addSystemReceiver(this); menuBar = new SimulatorMenuBar(this); setJMenuBar(menuBar); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index ab82982..fc6b3f4 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -59,6 +59,7 @@ List> constructorParams = new ArrayList<>(); List> constructorStatements = new ArrayList<>(); Map> updateStatements = new HashMap<>(); + Map> childGetters = new HashMap<>(); // For each components (1st pass). for (Node componentNode: components) { @@ -105,9 +106,10 @@ // Declare the accessor method in the main component to call the getter method. declareAccessorInMainComponent(mainComponent, resourceNode, stateGetter, langSpec); - + } + if (component != null) { // Declare the getter methods in this resource to obtain the children resources. - declareChildGetterMethod(resourceNode, component, langSpec); + declareChildGetterMethod(resourceNode, component, childGetters, langSpec); } } } @@ -236,7 +238,7 @@ while (termEntItr.hasNext()) { Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); - if (jsonTerm.getType().equals(replacedJsonType)) { + if (jsonTerm.getType() != null && jsonTerm.getType().equals(replacedJsonType)) { MethodDeclaration childConstructor = getConstructor(childComponent); List params = new ArrayList<>(); for (VariableDeclaration var: childConstructor.getParameters()) { @@ -394,7 +396,7 @@ // The child has a component. childType = new Type(childTypeName, childTypeName); String fieldName = langSpec.toVariableName(childTypeName); - FieldDeclaration stateField = langSpec.newFieldDeclaration(childType, fieldName, langSpec.getFieldInitializer(resStateType, resourceNode.getResourceHierarchy().getInitialValue())); + FieldDeclaration stateField = langSpec.newFieldDeclaration(childType, fieldName, langSpec.getConstructorInvocation(childTypeName, new ArrayList<>())); component.addField(stateField); } } @@ -714,9 +716,13 @@ } } - private void declareChildGetterMethod(ResourceNode resourceNode, TypeDeclaration component, ILanguageSpecific langSpec) { + private void declareChildGetterMethod(ResourceNode resourceNode, TypeDeclaration component, Map> childGetters, ILanguageSpecific langSpec) { // Declare the getter methods in this resource to obtain the children resources. - Set children = new HashSet<>(); + Set children = childGetters.get(resourceNode.getResourceHierarchy()); + if (children == null) { + children = new HashSet<>(); + childGetters.put(resourceNode.getResourceHierarchy(), children); + } for (ResourceNode child: resourceNode.getChildren()) { if (generatesComponent(child.getResourceHierarchy())) { // A component for the child is generated. @@ -724,12 +730,13 @@ children.add(child.getResourceHierarchy()); List params = new ArrayList<>(); int v = 1; - for (Selector param: child.getSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); + Expression param = child.getPrimaryResourcePath().getLastParam(); + if (param != null) { + if (param instanceof Variable) { + Variable var = (Variable) param; params.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); + } else if (param instanceof Term) { + Term var = (Term) param; params.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); } v++; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index e86cc63..7c9ad00 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -133,6 +133,7 @@ Map> updates = new HashMap<>(); Map> inputs = new HashMap<>(); List> fields = new ArrayList<>(); + Map> childGetters = new HashMap<>(); List> constructorParams = new ArrayList<>(); Map> dependedRootComponentGraph = getDependedRootComponentGraph(model); @@ -259,7 +260,7 @@ // The child has a component. childType = new Type(childTypeName, childTypeName); String fieldName = toVariableName(childTypeName); - component.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); + component.addField(new FieldDeclaration(childType, fieldName, "new " + childTypeName + "()")); } } } @@ -272,9 +273,14 @@ // Declare the accessor method in the main type to call the getter method. declareAccessorMethodInMainComponent(resourceNode, mainComponent); - + } + if (component != null) { // Declare the getter methods to obtain the children resources. - Set children = new HashSet<>(); + Set children = childGetters.get(resourceNode.getResourceHierarchy()); + if (children == null) { + children = new HashSet<>(); + childGetters.put(resourceNode.getResourceHierarchy(), children); + } for (ResourceNode child: resourceNode.getChildren()) { if (generatesComponent(child.getResourceHierarchy())) { // A component for the child is generated. @@ -282,12 +288,13 @@ children.add(child.getResourceHierarchy()); List params = new ArrayList<>(); int v = 1; - for (Selector param: child.getSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); + Expression param = child.getPrimaryResourcePath().getLastParam(); + if (param != null) { + if (param instanceof Variable) { + Variable var = (Variable) param; params.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); + } else if (param instanceof Term) { + Term var = (Term) param; params.add(new VariableDeclaration(var.getType(), "v" + v)); } v++; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index 08bc6ec..4ab9dd3 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -832,7 +832,7 @@ while (termEntItr.hasNext()) { Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); - if (jsonTerm.getType().equals(replacedJsonType)) { + if (jsonTerm.getType() != null && jsonTerm.getType().equals(replacedJsonType)) { String constructorInvocation = "new " + replacingClassName + "("; MethodDeclaration childConstructor = getConstructor(childComponent); String delimiter = ""; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index 78a04d2..33fae7a 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -136,6 +136,7 @@ Map> updates = new HashMap<>(); Map> inputs = new HashMap<>(); List> fields = new ArrayList<>(); + Map> childGetters = new HashMap<>(); Map getterAccessors = new HashMap<>(); Map inputAccessors = new HashMap<>(); Map> constructorParams = new HashMap<>(); @@ -203,7 +204,7 @@ // The child has a component. childType = new Type(childTypeName, childTypeName); String fieldName = toVariableName(childTypeName); - component.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); + component.addField(new FieldDeclaration(childType, fieldName, "new " + childTypeName + "()")); } } } @@ -218,9 +219,14 @@ stateGetter.addAnnotation(new Annotation("GET")); } component.addMethod(stateGetter); - + } + if (component != null) { // Declare the getter methods to obtain the children resources. - Set children = new HashSet<>(); + Set children = childGetters.get(resourceNode.getResourceHierarchy()); + if (children == null) { + children = new HashSet<>(); + childGetters.put(resourceNode.getResourceHierarchy(), children); + } for (ResourceNode child: resourceNode.getChildren()) { if (generatesComponent(child.getResourceHierarchy())) { // The child generates a component. @@ -228,7 +234,8 @@ children.add(child.getResourceHierarchy()); List pathParams = new ArrayList<>(); int v = 1; - for (Expression pathParam: child.getPrimaryResourcePath().getPathParams()) { + Expression pathParam = child.getPrimaryResourcePath().getLastParam(); + if (pathParam != null) { if (pathParam instanceof Variable) { Variable var = (Variable) pathParam; pathParams.add(new VariableDeclaration(var.getType(), var.getName())); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index 4efb2dd..d695463 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -952,7 +952,7 @@ while (termEntItr.hasNext()) { Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); - if (jsonTerm.getType().equals(replacedJsonType)) { + if (jsonTerm.getType() != null && jsonTerm.getType().equals(replacedJsonType)) { String constructorInvocation = "new " + replacingClassName + "("; MethodDeclaration childConstructor = getConstructor(childComponent); String delimiter = ""; diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index cfef320..95c2b47 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -75,8 +75,13 @@ public HashMap getSubTerms(Class clazz) { HashMap subTerms = new HashMap<>(); - if (clazz == this.getClass()) { - subTerms.put(new Position(), (T) this); + Class thisClass = this.getClass(); + while (thisClass != null) { + if (clazz == thisClass) { + subTerms.put(new Position(), (T) this); + break; + } + thisClass = thisClass.getSuperclass(); } for (int i = 0; i < children.size(); i++) { HashMap terms = children.get(i).getSubTerms(clazz); diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java index e408a54..3b573d2 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java @@ -73,7 +73,7 @@ public boolean isAncestorOf(Type another) { if (this.equals(another)) return true; - if (another.getParentTypes() == null) return false; + if (another == null || another.getParentTypes() == null) return false; for (Type anothersParentType: another.getParentTypes()) { if (isAncestorOf(anothersParentType)) return true; } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 0962ce2..a76879f 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -178,7 +178,19 @@ return new Constant(Integer.toString(-Integer.parseInt(sArg))); } }); - public static final Symbol eq = new Symbol(Parser.EQ, 2, Symbol.Type.INFIX, "==", Symbol.Type.INFIX, new Symbol.ICalculator() { + 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].equals(typeString) && childrenTypes[1].equals(typeString)) { + return children[0] + ".equals(" + children[1] + ")"; + } + return "(" + children[0] + "==" + children[1] + ")"; + } + + }, new Symbol.ICalculator() { @Override public Expression calculate(List args) { if (!(args.get(0) instanceof Constant)) { @@ -201,7 +213,7 @@ } 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())); + result = sArg0.toString().equals(sArg1.toString()); } if (result) { return new Constant(true_); @@ -210,7 +222,19 @@ } } }); - public static final Symbol neq = new Symbol(Parser.NEQ, 2, Symbol.Type.INFIX, "!=", Symbol.Type.INFIX, new Symbol.ICalculator() { + 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].equals(typeString) && childrenTypes[1].equals(typeString)) { + return "!" + children[0] + ".equals(" + children[1] + ")"; + } + return "(" + children[0] + "!=" + children[1] + ")"; + } + + }, new Symbol.ICalculator() { @Override public Expression calculate(List args) { if (!(args.get(0) instanceof Constant)) { @@ -232,6 +256,8 @@ 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_); @@ -507,7 +533,7 @@ } } } - return new Constant(false_); + return null; } }); public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ResourceHierarchy.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ResourceHierarchy.java index 7412266..be99827 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ResourceHierarchy.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ResourceHierarchy.java @@ -97,6 +97,7 @@ public ResourceHierarchy(ResourceHierarchy parent, Expression parameterExp, Type resourceStateType) { this.parent = parent; + if (this.children == null) this.children = new HashSet<>(); this.resourceName = null; this.numParameters = 1; this.resourceStateType = resourceStateType; @@ -120,6 +121,7 @@ public ResourceHierarchy(ResourceHierarchy parent, int numParameters, Type resourceStateType) { this.parent = parent; + if (this.children == null) this.children = new HashSet<>(); this.resourceName = null; this.numParameters = numParameters; this.resourceStateType = resourceStateType; diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index 3362f4f..abec1de 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -166,11 +166,14 @@ } String leftBracket = stream.next(); if (leftBracket.equals(LEFT_BRACKET)) { - // has a selector - String selector = stream.next(); - Variable var = parseVariable(stream, model, selector); - channel.addSelector(var); - String rightBracket = stream.next(); + // has selectors + String rightBracket = null; + do { + String selector = stream.next(); + Variable var = parseVariable(stream, model, selector); + channel.addSelector(var); + rightBracket = stream.next(); + } while (rightBracket.equals(COMMA)); if (!rightBracket.equals(RIGHT_BRACKET)) throw new ExpectedRightBracket(stream.getLine()); leftBracket = stream.next(); } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java index 58a9df8..b0feb2b 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java @@ -235,8 +235,11 @@ for (ChannelMember depending: dependency.keySet()) { toResolve.remove(depending); } + Expression messageConstraint = null; + if ((messageConstraint = getMessage()) instanceof Term) { + unifiedMessage = (Term) messageConstraint; + } for (ChannelMember leafMember: toResolve) { - Expression messageConstraint = null; if (channel.getInputChannelMembers().contains(leafMember)) { // Calculate message constraint from an input state transition messageConstraint = channel.calcMessageConstraintForInputMember(leafMember, null, resouceStateAccessor, null, substitutedPositionsInMessageFromChannels); @@ -287,7 +290,6 @@ } // Calculate message constraint - Expression messageConstraint = null; if (channel.getInputChannelMembers().contains(dependingMem)) { // Calculate message constraint from an input state transition messageConstraint = channel.calcMessageConstraintForInputMember(dependingMem, null, resouceStateAccessor, null, substitutedPositionsInMessageFromChannels); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java b/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java index d454391..d0463cf 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java @@ -24,7 +24,12 @@ } public void setPathParam(int paramIdx, Constant param) { - pathParams.set(paramIdx, param); + if (paramIdx < pathParams.size()) { + pathParams.set(paramIdx, param); + if (parent != null) { + ((ResourceIdentifier) parent).setPathParam(paramIdx, param); + } + } } public boolean equals(ResourceIdentifier another) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 6197b03..56a9cb7 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -84,6 +84,7 @@ public SystemState transition(Event inputEvent) throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { SystemState nextSystemState = new SystemState(curState); + inputEvent.updateDependingParameters(new ResourceStateValueProvider(curState, nextSystemState)); nextSystemState.addEvent(inputEvent); fireEvent(inputEvent, curState, nextSystemState); @@ -174,16 +175,25 @@ if (channel.getOutputResources().size() > 0) { // For each output resource, calculate the next state. for (ChannelMember out: channel.getOutputChannelMembers()) { + // Calculate the next state expression. Expression nextResState = null; if (!event.isInput()) { nextResState = channel.deriveUpdateExpressionOf(out, resouceStateAccessor).getKey(); } else { nextResState = channel.deriveUpdateExpressionOf(out, (Term) event.getMessage(), resouceStateAccessor); } - ResourceIdentifier outResId = event.getOutputResourceIdentifier(out.getResource()); + // Substitute each channel selector in the expression to a value. + for (Map.Entry selestorAndVal: event.getChannelSelectorAndValues()) { + Expression selExp = selestorAndVal.getKey().getExpression(); + if (nextResState instanceof Term && selExp instanceof Variable) { + nextResState = ((Term) nextResState).substitute((Variable) selExp, selestorAndVal.getValue()); + } + } if (nextResState instanceof Term) { nextResState = ((Term) nextResState).reduce(); } + // Update the resource state. + ResourceIdentifier outResId = event.getOutputResourceIdentifier(out.getResource()); ResourceIdentifier updatedOutResId = nextSystemState.updateResourceState(outResId, nextResState); while (updatedOutResId != null) { // In addition to the target state, its descendants' states are also changed. for (Event nextEvent: getNextEvents(updatedOutResId, curSystemState, nextSystemState)) { @@ -203,22 +213,10 @@ } } - private Set getNextEvents(ResourceIdentifier inResId, final SystemState curSystemState, final SystemState nextSystemState) + private Set getNextEvents(ResourceIdentifier inResId, SystemState curSystemState, SystemState nextSystemState) throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { Set nextEvents = new HashSet<>(); - IResourceStateValueProvider resourceStateValueProvider = new IResourceStateValueProvider() { - @Override - public Expression getCurrentStateValueOf(ResourceIdentifier resId) { - if (curSystemState.getResource(resId) == null) return null; - return curSystemState.getResource(resId).getState().getValue(); - } - - @Override - public Expression getNextStateValueOf(ResourceIdentifier resId) { - if (nextSystemState.getResource(resId) == null) return null; - return nextSystemState.getResource(resId).getState().getValue(); - } - }; + IResourceStateValueProvider resourceStateValueProvider = new ResourceStateValueProvider(curSystemState, nextSystemState); for (Map.Entry chEntry: nextSystemState.getChannelStates().entrySet()) { DataTransferChannel channel = chEntry.getKey(); ChannelState nextChState = chEntry.getValue(); @@ -316,4 +314,26 @@ } return nextEvents; } + + private static class ResourceStateValueProvider implements IResourceStateValueProvider { + SystemState curSystemState; + SystemState nextSystemState; + + public ResourceStateValueProvider(SystemState curSystemState, SystemState nextSystemState) { + this.curSystemState = curSystemState; + this.nextSystemState = nextSystemState; + } + + @Override + public Expression getCurrentStateValueOf(ResourceIdentifier resId) { + if (curSystemState.getResource(resId) == null) return null; + return curSystemState.getResource(resId).getState().getValue(); + } + + @Override + public Expression getNextStateValueOf(ResourceIdentifier resId) { + if (nextSystemState.getResource(resId) == null) return null; + return nextSystemState.getResource(resId).getState().getValue(); + } + }; } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 645ed14..98f752e 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -12,6 +12,7 @@ import models.algebra.Expression; import models.algebra.Term; import models.algebra.Type; +import models.algebra.Variable; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.ListTerm; @@ -88,9 +89,19 @@ ResourceIdentifier createdResource = null; for (int i = 0; i < listValue.size(); i++) { Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (listValue.get(i) instanceof Variable) { + childResType = ((Variable) listValue.get(i)).getType(); + } else if (listValue.get(i) instanceof Term) { + childResType = ((Term) listValue.get(i)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.get(i)); ((ListResourceState) state).addChildState(childInfo.getKey()); createdResource = childInfo.getValue(); @@ -119,7 +130,13 @@ if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); } else { - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1); + Type childResType = null; + if (listValue.getChild(1) instanceof Variable) { + childResType = ((Variable) listValue.getChild(1)).getType(); + } else if (listValue.getChild(1) instanceof Term) { + childResType = ((Term) listValue.getChild(1)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.getChild(1)); @@ -136,9 +153,19 @@ ResourceIdentifier createdResource = null; for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); ((MapResourceState) state).addChildState(key, childInfo.getKey()); createdResource = childInfo.getValue(); @@ -151,9 +178,19 @@ ResourceIdentifier createdResource = null; for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); ((MapResourceState) state).addChildState(key, childInfo.getKey()); createdResource = childInfo.getValue(); @@ -180,7 +217,13 @@ if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); } else { - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1); + Type childResType = null; + if (mapValue.getChild(2) instanceof Variable) { + childResType = ((Variable) mapValue.getChild(2)).getType(); + } else if (mapValue.getChild(2) instanceof Term) { + childResType = ((Term) mapValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); String childId = ((Constant) childExp).toString(); @@ -207,7 +250,13 @@ } } if (childResourceHierarchy == null) { - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName); + Type childResType = null; + if (jsonValue.get(key) instanceof Variable) { + childResType = ((Variable) jsonValue.get(key)).getType(); + } else if (jsonValue.get(key) instanceof Term) { + childResType = ((Term) jsonValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.get(key)); @@ -236,7 +285,13 @@ } } if (childResourceHierarchy == null) { - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName); + Type childResType = null; + if (jsonValue.getChild(2) instanceof Variable) { + childResType = ((Variable) jsonValue.getChild(2)).getType(); + } else if (jsonValue.getChild(2) instanceof Term) { + childResType = ((Term) jsonValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); String childId = ((Constant) childExp).toString(); @@ -275,12 +330,11 @@ } public Map.Entry createResourceState(ResourceIdentifier resourceIdentifier, Expression resStateValue) { -// Type resType = null; -// if (resStateValue instanceof Term) { -// resType = ((Term) resStateValue).getType(); -// resStateValue = ((Term) resStateValue).reduce(); -// } Type resType = resourceIdentifier.getResourceStateType(); + if (resType == null && resStateValue instanceof Term) { + resType = ((Term) resStateValue).getType(); + resStateValue = ((Term) resStateValue).reduce(); + } if (resType != null) { if (DataConstraintModel.typeList.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { @@ -290,9 +344,19 @@ Map.Entry createInfo = null; for (int i = 0; i < listValue.size(); i++) { Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (listValue.get(i) instanceof Variable) { + childResType = ((Variable) listValue.get(i)).getType(); + } else if (listValue.get(i) instanceof Term) { + childResType = ((Term) listValue.get(i)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.get(i)); state.addChildState(childInfo.getKey()); createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); @@ -303,9 +367,19 @@ if (listValue.getSymbol().equals(DataConstraintModel.append)) { ListResourceState state = new ListResourceState(); Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (listValue.getChild(1) instanceof Variable) { + childResType = ((Variable) listValue.getChild(1)).getType(); + } else if (listValue.getChild(1) instanceof Term) { + childResType = ((Term) listValue.getChild(1)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.getChild(1)); state.addChildState(childInfo.getKey()); return new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); @@ -319,9 +393,19 @@ Map.Entry createInfo = null; for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); state.addChildState(key, childInfo.getKey()); createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); @@ -333,9 +417,19 @@ Map.Entry createInfo = null; for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); state.addChildState(key, childInfo.getKey()); createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); @@ -347,9 +441,19 @@ Expression childExp = mapValue.getChild(1); if (childExp instanceof Constant) { MapResourceState state = new MapResourceState(); - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, - childExp, - resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.getChild(2) instanceof Variable) { + childResType = ((Variable) mapValue.getChild(2)).getType(); + } else if (mapValue.getChild(2) instanceof Term) { + childResType = ((Term) mapValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); String childId = ((Constant) childExp).toString(); Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.getChild(2)); state.addChildState(childId, childInfo.getKey()); @@ -373,7 +477,13 @@ } } if (childResourceHierarchy == null) { - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName); + Type childResType = null; + if (jsonValue.get(key) instanceof Variable) { + childResType = ((Variable) jsonValue.get(key)).getType(); + } else if (jsonValue.get(key) instanceof Term) { + childResType = ((Term) jsonValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.get(key)); @@ -402,7 +512,13 @@ } } if (childResourceHierarchy == null) { - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName); + Type childResType = null; + if (jsonValue.getChild(2) instanceof Variable) { + childResType = ((Variable) jsonValue.getChild(2)).getType(); + } else if (jsonValue.getChild(2) instanceof Term) { + childResType = ((Term) jsonValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); String childId = ((Constant) childExp).toString();