diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java b/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java new file mode 100644 index 0000000..c571236 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java @@ -0,0 +1,37 @@ +package simulator; + +import java.util.Map; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import models.algebra.Constant; +import models.algebra.Expression; +import models.dataConstraintModel.Selector; +import models.dataFlowModel.DataTransferChannel; + +public class ChannelState { + private DataTransferChannel channel; + private Map> childrenMap; + private Map, Map> referenceStructure; + + public ChannelState(DataTransferChannel channel) { + this.channel = channel; + } + + public Map getDependentParams(Map channelParameters) { + Map dependentParams = new HashMap<>(); + if (referenceStructure != null) { + List channelParams = new ArrayList<>(); + for (Selector sel: channel.getAllSelectors()) { + channelParams.add(channelParameters.get(sel)); + } + for (Map.Entry paramEnt: referenceStructure.get(channelParams).entrySet()) { + dependentParams.put(paramEnt.getKey(), paramEnt.getValue()); + } + } + return dependentParams; + } + + +} diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/ConcreteResourcePath.java b/AlgebraicDataflowArchitectureModel/src/simulator/ConcreteResourcePath.java deleted file mode 100644 index 3f07fb8..0000000 --- a/AlgebraicDataflowArchitectureModel/src/simulator/ConcreteResourcePath.java +++ /dev/null @@ -1,11 +0,0 @@ -package simulator; - -import models.dataConstraintModel.ResourcePath; - -public class ConcreteResourcePath extends ResourcePath { - - public ConcreteResourcePath(ResourcePath another) { - super(another); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java index b5a174b..abfcf67 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Set; +import models.algebra.Constant; import models.algebra.Expression; import models.dataConstraintModel.Channel; import models.dataConstraintModel.ResourcePath; @@ -15,91 +16,86 @@ public class Event { private DataTransferChannel channel; private Expression message; - private List channelParameters; + private boolean isInput = false; + + private Map channelParameters = new HashMap<>(); private Set inputResources; private Set outputResources; private Set succEvents = new HashSet<>(); - private Map> channelSelectorToInputResource = new HashMap<>(); - private Map> channelSelectorToOutputResource = new HashMap<>(); + private Map> channelSelectorToInputResourcePathParam = new HashMap<>(); + private Map> channelSelectorToOutputResourcePathParam = new HashMap<>(); - public Event(DataTransferChannel channel, Expression message, Resource outputResource) { + public Event(DataTransferChannel channel, ChannelState channelState, Expression message, Resource outputResource) { this.channel = channel; this.message = message; + this.isInput = true; this.outputResources.add(outputResource); - connectChannelAndPathParameters(); + connectChannelSelectorAndPathParameters(); // Extract channel parameters from the output resource. List channelSelectors = channel.getAllSelectors(); Set outputResPathSet = null; - for (int i = 0; i < channelSelectors.size(); i++) { + for (Selector sel: channelSelectors) { if (outputResPathSet == null) { - outputResPathSet = channelSelectorToOutputResource.get(i).keySet(); + outputResPathSet = channelSelectorToOutputResourcePathParam.get(sel).keySet(); } else { - outputResPathSet.retainAll(channelSelectorToOutputResource.get(i).keySet()); + outputResPathSet.retainAll(channelSelectorToOutputResourcePathParam.get(sel).keySet()); } } if (outputResPathSet.size() > 0) { ResourcePath outputResPath = outputResPathSet.iterator().next(); - for (int i = 0; i < channelSelectors.size(); i++) { - int paramIdx = channelSelectorToOutputResource.get(i).get(outputResPath); + for (Selector sel: channelSelectors) { + int paramIdx = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); Resource ancestor = outputResource; + int idx = outputResPath.getPathParams().size(); while (ancestor != null) { if (ancestor.getResourceHierarchy().getNumParameters() > 0) { - paramIdx++; - if (paramIdx == outputResPath.getPathParams().size()) break; + idx--; + if (idx == paramIdx) break; } ancestor = ancestor.getParent(); } - channelParameters.add(ancestor.getParameter()); + channelParameters.put(sel, ancestor.getParameter()); } } } - public Event(DataTransferChannel channel, Resource inputResource) { + public Event(DataTransferChannel channel, ChannelState channelState, ResourcePath inputResPath, Resource inputResource) { this.channel = channel; + this.isInput = false; this.inputResources.add(inputResource); - connectChannelAndPathParameters(); + connectChannelSelectorAndPathParameters(); // Extract channel parameters from the input resource. List channelSelectors = channel.getAllSelectors(); - Set inputResPathSet = null; - for (int i = 0; i < channelSelectors.size(); i++) { - if (inputResPathSet == null) { - inputResPathSet = channelSelectorToInputResource.get(i).keySet(); - } else { - inputResPathSet.retainAll(channelSelectorToInputResource.get(i).keySet()); - } - } - if (inputResPathSet.size() > 0) { - ResourcePath inputResPath = inputResPathSet.iterator().next(); - for (int i = 0; i < channelSelectors.size(); i++) { - if (inputResPath != null) { - int paramIdx = channelSelectorToInputResource.get(i).get(inputResPath); - Resource ancestor = inputResource; - while (ancestor != null) { - if (ancestor.getResourceHierarchy().getNumParameters() > 0) { - paramIdx++; - if (paramIdx == inputResPath.getPathParams().size()) break; - } - ancestor = ancestor.getParent(); + for (Selector sel: channelSelectors) { + if (inputResPath != null) { + int paramIdx = channelSelectorToInputResourcePathParam.get(sel).get(inputResPath); + Resource ancestor = inputResource; + int idx = inputResPath.getPathParams().size(); + while (ancestor != null) { + if (ancestor.getResourceHierarchy().getNumParameters() > 0) { + idx--; + if (idx == paramIdx) break; } - channelParameters.add(ancestor.getParameter()); + ancestor = ancestor.getParent(); } + channelParameters.put(sel, ancestor.getParameter()); } } + channelParameters.putAll(channelState.getDependentParams(channelParameters)); } - private void connectChannelAndPathParameters() { + private void connectChannelSelectorAndPathParameters() { List channelSelectors = channel.getAllSelectors(); - for (int i = 0; i < channelSelectors.size(); i++) { - Selector sel = channelSelectors.get(i); + for (Selector sel: channelSelectors) { for (ResourcePath resPath: channel.getInputResources()) { int paramIdx = resPath.getPathParams().indexOf(sel.getExpression()); if (paramIdx >= 0) { - Map pathToIdx = channelSelectorToInputResource.get(i); + Map pathToIdx = channelSelectorToInputResourcePathParam.get(sel); if (pathToIdx == null) { pathToIdx = new HashMap<>(); - channelSelectorToInputResource.put(i, pathToIdx); + channelSelectorToInputResourcePathParam.put(sel, pathToIdx); } pathToIdx.put(resPath, paramIdx); } @@ -107,10 +103,10 @@ for (ResourcePath resPath: channel.getOutputResources()) { int paramIdx = resPath.getPathParams().indexOf(sel.getExpression()); if (paramIdx >= 0) { - Map pathToIdx = channelSelectorToOutputResource.get(i); + Map pathToIdx = channelSelectorToOutputResourcePathParam.get(sel); if (pathToIdx == null) { pathToIdx = new HashMap<>(); - channelSelectorToOutputResource.put(i, pathToIdx); + channelSelectorToOutputResourcePathParam.put(sel, pathToIdx); } pathToIdx.put(resPath, paramIdx); } @@ -118,7 +114,7 @@ } } - public Channel getChannel() { + public DataTransferChannel getChannel() { return channel; } @@ -130,6 +126,10 @@ this.message = message; } + public boolean isInput() { + return isInput; + } + public Set getInputResources() { return inputResources; } @@ -146,7 +146,21 @@ succEvents.add(succEvt); } - public ConcreteResourcePath getConcreteResourcePath(ResourcePath resPath) { - return null; + public ResourceIdentifier getInputResourceIdentifier(ResourcePath inputResPath) { + ResourceIdentifier resId = new ResourceIdentifier(inputResPath); + for (Selector sel: channelParameters.keySet()) { + int paramIdx = channelSelectorToInputResourcePathParam.get(sel).get(inputResPath); + resId.setPathParam(paramIdx, channelParameters.get(sel)); + } + return resId; + } + + public ResourceIdentifier getOutputResourceIdentifier(ResourcePath outputResPath) { + ResourceIdentifier resId = new ResourceIdentifier(outputResPath); + for (Selector sel: channelParameters.keySet()) { + int paramIdx = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); + resId.setPathParam(paramIdx, channelParameters.get(sel)); + } + return resId; } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java index 7efc83f..84fb717 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java @@ -71,19 +71,19 @@ return resourceHierarchy; } - public ResourcePath getResourcePath() { - ResourcePath resPath = null; + public ResourceIdentifier getResourceIdentifier() { + ResourceIdentifier resId = null; if (parent != null) { - ResourcePath parentResPath = parent.getResourcePath(); + ResourceIdentifier parentResId = parent.getResourceIdentifier(); if (resourceHierarchy.getNumParameters() == 0) { - resPath = new ResourcePath(parentResPath, resourceHierarchy.getResourceName(), resourceHierarchy); + resId = new ResourceIdentifier(parentResId, resourceHierarchy.getResourceName(), resourceHierarchy); } else { - resPath = new ResourcePath(parentResPath, parameter.toString(), resourceHierarchy); + resId = new ResourceIdentifier(parentResId, parameter.toString(), resourceHierarchy); } } else { - resPath = new ResourcePath(resourceHierarchy.getResourceName(), resourceHierarchy); + resId = new ResourceIdentifier(resourceHierarchy.getResourceName(), resourceHierarchy); } - return resPath; + return resId; } public ResourceState getState() { @@ -119,4 +119,13 @@ } return children; } + + public Resource getDescendant(ResourceIdentifier resId) { + if (this.getResourceIdentifier().toString().equals(resId.toString())) return this; + for (Resource child: getChildren()) { + Resource res = child.getDescendant(resId); + if (res != null) return res; + } + return null; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java b/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java new file mode 100644 index 0000000..0bff536 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/simulator/ResourceIdentifier.java @@ -0,0 +1,61 @@ +package simulator; + +import java.util.HashMap; +import java.util.Map; + +import models.algebra.Constant; +import models.algebra.Expression; +import models.dataConstraintModel.ResourceHierarchy; +import models.dataConstraintModel.ResourcePath; +import models.dataConstraintModel.Selector; + +public class ResourceIdentifier extends ResourcePath { + + public ResourceIdentifier(ResourcePath another) { + super(another); + } + + public ResourceIdentifier(String resourceName, ResourceHierarchy resourceHierarchy) { + super(resourceName, resourceHierarchy); + } + + public ResourceIdentifier(ResourceIdentifier parentResId, String resourceName, ResourceHierarchy resourceHierarchy) { + super(parentResId, resourceName, resourceHierarchy); + } + + public void setPathParam(int paramIdx, Constant param) { + pathParams.set(paramIdx, param); + } + + public boolean isInstanceOf(ResourcePath resPath) { + ResourcePath resId = this; + while (resId != null && resPath != null) { + if (resId.getResourceHierarchy().getNumParameters() == 0) { + if (!resPath.getName().equals(resId.getName())) { + return false; + } + } + resId = resId.getParent(); + resPath = resPath.getParent(); + } + return true; + } + + public Map extractParameters(ResourcePath resPath) { + ResourcePath resId = this; + Map paramMap = new HashMap<>(); + while (resId != null && resPath != null) { + if (resId.getResourceHierarchy().getNumParameters() > 0) { + paramMap.put(resPath.getLastParam(), (Constant) resId.getLastParam()); + } else { + if (!resPath.getName().equals(resId.getName())) { + return null; + } + } + resId = resId.getParent(); + resPath = resPath.getParent(); + } + return paramMap; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 6e1f4b7..934f527 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -1,13 +1,23 @@ package simulator; import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import models.algebra.Expression; +import models.algebra.InvalidMessage; import models.algebra.Parameter; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Term; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; public class Simulator { @@ -34,32 +44,64 @@ return curState; } - public SystemState transition(final Event inputEvent) { - final SystemState nextState = new SystemState(curState); - nextState.addEvent(inputEvent); + public SystemState transition(Event inputEvent) + throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { + SystemState nextSystemState = new SystemState(curState); + nextSystemState.addEvent(inputEvent); + fireEvent(inputEvent, curState, nextSystemState); + + curState = nextSystemState; + return nextSystemState; + } + + private void fireEvent(final Event event, final SystemState curSystemState, final SystemState nextSystemState) + throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { IResourceStateAccessor resouceStateAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ConcreteResourcePath resPath = inputEvent.getConcreteResourcePath(target.getResource()); - return curState.getResource(resPath).getState().getValue(); + ResourceIdentifier resId = event.getInputResourceIdentifier(target.getResource()); + return curSystemState.getResource(resId).getState().getValue(); } @Override public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ConcreteResourcePath resPath = inputEvent.getConcreteResourcePath(target.getResource()); - return nextState.getResource(resPath).getState().getValue(); + ResourceIdentifier resId = event.getInputResourceIdentifier(target.getResource()); + return nextSystemState.getResource(resId).getState().getValue(); } @Override public Expression getDirectStateAccessorFor(ResourcePath target, ResourcePath from) { - ConcreteResourcePath resPath = inputEvent.getConcreteResourcePath(target); - return curState.getResource(resPath).getState().getValue(); + ResourceIdentifier resId = event.getInputResourceIdentifier(target); + return curSystemState.getResource(resId).getState().getValue(); } }; - - curState = nextState; - return nextState; + for (ChannelMember out: event.getChannel().getOutputChannelMembers()) { + Expression nextResState = event.getChannel().deriveUpdateExpressionOf(out, resouceStateAccessor).getKey(); + ResourceIdentifier outResId = event.getOutputResourceIdentifier(out.getResource()); + if (nextResState instanceof Term) { + nextResState = ((Term) nextResState).reduce(); + } + nextSystemState.setResourceState(outResId, nextResState); + for (Event nextEvent: getNextEvents(outResId, nextSystemState)) { + fireEvent(nextEvent, curSystemState, nextSystemState); + } + } + } + + private Set getNextEvents(ResourceIdentifier inResId, SystemState nextSystemState) { + Set nextEvents = new HashSet<>(); + for (Map.Entry chEntry: nextSystemState.getChannelStates().entrySet()) { + DataTransferChannel channel = chEntry.getKey(); + for (ResourcePath inResPath: channel.getInputResources()) { + if (inResId.isInstanceOf(inResPath)) { + ChannelState channelState = chEntry.getValue(); + Event nextEvent = new Event(channel, channelState, inResPath, nextSystemState.getResource(inResId)); + nextEvents.add(nextEvent); + } + } + } + return nextEvents; } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 62c1a30..38068f3 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -1,14 +1,21 @@ package simulator; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; -import models.dataConstraintModel.ResourcePath; +import models.algebra.Constant; +import models.algebra.Expression; +import models.dataFlowModel.DataTransferChannel; +import simulator.states.PrimitiveResourceState; +import simulator.states.ResourceState; public class SystemState { private Set rootResources = new HashSet<>(); + private Map channelStates = new HashMap<>(); private List events = new ArrayList<>(); public SystemState() { @@ -16,6 +23,7 @@ public SystemState(SystemState prevState) { rootResources = new HashSet<>(prevState.getRootResources()); + channelStates = new HashMap<>(prevState.getChannelStates()); } public Set getRootResources() { @@ -26,6 +34,30 @@ rootResources.add(rootResource); } + public Resource getResource(ResourceIdentifier resourceIdentifier) { + for (Resource root: rootResources) { + Resource descendant = root.getDescendant(resourceIdentifier); + if (descendant != null) return descendant; + } + return null; + } + + public void setResourceState(ResourceIdentifier resourceIdentifier, Expression resState) { + Resource res = getResource(resourceIdentifier); + if (res !=null) { + ResourceState state = res.getState(); + if (state instanceof PrimitiveResourceState) { + if (resState instanceof Constant) { + ((PrimitiveResourceState) state).setValue((Constant) resState); + } + } + } + } + + public Map getChannelStates() { + return channelStates; + } + public List getEvents() { return events; } @@ -33,8 +65,4 @@ public void addEvent(Event event) { events.add(event); } - - public Resource getResource(ConcreteResourcePath concreteResourcePath) { - return null; - } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java index 1e6804d..6ad1362 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java @@ -13,6 +13,10 @@ public Constant getValue() { return value; } + + public void setValue(Constant newValue) { + value = newValue; + } @Override boolean hasChildren() {