001 // Solutions to various exercises in the paper 002 003 import java.util.*; 004 aspect Exercises { 005 // Exercise 8: alreadyDeclared 006 syn boolean State.alreadyDeclared() = lookup(this.getLabel()) != this; 007 008 // Exercise 9: multiplyDeclared 009 syn boolean State.multiplyDeclared() = 010 alreadyDeclared() || hasLaterNamesake(); 011 012 syn boolean State.hasLaterNamesake() = 013 lookupForward(getLabel()) != null; 014 015 inh State Declaration.lookupForward(String label); 016 017 eq StateMachine.getDeclaration(int i).lookupForward(String label) { 018 for (int k = i+1; k<getNumDeclaration(); k++) { 019 Declaration d = getDeclaration(k); 020 State match = d.localLookup(label); 021 if (match != null) return match; 022 } 023 return null; 024 } 025 026 // Exercise 10: altTransitions 027 syn Set<Transition> State.altTransitions() = transitionsOf(this); 028 inh Set<Transition> State.transitionsOf(State s); 029 030 eq StateMachine.getDeclaration(int i).transitionsOf(State s) { 031 HashSet<Transition> result = new HashSet<Transition>(); 032 for (Declaration d : getDeclarationList()) { 033 Transition t = d.transitionOf(s); 034 if (t != null) result.add(t); 035 } 036 return result; 037 } 038 039 syn Transition Declaration.transitionOf(State s) = null; 040 eq Transition.transitionOf(State s) { 041 if (source() == s) 042 return this; 043 else 044 return null; 045 } 046 047 // Exercise 11: altSuccessors 048 coll Set<State> State.altSuccessors() [new HashSet<State>()] with add; 049 050 Transition contributes target() 051 when target() != null && source() != null 052 to State.altSuccessors() 053 for source(); 054 055 056 // Exercise 12: predecessors 057 coll Set<State> State.predecessors() [new HashSet<State>()] with add; 058 059 State contributes this 060 to State.predecessors() 061 for each successors(); 062 063 // Exercise 13: numberOfTransitions 064 syn int StateMachine.numberOfTransitions() = 065 numberOfTransitionsColl().value(); 066 coll Counter StateMachine.numberOfTransitionsColl() [new Counter()] with add; 067 068 Transition contributes 1 069 to StateMachine.numberOfTransitionsColl() 070 for theMachine(); 071 072 inh StateMachine Declaration.theMachine(); 073 eq StateMachine.getDeclaration(int i).theMachine() = this; 074 075 public class Counter { 076 private int value; 077 public Counter() { value = 0; } 078 public void add(int value) { this.value += value; } 079 public int value() { return value; } 080 } 081 082 // Exercise 14: errors 083 coll Set<String> StateMachine.errors() 084 [new HashSet<String>()] with add; 085 086 State contributes getLabel()+" is already declared" 087 when alreadyDeclared() 088 to StateMachine.errors() 089 for theMachine(); 090 091 Transition contributes "Missing declaration of "+getSourceLabel() 092 when source() == null 093 to StateMachine.errors() 094 for theMachine(); 095 096 Transition contributes "Missing declaration of "+getTargetLabel() 097 when target() == null 098 to StateMachine.errors() 099 for theMachine(); 100 101 // Exercise 18: altReachable 102 coll Set<State> State.altReachable() circular [new HashSet<State>()] with addAll; 103 104 State contributes union(asSet(this),altReachable()) 105 to State.altReachable() 106 for each predecessors(); 107 108 // helper functions asSet and union 109 Set<State> ASTNode.asSet(State o) { 110 HashSet<State> result = new HashSet<State>(); 111 result.add(o); 112 return result; 113 } 114 115 Set<State> ASTNode.union(Set<State> s1, Set<State> s2) { 116 HashSet<State> result = new HashSet<State>(); 117 for (State s: s1) result.add(s); 118 for (State s: s2) result.add(s); 119 return result; 120 } 121 }