package org.scribble.del.local; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.scribble.ast.AstFactoryImpl; import org.scribble.ast.InteractionNode; import org.scribble.ast.ScribNode; import org.scribble.ast.local.LInteractionNode; import org.scribble.ast.local.LInteractionSeq; import org.scribble.ast.local.LRecursion; import org.scribble.del.InteractionSeqDel; import org.scribble.del.ScribDelBase; import org.scribble.main.ScribbleException; import org.scribble.model.endpoint.EState; import org.scribble.sesstype.kind.Local; import org.scribble.visit.ProtocolDefInliner; import org.scribble.visit.context.EGraphBuilder; import org.scribble.visit.context.ProjectedChoiceDoPruner; import org.scribble.visit.context.RecRemover; import org.scribble.visit.env.InlineProtocolEnv; import org.scribble.visit.wf.ReachabilityChecker; import org.scribble.visit.wf.env.ReachabilityEnv; public class LInteractionSeqDel extends InteractionSeqDel { @Override public ScribNode leaveProjectedChoiceDoPruning(ScribNode parent, ScribNode child, ProjectedChoiceDoPruner pruner, ScribNode visited) throws ScribbleException { LInteractionSeq lc = (LInteractionSeq) visited; List<LInteractionNode> actions = lc.getInteractions().stream().filter((li) -> li != null).collect(Collectors.toList()); return lc.reconstruct(actions); } // enter in super @Override public ScribNode leaveProtocolInlining(ScribNode parent, ScribNode child, ProtocolDefInliner inl, ScribNode visited) throws ScribbleException { LInteractionSeq lis = (LInteractionSeq) visited; List<LInteractionNode> lins = new LinkedList<LInteractionNode>(); for (LInteractionNode li : lis.getInteractions()) { ScribNode inlined = ((InlineProtocolEnv) li.del().env()).getTranslation(); if (inlined instanceof LInteractionSeq) { lins.addAll(((LInteractionSeq) inlined).getInteractions()); } else { lins.add((LInteractionNode) inlined); } } LInteractionSeq inlined = AstFactoryImpl.FACTORY.LInteractionSeq(lis.getSource(), lins); inl.pushEnv(inl.popEnv().setTranslation(inlined)); return (LInteractionSeq) ScribDelBase.popAndSetVisitorEnv(this, inl, lis); } // Replaces visitChildrenInSubprotocols for LocalInteractionSequence public LInteractionSeq visitForReachabilityChecking(ReachabilityChecker checker, LInteractionSeq child) throws ScribbleException { List<LInteractionNode> visited = new LinkedList<>(); for (InteractionNode<Local> li : child.getInteractions()) { ReachabilityEnv re = checker.peekEnv(); if (!re.isSequenceable()) { throw new ScribbleException(li.getSource(), "Invalid/unreachable sequence to: " + li); } visited.add((LInteractionNode) li.accept(checker)); } return child; } public LInteractionSeq visitForFsmConversion(EGraphBuilder conv, LInteractionSeq child) throws ScribbleException { EState entry = conv.util.getEntry(); EState exit = conv.util.getExit(); //try { /*for (int i = child.getInteractions().size() - 1; i >= 0; i--) // Backwards for "tau-less" continue { if (i > 0) { EndpointState tmp = conv.builder.newState(Collections.emptySet()); conv.builder.setEntry(tmp); child.getInteractions().get(i).accept(conv); conv.builder.setExit(conv.builder.getEntry()); // entry may not be tmp, entry/exit can be modified, e.g. continue } else { conv.builder.setEntry(entry); child.getInteractions().get(i).accept(conv); } }*/ for (int i = 0; i < child.getInteractions().size(); i++) { if (i == child.getInteractions().size() - 1) { conv.util.setExit(exit); child.getInteractions().get(i).accept(conv); } else { EState tmp = conv.util.newState(Collections.emptySet()); conv.util.setExit(tmp); child.getInteractions().get(i).accept(conv); conv.util.setEntry(conv.util.getExit()); // exit may not be tmp, entry/exit can be modified, e.g. continue } } } /*catch (ScribbleException e) // Hack: EFSM building now done before reachability check, removeEdge can fail { throw new RuntimeException("Shouldn't get in here: " + e); }*/ //conv.builder.setExit(exit); conv.util.setEntry(entry); return child; } // Duplicated from GInteractionSeq @Override public LInteractionSeq leaveRecRemoval(ScribNode parent, ScribNode child, RecRemover rem, ScribNode visited) throws ScribbleException { LInteractionSeq lis = (LInteractionSeq) visited; List<LInteractionNode> lins = lis.getInteractions().stream().flatMap((li) -> (li instanceof LRecursion && rem.toRemove(((LRecursion) li).recvar.toName())) ? ((LRecursion) li).getBlock().getInteractionSeq().getInteractions().stream() : Stream.of(li) ).collect(Collectors.toList()); return AstFactoryImpl.FACTORY.LInteractionSeq(lis.getSource(), lins); } }