~tapaal-contributor/tapaal/disappearing-tokens-1940098

« back to all changes in this revision

Viewing changes to src/dk/aau/cs/model/tapn/NetworkMarking.java

  • Committer: Kenneth Yrke Jørgensen
  • Date: 2011-04-12 09:50:16 UTC
  • mfrom: (329.1.188 tapaal-1.5)
  • Revision ID: mail@yrke.dk-20110412095016-e4hqdgab5596ja09
Merged with branch addning support for new 1.5 features

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package dk.aau.cs.model.tapn;
 
2
 
 
3
import java.math.BigDecimal;
 
4
import java.util.ArrayList;
 
5
import java.util.HashMap;
 
6
import java.util.List;
 
7
import java.util.Map.Entry;
 
8
 
 
9
import dk.aau.cs.model.tapn.simulation.FiringMode;
 
10
import dk.aau.cs.util.Require;
 
11
 
 
12
public class NetworkMarking implements TimedMarking {
 
13
        private HashMap<TimedArcPetriNet, LocalTimedMarking> markings = new HashMap<TimedArcPetriNet, LocalTimedMarking>();
 
14
        private HashMap<TimedPlace, List<TimedToken>> sharedPlacesTokens = new HashMap<TimedPlace, List<TimedToken>>();
 
15
 
 
16
        public NetworkMarking() {
 
17
        }
 
18
 
 
19
        public void addMarking(TimedArcPetriNet tapn, LocalTimedMarking marking) {
 
20
                Require.that(tapn != null, "tapn must not be null");
 
21
                Require.that(!markings.containsKey(tapn), "There is already a marking for that tapn");
 
22
 
 
23
                marking.setNetworkMarking(this);
 
24
                markings.put(tapn, marking);
 
25
        }
 
26
        
 
27
        public void removeMarkingFor(TimedArcPetriNet tapn) {
 
28
                Require.that(tapn != null, "tapn must be non-null");
 
29
 
 
30
                if (markings.containsKey(tapn)){
 
31
                        LocalTimedMarking marking = markings.remove(tapn);
 
32
                        marking.setNetworkMarking(null);
 
33
                }
 
34
        }
 
35
        
 
36
        private LocalTimedMarking getMarkingFor(TimedArcPetriNet tapn) {
 
37
                return markings.get(tapn);
 
38
        }
 
39
 
 
40
        public NetworkMarking clone() {
 
41
                return delay(BigDecimal.ZERO);
 
42
        }
 
43
 
 
44
//      private NetworkMarking shallowCopy() {
 
45
//              NetworkMarking shallowCopy = new NetworkMarking();
 
46
//
 
47
//              for (Entry<TimedArcPetriNet, LocalTimedMarking> entry : markings.entrySet()) {
 
48
//                      shallowCopy.markings.put(entry.getKey(), entry.getValue());
 
49
//              }
 
50
//              
 
51
//              for(Entry<TimedPlace, List<TimedToken>> entry : sharedPlacesTokens.entrySet()){
 
52
//                      shallowCopy.sharedPlacesTokens.put(entry.getKey(), entry.getValue());
 
53
//              }
 
54
//
 
55
//              return shallowCopy;
 
56
//      }
 
57
 
 
58
        public boolean isDelayPossible(BigDecimal delay) {
 
59
                for(List<TimedToken> listOfTokens: sharedPlacesTokens.values()){
 
60
                        for(TimedToken token : listOfTokens){
 
61
                                TimeInvariant invariant = token.place().invariant();
 
62
                                if (!invariant.isSatisfied(token.age().add(delay))) {
 
63
                                        return false;
 
64
                                }
 
65
                        }
 
66
                }
 
67
                
 
68
                for (LocalTimedMarking marking : markings.values()) {
 
69
                        if (!marking.isDelayPossible(delay))
 
70
                                return false;
 
71
                }
 
72
                return true;
 
73
        }
 
74
 
 
75
        public NetworkMarking delay(BigDecimal amount) {
 
76
                Require.that(amount != null, "Delay must not be null");
 
77
                Require.that(isDelayPossible(amount), "Delay breaks invariant.");
 
78
 
 
79
                NetworkMarking newMarking = new NetworkMarking();
 
80
                for(Entry<TimedPlace, List<TimedToken>> entry : sharedPlacesTokens.entrySet()){
 
81
                        List<TimedToken> newTokens = new ArrayList<TimedToken>(entry.getValue().size());
 
82
                        for(TimedToken token : entry.getValue()){
 
83
                                newTokens.add(token.delay(amount));
 
84
                        }
 
85
                        newMarking.sharedPlacesTokens.put(entry.getKey(), newTokens);
 
86
                }
 
87
                
 
88
                for (Entry<TimedArcPetriNet, LocalTimedMarking> entry : markings.entrySet()) {
 
89
                        newMarking.addMarking(entry.getKey(), entry.getValue().delay(amount));
 
90
                }
 
91
                return newMarking;
 
92
        }
 
93
 
 
94
        public NetworkMarking fireTransition(TimedTransition transition, FiringMode firingMode) {
 
95
                Require.that(transition != null, "transition cannot be null");
 
96
                Require.that(firingMode != null, "firingMode cannot be null");
 
97
                
 
98
                if(transition.isShared()) return fireSharedTransition(transition.sharedTransition(), firingMode);
 
99
 
 
100
                NetworkMarking clone = clone(); // TODO: try to conserve memory by reusing unchanged markings (they are immutable wrt. transition firing and delay)
 
101
                LocalTimedMarking newMarking = clone.getMarkingFor(transition.model()).fireTransition(transition, firingMode);
 
102
 
 
103
                clone.removeMarkingFor(transition.model());
 
104
                clone.addMarking(transition.model(), newMarking);
 
105
                
 
106
                return clone;
 
107
        }
 
108
 
 
109
        private NetworkMarking fireSharedTransition(SharedTransition sharedTransition, FiringMode firingMode) {
 
110
                // validity of arguments already checked above
 
111
                NetworkMarking clone = clone();
 
112
                for(TimedTransition transition : sharedTransition.transitions()){
 
113
                        LocalTimedMarking ltm = clone.getMarkingFor(transition.model()).fireTransition(transition, firingMode);
 
114
                        
 
115
                        clone.removeMarkingFor(transition.model());
 
116
                        clone.addMarking(transition.model(), ltm);
 
117
                }
 
118
                
 
119
                return clone;
 
120
        }
 
121
 
 
122
        private NetworkMarking fireSharedTransition(SharedTransition sharedTransition, List<TimedToken> tokensToConsume) {
 
123
                HashMap<TimedTransition, List<TimedToken>> tokensPerTransition = distributeTokensToIndividualTransitions(sharedTransition, tokensToConsume);
 
124
                
 
125
                NetworkMarking clone = clone();
 
126
                for(TimedTransition transition : sharedTransition.transitions()){
 
127
                        LocalTimedMarking ltm = clone.getMarkingFor(transition.model()).fireTransition(transition, tokensPerTransition.get(transition));
 
128
                        
 
129
                        clone.removeMarkingFor(transition.model());
 
130
                        clone.addMarking(transition.model(), ltm);
 
131
                }
 
132
                
 
133
                return clone;
 
134
        }
 
135
 
 
136
        private HashMap<TimedTransition, List<TimedToken>> distributeTokensToIndividualTransitions(SharedTransition sharedTransition, List<TimedToken> tokensToConsume) {
 
137
                HashMap<TimedTransition, List<TimedToken>> distributedTokens = new HashMap<TimedTransition, List<TimedToken>>();
 
138
                
 
139
                for(TimedToken token : tokensToConsume){
 
140
                        for(TimedTransition transition : sharedTransition.transitions()){
 
141
                                if(!distributedTokens.containsKey(transition)) distributedTokens.put(transition, new ArrayList<TimedToken>());
 
142
                                
 
143
                                if(transition.model().equals(((LocalTimedPlace)token.place()).model())){
 
144
                                        distributedTokens.get(transition).add(token);
 
145
                                        break;
 
146
                                }
 
147
                        }
 
148
                }
 
149
                
 
150
                return distributedTokens;
 
151
        }
 
152
 
 
153
        public NetworkMarking fireTransition(TimedTransition transition, List<TimedToken> tokensToConsume) {
 
154
                Require.that(transition != null, "transition cannot be null");
 
155
                Require.that(tokensToConsume != null, "Must specify a list of tokens");
 
156
                
 
157
                if(transition.isShared()) return fireSharedTransition(transition.sharedTransition(), tokensToConsume);
 
158
                
 
159
                NetworkMarking clone = clone(); // TODO: Try to conserve memory by reusing unchanged markings (they are immutable wrt. transition firing and delay)
 
160
                                                                                // cannot be done right now because the fireTransition call on local marking needs the reference setup properly to the new network marking
 
161
                LocalTimedMarking newMarking = clone.getMarkingFor(transition.model()).fireTransition(transition, tokensToConsume);
 
162
 
 
163
                clone.removeMarkingFor(transition.model());
 
164
                clone.addMarking(transition.model(), newMarking);
 
165
 
 
166
                return clone;
 
167
        }
 
168
 
 
169
 
 
170
        public int size() {
 
171
                int size = 0;
 
172
                for (LocalTimedMarking marking : markings.values()) {
 
173
                        size += marking.size();
 
174
                }
 
175
                
 
176
                for(List<TimedToken> tokens : sharedPlacesTokens.values()){
 
177
                        size += tokens.size();
 
178
                }
 
179
                return size;
 
180
        }
 
181
 
 
182
        public void add(TimedToken token) {
 
183
                if(token.place().isShared()){
 
184
                        addTokenToSharedPlace(token);
 
185
                }else{
 
186
                        getMarkingFor(((LocalTimedPlace)token.place()).model()).add(token); // TODO: ugly cast, but only way to get model?
 
187
                }
 
188
        }
 
189
 
 
190
        private void addTokenToSharedPlace(TimedToken token) {
 
191
                Require.that(token.place().isShared(), "Token must be located in a shared place");
 
192
                if(!sharedPlacesTokens.containsKey(token.place())){
 
193
                        sharedPlacesTokens.put(token.place(), new ArrayList<TimedToken>());
 
194
                }
 
195
 
 
196
                sharedPlacesTokens.get(token.place()).add(token);
 
197
        }
 
198
 
 
199
        public List<TimedToken> getTokensFor(TimedPlace place){
 
200
                if(place.isShared()){
 
201
                        if(!sharedPlacesTokens.containsKey(place)) return new ArrayList<TimedToken>();
 
202
                        return sharedPlacesTokens.get(place);
 
203
                }else{
 
204
                        LocalTimedPlace timedPlace = (LocalTimedPlace)place;
 
205
                        return getMarkingFor(timedPlace.model()).getTokensFor(timedPlace);
 
206
                }
 
207
        }
 
208
        
 
209
        public void remove(TimedToken token) {
 
210
                TimedPlace place = token.place();
 
211
                if(place.isShared()){
 
212
                        if(sharedPlacesTokens.containsKey(place)){
 
213
                                sharedPlacesTokens.get(place).remove(token);
 
214
                        }
 
215
                }else{
 
216
                        getMarkingFor(((LocalTimedPlace)place).model()).remove(token); // TODO: this is ugly but only way to obtain the model?
 
217
                }
 
218
        }
 
219
 
 
220
        public void removePlaceFromMarking(TimedPlace place) {
 
221
                if(place.isShared()){
 
222
                        if(sharedPlacesTokens.containsKey(place)){
 
223
                                sharedPlacesTokens.remove(place);
 
224
                        }
 
225
                }else{
 
226
                        getMarkingFor(((LocalTimedPlace)place).model()).removePlaceFromMarking(place);  
 
227
                }
 
228
                
 
229
        }
 
230
}