package org.scribble.model; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.stream.Collectors; import org.scribble.sesstype.kind.ProtocolKind; public abstract class MPrettyState <L, A extends MAction<K>, S extends MPrettyState<L, A, S, K>, K extends ProtocolKind> extends MState<L, A, S, K> implements MPrettyPrint { public MPrettyState(Set<L> labs) // Immutable singleton node { super(labs); } public String toLongString() { String s = "\"" + this.id + "\":["; Iterator<S> ss = this.succs.iterator(); s += this.actions.stream().map((a) -> a + "=\"" + ss.next().id + "\"").collect(Collectors.joining(", ")); return s + "]"; } @Override public final String toDot() { String s = "digraph G {\n" // rankdir=LR;\n + "compound = true;\n"; s += toDot(new HashSet<>()); return s + "\n}"; } //protected final String toDot(Set<S> seen) protected final String toDot(Set<MPrettyState<L, A, S, K>> seen) { seen.add(this); String dot = toNodeDot(); //for (Entry<A, S> e : this.edges.entrySet()) for (int i = 0; i < this.actions.size(); i ++) { /*A msg = e.getKey(); S p = e.getValue();*/ A a = this.actions.get(i); S s = this.succs.get(i); dot += "\n" + toEdgeDot(a, s); if (!seen.contains(s)) { dot += "\n" + s.toDot(seen); } } return dot; } protected final String toEdgeDot(String src, String dest, String lab) { return src + " -> " + dest + " [ " + lab + " ];"; } // dot node declaration // Override to change drawing declaration of "this" node protected String toNodeDot() { return getDotNodeId() + " [ " + getNodeLabel() + " ];"; } protected String getNodeLabel() { String labs = this.labs.toString(); //return "label=\"" + labs.substring(1, labs.length() - 1) + "\""; return "label=\"" + this.id + ": " + labs.substring(1, labs.length() - 1) + "\""; // FIXME } protected String getDotNodeId() { return "\"" + this.id + "\""; } // Override to change edge drawing from "this" as src protected String toEdgeDot(A msg, S next) { return toEdgeDot(getDotNodeId(), next.getDotNodeId(), next.getEdgeLabel(msg)); } // "this" is the dest node of the edge // Override to change edge drawing to "this" as dest protected String getEdgeLabel(A msg) { return "label=\"" + msg + "\""; } @Override public final String toAut() { Set<MPrettyState<L, A, S, K>> all = new HashSet<>(); all.add(this); all.addAll(getReachableStates(this)); String aut = ""; int edges = 0; Set<Integer> seen = new HashSet<>(); for (MPrettyState<L, A, S, K> s : all) { if (seen.contains(s.id)) { continue; } seen.add(s.id); Iterator<A> as = s.getAllActions().iterator(); Iterator<S> ss = s.getAllSuccessors().iterator(); for (; as.hasNext(); edges++) { A a = as.next(); S succ = ss.next(); String msg = a.toStringWithMessageIdHack(); // HACK aut += "\n(" + s.id + ",\"" + msg + "\"," + succ.id + ")"; } } return "des (" + this.id + "," + edges + "," + all.size() + ")" + aut + "\n"; } @Override public int hashCode() { int hash = 71; hash = 31 * hash + super.hashCode(); return hash; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof MPrettyState)) { return false; } return super.equals(o); // Checks canEquals } @Override public String toString() { return Integer.toString(this.id); // FIXME -- ? } }