diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 7528793..7e222cb 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -51,12 +51,12 @@ // root resource Resource resource = new Resource(res); curState.addResource(resource); - Expression initilValue = res.getInitialValue(); - if (initilValue != null) { - if (initilValue instanceof Term) { - initilValue = ((Term) initilValue).reduce(); + Expression initialValue = res.getInitialValue(); + if (initialValue != null) { + if (initialValue instanceof Term) { + initialValue = ((Term) initialValue).reduce(); } - curState.updateResourceState(resource.getResourceIdentifier(), initilValue); + curState.updateResourceState(resource.getResourceIdentifier(), null, null, initialValue); } } } @@ -145,9 +145,12 @@ */ private void fireEvent(final Event event, final SystemState curSystemState, final SystemState nextSystemState) throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { + final ChannelMember[] outTarget = new ChannelMember[1]; + final Variable[] outResVar = new Variable[1]; IResourceStateAccessor resouceStateAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + if (target == outTarget[0]) return outResVar[0]; // the current state of each output resource is not to be replaced with its value. ResourceIdentifier resId = event.getResourceIdentifier(target.getResource()); Resource res = curSystemState.getResource(resId); if (res == null) return null; @@ -176,7 +179,9 @@ // For each output resource, calculate the next state. for (ChannelMember out: channel.getOutputChannelMembers()) { // Calculate the next state expression. - Expression nextResState = null; + Expression nextResState = null; + outTarget[0] = out; + outResVar[0] = new Variable(channel.getChannelName() + "$" + out.getResource().toString() + "$this"); // A special variable to represent the current state of each output resource. if (!event.isInput()) { nextResState = channel.deriveUpdateExpressionOf(out, resouceStateAccessor).getKey(); } else { @@ -189,18 +194,25 @@ 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)) { - fireEvent(nextEvent, curSystemState, nextSystemState); + Expression curResState = null; + if (curSystemState.getResource(outResId) != null) { + curResState = curSystemState.getResource(outResId).getState().getValue(); + } + List updatedOutResIds = nextSystemState.updateResourceState(outResId, outResVar[0], curResState, nextResState); + if (updatedOutResIds != null) { + Set ancestors = new HashSet<>(); + for (ResourceIdentifier updatedOutResId: updatedOutResIds) { + while (updatedOutResId != null && !ancestors.contains(updatedOutResId)) { // In addition to the target state, its ancestors' states are also changed. + ancestors.add(updatedOutResId); + for (Event nextEvent: getNextEvents(updatedOutResId, curSystemState, nextSystemState)) { + fireEvent(nextEvent, curSystemState, nextSystemState); + } + if (channel.isNative()) break; // To avoid multiple updates of the same resource. + updatedOutResId = (ResourceIdentifier) updatedOutResId.getParent(); + } } - if (channel.isNative()) break; // To avoid multiple updates of the same resource. - updatedOutResId = (ResourceIdentifier) updatedOutResId.getParent(); } } } else if (channel.isNative()) {