Merge lp:~peter-gjoel/verifydtapn/PTrieWorkflow into lp:verifydtapn

Proposed by Peter Gjøl Jensen
Status: Merged
Approved by: Jiri Srba
Approved revision: 364
Merged at revision: 333
Proposed branch: lp:~peter-gjoel/verifydtapn/PTrieWorkflow
Merge into: lp:verifydtapn
Prerequisite: lp:~peter-gjoel/verifydtapn/WorkflowRefactor
Diff against target: 1810 lines (+1104/-120)
15 files modified
makefile.linux64 (+2/-2)
src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.cpp (+190/-0)
src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.h (+57/-0)
src/DiscreteVerification/DataStructures/MarkingEncoder.h (+31/-9)
src/DiscreteVerification/DataStructures/NonStrictMarking.hpp (+12/-0)
src/DiscreteVerification/DataStructures/WorkflowPWList.cpp (+130/-10)
src/DiscreteVerification/DataStructures/WorkflowPWList.hpp (+23/-0)
src/DiscreteVerification/DataStructures/binarywrapper.h (+168/-56)
src/DiscreteVerification/DataStructures/ptrie.h (+158/-12)
src/DiscreteVerification/DataStructures/visitor.h (+30/-0)
src/DiscreteVerification/DiscreteVerification.cpp (+44/-23)
src/DiscreteVerification/VerificationTypes/WorkflowSoundness.cpp (+109/-4)
src/DiscreteVerification/VerificationTypes/WorkflowSoundness.hpp (+18/-0)
src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.cpp (+112/-4)
src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.hpp (+20/-0)
To merge this branch: bzr merge lp:~peter-gjoel/verifydtapn/PTrieWorkflow
Reviewer Review Type Date Requested Status
Jiri Srba Approve
Jakob Taankvist Pending
Mathias Grund Sørensen Pending
Review via email: mp+262676@code.launchpad.net

Description of the change

Implementation of ptries for workflow verification.

To post a comment you must log in.
Revision history for this message
Jiri Srba (srba) wrote :

Please, merge trunk to this branch and resolve the numerous conflicts.

review: Needs Fixing
358. By Peter Gjøl Jensen

merged with trunk

Revision history for this message
Peter Gjøl Jensen (peter-gjoel) wrote :

Fixed.

Revision history for this message
Jiri Srba (srba) wrote :

Thanks. I am still getting some warnings:

In file included from src/DiscreteVerification/DataStructures/../SearchStrategies/../DataStructures/NonStrictMarking.hpp:15:
src/DiscreteVerification/DataStructures/ptrie.h:388:45: warning: variable 'node'
      is uninitialized when used within its own initialization [-Wuninitialized]
                    node_t* node = get_node(node->_lowpos);
                            ~~~~ ^~~~
src/DiscreteVerification/DataStructures/WorkflowPWList.cpp:192:20: note: in
      instantiation of member function
      'ptrie::ptrie_t<VerifyTAPN::DiscreteVerification::MetaData *>::visit'
      requested here
            passed.visit(visitor);
                   ^
In file included from src/DiscreteVerification/DataStructures/WorkflowPWList.cpp:3:
src/DiscreteVerification/DataStructures/WorkflowPWList.hpp:60:27: warning:
      private field 'last' is not used [-Wunused-private-field]
        NonStrictMarking* last;
                          ^
2 warnings generated.

review: Needs Fixing
359. By Peter Gjøl Jensen

fixed warnings

360. By Peter Gjøl Jensen

fixed covered marking visitor

361. By Peter Gjøl Jensen

readded limit on cover-check

362. By Peter Gjøl Jensen

fixed problem with ptries and unbounded markings

363. By Peter Gjøl Jensen

merged with trunk

364. By Peter Gjøl Jensen

changed comparison function for ptries, simplifying code and giving a speedup on VERY large markings

Revision history for this message
Peter Gjøl Jensen (peter-gjoel) wrote :

Minor re-factoring, improving on code-quality and possibly giving speedup on very large markings (several hundreds of tokens).

Revision history for this message
Jiri Srba (srba) wrote :

Extensively tested and it works flawlessly on all my examples.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'makefile.linux64'
--- makefile.linux64 2015-06-17 10:05:28 +0000
+++ makefile.linux64 2015-08-20 13:27:24 +0000
@@ -8,9 +8,9 @@
8CUT = cut8CUT = cut
99
10# Compiler and linker flags10# Compiler and linker flags
11CFLAGS = -fpermissive -DBOOST_DISABLE_THREADS -DNDEBUG -DDISABLE_ASSERTX -static -O3 -Wall -mtune=core211CFLAGS = -DBOOST_DISABLE_THREADS -DNDEBUG -DDISABLE_ASSERTX -static -O3 -Wall -mtune=core2
1212
13LDFLAGS = -fpermissive -DBOOST_DISABLE_THREADS -DNDEBUG -DDISABLE_ASSERTX -static -O3 -Wall -mtune=core213LDFLAGS = -DBOOST_DISABLE_THREADS -DNDEBUG -DDISABLE_ASSERTX -static -O3 -Wall -mtune=core2
1414
15# Input files15# Input files
16SOURCES = $(shell find * -name "*.cpp") 16SOURCES = $(shell find * -name "*.cpp")
1717
=== added file 'src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.cpp'
--- src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.cpp 1970-01-01 00:00:00 +0000
+++ src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.cpp 2015-08-20 13:27:24 +0000
@@ -0,0 +1,190 @@
1/*
2 * File: CoveredMarkingVisitor.cpp
3 * Author: Peter G. Jensen
4 *
5 * Created on 18 June 2015, 14:23
6 */
7
8#include "CoveredMarkingVisitor.h"
9
10
11using namespace ptrie;
12namespace VerifyTAPN {
13namespace DiscreteVerification {
14
15 CoveredMarkingVisitor::CoveredMarkingVisitor(
16 MarkingEncoder<MetaData*, NonStrictMarking>& enc)
17 : encoder(enc), scratchpad(0)
18 {
19
20 }
21
22
23 CoveredMarkingVisitor::~CoveredMarkingVisitor()
24 {
25 scratchpad.release();
26 }
27
28 void CoveredMarkingVisitor::set_target(NonStrictMarking* m, ptriepointer_t<MetaData*> me)
29 {
30 target = m;
31 _found=false;
32 _targetencoding = me;
33
34 if(encoder.scratchpad.size() > scratchpad.size())
35 {
36 scratchpad.release();
37 scratchpad = encoder.scratchpad.clone();
38 }
39 }
40
41 bool CoveredMarkingVisitor::set(int index, bool value)
42 {
43 if(_found) return true; // end
44 scratchpad.set(index, value);
45 // If we have enough bits to constitute a single token (with placement)
46 if((index + 1) % encoder.offsetBitSize == 0 && index > 0)
47 {
48 size_t begin = (index / encoder.offsetBitSize) * encoder.offsetBitSize;
49 unsigned long long data = 0;
50 uint count = 0;
51 uint cbit = index;
52
53 while (cbit >= begin + encoder.countBitSize) {
54 data = data << 1;
55 if(scratchpad.at(cbit))
56 {
57 data |= 1;
58 }
59 --cbit;
60 }
61
62 while(cbit >= begin)
63 {
64 count = count << 1;
65 if(scratchpad.at(cbit))
66 {
67 count |= 1;
68 }
69 if(cbit == 0) break;
70 cbit--;
71 }
72
73 if (count) {
74 return !target_contains_token(data, count);
75 }
76 // should not really happen
77 assert(false);
78 return true; // skip if happens!
79 }
80 else
81 {
82 return false; // not enough info
83 }
84 }
85
86 bool CoveredMarkingVisitor::set_remainder(int index,
87 ptriepointer_t<MetaData*> pointer)
88 {
89 // special case, marking cannot cover itself
90 if(pointer.index == _targetencoding.index) return false;
91 if(_found) return true; // end
92
93 encoding_t remainder = pointer.remainder();
94 uint offset = index - (index % 8); // offset matches on a byte
95 uint begin = (index / encoder.offsetBitSize ) * encoder.offsetBitSize; // start from whole token
96 // check inclusion
97
98 bool bit;
99
100 while(true)
101 {
102 uint cbit = begin;
103 unsigned long long data = 0;
104 uint count = 0;
105 cbit += encoder.offsetBitSize - 1;
106 // unpack place/age/count
107 while (cbit >= begin + encoder.countBitSize) {
108 data = data << 1;
109
110 if(cbit < offset) bit = scratchpad.at(cbit);
111 else bit = remainder.at(cbit - offset);
112
113 if(bit)
114 {
115 data |= 1;
116 }
117 --cbit;
118 }
119
120 while(cbit >= begin)
121 {
122 count = count << 1;
123
124 if(cbit < offset) bit = scratchpad.at(cbit);
125 else bit = remainder.at(cbit - offset);
126
127 if(bit)
128 {
129 count |= 1;
130 }
131 if(cbit == 0) break;
132 cbit--;
133 }
134 begin += encoder.offsetBitSize;
135 if (count)
136 {
137 if(!target_contains_token(data, count))
138 {
139 return false;
140 }
141 }
142 else
143 {
144 break;
145 }
146 }
147
148 match = pointer;
149 _found = true;
150 return true;
151 }
152
153 bool CoveredMarkingVisitor::back(int index)
154 {
155 return false;
156 }
157
158 bool CoveredMarkingVisitor::target_contains_token(unsigned long long placeage, uint count)
159 {
160 if(count == 0) return true;
161
162 int age = floor(placeage / encoder.numberOfPlaces);
163 int place = (placeage % encoder.numberOfPlaces);
164 int cnt = count;
165 const TokenList& tokens = target->getTokenList(place);
166
167
168 for( TokenList::const_iterator it = tokens.begin();
169 it != tokens.end(); ++it)
170 {
171 if(it->getAge() == age)
172 {
173 if(it->getCount() >= cnt) return true; // continue
174 else return false; // skip branch
175 }
176 else if(it->getAge() > age) return false; // skip branch
177 }
178
179 return false; // skip branch
180 }
181
182 NonStrictMarking* CoveredMarkingVisitor::decode()
183 {
184 NonStrictMarking* m = encoder.decode(match);
185 m->meta = match.get_meta();
186 return m;
187 }
188
189}
190}
0\ No newline at end of file191\ No newline at end of file
1192
=== added file 'src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.h'
--- src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.h 1970-01-01 00:00:00 +0000
+++ src/DiscreteVerification/DataStructures/CoveredMarkingVisitor.h 2015-08-20 13:27:24 +0000
@@ -0,0 +1,57 @@
1/*
2 * File: CoveredMarkingVisitor.h
3 * Author: Peter G. Jensen
4 *
5 * Created on 17 June 2015, 00:04
6 */
7
8#ifndef COVEREDMARKINGVISITOR_H
9#define COVEREDMARKINGVISITOR_H
10
11#include "binarywrapper.h"
12#include <limits>
13#include <vector>
14#include "ptrie.h"
15#include "visitor.h"
16#include "MarkingEncoder.h"
17#include "NonStrictMarkingBase.hpp"
18#include "NonStrictMarking.hpp"
19
20
21using namespace ptrie;
22namespace VerifyTAPN {
23namespace DiscreteVerification {
24
25 class CoveredMarkingVisitor
26 : public visitor_t<MetaData*>
27 {
28 typedef binarywrapper_t<MetaData*> encoding_t;
29 private:
30 MarkingEncoder<MetaData*, NonStrictMarking>& encoder;
31 NonStrictMarking* target;
32 encoding_t scratchpad;
33 ptriepointer_t<MetaData*> match;
34 bool _found;
35 ptriepointer_t<MetaData*> _targetencoding;
36
37 private:
38 bool target_contains_token(unsigned long long placeage, uint count);
39
40 public:
41 CoveredMarkingVisitor(
42 MarkingEncoder<MetaData*, NonStrictMarking>& enc);
43 ~CoveredMarkingVisitor();
44 virtual bool back(int index);
45 virtual bool set(int index, bool value);
46 virtual bool set_remainder(int index,
47 ptriepointer_t<MetaData*> pointer);
48 void set_target(NonStrictMarking* m, ptriepointer_t<MetaData*> me);
49 NonStrictMarking* decode();
50 bool found(){return _found;}
51 };
52
53}
54}
55
56#endif /* BINARYMARKINGVISITOR_H */
57
058
=== modified file 'src/DiscreteVerification/DataStructures/MarkingEncoder.h'
--- src/DiscreteVerification/DataStructures/MarkingEncoder.h 2015-06-22 21:03:26 +0000
+++ src/DiscreteVerification/DataStructures/MarkingEncoder.h 2015-08-20 13:27:24 +0000
@@ -20,9 +20,12 @@
20namespace VerifyTAPN {20namespace VerifyTAPN {
21 namespace DiscreteVerification {21 namespace DiscreteVerification {
2222
23 class CoveredMarkingVisitor;
24
23 template<typename T, typename M = NonStrictMarkingBase>25 template<typename T, typename M = NonStrictMarkingBase>
24 class MarkingEncoder26 class MarkingEncoder
25 {27 {
28 friend class CoveredMarkingVisitor;
26 typedef binarywrapper_t<T> encoding_t;29 typedef binarywrapper_t<T> encoding_t;
2730
28 private:31 private:
@@ -32,10 +35,9 @@
32 const uint countBitSize;35 const uint countBitSize;
33 const uint placeAgeBitSize;36 const uint placeAgeBitSize;
34 const uint offsetBitSize; 37 const uint offsetBitSize;
35 uint markingBitSize;38 const uint markingBitSize;
36 TAPN::TimedArcPetriNet& tapn;39 TAPN::TimedArcPetriNet& tapn;
37 encoding_t scratchpad;40 encoding_t scratchpad;
38 void* raw;
39 public:41 public:
40 MarkingEncoder(TAPN::TimedArcPetriNet& tapn, int knumber,42 MarkingEncoder(TAPN::TimedArcPetriNet& tapn, int knumber,
41 int nplaces, int mage);43 int nplaces, int mage);
@@ -58,8 +60,7 @@
58 markingBitSize(offsetBitSize * (knumber ? knumber : 1)),60 markingBitSize(offsetBitSize * (knumber ? knumber : 1)),
59 tapn(tapn)61 tapn(tapn)
60 {62 {
61 scratchpad = encoding_t(markingBitSize);63 scratchpad = encoding_t(0);
62 raw = (void*)scratchpad.raw();
63 }64 }
64 65
65 template<typename T, typename M>66 template<typename T, typename M>
@@ -71,7 +72,10 @@
71 template<typename T, typename M>72 template<typename T, typename M>
72 M* MarkingEncoder<T, M>::decode(const ptriepointer_t<T>& pointer)73 M* MarkingEncoder<T, M>::decode(const ptriepointer_t<T>& pointer)
73 {74 {
74 assert(scratchpad.raw() == raw);75 // we allready know here that the scratchpad is large enough,
76 // it is monotonically increased when we encode, ie; no marking
77 // taking up more bits are currently in the ptrie.
78
75 M* m = new M();79 M* m = new M();
76 assert(pointer.container->consistent());80 assert(pointer.container->consistent());
77 const encoding_t remainder = pointer.remainder();81 const encoding_t remainder = pointer.remainder();
@@ -81,12 +85,13 @@
81 85
82 uint cbit = 0;86 uint cbit = 0;
83 // foreach token87 // foreach token
84 uint data = 0;88
85 uint count = 0;
86 bool bit;89 bool bit;
87 for (uint i = 0; i < maxNumberOfTokens; i++) {90 for (uint i = 0; i < maxNumberOfTokens; i++) {
88 uint offset = offsetBitSize * i;91 uint offset = offsetBitSize * i;
89 cbit = offset + offsetBitSize - 1;92 cbit = offset + offsetBitSize - 1;
93 unsigned long long data = 0;
94 uint count = 0;
90 95
91 while (cbit >= offset + countBitSize) {96 while (cbit >= offset + countBitSize) {
92 data = data << 1;97 data = data << 1;
@@ -137,8 +142,6 @@
137 uint place = (data % this->numberOfPlaces);142 uint place = (data % this->numberOfPlaces);
138 Token t = Token(age, count);143 Token t = Token(age, count);
139 m->addTokenInPlace(tapn.getPlace(place), t);144 m->addTokenInPlace(tapn.getPlace(place), t);
140 data = 0;
141 count = 0;
142 }145 }
143 else146 else
144 {147 {
@@ -157,6 +160,25 @@
157 template<typename T, typename M>160 template<typename T, typename M>
158 binarywrapper_t<T> MarkingEncoder<T, M>::encode(M* marking)161 binarywrapper_t<T> MarkingEncoder<T, M>::encode(M* marking)
159 {162 {
163 // make sure we have space to encode marking
164 size_t count = 0;
165 for (vector<Place>::const_iterator pi = marking->getPlaceList().begin();
166 pi != marking->getPlaceList().end();
167 pi++) {
168 count += pi->tokens.size();
169 }
170 count *= offsetBitSize;
171 count /= 8;
172 count += 1;
173
174 if(scratchpad.size() < count)
175 {
176 scratchpad.release();
177 scratchpad = encoding_t(count * 8);
178 }
179
180
181
160 scratchpad.zero();182 scratchpad.zero();
161 int tc = 0;183 int tc = 0;
162 uint bitcount = 0;184 uint bitcount = 0;
163185
=== modified file 'src/DiscreteVerification/DataStructures/NonStrictMarking.hpp'
--- src/DiscreteVerification/DataStructures/NonStrictMarking.hpp 2015-06-22 21:03:26 +0000
+++ src/DiscreteVerification/DataStructures/NonStrictMarking.hpp 2015-08-20 13:27:24 +0000
@@ -48,6 +48,18 @@
48 MetaDataWithTraceAndEncoding* parent;48 MetaDataWithTraceAndEncoding* parent;
49 };49 };
50 50
51 struct WorkflowSoundnessMetaDataWithEncoding : public MetaDataWithTraceAndEncoding {
52 public:
53 WorkflowSoundnessMetaDataWithEncoding() : MetaDataWithTraceAndEncoding(), parents()
54 { totalDelay = INT_MAX;};
55 virtual ~WorkflowSoundnessMetaDataWithEncoding()
56 {
57 parents.clear();
58 }
59
60 vector<MetaData*> parents;
61 };
62
51 class NonStrictMarking : public NonStrictMarkingBase{63 class NonStrictMarking : public NonStrictMarkingBase{
52 public:64 public:
53 NonStrictMarking():NonStrictMarkingBase(), meta(NULL){}65 NonStrictMarking():NonStrictMarkingBase(), meta(NULL){}
5466
=== modified file 'src/DiscreteVerification/DataStructures/WorkflowPWList.cpp'
--- src/DiscreteVerification/DataStructures/WorkflowPWList.cpp 2015-06-22 22:10:16 +0000
+++ src/DiscreteVerification/DataStructures/WorkflowPWList.cpp 2015-08-20 13:27:24 +0000
@@ -88,7 +88,8 @@
88 }88 }
8989
90 bool isFirst = true;90 bool isFirst = true;
91 for (vector<NonStrictMarking*>::iterator iter = coveredMarkings.begin(); iter != coveredMarkings.end(); ++iter) {91 for (vector<NonStrictMarking*>::iterator iter = coveredMarkings.begin();
92 iter != coveredMarkings.end(); ++iter) {
92 if (isFirst) {93 if (isFirst) {
93 isFirst = false;94 isFirst = false;
94 continue;95 continue;
@@ -96,22 +97,15 @@
96 NonStrictMarking* covered = lookup(*iter);97 NonStrictMarking* covered = lookup(*iter);
97 if (covered != NULL) {98 if (covered != NULL) {
98 // cleanup99 // cleanup
99 for (vector<NonStrictMarking*>::iterator del = coveredMarkings.begin();100 for (;iter != coveredMarkings.end(); ++iter)
100 del != coveredMarkings.end(); ++del)
101 {101 {
102 delete *del;102 delete *iter;
103 }103 }
104 return covered;104 return covered;
105 }105 }
106 delete *iter;106 delete *iter;
107 }107 }
108 108
109 // Cleanup
110 for (vector<NonStrictMarking*>::iterator del = coveredMarkings.begin();
111 del != coveredMarkings.end(); ++del)
112 {
113 delete *del;
114 }
115 }109 }
116 return NULL;110 return NULL;
117 }111 }
@@ -163,6 +157,132 @@
163 }157 }
164158
165159
160 WorkflowPWListHybrid::WorkflowPWListHybrid(
161 TAPN::TimedArcPetriNet& tapn,
162 WaitingList<ptriepointer_t<MetaData*> >* w_l,
163 int knumber,
164 int nplaces,
165 int mage)
166 : PWListHybrid(tapn, w_l, knumber, nplaces, mage, false, true),
167 visitor(encoder)
168 {
169
170 }
171
172 WorkflowPWListHybrid::~WorkflowPWListHybrid()
173 {
174 ptriepointer_t<MetaData*> begin = passed.begin();
175 while(begin != passed.end())
176 {
177 delete begin.get_meta();
178 ++ begin;
179 }
180 }
181
182 NonStrictMarking* WorkflowPWListHybrid::getCoveredMarking
183 (NonStrictMarking* marking, bool useLinearSweep)
184 {
185 visitor.set_target(marking, last_pointer);
186 passed.visit(visitor);
187 if(visitor.found())
188 {
189 NonStrictMarking* m = visitor.decode();
190 return m;
191 }
192 else
193 {
194 return NULL;
195 }
196 }
197
198 NonStrictMarking* WorkflowPWListHybrid::getUnpassed()
199 {
200 ptriepointer_t<MetaData*> it = passed.last();
201 for(; it != passed.rend(); --it)
202 {
203 if(!it.get_meta()->passed)
204 {
205 NonStrictMarking* m = encoder.decode(it);
206 m->meta = it.get_meta();
207 return m;
208 }
209 }
210 return NULL;
211 }
212
213 bool WorkflowPWListHybrid::add(NonStrictMarking* marking)
214 {
215 discoveredMarkings++;
216 std::pair<bool, ptriepointer_t<MetaData*> > res =
217 passed.insert(encoder.encode(marking));
218
219 if (!res.first) {
220 return false;
221 }
222 else
223 {
224 MetaDataWithTraceAndEncoding* meta =
225 new MetaDataWithTraceAndEncoding();
226 meta->generatedBy = marking->getGeneratedBy();
227 meta->ep = res.second;
228 meta->parent = parent;
229 meta->totalDelay = marking->calculateTotalDelay();
230
231 res.second.set_meta(meta);
232
233 stored++;
234
235 // using min first waiting-list, weight is allready in pointer
236 waiting_list->add(NULL, res.second);
237 return true;
238 }
239 }
240
241 NonStrictMarking* WorkflowPWListHybrid::addToPassed
242 (NonStrictMarking* marking, bool strong)
243 {
244 discoveredMarkings++;
245 std::pair<bool, ptriepointer_t<MetaData*> > res =
246 passed.insert(encoder.encode(marking));
247
248
249
250 if (!res.first) {
251 NonStrictMarking* old = encoder.decode(res.second);
252
253 MetaDataWithTraceAndEncoding* meta =
254 (MetaDataWithTraceAndEncoding*)res.second.get_meta();
255 old->setGeneratedBy(meta->generatedBy);
256 old->meta = meta;
257 last_pointer = res.second;
258 return old;
259 } else {
260 stored++;
261
262 if(strong) marking->meta = new MetaDataWithTraceAndEncoding();
263 else marking->meta = new WorkflowSoundnessMetaDataWithEncoding();
264
265 MetaDataWithTraceAndEncoding* meta =
266 (MetaDataWithTraceAndEncoding*) marking->meta;
267 meta->ep = res.second;
268 meta->parent = this->parent;
269 meta->generatedBy = marking->getGeneratedBy();
270 meta->totalDelay = marking->meta->totalDelay;
271
272 res.second.set_meta(meta);
273 last_pointer = res.second;
274 return NULL;
275 }
276 }
277
278 void WorkflowPWListHybrid::addLastToWaiting()
279 {
280 // using min first waiting-list, weight is allready in pointer
281 waiting_list->add(NULL, last_pointer);
282 }
283
284
285
166286
167 }287 }
168}288}
169289
=== modified file 'src/DiscreteVerification/DataStructures/WorkflowPWList.hpp'
--- src/DiscreteVerification/DataStructures/WorkflowPWList.hpp 2015-06-22 22:10:16 +0000
+++ src/DiscreteVerification/DataStructures/WorkflowPWList.hpp 2015-08-20 13:27:24 +0000
@@ -15,6 +15,7 @@
15#include "NonStrictMarking.hpp"15#include "NonStrictMarking.hpp"
16#include "WaitingList.hpp"16#include "WaitingList.hpp"
17#include "PWList.hpp"17#include "PWList.hpp"
18#include "CoveredMarkingVisitor.h"
1819
19namespace VerifyTAPN {20namespace VerifyTAPN {
20namespace DiscreteVerification {21namespace DiscreteVerification {
@@ -51,6 +52,28 @@
51 }52 }
5253
53 };54 };
55
56 class WorkflowPWListHybrid : public WorkflowPWListBasic, public PWListHybrid {
57 private:
58 CoveredMarkingVisitor visitor;
59 ptriepointer_t<MetaData*> last_pointer;
60 public:
61 WorkflowPWListHybrid(TAPN::TimedArcPetriNet& tapn,
62 WaitingList<ptriepointer_t<MetaData*> >* w_l,
63 int knumber,
64 int nplaces,
65 int mage);
66 ~WorkflowPWListHybrid();
67 virtual NonStrictMarking* getCoveredMarking(NonStrictMarking* marking, bool useLinearSweep);
68 virtual NonStrictMarking* getUnpassed();
69 virtual bool add(NonStrictMarking* marking);
70 virtual NonStrictMarking* addToPassed(NonStrictMarking* marking, bool strong);
71 virtual void addLastToWaiting();
72 virtual void setParent(NonStrictMarking* marking, NonStrictMarking*)
73 {
74 ((MetaDataWithTraceAndEncoding*)marking->meta)->parent = parent;
75 }
76 };
5477
55} /* namespace DiscreteVerification */78} /* namespace DiscreteVerification */
56} /* namespace VerifyTAPN */79} /* namespace VerifyTAPN */
5780
=== modified file 'src/DiscreteVerification/DataStructures/binarywrapper.h'
--- src/DiscreteVerification/DataStructures/binarywrapper.h 2015-06-17 09:03:12 +0000
+++ src/DiscreteVerification/DataStructures/binarywrapper.h 2015-08-20 13:27:24 +0000
@@ -9,6 +9,8 @@
9#include <stdio.h>9#include <stdio.h>
10#include <iostream>10#include <iostream>
11#include <string.h>11#include <string.h>
12#include <assert.h>
13#include <stdint.h>
1214
13#ifndef BINARYWRAPPER_H15#ifndef BINARYWRAPPER_H
14#define BINARYWRAPPER_H16#define BINARYWRAPPER_H
@@ -17,44 +19,175 @@
17 typedef unsigned int uint;19 typedef unsigned int uint;
18 typedef unsigned char uchar;20 typedef unsigned char uchar;
19 21
22 /**
23 * Wrapper for binary data. This provides easy access to individual bits,
24 * heap allocation and comparison. Notice that one has to make sure to
25 * explicitly call release() if one wishes to deallocate (possibly shared data).
26 *
27 */
20 template<class T>28 template<class T>
21 class binarywrapper_t29 class binarywrapper_t
22 {30 {
23 public:31 public:
24 // Constructors32 // Constructors
33 /**
34 * Empty constructor, no data is allocated
35 */
36 inline
25 binarywrapper_t(); 37 binarywrapper_t();
38
39 /**
40 Allocates a room for at least size bits
41 */
42 inline
26 binarywrapper_t(uint size);43 binarywrapper_t(uint size);
44
45 /**
46 * Constructor for copying over data from latest the offset'th bit.
47 * Detects overflows.
48 * @param other: wrapper to copy from
49 * @param offset: maximal number of bits to skip.
50 */
51 inline
27 binarywrapper_t(const binarywrapper_t& other, uint offset);52 binarywrapper_t(const binarywrapper_t& other, uint offset);
28 binarywrapper_t(const binarywrapper_t& other, uint size, uint offset, 53 binarywrapper_t(const binarywrapper_t& other, uint size, uint offset,
29 uint encodingsize);54 uint encodingsize);
30 binarywrapper_t(uchar* raw, uint size, uint offset, uint encsize);55 binarywrapper_t(uchar* raw, uint size, uint offset, uint encsize);
56
57 /**
58 * Assign (not copy) raw data to pointer. Set number of bytes to size
59 * @param raw: some memory to point to
60 * @param size: number of bytes.
61 */
62 inline
31 binarywrapper_t(uchar* raw, uint size);63 binarywrapper_t(uchar* raw, uint size);
32 64
33 // Destructor65 /**
66 * Empty destructor. Does NOT deallocate data - do this with explicit
67 * call to release().
68 */
69 inline
34 ~binarywrapper_t();70 ~binarywrapper_t();
35 71
36 // Copy and clones72 /**
73 * Makes a complete copy, including new heap-allocation
74 * @return an exact copy, but in a different area of the heap.
75 */
76 inline
37 binarywrapper_t clone() const;77 binarywrapper_t clone() const;
78
79 /**
80 * Copy over data and meta-data from other, but insert only into target
81 * after offset bits.
82 * Notice that this can cause memory-corruption if there is not enough
83 * room in target, or to many bits are skipped.
84 * @param other: wrapper to copy from
85 * @param offset: bits to skip
86 */
87 inline
38 void copy(const binarywrapper_t& other, uint offset);88 void copy(const binarywrapper_t& other, uint offset);
89
90 /**
91 * Copy over size bytes form raw data. Assumes that current wrapper has
92 * enough room.
93 * @param raw: source data
94 * @param size: number of bytes to copy
95 */
96 inline
39 void copy(const uchar* raw, uint size);97 void copy(const uchar* raw, uint size);
40 98
41 // accessors99 // accessors
100 /**
101 * Get value of the place'th bit
102 * @param place: bit index
103 * @return
104 */
105 inline
42 bool at(const uint place) const;106 bool at(const uint place) const;
107
108 /**
109 * number of bytes allocated in heap
110 * @return
111 */
112 inline
43 uint size() const;113 uint size() const;
44 uchar* raw() const;114
115 /**
116 * Raw access to data
117 * @return
118 */
119 inline
120 uchar*& raw();
121
122 /**
123 * Raw access to data when in const setting
124 * @return
125 */
126 inline
127 uchar* const_raw() const;
128
129 /**
130 * pretty print of content
131 */
132 inline
45 void print() const;133 void print() const;
134
135 /**
136 * finds the overhead (unused number of bits) when allocating for size
137 * bits.
138 * @param size: number of bits
139 * @return
140 */
141 inline
46 static size_t overhead(uint size);142 static size_t overhead(uint size);
47 143
48 // modifiers144 // modifiers
145 /**
146 * Change value of place'th bit
147 * @param place: index of bit to change
148 * @param value: desired value
149 */
150 inline
49 void set(const uint place, const bool value) const;151 void set(const uint place, const bool value) const;
152
153 /**
154 * Sets all memory on heap to 0
155 */
156 inline
50 void zero() const;157 void zero() const;
51 void release() const;158
159 /**
160 * Deallocates memory stored on heap
161 */
162 inline
163 void release();
164
52 void set_meta(T data);165 void set_meta(T data);
53 T get_meta() const;166 T get_meta() const;
167
168 /**
169 * Nice access to single bits
170 * @param i: index to access
171 * @return
172 */
173 inline
54 uchar operator[](int i);174 uchar operator[](int i);
175
176 /**
177 * Removes a number of bytes from end of heap-allocated data if any is
178 * allocated nothing happens if not. Bound-checks.
179 * @param number of bytes to remove.
180 */
181 inline
55 void pop_front(unsigned short);182 void pop_front(unsigned short);
56 183
57 inline int cmp(const binarywrapper_t &other)184 /**
185 * Compares two wrappers. Assumes that smaller number of bytes also means
186 * a smaller wrapper. Otherwise compares byte by byte.
187 * @param other: wrapper to compare to
188 * @return -1 if other is smaller, 0 if same, 1 if other is larger
189 */
190 inline int cmp(const binarywrapper_t &other) const
58 {191 {
59 if(_nbytes != other._nbytes)192 if(_nbytes != other._nbytes)
60 {193 {
@@ -62,63 +195,33 @@
62 else return 1;195 else return 1;
63 }196 }
64 197
65 for(int i = _nbytes - 1; i >= 0; i--)198 return memcmp(_blob, other.const_raw(), other._nbytes );
66 {199 }
67 if(_blob[i] < other._blob[i])
68 return -1;
69 else if (_blob[i] > other._blob[i])
70 return 1;
71 }
72 200
73 return 0;201 /**
74 }202 * Compares wrappers bytes by bytes. If sizes do not match, they are not
75 203 * equal. If sizes match, compares byte by byte.
76 // Operators204 * @param enc1
205 * @param enc2
206 * @return true if a match, false otherwise
207 */
77 inline friend bool operator==( const binarywrapper_t &enc1, 208 inline friend bool operator==( const binarywrapper_t &enc1,
78 const binarywrapper_t &enc2) {209 const binarywrapper_t &enc2) {
79 if(enc1._nbytes != enc2._nbytes)210 return enc1.cmp(enc2) == 0;
80 return false;
81
82 for(size_t i = 0; i < enc1._nbytes; i++)
83 if(enc1._blob[i] != enc2._blob[i])
84 return false;
85
86 return true;
87 }
88
89 /* inline friend bool operator <=( const binarywrapper &enc1,
90 const binarywrapper &enc2)
91 {
92 if(enc1.numberOfBytes != enc2.numberOfBytes)
93 return enc1.numberOfBytes < enc2.numberOfBytes;
94
95 for(size_t i = 0; i < enc1.numberOfBytes; i++)
96 if(enc1.blob[i] < enc2.blob[i])
97 return true;
98 else if (enc1.blob[i] > enc2.blob[i])
99 return false;
100
101 return true;
102 }*/
103
104 inline friend bool operator<( const binarywrapper_t &enc1,
105 const binarywrapper_t &enc2) {
106 if(enc1._nbytes != enc2._nbytes)
107 return enc1._nbytes < enc2._nbytes;
108
109 for(size_t i = 0; i < enc1._nbytes; i++)
110 if(enc1._blob[i] < enc2._blob[i])
111 return true;
112 else if (enc1._blob[i] > enc2._blob[i])
113 return false;
114
115 return false;
116 }211 }
117 212
118 private:213 private:
214
215 // blob of heap-allocated data
119 uchar* _blob;216 uchar* _blob;
120 unsigned short _nbytes;217
218 // number of bytes allocated on heap
219 unsigned short _nbytes;
220
221 // meta data to carry
121 T _meta;222 T _meta;
223
224 // masks for single-bit access
122 const static uchar _masks[8];225 const static uchar _masks[8];
123 };226 };
124 227
@@ -273,7 +376,13 @@
273 }376 }
274 377
275 template<class T>378 template<class T>
276 uchar* binarywrapper_t<T>::raw() const379 uchar*& binarywrapper_t<T>::raw()
380 {
381 return _blob;
382 }
383
384 template<class T>
385 uchar* binarywrapper_t<T>::const_raw() const
277 {386 {
278 return _blob; 387 return _blob;
279 }388 }
@@ -292,6 +401,8 @@
292 {401 {
293 if(_nbytes == 0) return; // Special case, nothing to do!402 if(_nbytes == 0) return; // Special case, nothing to do!
294 unsigned short int nbytes;403 unsigned short int nbytes;
404
405 // make sure we do not remove to much, but as much as we can.
295 if(topop >= _nbytes)406 if(topop >= _nbytes)
296 {407 {
297 topop = _nbytes;408 topop = _nbytes;
@@ -340,9 +451,10 @@
340 }451 }
341 452
342 template<class T>453 template<class T>
343 void binarywrapper_t<T>::release() const454 void binarywrapper_t<T>::release()
344 {455 {
345 delete[] _blob;456 delete[] _blob;
457 _blob = NULL;
346 }458 }
347 459
348 template<class T>460 template<class T>
349461
=== modified file 'src/DiscreteVerification/DataStructures/ptrie.h'
--- src/DiscreteVerification/DataStructures/ptrie.h 2015-06-22 21:03:26 +0000
+++ src/DiscreteVerification/DataStructures/ptrie.h 2015-08-20 13:27:24 +0000
@@ -1,5 +1,5 @@
1/* 1/*
2 * File: PTrie.h2 * File: ptrie.h
3 * Author: Peter G. Jensen3 * Author: Peter G. Jensen
4 *4 *
5 * Created on 10 June 2015, 18:445 * Created on 10 June 2015, 18:44
@@ -9,10 +9,12 @@
9#define PTRIE_H9#define PTRIE_H
1010
11#include "binarywrapper.h"11#include "binarywrapper.h"
12#include "visitor.h"
12#include <assert.h>13#include <assert.h>
13#include <limits>14#include <limits>
14#include <vector>15#include <vector>
15#include <stdint.h>16#include <stdint.h>
17#include <stack>
1618
17namespace ptrie19namespace ptrie
18{20{
@@ -35,7 +37,15 @@
35 void set_meta(T);37 void set_meta(T);
36 uint write_partial_encoding(encoding_t&) const;38 uint write_partial_encoding(encoding_t&) const;
37 encoding_t& remainder() const;39 encoding_t& remainder() const;
40
38 ptriepointer_t() : container(NULL), index(0) {};41 ptriepointer_t() : container(NULL), index(0) {};
42
43 ptriepointer_t<T>& operator=(const ptriepointer_t<T>&);
44 ptriepointer_t<T>& operator++();
45 ptriepointer_t<T>& operator--();
46 bool operator==(const ptriepointer_t<T>& other);
47 bool operator!=(const ptriepointer_t<T>& other);
48
39 };49 };
40 50
41 template<typename T>51 template<typename T>
@@ -45,6 +55,55 @@
45 }55 }
46 56
47 template<typename T>57 template<typename T>
58
59 ptriepointer_t<T>& ptriepointer_t<T>::operator=
60 (const ptriepointer_t<T>& other)
61 {
62 container = other.container;
63 index = other.index;
64 return *this;
65 }
66
67 template<typename T>
68 ptriepointer_t<T>& ptriepointer_t<T>::operator++()
69 {
70 ++index;
71 assert(index <= container->_next_free_entry);
72 return *this;
73 }
74
75 template<typename T>
76 ptriepointer_t<T>& ptriepointer_t<T>::operator--()
77 {
78 --index;
79 return *this;
80 }
81
82 template<typename T>
83 bool ptriepointer_t<T>::operator==(const ptriepointer_t<T>& other)
84 {
85 return other.container == container && other.index == index;
86 }
87
88 template<typename T>
89 bool ptriepointer_t<T>::operator!=(const ptriepointer_t<T>& other)
90 {
91 return !(*this == other);
92 }
93
94 /*
95 template<typename T>
96 void swap(ptriepointer<T>& lhs, ptriepointer<T>& rhs)
97 {
98 ptrie<T>* container = lhs.container;
99 uint index = lhs.index;
100 lhs.container = rhs.container;
101 lhs.index = rhs.index;
102 rhs.index = index;
103 rhs.container = container;
104 }*/
105
106 template<typename T>
48 T ptriepointer_t<T>::get_meta() const107 T ptriepointer_t<T>::get_meta() const
49 {108 {
50 return container->get_entry(index)->_data.get_meta();109 return container->get_entry(index)->_data.get_meta();
@@ -72,7 +131,7 @@
72 class ptrie_t {131 class ptrie_t {
73 typedef binarywrapper_t<T> encoding_t; 132 typedef binarywrapper_t<T> encoding_t;
74 friend class ptriepointer_t<T>;133 friend class ptriepointer_t<T>;
75 public:134 private:
76 135
77 // nodes in the tree136 // nodes in the tree
78 struct node_t137 struct node_t
@@ -123,6 +182,12 @@
123 std::pair<bool, ptriepointer_t<T> > find(const encoding_t& encoding);182 std::pair<bool, ptriepointer_t<T> > find(const encoding_t& encoding);
124 bool consistent() const;183 bool consistent() const;
125 uint size() const { return _next_free_entry; }184 uint size() const { return _next_free_entry; }
185 ptriepointer_t<T> begin();
186 ptriepointer_t<T> end();
187 ptriepointer_t<T> last();
188 ptriepointer_t<T> rend();
189
190 void visit(visitor_t<T>&);
126 };191 };
127 192
128 template<typename T>193 template<typename T>
@@ -173,6 +238,30 @@
173 }238 }
174 239
175 template<typename T>240 template<typename T>
241 ptriepointer_t<T> ptrie_t<T>::begin()
242 {
243 return ptriepointer_t<T>(this, 0);
244 }
245
246 template<typename T>
247 ptriepointer_t<T> ptrie_t<T>::end()
248 {
249 return ptriepointer_t<T>(this, _next_free_entry);
250 }
251
252 template<typename T>
253 ptriepointer_t<T> ptrie_t<T>::last()
254 {
255 return ptriepointer_t<T>(this, _next_free_entry-1);
256 }
257
258 template<typename T>
259 ptriepointer_t<T> ptrie_t<T>::rend()
260 {
261 return ptriepointer_t<T>(this, std::numeric_limits<uint>::max());
262 }
263
264 template<typename T>
176 typename ptrie_t<T>::node_t*265 typename ptrie_t<T>::node_t*
177 ptrie_t<T>::get_node(uint index) const266 ptrie_t<T>::get_node(uint index) const
178 {267 {
@@ -218,6 +307,8 @@
218 bool ptrie_t<T>::consistent() const307 bool ptrie_t<T>::consistent() const
219 {308 {
220 return true;309 return true;
310 assert(_next_free_node >= _nodevector.size());
311 assert(_next_free_entry >= _entryvector.size());
221 for(size_t i = 0; i < _next_free_node; ++i)312 for(size_t i = 0; i < _next_free_node; ++i)
222 {313 {
223 node_t* node = get_node(i);314 node_t* node = get_node(i);
@@ -269,6 +360,61 @@
269 }360 }
270 361
271 template<typename T>362 template<typename T>
363 void ptrie_t<T>::visit(visitor_t<T>& visitor)
364 {
365 std::stack<std::pair<uint, uint> > waiting;
366 waiting.push(std::pair<int, uint>(-1, 0));
367
368 bool stop = false;
369 do{
370 int distance = waiting.top().first;
371 uint n_index = waiting.top().second;
372 waiting.pop();
373
374 if(distance > -1)
375 {
376 visitor.back(distance);
377 visitor.set(distance, true); // only high on stack
378 }
379
380 node_t* node = get_node(n_index);
381 bool skip = false;
382 do
383 {
384
385 if(node->_highpos != 0)
386 {
387 waiting.push(std::pair<uint, uint>(distance + 1, node->_highpos));
388 }
389
390 if(node->_lowpos == 0) break;
391 else
392 {
393 ++distance;
394 node = get_node(node->_lowpos);
395 skip = visitor.set(distance, false);
396 }
397
398 } while(!skip);
399
400 distance += 1;
401
402 uint bucketsize = 0;
403 if(!skip)
404 {
405 if(node->_highcount > 0) bucketsize += node->_highcount;
406 if(node->_lowcount > 0) bucketsize += node->_lowcount;
407
408 for(uint i = 0; i < bucketsize && !stop; ++i)
409 {
410 stop = visitor.set_remainder(distance,
411 ptriepointer_t<T>(this, node->_entries[i]));
412 }
413 }
414 } while(!waiting.empty() && !stop);
415 }
416
417 template<typename T>
272 bool ptrie_t<T>::best_match(const encoding_t& encoding, uint& tree_pos, 418 bool ptrie_t<T>::best_match(const encoding_t& encoding, uint& tree_pos,
273 uint& e_index, uint& enc_pos, uint& b_index, uint& bucketsize)419 uint& e_index, uint& enc_pos, uint& b_index, uint& bucketsize)
274 {420 {
@@ -316,7 +462,7 @@
316 // start by creating an encoding that "points" to the "unmatched"462 // start by creating an encoding that "points" to the "unmatched"
317 // part of the encoding. Notice, this is a shallow copy, no actual463 // part of the encoding. Notice, this is a shallow copy, no actual
318 // heap-allocation happens!464 // heap-allocation happens!
319 encoding_t s_enc = encoding_t( encoding.raw(), 465 encoding_t s_enc = encoding_t( encoding.const_raw(),
320 (encsize - enc_pos), 466 (encsize - enc_pos),
321 enc_pos, 467 enc_pos,
322 encsize);468 encsize);
@@ -341,18 +487,18 @@
341 e_index = node->_entries[b_index];487 e_index = node->_entries[b_index];
342 break;488 break;
343 }489 }
344 else if(cmp == 1)490 else if(cmp > 0)
345 {491 {
346 low = b_index + 1;492 low = b_index + 1;
347 }493 }
348 else //if cmp == -1494 else //if cmp < 0
349 {495 {
350 high = b_index - 1;496 high = b_index - 1;
351 }497 }
352 498
353 if(low > high)499 if(low > high)
354 {500 {
355 if(cmp == 1)501 if(cmp > 0)
356 b_index += 1;502 b_index += 1;
357 break;503 break;
358 }504 }
@@ -367,13 +513,13 @@
367 /*int tmp;// refference debug code!513 /*int tmp;// refference debug code!
368 for(tmp = 0; tmp < bucketsize; ++tmp)514 for(tmp = 0; tmp < bucketsize; ++tmp)
369 {515 {
370 entry_t* ent = getEntry(node->entries[tmp]);516 entry_t* ent = get_entry(node->_entries[tmp]);
371 if(ent->data < s_enc)517 if(ent->_data.cmp(s_enc) < 0)
372 {518 {
373 continue;519 continue;
374 }520 }
375 else521 else
376 if(ent->data == s_enc)522 if(ent->_data == s_enc)
377 {523 {
378 assert(found);524 assert(found);
379 break;525 break;
@@ -491,8 +637,8 @@
491 uint enc_pos;637 uint enc_pos;
492 uint bucketsize;638 uint bucketsize;
493 uint e_index;639 uint e_index;
494 640 uint b_index;
495 if(best_match(encoding, tree_pos, e_index, enc_pos, bucketsize))641 if(best_match(encoding, tree_pos, e_index, enc_pos, b_index, bucketsize))
496 {642 {
497 return std::pair<bool, ptriepointer_t<T> >(true, 643 return std::pair<bool, ptriepointer_t<T> >(true,
498 ptriepointer_t<T>(this, e_index));644 ptriepointer_t<T>(this, e_index));
@@ -534,7 +680,7 @@
534 remainder_size, 680 remainder_size,
535 enc_pos, 681 enc_pos,
536 encsize);682 encsize);
537 assert(n_entry->_data.raw() != encoding.raw());683 //assert(n_entry->_data.const_raw() != encoding.const_raw());
538 684
539 n_entry->_nodeindex = tree_pos;685 n_entry->_nodeindex = tree_pos;
540 686
541687
=== added file 'src/DiscreteVerification/DataStructures/visitor.h'
--- src/DiscreteVerification/DataStructures/visitor.h 1970-01-01 00:00:00 +0000
+++ src/DiscreteVerification/DataStructures/visitor.h 2015-08-20 13:27:24 +0000
@@ -0,0 +1,30 @@
1/*
2 * File: visitor.h
3 * Author: Peter G. Jensen
4 *
5 * Created on 16 June 2015, 23:15
6 */
7
8#ifndef VISITOR_H
9#define VISITOR_H
10
11#include <stdint.h>
12
13namespace ptrie
14{
15 template<typename T>
16 class ptriepointer_t;
17
18 template<typename T>
19 class visitor_t
20 {
21 public:
22 virtual bool back(int index) = 0;
23 virtual bool set(int index, bool value) = 0;
24 virtual bool set_remainder(int index, ptriepointer_t<T> pointer) = 0;
25 };
26}
27
28
29#endif /* VISITOR_H */
30
031
=== modified file 'src/DiscreteVerification/DiscreteVerification.cpp'
--- src/DiscreteVerification/DiscreteVerification.cpp 2015-06-17 09:03:12 +0000
+++ src/DiscreteVerification/DiscreteVerification.cpp 2015-08-20 13:27:24 +0000
@@ -53,42 +53,63 @@
53 exit(1);53 exit(1);
54 }54 }
5555
56 if (options.getMemoryOptimization() != VerificationOptions::NO_MEMORY_OPTIMIZATION) {
57 cout << "Workflow analysis currently does not support any memory optimizations (i.e. no PTries)." << endl;
58 exit(1);
59 }
60 WaitingList<NonStrictMarking*>* strategy = getWaitingList<NonStrictMarking* > (query, options);
61 if(options.getWorkflowMode() == VerificationOptions::WORKFLOW_SOUNDNESS){56 if(options.getWorkflowMode() == VerificationOptions::WORKFLOW_SOUNDNESS){
62 WorkflowSoundness* verifier = new WorkflowSoundness(tapn, *initialMarking, query, options, strategy);57 WorkflowSoundness* verifier;
58 if(options.getMemoryOptimization() == VerificationOptions::NO_MEMORY_OPTIMIZATION)
59 {
60 verifier = new WorkflowSoundness(tapn, *initialMarking, query, options,
61 getWaitingList<NonStrictMarking* > (query, options));
62 }
63 else
64 {
65 verifier = new WorkflowSoundnessPTrie(tapn, *initialMarking, query, options,
66 getWaitingList<ptriepointer_t<MetaData*> > (query, options));
67 }
6368
64 if(verifier->getModelType() == verifier->NOTTAWFN){69 if(verifier->getModelType() == verifier->NOTTAWFN){
65 std::cerr << "Model is not a TAWFN!" << std::endl;70 std::cerr << "Model is not a TAWFN!" << std::endl;
66 return -1;71 return -1;
67 }else if(verifier->getModelType() == verifier->ETAWFN){72 }else if(verifier->getModelType() == verifier->ETAWFN){
68 std::cout << "Model is a ETAWFN" << std::endl << std::endl;73 std::cout << "Model is a ETAWFN" << std::endl << std::endl;
69 }else if(verifier->getModelType() == verifier->MTAWFN){74 }else if(verifier->getModelType() == verifier->MTAWFN){
70 std::cout << "Model is a MTAWFN" << std::endl << std::endl;75 std::cout << "Model is a MTAWFN" << std::endl << std::endl;
71 }76 }
72 VerifyAndPrint(77 VerifyAndPrint(
73 tapn,78 tapn,
74 *verifier,79 *verifier,
75 options,80 options,
76 query);81 query);
77 verifier->printExecutionTime(cout);82 verifier->printExecutionTime(cout);
78 verifier->printMessages(cout);83 verifier->printMessages(cout);
84#ifdef CLEANUP
85 delete verifier;
86#endif
79 }87 }
80 else{88 else{
81 // Assumes correct structure of net!89 // Assumes correct structure of net!
82 WorkflowStrongSoundnessReachability* verifier = new WorkflowStrongSoundnessReachability(tapn, *initialMarking, query, options, strategy);90 WorkflowStrongSoundnessReachability* verifier;
91 if(options.getMemoryOptimization() == VerificationOptions::NO_MEMORY_OPTIMIZATION)
92 {
93 verifier = new WorkflowStrongSoundnessReachability(tapn, *initialMarking, query, options,
94 getWaitingList<NonStrictMarking* > (query, options));
95 }
96 else
97 {
98 verifier = new WorkflowStrongSoundnessPTrie(tapn, *initialMarking, query, options,
99 getWaitingList<ptriepointer_t<MetaData*> > (query, options));
100 }
83 VerifyAndPrint(101 VerifyAndPrint(
84 tapn,102 tapn,
85 *verifier,103 *verifier,
86 options,104 options,
87 query);105 query);
88 verifier->printExecutionTime(cout);106 verifier->printExecutionTime(cout);
107#ifdef CLEANUP
108 delete verifier;
109#endif
89 }110 }
90111
91 delete strategy;112
92 return 0;113 return 0;
93 }114 }
94 115
95116
=== modified file 'src/DiscreteVerification/VerificationTypes/WorkflowSoundness.cpp'
--- src/DiscreteVerification/VerificationTypes/WorkflowSoundness.cpp 2015-06-22 22:10:16 +0000
+++ src/DiscreteVerification/VerificationTypes/WorkflowSoundness.cpp 2015-08-20 13:27:24 +0000
@@ -6,6 +6,7 @@
6 */6 */
77
8#include "WorkflowSoundness.hpp"8#include "WorkflowSoundness.hpp"
9#include <limits>
910
10namespace VerifyTAPN {11namespace VerifyTAPN {
11namespace DiscreteVerification {12namespace DiscreteVerification {
@@ -13,6 +14,7 @@
13WorkflowSoundness::WorkflowSoundness(TAPN::TimedArcPetriNet& tapn, NonStrictMarking& initialMarking, AST::Query* query, VerificationOptions options, WaitingList<NonStrictMarking*>* waiting_list)14WorkflowSoundness::WorkflowSoundness(TAPN::TimedArcPetriNet& tapn, NonStrictMarking& initialMarking, AST::Query* query, VerificationOptions options, WaitingList<NonStrictMarking*>* waiting_list)
14: Workflow(tapn, initialMarking, query, options), passedStack(), minExec(INT_MAX), linearSweepTreshold(3), coveredMarking(NULL), modelType(calculateModelType()){15: Workflow(tapn, initialMarking, query, options), passedStack(), minExec(INT_MAX), linearSweepTreshold(3), coveredMarking(NULL), modelType(calculateModelType()){
15 pwList = new WorkflowPWList(waiting_list);16 pwList = new WorkflowPWList(waiting_list);
17
16}18}
1719
1820
@@ -21,6 +23,17 @@
21 23
22};24};
2325
26WorkflowSoundnessPTrie::WorkflowSoundnessPTrie(TAPN::TimedArcPetriNet& tapn, NonStrictMarking& initialMarking, AST::Query* query, VerificationOptions options, WaitingList<ptriepointer_t<MetaData*> >* waiting_list)
27: WorkflowSoundness(tapn, initialMarking, query, options) {
28 int kbound = modelType == MTAWFN ? (std::numeric_limits<int>::max() - 1) : options.getKBound();
29 pwList = new WorkflowPWListHybrid( tapn,
30 waiting_list,
31 kbound,
32 tapn.getNumberOfPlaces(),
33 tapn.getMaxConstant());
34
35}
36
2437
25bool WorkflowSoundness::verify(){38bool WorkflowSoundness::verify(){
26 if(addToPW(&initialMarking, NULL)){39 if(addToPW(&initialMarking, NULL)){
@@ -50,6 +63,7 @@
50 return false;63 return false;
51 }64 }
52 }65 }
66 deleteMarking(next_marking);
53 }67 }
5468
55 // Phase 269 // Phase 2
@@ -82,6 +96,25 @@
82 return passed;96 return passed;
83}97}
8498
99int WorkflowSoundnessPTrie::numberOfPassed()
100{
101 int passed = 0;
102 while(passedStack.size()){
103 WorkflowSoundnessMetaDataWithEncoding* next =
104 static_cast<WorkflowSoundnessMetaDataWithEncoding*>(passedStack.top());
105
106 passedStack.pop();
107 if(next->passed) continue;
108 next->passed = true;
109 ++passed;
110 for(vector<MetaData*>::iterator iter = next->parents.begin();
111 iter != next->parents.end(); iter++){
112 passedStack.push(*iter);
113 }
114 }
115 return passed;
116}
117
85118
86bool WorkflowSoundness::addToPW(NonStrictMarking* marking, NonStrictMarking* parent){119bool WorkflowSoundness::addToPW(NonStrictMarking* marking, NonStrictMarking* parent){
87 marking->cut(placeStats);120 marking->cut(placeStats);
@@ -91,7 +124,9 @@
91 // Check K-bound124 // Check K-bound
92 pwList->setMaxNumTokensIfGreater(size);125 pwList->setMaxNumTokensIfGreater(size);
93 if(modelType == ETAWFN && size > options.getKBound()) {126 if(modelType == ETAWFN && size > options.getKBound()) {
94 lastMarking = marking;127 if(lastMarking != NULL) deleteMarking(lastMarking);
128 lastMarking = marking;
129 setMetaParent(lastMarking);
95 return true; // Terminate false130 return true; // Terminate false
96 }131 }
97132
@@ -101,8 +136,6 @@
101 NonStrictMarking* old = pwList->addToPassed(marking, false);136 NonStrictMarking* old = pwList->addToPassed(marking, false);
102 if(old == NULL){137 if(old == NULL){
103 isNew = true;138 isNew = true;
104 marking->meta = new WorkflowSoundnessMetaData();
105 marking->setParent(parent);
106 } else {139 } else {
107 delete marking;140 delete marking;
108 marking = old;141 marking = old;
@@ -130,11 +163,14 @@
130 marking->meta->totalDelay = min(marking->meta->totalDelay, parent->meta->totalDelay); // Transition163 marking->meta->totalDelay = min(marking->meta->totalDelay, parent->meta->totalDelay); // Transition
131 // keep track of shortest trace164 // keep track of shortest trace
132 if (marking->meta->totalDelay < minExec) {165 if (marking->meta->totalDelay < minExec) {
166 if(lastMarking != NULL) deleteMarking(lastMarking);
167
133 minExec = marking->meta->totalDelay;168 minExec = marking->meta->totalDelay;
134 lastMarking = marking;169 lastMarking = marking;
135 return false;170 return false;
136 }171 }
137 }else{172 }else{
173 if(lastMarking != NULL) deleteMarking(lastMarking);
138 lastMarking = marking;174 lastMarking = marking;
139 return true; // Terminate false175 return true; // Terminate false
140 }176 }
@@ -143,15 +179,18 @@
143 if(isNew){179 if(isNew){
144 pwList->addLastToWaiting();180 pwList->addLastToWaiting();
145 if(parent != NULL && marking->canDeadlock(tapn, 0)){181 if(parent != NULL && marking->canDeadlock(tapn, 0)){
182 if(lastMarking != NULL) deleteMarking(lastMarking);
146 lastMarking = marking;183 lastMarking = marking;
147 return true;184 return true;
148 }185 }
149 if(modelType == MTAWFN && checkForCoveredMarking(marking)){186 if(modelType == MTAWFN && checkForCoveredMarking(marking)){
150 lastMarking = marking;187 if(lastMarking != NULL) deleteMarking(lastMarking);
188 lastMarking = marking;
151 return true; // Terminate false189 return true; // Terminate false
152 }190 }
153 }191 }
154 }192 }
193 deleteMarking(marking);
155 return false;194 return false;
156}195}
157196
@@ -162,6 +201,14 @@
162201
163}202}
164203
204void WorkflowSoundnessPTrie::addParentMeta(MetaData* meta, MetaData* parent)
205{
206 assert(meta != NULL);
207 assert(parent != NULL);
208 WorkflowSoundnessMetaDataWithEncoding* markingmeta = ((WorkflowSoundnessMetaDataWithEncoding*)meta);
209 markingmeta->parents.push_back(parent);
210
211}
165212
166bool WorkflowSoundness::checkForCoveredMarking(NonStrictMarking* marking){213bool WorkflowSoundness::checkForCoveredMarking(NonStrictMarking* marking){
167 if(marking->size() <= options.getKBound()){214 if(marking->size() <= options.getKBound()){
@@ -193,6 +240,64 @@
193}240}
194241
195242
243void WorkflowSoundnessPTrie::getTrace(NonStrictMarking* marking){
244
245 PWListHybrid* pwhlist = dynamic_cast<PWListHybrid*>(this->pwList);
246
247 stack < NonStrictMarking*> printStack;
248
249 if(marking != NULL){
250 printStack.push(marking);
251
252 MetaDataWithTraceAndEncoding* meta =
253 static_cast<MetaDataWithTraceAndEncoding*>(marking->meta);
254 if(meta)
255 {
256 marking->setGeneratedBy(meta->generatedBy);
257
258 meta = meta->parent;
259 while(meta != NULL)
260 {
261 NonStrictMarking* next = pwhlist->decode(meta->ep);
262 printStack.push(next);
263 next->setGeneratedBy(meta->generatedBy);
264 printStack.top()->setParent(next);
265 meta = meta->parent;
266 }
267 }
268 printStack.top()->setGeneratedBy(NULL);
269 }
270
271#ifdef CLEANUP
272 stack < NonStrictMarking*> clearStack = printStack;
273#endif
274 printXMLTrace(marking, printStack, query, tapn);
275#ifdef CLEANUP
276 while(!clearStack.empty())
277 {
278 if(clearStack.top() == lastMarking) break; // deleted elsewhere
279 delete clearStack.top();
280 clearStack.pop();
281 }
282#endif
283}
284
285
286void WorkflowSoundnessPTrie::setMetaParent(NonStrictMarking* marking){
287 PWListHybrid* pwhlist = dynamic_cast<PWListHybrid*>(this->pwList);
288
289 if(marking->meta == NULL)
290 {
291 marking->meta = new MetaDataWithTraceAndEncoding();
292 }
293
294 MetaDataWithTraceAndEncoding* mte =
295 static_cast<MetaDataWithTraceAndEncoding*>(marking->meta);
296 mte->parent = pwhlist->parent;
297 mte->generatedBy = marking->getGeneratedBy();
298}
299
300
196301
197WorkflowSoundness::ModelType WorkflowSoundness::calculateModelType() {302WorkflowSoundness::ModelType WorkflowSoundness::calculateModelType() {
198 bool isin, isout;303 bool isin, isout;
199304
=== modified file 'src/DiscreteVerification/VerificationTypes/WorkflowSoundness.hpp'
--- src/DiscreteVerification/VerificationTypes/WorkflowSoundness.hpp 2015-06-22 22:10:16 +0000
+++ src/DiscreteVerification/VerificationTypes/WorkflowSoundness.hpp 2015-08-20 13:27:24 +0000
@@ -26,6 +26,7 @@
26#include "../DataStructures/WaitingList.hpp"26#include "../DataStructures/WaitingList.hpp"
27#include "Workflow.hpp"27#include "Workflow.hpp"
2828
29using namespace ptrie;
29namespace VerifyTAPN {30namespace VerifyTAPN {
30namespace DiscreteVerification {31namespace DiscreteVerification {
3132
@@ -71,6 +72,23 @@
7172
72};73};
7374
75
76class WorkflowSoundnessPTrie : public WorkflowSoundness
77{
78public:
79 WorkflowSoundnessPTrie(TAPN::TimedArcPetriNet& tapn, NonStrictMarking& initialMarking, AST::Query* query, VerificationOptions options, WaitingList<ptriepointer_t<MetaData*> >* waiting_list);
80
81 virtual void addParentMeta(MetaData* meta, MetaData* parent);
82 virtual int numberOfPassed();
83 virtual void deleteMarking(NonStrictMarking* marking)
84 {
85 delete marking;
86 }
87 virtual void getTrace(NonStrictMarking* marking);
88protected:
89 virtual void setMetaParent(NonStrictMarking*);
90};
91
74} /* namespace DiscreteVerification */92} /* namespace DiscreteVerification */
75} /* namespace VerifyTAPN */93} /* namespace VerifyTAPN */
76#endif /* NONSTRICTSEARCH_HPP_ */94#endif /* NONSTRICTSEARCH_HPP_ */
7795
=== modified file 'src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.cpp'
--- src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.cpp 2015-06-22 22:10:16 +0000
+++ src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.cpp 2015-08-20 13:27:24 +0000
@@ -16,6 +16,10 @@
16 findInOut();16 findInOut();
17 };17 };
18 18
19 WorkflowStrongSoundnessReachability::WorkflowStrongSoundnessReachability(TAPN::TimedArcPetriNet& tapn, NonStrictMarking& initialMarking, AST::Query* query, VerificationOptions options)
20 : Workflow(tapn, initialMarking, query, options), maxValue(-1), outPlace(NULL){
21 findInOut();
22 };
19 23
20 void WorkflowStrongSoundnessReachability::findInOut()24 void WorkflowStrongSoundnessReachability::findInOut()
21 {25 {
@@ -25,8 +29,27 @@
25 break;29 break;
26 }30 }
27 }31 }
28 };32 }
2933
34 WorkflowStrongSoundnessPTrie::WorkflowStrongSoundnessPTrie(
35 TAPN::TimedArcPetriNet& tapn,
36 NonStrictMarking& initialMarking,
37 AST::Query* query,
38 VerificationOptions options,
39 WaitingList<ptriepointer_t<MetaData*> >* waiting_list) :
40 WorkflowStrongSoundnessReachability(
41 tapn,
42 initialMarking,
43 query,
44 options)
45 {
46 pwList = new WorkflowPWListHybrid( tapn,
47 waiting_list,
48 options.getKBound(),
49 tapn.getNumberOfPlaces(),
50 tapn.getMaxConstant());
51 }
52
30 bool WorkflowStrongSoundnessReachability::verify() {53 bool WorkflowStrongSoundnessReachability::verify() {
31 54
32 if (outPlace == NULL)55 if (outPlace == NULL)
@@ -53,6 +76,7 @@
53 bool noDelay = false;76 bool noDelay = false;
54 Result res = successorGenerator.generateAndInsertSuccessors(*next_marking);77 Result res = successorGenerator.generateAndInsertSuccessors(*next_marking);
55 if (res == ADDTOPW_RETURNED_TRUE) {78 if (res == ADDTOPW_RETURNED_TRUE) {
79 clearTrace();
56 return true;80 return true;
57 } else if (res == ADDTOPW_RETURNED_FALSE_URGENTENABLED) {81 } else if (res == ADDTOPW_RETURNED_FALSE_URGENTENABLED) {
58 noDelay = true;82 noDelay = true;
@@ -65,7 +89,7 @@
65 marking->setGeneratedBy(NULL);89 marking->setGeneratedBy(NULL);
66 90
67 if (addToPW(marking, next_marking)) {91 if (addToPW(marking, next_marking)) {
6892 clearTrace();
69 lastMarking = marking;93 lastMarking = marking;
70 return true;94 return true;
71 }95 }
@@ -77,6 +101,7 @@
77 // remove childless markings from stack101 // remove childless markings from stack
78 while(!trace.empty() && trace.top()->getNumberOfChildren() <= 1){102 while(!trace.empty() && trace.top()->getNumberOfChildren() <= 1){
79 trace.top()->meta->inTrace = false;103 trace.top()->meta->inTrace = false;
104 deleteMarking(trace.top());
80 trace.pop();105 trace.pop();
81 }106 }
82 if(trace.empty()){107 if(trace.empty()){
@@ -108,6 +133,64 @@
108 printXMLTrace(lastMarking, printStack, query, tapn);133 printXMLTrace(lastMarking, printStack, query, tapn);
109 }134 }
110135
136 void WorkflowStrongSoundnessPTrie::getTrace() {
137
138 PWListHybrid* pwhlist = dynamic_cast<PWListHybrid*>(this->pwList);
139
140 std::stack < NonStrictMarking*> printStack;
141
142 NonStrictMarking* next = lastMarking;
143 if(next != NULL)
144 {
145
146 printStack.push(next);
147 MetaDataWithTraceAndEncoding* meta =
148 static_cast<MetaDataWithTraceAndEncoding*>(next->meta);
149
150 if(meta == NULL)
151 {
152 // We assume the parent was not deleted on return
153 NonStrictMarking* parent = (NonStrictMarking*)lastMarking->getParent();
154 if(parent != NULL) meta =
155 static_cast<MetaDataWithTraceAndEncoding*>(parent->meta);
156 delete parent;
157 }
158 else
159 {
160 meta = meta->parent;
161 }
162
163 while(meta != NULL)
164 {
165 next = pwhlist->decode(meta->ep);
166 next->setGeneratedBy(meta->generatedBy);
167 printStack.top()->setParent(next);
168 printStack.push(next);
169 meta = meta->parent;
170 }
171 }
172#ifdef CLEANUP
173 std::stack < NonStrictMarking*> cleanup = printStack;
174#endif
175 printXMLTrace(lastMarking, printStack, query, tapn);
176
177#ifdef CLEANUP
178 while(!cleanup.empty())
179 {
180 if(cleanup.top() != lastMarking) // deleted elsewhere
181 {
182 delete cleanup.top();
183 cleanup.pop();
184 }
185 else
186 {
187 break;
188 }
189 }
190#endif
191 }
192
193
111 bool WorkflowStrongSoundnessReachability::addToPW(NonStrictMarking* marking, NonStrictMarking* parent) {194 bool WorkflowStrongSoundnessReachability::addToPW(NonStrictMarking* marking, NonStrictMarking* parent) {
112 marking->cut(placeStats);195 marking->cut(placeStats);
113 marking->setParent(parent);196 marking->setParent(parent);
@@ -135,6 +218,7 @@
135 // make sure we can print trace218 // make sure we can print trace
136 marking->setNumberOfChildren(1);219 marking->setNumberOfChildren(1);
137 maxValue = totalDelay;220 maxValue = totalDelay;
221 deleteMarking(old);
138 return true;222 return true;
139 } else {223 } else {
140 // search again to find maxdelay224 // search again to find maxdelay
@@ -145,12 +229,12 @@
145 // fall through on purpose229 // fall through on purpose
146 }230 }
147 } else {231 } else {
232 deleteMarking(old);
148 delete marking;233 delete marking;
149 // already seen this maxage/marking combination234 // already seen this maxage/marking combination
150 return false;235 return false;
151 }236 }
152 } else {237 } else {
153 marking->meta = new MetaData();
154 marking->meta->totalDelay = totalDelay;238 marking->meta->totalDelay = totalDelay;
155 }239 }
156 240
@@ -166,10 +250,14 @@
166 // if terminal, update max_value and last marking of trace250 // if terminal, update max_value and last marking of trace
167 if(maxValue < marking->meta->totalDelay) {251 if(maxValue < marking->meta->totalDelay) {
168 maxValue = marking->meta->totalDelay;252 maxValue = marking->meta->totalDelay;
253 if(lastMarking != NULL) deleteMarking(lastMarking);
169 lastMarking = marking;254 lastMarking = marking;
170 return false;255 return false;
171 }256 }
172 }257 }
258
259 deleteMarking(marking);
260
173 return false;261 return false;
174 }262 }
175 263
@@ -179,5 +267,25 @@
179 old->setParent(marking->getParent());267 old->setParent(marking->getParent());
180 }268 }
181269
270 void WorkflowStrongSoundnessPTrie::swapData(NonStrictMarking* marking, NonStrictMarking* parent)
271 {
272 PWListHybrid* pwhlist = dynamic_cast<PWListHybrid*>(this->pwList);
273 MetaDataWithTraceAndEncoding* meta =
274 static_cast<MetaDataWithTraceAndEncoding*>(parent->meta);
275
276 meta->generatedBy = marking->getGeneratedBy();
277 meta->parent = pwhlist->parent;
278 }
279
280 void WorkflowStrongSoundnessPTrie::clearTrace()
281 {
282 if(!trace.empty()) trace.pop(); // pop parent, used in getTrace
283 while(!trace.empty())
284 {
285 delete trace.top();
286 trace.pop();
287 }
288 }
289
182 } /* namespace DiscreteVerification */290 } /* namespace DiscreteVerification */
183} /* namespace VerifyTAPN */291} /* namespace VerifyTAPN */
184292
=== modified file 'src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.hpp'
--- src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.hpp 2015-06-22 22:10:16 +0000
+++ src/DiscreteVerification/VerificationTypes/WorkflowStrongSoundness.hpp 2015-08-20 13:27:24 +0000
@@ -53,6 +53,26 @@
53 int validChildren;53 int validChildren;
54};54};
5555
56class WorkflowStrongSoundnessPTrie : public WorkflowStrongSoundnessReachability
57{
58public:
59 WorkflowStrongSoundnessPTrie(
60 TAPN::TimedArcPetriNet& tapn,
61 NonStrictMarking& initialMarking,
62 AST::Query* query,
63 VerificationOptions options,
64 WaitingList<ptriepointer_t<MetaData*> >* waiting_list);
65 virtual void getTrace();
66 virtual void deleteMarking(NonStrictMarking* marking)
67 {
68 delete marking;
69 }
70
71protected:
72 virtual void swapData(NonStrictMarking* marking, NonStrictMarking* old);
73 virtual void clearTrace();
74};
75
56} /* namespace DiscreteVerification */76} /* namespace DiscreteVerification */
57} /* namespace VerifyTAPN */77} /* namespace VerifyTAPN */
58#endif /* NONSTRICTSEARCH_HPP_ */78#endif /* NONSTRICTSEARCH_HPP_ */

Subscribers

People subscribed via source and target branches

to all changes: