use of org.lflang.ASTUtils in project lingua-franca by lf-lang.
the class FedASTUtils method findMaxSTP.
/**
* Find the maximum STP offset for the given 'port'.
*
* An STP offset predicate can be nested in contained reactors in
* the federate.
* @param port The port to generate the STP list for.
* @param generator The GeneratorBase instance used to perform some target-specific actions
* @param reactor The top-level reactor (not the federate reactor)
* @return The maximum STP as a TimeValue
*/
private static TimeValue findMaxSTP(Variable port, FederateInstance instance, GeneratorBase generator, Reactor reactor) {
// Find a list of STP offsets (if any exists)
List<Value> STPList = new LinkedList<>();
// First, check if there are any connections to contained reactors that
// need to be handled
List<Connection> connectionsWithPort = ASTUtils.allConnections(reactor).stream().filter(c -> c.getLeftPorts().stream().anyMatch((VarRef v) -> v.getVariable().equals(port))).collect(Collectors.toList());
// Find the list of reactions that have the port as trigger or source
// (could be a variable name)
List<Reaction> reactionsWithPort = ASTUtils.allReactions(reactor).stream().filter(r -> {
// Check the triggers of reaction r first
return r.getTriggers().stream().anyMatch(t -> {
if (t instanceof VarRef) {
// Check if the variables match
return ((VarRef) t).getVariable() == port;
} else {
// Not a network port (startup or shutdown)
return false;
}
}) || // Then check the sources of reaction r
r.getSources().stream().anyMatch(s -> s.getVariable() == port);
}).collect(Collectors.toList());
// Find a list of STP offsets (if any exists)
if (generator.isFederatedAndDecentralized()) {
for (Reaction r : safe(reactionsWithPort)) {
if (!instance.contains(r)) {
continue;
}
// If not, assume it is zero
if (r.getStp() != null) {
if (r.getStp().getValue().getParameter() != null) {
List<Instantiation> instantList = new ArrayList<>();
instantList.add(instance.instantiation);
STPList.addAll(ASTUtils.initialValue(r.getStp().getValue().getParameter(), instantList));
} else {
STPList.add(r.getStp().getValue());
}
}
}
// Check the children for STPs as well
for (Connection c : safe(connectionsWithPort)) {
VarRef childPort = c.getRightPorts().get(0);
Reactor childReactor = (Reactor) childPort.getVariable().eContainer();
// Find the list of reactions that have the port as trigger or
// source (could be a variable name)
List<Reaction> childReactionsWithPort = ASTUtils.allReactions(childReactor).stream().filter(r -> r.getTriggers().stream().anyMatch(t -> {
if (t instanceof VarRef) {
// Check if the variables match
return ((VarRef) t).getVariable() == childPort.getVariable();
} else {
// Not a network port (startup or shutdown)
return false;
}
}) || r.getSources().stream().anyMatch(s -> s.getVariable() == childPort.getVariable())).collect(Collectors.toList());
for (Reaction r : safe(childReactionsWithPort)) {
if (!instance.contains(r)) {
continue;
}
// If not, assume it is zero
if (r.getStp() != null) {
if (r.getStp().getValue() instanceof Parameter) {
List<Instantiation> instantList = new ArrayList<>();
instantList.add(childPort.getContainer());
STPList.addAll(ASTUtils.initialValue(r.getStp().getValue().getParameter(), instantList));
} else {
STPList.add(r.getStp().getValue());
}
}
}
}
}
return STPList.stream().map(ASTUtils::getLiteralTimeValue).filter(Objects::nonNull).reduce(TimeValue.ZERO, TimeValue::max);
}
Aggregations