diff --git a/src/main/java/avatartranslator/AvatarCompactDependencyGraph.java b/src/main/java/avatartranslator/AvatarCompactDependencyGraph.java index 2b0efc82a696f484bbd23a777bc82bd88e6a0dba..17966777c1b1e6c9713673a3a100a2fbc95a9dbd 100644 --- a/src/main/java/avatartranslator/AvatarCompactDependencyGraph.java +++ b/src/main/java/avatartranslator/AvatarCompactDependencyGraph.java @@ -39,6 +39,8 @@ package avatartranslator; +import common.CanBeTagged; +import common.Tags; import graph.AUTGraph; import graph.AUTState; import graph.AUTTransition; @@ -205,6 +207,7 @@ public class AvatarCompactDependencyGraph { tr = new AUTTransition(newState.id, "", newStateD.id); tr.addTag(AUTGraph.COMM_TAG); + //TraceManager.addDev("**** Adding COMM Tag to transition " + tr); transitions.add(tr); newState.addOutTransition(tr); newStateD.addInTransition(tr); @@ -213,6 +216,7 @@ public class AvatarCompactDependencyGraph { if (!(ar.isAsynchronous())) { tr = new AUTTransition(newStateD.id, "", newState.id); tr.addTag(AUTGraph.COMM_TAG); + //TraceManager.addDev("**** Adding COMM Tag to transition " + tr); transitions.add(tr); newStateD.addOutTransition(tr); newState.addInTransition(tr); @@ -418,6 +422,8 @@ public class AvatarCompactDependencyGraph { // Make the graph graph = new AUTGraph(states, transitions); + TraceManager.addDev("Graph done"); + } @@ -568,11 +574,13 @@ public class AvatarCompactDependencyGraph { } // Handling all nexts + //TraceManager.addDev("Handling all nexts"); //if (!(_elt instanceof AvatarActionOnSignal)) { for (AvatarStateMachineElement eltN : _elt.getNexts()) { makeCompactDependencyGraphForAvatarElement(bl, eltN, state, _elt, _states, _transitions, withID, null); } //} + //TraceManager.addDev("Done."); return state; } @@ -994,5 +1002,131 @@ public class AvatarCompactDependencyGraph { }*/ } + public void reduceGraph(String[] tags) { + // print transitions with COMM_TAG + /*TraceManager.addDev("Transition with COMM TAG - Total of transitions:" + graph.getTransitions().size()); + for(AUTTransition tr: graph.getTransitions()) { + if (tr.hasTag(AUTGraph.COMM_TAG)) { + TraceManager.addDev("\t" + tr.toExtendedString()); + } + }*/ + + // 1. We remove all vertices which tags are all in tags + ArrayList<AUTState> toBeRemoved = new ArrayList<>(); + for(AUTState state: graph.getStates()) { + if ((state.referenceObject != null)) { + if (isTagged(state, tags)) { + toBeRemoved.add(state); + TraceManager.addDev("Removing first element: " + state + "/" + state.referenceObject); + removeCommElements(state, toBeRemoved); + } + } + } + + TraceManager.addDev("Tagged states removed. Working on dependencies"); + + // 2. We iteratively remove elements with no backward dependencies that are not a start state, with no incoming edge + boolean modified = true; + + while(modified) { + // We consider non-removed state. If they have no other dependency than nothing (but not a start state) or a remove state, + // they are added to remove + modified = false; + for(AUTState state: graph.getStates()) { + if (! toBeRemoved.contains(state)) { + if (!(hasStartStateInReference(state))) { + if (hasOnlyTransitionFromRemovedStatesOrComm(state, toBeRemoved)) { + toBeRemoved.add(state); + TraceManager.addDev("Removing secondary state: " + state + "/" + state.referenceObject + " of class " + + state.referenceObject.getClass()); + // We also need to remove all states leading to the remove state if they are comm elements + removeCommElements(state, toBeRemoved); + modified = true; + } + } + } + } + } + + + // We finally remove the state + graph.removeStates(toBeRemoved); + removeReferencesOf(toBeRemoved); + } + + public boolean hasOnlyTransitionFromRemovedStatesOrComm(AUTState state, ArrayList<AUTState>toBeRemoved) { + for(AUTTransition tr: state.inTransitions) { + if (!(tr.hasTag(AUTGraph.COMM_TAG))) { + AUTState previous = graph.getState(tr.origin); + if (!(toBeRemoved.contains(previous))) { + return false; + } + } + } + return true; + } + + public void removeCommElements(AUTState state, ArrayList<AUTState>toBeRemoved) { + //TraceManager.addDev("Looking for comm transition starting from state " + state); + for(AUTTransition tr: state.outTransitions) { + AUTState next = graph.getState(tr.destination); + //TraceManager.addDev("Investigating transition " + tr.toExtendedString() + " from " + state + " TO " + next); + if (tr.hasTag(AUTGraph.COMM_TAG)) { + //TraceManager.addDev("Found comm tag in out transition from state " + state); + if (!toBeRemoved.contains(next)) { + //TraceManager.addDev("Removing comm state: " + state + "/" + state.referenceObject); + toBeRemoved.add(next); + } + } + } + } + + public boolean hasStartStateInReference(AUTState state) { + if (state.referenceObject == null) { + return false; + } + + if (!(state.referenceObject instanceof ArrayList)) { + return false; + } + + ArrayList al = (ArrayList) (state.referenceObject); + + for(Object o: al) { + if (o instanceof AvatarStartState) { + return true; + } + } + + return false; + + } + + public boolean isTagged(AUTState state, String[] tags) { + if (state.referenceObject == null) { + return false; + } + + if (!(state.referenceObject instanceof ArrayList)) { + return false; + } + + ArrayList al = (ArrayList) (state.referenceObject); + if (al.size() > 0) { + for(Object o: al) { + //TraceManager.addDev("Investigating object: " + o.toString() + " for state " + state); + if (o instanceof CanBeTagged) { + if (Tags.hasAtLeastOneTagOf((CanBeTagged) o, tags)) { + //TraceManager.addDev("tagged"); + return true; + } + } + } + } + + return false; + } + + } diff --git a/src/main/java/avatartranslator/AvatarDependencyGraph.java b/src/main/java/avatartranslator/AvatarDependencyGraph.java index 29152a8b35673610af64a12bb7f50d97ea942452..063d56b29943cee0bfaa783d05211930b41322c6 100644 --- a/src/main/java/avatartranslator/AvatarDependencyGraph.java +++ b/src/main/java/avatartranslator/AvatarDependencyGraph.java @@ -612,4 +612,6 @@ public class AvatarDependencyGraph { } + + } diff --git a/src/main/java/cli/Action.java b/src/main/java/cli/Action.java index 8e8047808ef9a692202902a056dd09619e2ef5f9..f275dfbccef2b34fe8f70ecca47e624f4503c70b 100644 --- a/src/main/java/cli/Action.java +++ b/src/main/java/cli/Action.java @@ -1626,33 +1626,36 @@ public class Action extends Command implements ProVerifOutputListener { return Interpreter.BAD; } - AvatarSpecification spec = interpreter.mgui.gtm.getAvatarSpecification(); + AvatarSpecification spec = getAvatarSpecification(interpreter); if (spec == null) { return "No AVATAR specification"; } - List<String> mutationList = null; - try { - mutationList = Files.readAllLines(new File(command).toPath()); - } catch (IOException e) { - throw new RuntimeException(e); - } + // 1. Generate Dependency graph from Avatar Spec + AvatarCompactDependencyGraph acdg = new AvatarCompactDependencyGraph(); + acdg.buildGraph(spec, true); - for (String mutationCommand:mutationList){ - try { - AvatarMutation am = AvatarMutation.createFromString(mutationCommand); - if (am != null) { - am.apply(spec); - } - } catch (ParseMutationException e) { - TraceManager.addDev("Exception in parsing mutation: " + e.getMessage()); - return e.getMessage(); - } catch (ApplyMutationException e) { - TraceManager.addDev("Exception in applying mutation: " + e.getMessage()); - return e.getMessage(); - } - } + RG rg = new RG("Dependency Graph"); + rg.graph = acdg.getGraph(); + rg.nbOfStates = rg.graph.getNbOfStates(); + rg.nbOfTransitions = rg.graph.getNbOfTransitions(); + + interpreter.mgui.addRG(rg); + + // 2. Reduce graph by removing elements with given tags + their dependencies + AvatarCompactDependencyGraph acdgReduced = acdg.clone(); + acdgReduced.reduceGraph(commands); + + rg = new RG("Dependency Graph"); + rg.graph = acdgReduced.getGraph(); + rg.nbOfStates = rg.graph.getNbOfStates(); + rg.nbOfTransitions = rg.graph.getNbOfTransitions(); + + interpreter.mgui.addRG(rg); + + // 3. Generate new Avatar spec + as = acdg.makeAvatarSpecification(); return null; } @@ -2741,6 +2744,7 @@ public class Action extends Command implements ProVerifOutputListener { addAndSortSubcommand(makeMutationFromAvatar); addAndSortSubcommand(makeComplexityAction); addAndSortSubcommand(makeMutationBatchFromAvatar); + addAndSortSubcommand(optimizeAvatarSpecRemoveTags); addAndSortSubcommand(drawAvatarSpec); addAndSortSubcommand(avatarSimulationToBrk); addAndSortSubcommand(avatarSimulationSelectTrace); diff --git a/src/main/java/common/Tags.java b/src/main/java/common/Tags.java index 8e3584e91f17d8fc3db3ad81dc157f9918cc6f69..0157db22417c45dc869b6cd4c92111fffc0e377f 100644 --- a/src/main/java/common/Tags.java +++ b/src/main/java/common/Tags.java @@ -41,6 +41,8 @@ package common; +import myutil.TraceManager; + import java.util.ArrayList; import java.util.List; @@ -123,6 +125,33 @@ public class Tags implements CanBeTagged { return ret.trim(); } + public static boolean hasAtLeastOneTagOf(CanBeTagged cbt, String[] tags) { + for(String t: tags) { + if (cbt.hasTag(t)) { + //TraceManager.addDev("Tag found:>" + t + "<"); + return true; + } + } + return false; + } + + public static boolean hasNoExtraTag(CanBeTagged cbt, String[] tags) { + for(Tag t: cbt.getAllTags()) { + boolean found = false; + for(String s: tags) { + if (t.getTag().compareTo(s) == 0) { + + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } + diff --git a/src/main/java/graph/AUTGraph.java b/src/main/java/graph/AUTGraph.java index 46745c872d7d5db70926ac0f6f8a19b9b20661a5..d93bce91e99339e8276ea5a335ded6ef075790fc 100755 --- a/src/main/java/graph/AUTGraph.java +++ b/src/main/java/graph/AUTGraph.java @@ -553,6 +553,11 @@ public class AUTGraph implements myutil.Graph { for (AUTTransition tr : transitions) { AUTTransition newTr = new AUTTransition(tr.origin, tr.transition, tr.destination); + if (tr.tags != null) { + for(AUTTag t: tr.tags) { + newTr.addTag(t); + } + } trN.add(newTr); // Update receiving and destination states AUTState s = statesN.get(tr.origin); diff --git a/src/main/java/graph/AUTTransition.java b/src/main/java/graph/AUTTransition.java index 5825d7ddd4069db0f25c1e29ab4467bad584e982..f9b0bd0592e4d77a5ce3a1ff4c1b66b71be2869c 100755 --- a/src/main/java/graph/AUTTransition.java +++ b/src/main/java/graph/AUTTransition.java @@ -93,6 +93,25 @@ public class AUTTransition implements Comparable<AUTTransition> { return "(" + origin + " ," + transition + ", " + destination + ")"; } + public String toExtendedString() { + return "(" + origin + " ," + transition + ", " + destination + ") AUTTag:" + AUTTagsToString(); + } + + + public String AUTTagsToString() { + if ((tags == null) || tags.size() == 0) { + return ""; + } + + String ret = ""; + for(AUTTag t: tags) { + ret += t.getID() + " "; + } + return ret.trim(); + + + } + public String getLabel() { int index0 = transition.indexOf("("); int index1 = transition.indexOf(")");