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 {
/** Compute all states reachable from the current state */
syn Set<State> State.reachable() circular [new HashSet<State>()] {
Set<State> result = new HashSet<>();
result.addAll(successors());
......@@ -8,24 +10,7 @@ aspect Analysis {
return result;
}
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)");
}
}
/** Compute the minimum number of transitions to the other state, ignoring states with empty labels */
syn int State.minDistTo(State other) circular [-1] {
if (this == other) {
return 0;
......@@ -41,37 +26,11 @@ aspect Analysis {
return result;
}
/** A transition is an epsilon transition if the label is empty */
syn boolean Transition.isEpsilon() = getLabel().isEmpty();
/** Collect all epsilon transitions */
coll Set<Transition> StateMachine.epsilonTransitions() [new HashSet<>()];
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 {
/** resolve a state using its name */
syn State StateMachine.resolveState(String id) {
for (State s : states()) {
if (s.getLabel().equals(id)) {
......@@ -8,6 +10,7 @@ aspect NameAnalysis {
return null;
}
/** resolve a transition using its name */
syn Transition StateMachine.resolveTransition(String id) {
for (Transition t : transitions()) {
if (t.getLabel().equals(id)) {
......
aspect Navigation {
// ======================================================
// Atributes to complete
// ======================================================
/** Check, whether an this element is a state */
syn boolean Element.isState() = false;
eq State.isState() = true;
......@@ -27,6 +31,7 @@ aspect Navigation {
return states;
}
/** Get all transitions */
syn List<Transition> StateMachine.transitions() {
List<Transition> transitions = new ArrayList<>();
for (Element element: getElementList()) {
......@@ -37,11 +42,17 @@ aspect Navigation {
return transitions;
}
/** Get the state machine the element is contained in */
inh StateMachine Element.containingStateMachine();
eq StateMachine.getElement().containingStateMachine() = this;
/** Determine whether the State is final */
syn boolean State.isInitial() = containingStateMachine().getInitial().equals(this);
/** Determine whether the State is final */
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());
}
aspect Printing {
/** Return a textual representation of the state machine */
syn String StateMachine.prettyPrint() {
StringBuilder sb = new StringBuilder();
states().forEach(s -> sb.append(s.prettyPrint()));
......@@ -6,6 +8,7 @@ aspect Printing {
return sb.toString();
}
/** Return a textual representation of the state machine */
syn String Element.prettyPrint();
eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + 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 {
/** Compute all states reachable from the current state */
syn Set<State> State.reachable() circular [new HashSet<State>()] {
Set<State> result = new HashSet<>();
result.addAll(successors());
......@@ -8,24 +10,7 @@ aspect Analysis {
return result;
}
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)");
}
}
/** Compute the minimum number of transitions to the other state, ignoring states with empty labels */
syn int State.minDistTo(State other) circular [-1] {
if (this == other) {
return 0;
......@@ -41,37 +26,11 @@ aspect Analysis {
return result;
}
/** A transition is an epsilon transition if the label is empty */
syn boolean Transition.isEpsilon() = getLabel().isEmpty();
/** Collect all epsilon transitions */
coll Set<Transition> StateMachine.epsilonTransitions() [new HashSet<>()];
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 {
/** resolve a state using its name */
syn State StateMachine.resolveState(String id) {
for (State s : states()) {
if (s.getLabel().equals(id)) {
......@@ -8,6 +10,7 @@ aspect NameAnalysis {
return null;
}
/** resolve a transition using its name */
syn Transition StateMachine.resolveTransition(String id) {
for (Transition t : transitions()) {
if (t.getLabel().equals(id)) {
......
aspect Navigation {
// ======================================================
// Atributes to complete
// ======================================================
/** Check, whether an this element is a state */
syn boolean Element.isState() = false;
eq State.isState() = true;
......@@ -27,6 +31,7 @@ aspect Navigation {
return states;
}
/** Get all transitions */
syn List<Transition> StateMachine.transitions() {
List<Transition> transitions = new ArrayList<>();
for (Element element: getElementList()) {
......@@ -37,11 +42,17 @@ aspect Navigation {
return transitions;
}
/** Get the state machine the element is contained in */
inh StateMachine Element.containingStateMachine();
eq StateMachine.getElement().containingStateMachine() = this;
/** Determine whether the State is final */
syn boolean State.isInitial() = containingStateMachine().getInitial().equals(this);
/** Determine whether the State is final */
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());
}
aspect Printing {
/** Return a textual representation of the state machine */
syn String StateMachine.prettyPrint() {
StringBuilder sb = new StringBuilder();
states().forEach(s -> sb.append(s.prettyPrint()));
......@@ -6,6 +8,7 @@ aspect Printing {
return sb.toString();
}
/** Return a textual representation of the state machine */
syn String Element.prettyPrint();
eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + 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 {
printHeading("StateMachine after");
System.out.println(stateMachine.prettyPrint());
}
printHeading("DotGraph");
System.out.println(stateMachine.toDot());
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