Skip to content
Snippets Groups Projects
Commit 7b3c1193 authored by Johannes Mey's avatar Johannes Mey
Browse files

add some comments, remove complicated additional analysis from task

parent f778ae67
No related branches found
No related tags found
No related merge requests found
Showing
with 143 additions and 155 deletions
aspect Analysis {
public void StateMachine.printSomeAnalysis() {
Set<Set<State>> sccs = this.SCC();
System.out.print("SCCs found: ");
for (Set<State> scc : sccs) {
System.out.print(scc + " ");
}
System.out.println();
for (State s : this.states()) {
System.out.println(s + ": successors() = " + s.successors() + ", reachable() = " + s.reachable());
}
for (State finalState : this.getFinalList()) {
System.out.println("initial state "+ this.getInitial() + " to " + finalState + " in " +
this.getInitial().minDistTo(finalState) + " step(s)");
}
}
}
aspect Analysis { aspect Analysis {
/** Compute all states reachable from the current state */
syn Set<State> State.reachable() circular [new HashSet<State>()] { syn Set<State> State.reachable() circular [new HashSet<State>()] {
Set<State> result = new HashSet<>(); Set<State> result = new HashSet<>();
result.addAll(successors()); result.addAll(successors());
...@@ -8,24 +10,7 @@ aspect Analysis { ...@@ -8,24 +10,7 @@ aspect Analysis {
return result; return result;
} }
public void StateMachine.printSomeAnalysis() { /** Compute the minimum number of transitions to the other state, ignoring states with empty labels */
Set<Set<State>> sccs = this.SCC();
System.out.print("SCCs found: ");
for (Set<State> scc : sccs) {
System.out.print(scc + " ");
}
System.out.println();
for (State s : this.states()) {
System.out.println(s + ": successors() = " + s.successors() + ", reachable() = " + s.reachable());
}
for (State finalState : this.getFinalList()) {
System.out.println("initial state "+ this.getInitial() + " to " + finalState + " in " +
this.getInitial().minDistTo(finalState) + " step(s)");
}
}
syn int State.minDistTo(State other) circular [-1] { syn int State.minDistTo(State other) circular [-1] {
if (this == other) { if (this == other) {
return 0; return 0;
...@@ -41,37 +26,11 @@ aspect Analysis { ...@@ -41,37 +26,11 @@ aspect Analysis {
return result; return result;
} }
/** A transition is an epsilon transition if the label is empty */
syn boolean Transition.isEpsilon() = getLabel().isEmpty(); syn boolean Transition.isEpsilon() = getLabel().isEmpty();
/** Collect all epsilon transitions */
coll Set<Transition> StateMachine.epsilonTransitions() [new HashSet<>()]; coll Set<Transition> StateMachine.epsilonTransitions() [new HashSet<>()];
Transition contributes this when isEpsilon() to StateMachine.epsilonTransitions(); Transition contributes this when isEpsilon() to StateMachine.epsilonTransitions();
public void StateMachine.removeEpsilonTransition(Transition t) {
if (t.isEpsilon()) {
State oldFrom = t.getFrom();
State oldTo = t.getTo();
if (oldFrom != oldTo) {
State combined = new State();
combined.setLabel(oldFrom.getLabel() + "+" + oldTo.getLabel());
if (oldFrom.isInitial() || oldTo.isInitial()) {
this.setInitial(combined);
}
if (oldFrom.isFinal() || oldTo.isFinal()) {
this.addFinal(combined);
}
new ArrayList<>(oldFrom.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldFrom.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
new ArrayList<>(oldTo.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldTo.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
this.removeFinal(oldFrom);
this.removeFinal(oldTo);
oldFrom.removeSelf();
oldTo.removeSelf();
this.addElement(combined);
}
t.removeSelf();
} else {
System.err.println("Won't remove non-epsilon transition " + t.getLabel());
}
}
} }
aspect NameAnalysis { aspect NameAnalysis {
/** resolve a state using its name */
syn State StateMachine.resolveState(String id) { syn State StateMachine.resolveState(String id) {
for (State s : states()) { for (State s : states()) {
if (s.getLabel().equals(id)) { if (s.getLabel().equals(id)) {
...@@ -8,6 +10,7 @@ aspect NameAnalysis { ...@@ -8,6 +10,7 @@ aspect NameAnalysis {
return null; return null;
} }
/** resolve a transition using its name */
syn Transition StateMachine.resolveTransition(String id) { syn Transition StateMachine.resolveTransition(String id) {
for (Transition t : transitions()) { for (Transition t : transitions()) {
if (t.getLabel().equals(id)) { if (t.getLabel().equals(id)) {
......
aspect Navigation { aspect Navigation {
// ======================================================
// Atributes to complete
// ======================================================
/** Check, whether an this element is a state */ /** Check, whether an this element is a state */
syn boolean Element.isState() = false; syn boolean Element.isState() = false;
eq State.isState() = true; eq State.isState() = true;
...@@ -27,6 +31,7 @@ aspect Navigation { ...@@ -27,6 +31,7 @@ aspect Navigation {
return states; return states;
} }
/** Get all transitions */
syn List<Transition> StateMachine.transitions() { syn List<Transition> StateMachine.transitions() {
List<Transition> transitions = new ArrayList<>(); List<Transition> transitions = new ArrayList<>();
for (Element element: getElementList()) { for (Element element: getElementList()) {
...@@ -37,11 +42,17 @@ aspect Navigation { ...@@ -37,11 +42,17 @@ aspect Navigation {
return transitions; return transitions;
} }
/** Get the state machine the element is contained in */
inh StateMachine Element.containingStateMachine(); inh StateMachine Element.containingStateMachine();
eq StateMachine.getElement().containingStateMachine() = this; eq StateMachine.getElement().containingStateMachine() = this;
/** Determine whether the State is final */
syn boolean State.isInitial() = containingStateMachine().getInitial().equals(this); syn boolean State.isInitial() = containingStateMachine().getInitial().equals(this);
/** Determine whether the State is final */
syn boolean State.isFinal() = containingStateMachine().getFinalList().contains(this); syn boolean State.isFinal() = containingStateMachine().getFinalList().contains(this);
/** Get all successor states */
syn Collection<State> State.successors() = getOutgoingList().stream().map(Transition::getTo).collect(Collectors.toList()); syn Collection<State> State.successors() = getOutgoingList().stream().map(Transition::getTo).collect(Collectors.toList());
} }
aspect Printing { aspect Printing {
/** Return a textual representation of the state machine */
syn String StateMachine.prettyPrint() { syn String StateMachine.prettyPrint() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
states().forEach(s -> sb.append(s.prettyPrint())); states().forEach(s -> sb.append(s.prettyPrint()));
...@@ -6,6 +8,7 @@ aspect Printing { ...@@ -6,6 +8,7 @@ aspect Printing {
return sb.toString(); return sb.toString();
} }
/** Return a textual representation of the state machine */
syn String Element.prettyPrint(); syn String Element.prettyPrint();
eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + getLabel() + ";\n"; eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + getLabel() + ";\n";
eq Transition.prettyPrint() = "trans " + getFrom().getLabel() + " -> " + getTo().getLabel() + (isEpsilon() ? "" : " : " + getLabel()) + ";\n"; eq Transition.prettyPrint() = "trans " + getFrom().getLabel() + " -> " + getTo().getLabel() + (isEpsilon() ? "" : " : " + getLabel()) + ";\n";
......
aspect Transformation {
/** remove transformations with empty labels */
public void StateMachine.removeEpsilonTransition(Transition t) {
if (t.isEpsilon()) {
State oldFrom = t.getFrom();
State oldTo = t.getTo();
if (oldFrom != oldTo) {
State combined = new State();
combined.setLabel(oldFrom.getLabel() + "+" + oldTo.getLabel());
if (oldFrom.isInitial() || oldTo.isInitial()) {
this.setInitial(combined);
}
if (oldFrom.isFinal() || oldTo.isFinal()) {
this.addFinal(combined);
}
new ArrayList<>(oldFrom.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldFrom.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
new ArrayList<>(oldTo.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldTo.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
this.removeFinal(oldFrom);
this.removeFinal(oldTo);
oldFrom.removeSelf();
oldTo.removeSelf();
this.addElement(combined);
}
t.removeSelf();
} else {
System.err.println("Won't remove non-epsilon transition " + t.getLabel());
}
}
}
aspect Util {
}
aspect Analysis {
public void StateMachine.printSomeAnalysis() {
for (State s : this.states()) {
System.out.println(s + ": successors() = " + s.successors() + ", reachable() = " + s.reachable());
}
for (State finalState : this.getFinalList()) {
System.out.println("initial state "+ this.getInitial() + " to " + finalState + " in " +
this.getInitial().minDistTo(finalState) + " step(s)");
}
}
}
aspect Analysis { aspect Analysis {
/** Compute all states reachable from the current state */
syn Set<State> State.reachable() circular [new HashSet<State>()] { syn Set<State> State.reachable() circular [new HashSet<State>()] {
Set<State> result = new HashSet<>(); Set<State> result = new HashSet<>();
result.addAll(successors()); result.addAll(successors());
...@@ -8,24 +10,7 @@ aspect Analysis { ...@@ -8,24 +10,7 @@ aspect Analysis {
return result; return result;
} }
public void StateMachine.printSomeAnalysis() { /** Compute the minimum number of transitions to the other state, ignoring states with empty labels */
Set<Set<State>> sccs = this.SCC();
System.out.print("SCCs found: ");
for (Set<State> scc : sccs) {
System.out.print(scc + " ");
}
System.out.println();
for (State s : this.states()) {
System.out.println(s + ": successors() = " + s.successors() + ", reachable() = " + s.reachable());
}
for (State finalState : this.getFinalList()) {
System.out.println("initial state "+ this.getInitial() + " to " + finalState + " in " +
this.getInitial().minDistTo(finalState) + " step(s)");
}
}
syn int State.minDistTo(State other) circular [-1] { syn int State.minDistTo(State other) circular [-1] {
if (this == other) { if (this == other) {
return 0; return 0;
...@@ -41,37 +26,11 @@ aspect Analysis { ...@@ -41,37 +26,11 @@ aspect Analysis {
return result; return result;
} }
/** A transition is an epsilon transition if the label is empty */
syn boolean Transition.isEpsilon() = getLabel().isEmpty(); syn boolean Transition.isEpsilon() = getLabel().isEmpty();
/** Collect all epsilon transitions */
coll Set<Transition> StateMachine.epsilonTransitions() [new HashSet<>()]; coll Set<Transition> StateMachine.epsilonTransitions() [new HashSet<>()];
Transition contributes this when isEpsilon() to StateMachine.epsilonTransitions(); Transition contributes this when isEpsilon() to StateMachine.epsilonTransitions();
public void StateMachine.removeEpsilonTransition(Transition t) {
if (t.isEpsilon()) {
State oldFrom = t.getFrom();
State oldTo = t.getTo();
if (oldFrom != oldTo) {
State combined = new State();
combined.setLabel(oldFrom.getLabel() + "+" + oldTo.getLabel());
if (oldFrom.isInitial() || oldTo.isInitial()) {
this.setInitial(combined);
}
if (oldFrom.isFinal() || oldTo.isFinal()) {
this.addFinal(combined);
}
new ArrayList<>(oldFrom.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldFrom.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
new ArrayList<>(oldTo.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldTo.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
this.removeFinal(oldFrom);
this.removeFinal(oldTo);
oldFrom.removeSelf();
oldTo.removeSelf();
this.addElement(combined);
}
t.removeSelf();
} else {
System.err.println("Won't remove non-epsilon transition " + t.getLabel());
}
}
} }
aspect ConnectedComponents {
/**
* Kosaraju's algorithm
*/
syn Set<Set<State>> StateMachine.SCC() {
Map<State, Set> visited = new HashMap<>();
LinkedList<State> locked = new LinkedList<>();
for (State n : states())
if (!visited.containsKey(n))
n.visit(visited, locked); // forward search
for (State n : locked)
if (visited.get(n) == null)
n.assign(visited, new HashSet()); // backward search
return new HashSet(visited.values());
}
void State.visit(Map<State, Set> visited, LinkedList<State> locked) {
visited.put(this, null);
for (Transition t : getOutgoingList())
if (!visited.containsKey(t.getTo()))
t.getTo().visit(visited, locked);
locked.addFirst(this);
}
void State.assign(Map<State, Set> visited, Set root) {
root.add(this);
visited.put(this, root);
for (Transition t : getIncomingList())
if (visited.get(t.getFrom()) == null)
t.getFrom().assign(visited, root);
}
}
aspect NameAnalysis { aspect NameAnalysis {
/** resolve a state using its name */
syn State StateMachine.resolveState(String id) { syn State StateMachine.resolveState(String id) {
for (State s : states()) { for (State s : states()) {
if (s.getLabel().equals(id)) { if (s.getLabel().equals(id)) {
...@@ -8,6 +10,7 @@ aspect NameAnalysis { ...@@ -8,6 +10,7 @@ aspect NameAnalysis {
return null; return null;
} }
/** resolve a transition using its name */
syn Transition StateMachine.resolveTransition(String id) { syn Transition StateMachine.resolveTransition(String id) {
for (Transition t : transitions()) { for (Transition t : transitions()) {
if (t.getLabel().equals(id)) { if (t.getLabel().equals(id)) {
......
aspect Navigation { aspect Navigation {
// ======================================================
// Atributes to complete
// ======================================================
/** Check, whether an this element is a state */ /** Check, whether an this element is a state */
syn boolean Element.isState() = false; syn boolean Element.isState() = false;
eq State.isState() = true; eq State.isState() = true;
...@@ -27,6 +31,7 @@ aspect Navigation { ...@@ -27,6 +31,7 @@ aspect Navigation {
return states; return states;
} }
/** Get all transitions */
syn List<Transition> StateMachine.transitions() { syn List<Transition> StateMachine.transitions() {
List<Transition> transitions = new ArrayList<>(); List<Transition> transitions = new ArrayList<>();
for (Element element: getElementList()) { for (Element element: getElementList()) {
...@@ -37,11 +42,17 @@ aspect Navigation { ...@@ -37,11 +42,17 @@ aspect Navigation {
return transitions; return transitions;
} }
/** Get the state machine the element is contained in */
inh StateMachine Element.containingStateMachine(); inh StateMachine Element.containingStateMachine();
eq StateMachine.getElement().containingStateMachine() = this; eq StateMachine.getElement().containingStateMachine() = this;
/** Determine whether the State is final */
syn boolean State.isInitial() = containingStateMachine().getInitial().equals(this); syn boolean State.isInitial() = containingStateMachine().getInitial().equals(this);
/** Determine whether the State is final */
syn boolean State.isFinal() = containingStateMachine().getFinalList().contains(this); syn boolean State.isFinal() = containingStateMachine().getFinalList().contains(this);
/** Get all successor states */
syn Collection<State> State.successors() = getOutgoingList().stream().map(Transition::getTo).collect(Collectors.toList()); syn Collection<State> State.successors() = getOutgoingList().stream().map(Transition::getTo).collect(Collectors.toList());
} }
aspect Printing { aspect Printing {
/** Return a textual representation of the state machine */
syn String StateMachine.prettyPrint() { syn String StateMachine.prettyPrint() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
states().forEach(s -> sb.append(s.prettyPrint())); states().forEach(s -> sb.append(s.prettyPrint()));
...@@ -6,6 +8,7 @@ aspect Printing { ...@@ -6,6 +8,7 @@ aspect Printing {
return sb.toString(); return sb.toString();
} }
/** Return a textual representation of the state machine */
syn String Element.prettyPrint(); syn String Element.prettyPrint();
eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + getLabel() + ";\n"; eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + getLabel() + ";\n";
eq Transition.prettyPrint() = "trans " + getFrom().getLabel() + " -> " + getTo().getLabel() + (isEpsilon() ? "" : " : " + getLabel()) + ";\n"; eq Transition.prettyPrint() = "trans " + getFrom().getLabel() + " -> " + getTo().getLabel() + (isEpsilon() ? "" : " : " + getLabel()) + ";\n";
......
aspect StateMachinetoDotG {
syn String StateMachine.toDot() {
StringBuilder b = new StringBuilder();
b.append("strict digraph cycles {\n");
for (State from : states()) {
b.append(" ").append(from.getLabel()).append("[label=\"").append(from.getLabel()).append("\"];\n");
for (Transition out : from.getOutgoingList()) {
b.append(" ").append(from.getLabel()).append(" -> ").append(out.getTo().getLabel())
.append("[label=\"").append(out.getLabel()).append("\"];\n");
}
}
b.append("}\n");
return b.toString();
}
}
aspect Transformation {
/** remove transformations with empty labels */
public void StateMachine.removeEpsilonTransition(Transition t) {
if (t.isEpsilon()) {
State oldFrom = t.getFrom();
State oldTo = t.getTo();
if (oldFrom != oldTo) {
State combined = new State();
combined.setLabel(oldFrom.getLabel() + "+" + oldTo.getLabel());
if (oldFrom.isInitial() || oldTo.isInitial()) {
this.setInitial(combined);
}
if (oldFrom.isFinal() || oldTo.isFinal()) {
this.addFinal(combined);
}
new ArrayList<>(oldFrom.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldFrom.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
new ArrayList<>(oldTo.getIncomingList()).forEach(trans -> trans.setTo(combined));
new ArrayList<>(oldTo.getOutgoingList()).forEach(trans -> trans.setFrom(combined));
this.removeFinal(oldFrom);
this.removeFinal(oldTo);
oldFrom.removeSelf();
oldTo.removeSelf();
this.addElement(combined);
}
t.removeSelf();
} else {
System.err.println("Won't remove non-epsilon transition " + t.getLabel());
}
}
}
aspect Util {
}
...@@ -39,8 +39,6 @@ public class Main { ...@@ -39,8 +39,6 @@ public class Main {
printHeading("StateMachine after"); printHeading("StateMachine after");
System.out.println(stateMachine.prettyPrint()); System.out.println(stateMachine.prettyPrint());
} }
printHeading("DotGraph");
System.out.println(stateMachine.toDot());
DrAST_root_node = stateMachine; DrAST_root_node = stateMachine;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment