Merge lp:~tapaal-ltl/verifypn/mcc2021 into lp:verifypn
- mcc2021
- Merge into new-trunk
Proposed by
Jiri Srba
Status: | Merged |
---|---|
Approved by: | Jiri Srba |
Approved revision: | 258 |
Merged at revision: | 231 |
Proposed branch: | lp:~tapaal-ltl/verifypn/mcc2021 |
Merge into: | lp:verifypn |
Diff against target: |
17037 lines (+10331/-2420) 115 files modified
CMakeLists.txt (+23/-9) include/CTL/Algorithm/CertainZeroFPA.h (+1/-2) include/CTL/DependencyGraph/Configuration.h (+12/-15) include/CTL/DependencyGraph/Edge.h (+11/-5) include/CTL/PetriNets/PetriConfig.h (+0/-2) include/LTL/Algorithm/ModelChecker.h (+72/-0) include/LTL/Algorithm/NestedDepthFirstSearch.h (+91/-0) include/LTL/Algorithm/ProductPrinter.h (+31/-0) include/LTL/Algorithm/RandomNDFS.h (+59/-0) include/LTL/Algorithm/TarjanModelChecker.h (+140/-0) include/LTL/AlgorithmTypes.h (+40/-0) include/LTL/BuchiSuccessorGenerator.h (+95/-0) include/LTL/LTL.h (+34/-0) include/LTL/LTLToBuchi.h (+131/-0) include/LTL/LTLValidator.h (+201/-0) include/LTL/ProductSuccessorGenerator.h (+146/-0) include/LTL/Simplification/SpotToPQL.h (+42/-0) include/LTL/Structures/BuchiAutomaton.h (+31/-0) include/LTL/Structures/ProductState.h (+81/-0) include/LTL/Structures/ProductStateFactory.h (+46/-0) include/PetriEngine/Colored/ArcIntervals.h (+108/-0) include/PetriEngine/Colored/BindingGenerator.h (+71/-0) include/PetriEngine/Colored/ColoredNetStructures.h (+22/-12) include/PetriEngine/Colored/ColoredPetriNetBuilder.h (+64/-43) include/PetriEngine/Colored/Colors.h (+127/-21) include/PetriEngine/Colored/Expressions.h (+777/-66) include/PetriEngine/Colored/GuardRestrictor.h (+83/-0) include/PetriEngine/Colored/IntervalGenerator.h (+197/-0) include/PetriEngine/Colored/Intervals.h (+630/-0) include/PetriEngine/PQL/CTLVisitor.h (+197/-0) include/PetriEngine/PQL/Contexts.h (+6/-6) include/PetriEngine/PQL/Expressions.h (+304/-187) include/PetriEngine/PQL/PQL.h (+70/-71) include/PetriEngine/PQL/QueryPrinter.h (+127/-0) include/PetriEngine/PQL/Visitor.h (+82/-6) include/PetriEngine/PetriNet.h (+1/-0) include/PetriEngine/Reachability/ReachabilityResult.h (+4/-2) include/PetriEngine/Reachability/ReachabilitySearch.h (+12/-2) include/PetriEngine/Reducer.h (+8/-3) include/PetriEngine/ReducingSuccessorGenerator.h (+25/-54) include/PetriEngine/Simplification/Member.h (+1/-1) include/PetriEngine/Structures/Queue.h (+2/-0) include/PetriEngine/Structures/State.h (+40/-7) include/PetriEngine/Structures/StateSet.h (+85/-14) include/PetriEngine/Structures/binarywrapper.h (+2/-2) include/PetriEngine/Structures/light_deque.h (+4/-5) include/PetriEngine/Stubborn/InterestingTransitionVisitor.h (+175/-0) include/PetriEngine/Stubborn/ReachabilityStubbornSet.h (+40/-0) include/PetriEngine/Stubborn/StubbornSet.h (+146/-0) include/PetriEngine/SuccessorGenerator.h (+10/-1) include/PetriEngine/TAR/ContainsVisitor.h (+0/-10) include/PetriEngine/TAR/PlaceUseVisitor.h (+0/-2) include/PetriEngine/TAR/RangeContext.h (+0/-2) include/PetriEngine/TAR/RangeEvalContext.h (+0/-2) include/PetriEngine/TAR/Solver.h (+1/-0) include/PetriEngine/TAR/range.h (+19/-1) include/PetriEngine/options.h (+82/-44) include/PetriParse/PNMLParser.h (+6/-1) include/PetriParse/QueryParser.h (+2/-3) include/PetriParse/QueryXMLParser.h (+1/-1) src/CMakeLists.txt (+13/-4) src/CTL/Algorithm/CertainZeroFPA.cpp (+81/-51) src/CTL/Algorithm/LocalFPA.cpp (+1/-11) src/CTL/DependencyGraph/Configuration.cpp (+21/-2) src/CTL/PetriNets/OnTheFlyDG.cpp (+20/-19) src/CTL/SearchStrategy/HeuristicSearch.cpp (+1/-1) src/LTL/Algorithm/CMakeLists.txt (+8/-0) src/LTL/Algorithm/LTLToBuchi.cpp (+162/-0) src/LTL/Algorithm/ModelChecker.cpp (+71/-0) src/LTL/Algorithm/NestedDepthFirstSearch.cpp (+185/-0) src/LTL/Algorithm/ProductPrinter.cpp (+71/-0) src/LTL/Algorithm/ProductSuccessorGenerator.cpp (+153/-0) src/LTL/Algorithm/RandomNDFS.cpp (+107/-0) src/LTL/Algorithm/TarjanModelChecker.cpp (+216/-0) src/LTL/CMakeLists.txt (+14/-0) src/LTL/Simplification/CMakeLists.txt (+8/-0) src/LTL/Simplification/SpotToPQL.cpp (+160/-0) src/LTL/_LTL.cpp (+52/-0) src/PetriEngine/CMakeLists.txt (+2/-1) src/PetriEngine/Colored/BindingGenerator.cpp (+161/-0) src/PetriEngine/Colored/CMakeLists.txt (+3/-1) src/PetriEngine/Colored/ColoredPetriNetBuilder.cpp (+305/-138) src/PetriEngine/Colored/Colors.cpp (+59/-9) src/PetriEngine/Colored/GuardRestrictor.cpp (+382/-0) src/PetriEngine/Colored/Multiset.cpp (+22/-14) src/PetriEngine/PQL/CMakeLists.txt (+2/-2) src/PetriEngine/PQL/CTLVisitor.cpp (+492/-0) src/PetriEngine/PQL/Expressions.cpp (+461/-778) src/PetriEngine/PQL/PQL.cpp (+6/-0) src/PetriEngine/PQL/PQLQueryParser.y (+2/-2) src/PetriEngine/PQL/QueryPrinter.cpp (+292/-0) src/PetriEngine/PetriNet.cpp (+5/-7) src/PetriEngine/PetriNetBuilder.cpp (+12/-14) src/PetriEngine/Reachability/ResultPrinter.cpp (+1/-1) src/PetriEngine/Reducer.cpp (+168/-124) src/PetriEngine/ReducingSuccessorGenerator.cpp (+31/-302) src/PetriEngine/Structures/AlignedEncoder.cpp (+1/-1) src/PetriEngine/Structures/Queue.cpp (+16/-2) src/PetriEngine/Stubborn/CMakeLists.txt (+3/-0) src/PetriEngine/Stubborn/InterestingTransitionVisitor.cpp (+326/-0) src/PetriEngine/Stubborn/ReachabilityStubbornSet.cpp (+41/-0) src/PetriEngine/Stubborn/StubbornSet.cpp (+302/-0) src/PetriEngine/SuccessorGenerator.cpp (+27/-0) src/PetriEngine/TAR/PlaceUseVisitor.cpp (+0/-12) src/PetriEngine/TAR/RangeContext.cpp (+0/-10) src/PetriEngine/TAR/RangeEvalContext.cpp (+0/-10) src/PetriEngine/TAR/Solver.cpp (+1/-1) src/PetriParse/PNMLParser.cpp (+221/-60) src/PetriParse/QueryBinaryParser.cpp (+24/-6) src/PetriParse/QueryXMLParser.cpp (+73/-133) src/VerifyPN.cpp (+447/-102) test_models/LTL/Bounded/model.pnml (+133/-0) test_models/LTL/Bounded/query.xml (+36/-0) test_models/LTL/generator.pnml (+60/-0) test_models/LTL/generator.xml (+52/-0) |
To merge this branch: | bzr merge lp:~tapaal-ltl/verifypn/mcc2021 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
VerifyPN Maintainers | Pending | ||
Review via email: mp+400587@code.launchpad.net |
Commit message
Numerous efficiency improvements, new LTL engine and improved CPN unfolding via color fixed-point computation.
Consistency verified against the current trunk version on MCC 2020 models and queries.
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2020-10-31 18:57:21 +0000 | |||
3 | +++ CMakeLists.txt 2021-04-02 18:07:40 +0000 | |||
4 | @@ -15,7 +15,7 @@ | |||
5 | 15 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) | 15 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) |
6 | 16 | 16 | ||
7 | 17 | 17 | ||
9 | 18 | set(VERIFYPN_VERSION 3.1.1) | 18 | set(VERIFYPN_VERSION 4.0.0) |
10 | 19 | add_compile_definitions(VERIFYPN_VERSION=\"${VERIFYPN_VERSION}\") | 19 | add_compile_definitions(VERIFYPN_VERSION=\"${VERIFYPN_VERSION}\") |
11 | 20 | 20 | ||
12 | 21 | project(verifypn VERSION ${VERIFYPN_VERSION} LANGUAGES CXX C) | 21 | project(verifypn VERSION ${VERIFYPN_VERSION} LANGUAGES CXX C) |
13 | @@ -32,11 +32,7 @@ | |||
14 | 32 | endif(VERIFYPN_MC_Simplification) | 32 | endif(VERIFYPN_MC_Simplification) |
15 | 33 | if (NOT APPLE) | 33 | if (NOT APPLE) |
16 | 34 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") | 34 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") |
17 | 35 | else(NOT APPLE) | ||
18 | 36 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") | ||
19 | 37 | endif(NOT APPLE) | 35 | endif(NOT APPLE) |
20 | 38 | else(VERIFYPN_Static) | ||
21 | 39 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") | ||
22 | 40 | endif (VERIFYPN_Static) | 36 | endif (VERIFYPN_Static) |
23 | 41 | 37 | ||
24 | 42 | if (VERIFYPN_MC_Simplification) | 38 | if (VERIFYPN_MC_Simplification) |
25 | @@ -47,14 +43,15 @@ | |||
26 | 47 | set(ARCH_TYPE "linux64") | 43 | set(ARCH_TYPE "linux64") |
27 | 48 | elseif(APPLE) | 44 | elseif(APPLE) |
28 | 49 | set(ARCH_TYPE "osx64") | 45 | set(ARCH_TYPE "osx64") |
31 | 50 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.8 -m64 ") | 46 | set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8) |
32 | 51 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mmacosx-version-min=10.8 -m64 ") | 47 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 ") |
33 | 48 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m64 ") | ||
34 | 52 | else() | 49 | else() |
35 | 53 | set(ARCH_TYPE "win64") | 50 | set(ARCH_TYPE "win64") |
36 | 54 | endif () | 51 | endif () |
37 | 55 | 52 | ||
40 | 56 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -pedantic-errors -O3 -DNDEBUG") | 53 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s -Wall -pedantic-errors -O3 -DNDEBUG") |
41 | 57 | 54 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -fno-omit-frame-pointer") | |
42 | 58 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -O3 -DNDEBUG") | 55 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -O3 -DNDEBUG") |
43 | 59 | if (VERIFYPN_Static AND NOT APPLE) | 56 | if (VERIFYPN_Static AND NOT APPLE) |
44 | 60 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -static") | 57 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -static") |
45 | @@ -81,6 +78,23 @@ | |||
46 | 81 | CONFIGURE_COMMAND mkdir -p ${CMAKE_BINARY_DIR}/external/include | 78 | CONFIGURE_COMMAND mkdir -p ${CMAKE_BINARY_DIR}/external/include |
47 | 82 | INSTALL_COMMAND cd ../rapidxml-ext && ${CMAKE_COMMAND} -E copy rapidxml.hpp rapidxml_iterators.hpp rapidxml_print.hpp rapidxml_utils.hpp ${EXTERNAL_INSTALL_LOCATION}/include | 79 | INSTALL_COMMAND cd ../rapidxml-ext && ${CMAKE_COMMAND} -E copy rapidxml.hpp rapidxml_iterators.hpp rapidxml_print.hpp rapidxml_utils.hpp ${EXTERNAL_INSTALL_LOCATION}/include |
48 | 83 | ) | 80 | ) |
49 | 81 | if (UNIX AND NOT APPLE) | ||
50 | 82 | ExternalProject_add(spot-ext | ||
51 | 83 | URL http://www.lrde.epita.fr/dload/spot/spot-2.9.6.tar.gz | ||
52 | 84 | URL_HASH SHA512=69ec8a3ce84b2c069bf40b8d2127e5085724c8e4ba88ffdefc3e2225f6334955959afd17bcfcde29fd6826d78d49a7f1303bd07ba756a8695473ff6cc5ade3a2 | ||
53 | 85 | BUILD_COMMAND make | ||
54 | 86 | CONFIGURE_COMMAND CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} <SOURCE_DIR>/configure --prefix ${EXTERNAL_INSTALL_LOCATION} --disable-python --disable-devel --disable-debug --disable-shared --enable-static CFLAGS=-flto CXXFLAGS=-flto LDFLAGS=-fuse-linker-plugin | ||
55 | 87 | INSTALL_COMMAND make install | ||
56 | 88 | ) | ||
57 | 89 | else () | ||
58 | 90 | ExternalProject_add(spot-ext | ||
59 | 91 | URL http://www.lrde.epita.fr/dload/spot/spot-2.9.6.tar.gz | ||
60 | 92 | URL_HASH SHA512=69ec8a3ce84b2c069bf40b8d2127e5085724c8e4ba88ffdefc3e2225f6334955959afd17bcfcde29fd6826d78d49a7f1303bd07ba756a8695473ff6cc5ade3a2 | ||
61 | 93 | BUILD_COMMAND make | ||
62 | 94 | CONFIGURE_COMMAND CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} <SOURCE_DIR>/configure --prefix ${EXTERNAL_INSTALL_LOCATION} --disable-python --disable-devel --disable-debug --disable-shared --enable-static CFLAGS=${CMAKE_CXX_FLAGS} LDFLAGS=${CMAKE_LINKER_FLAGS} | ||
63 | 95 | INSTALL_COMMAND make install | ||
64 | 96 | ) | ||
65 | 97 | endif () | ||
66 | 84 | 98 | ||
67 | 85 | if (WIN32) #If windows 32 or 64 | 99 | if (WIN32) #If windows 32 or 64 |
68 | 86 | set(GLPK_CFLAGS "-D __WOE__ -O3" ) | 100 | set(GLPK_CFLAGS "-D __WOE__ -O3" ) |
69 | 87 | 101 | ||
70 | === modified file 'Scripts/MCC20/competition-scripts/tapaal.sh' (properties changed: -x to +x) | |||
71 | === modified file 'include/CTL/Algorithm/CertainZeroFPA.h' | |||
72 | --- include/CTL/Algorithm/CertainZeroFPA.h 2020-03-02 21:03:24 +0000 | |||
73 | +++ include/CTL/Algorithm/CertainZeroFPA.h 2021-04-02 18:07:40 +0000 | |||
74 | @@ -27,9 +27,8 @@ | |||
75 | 27 | 27 | ||
76 | 28 | void checkEdge(DependencyGraph::Edge* e, bool only_assign = false); | 28 | void checkEdge(DependencyGraph::Edge* e, bool only_assign = false); |
77 | 29 | void finalAssign(DependencyGraph::Configuration *c, DependencyGraph::Assignment a); | 29 | void finalAssign(DependencyGraph::Configuration *c, DependencyGraph::Assignment a); |
78 | 30 | void finalAssign(DependencyGraph::Edge *e, DependencyGraph::Assignment a); | ||
79 | 30 | void explore(DependencyGraph::Configuration *c); | 31 | void explore(DependencyGraph::Configuration *c); |
80 | 31 | void addDependency(DependencyGraph::Edge *e, | ||
81 | 32 | DependencyGraph::Configuration *target); | ||
82 | 33 | 32 | ||
83 | 34 | }; | 33 | }; |
84 | 35 | } | 34 | } |
85 | 36 | 35 | ||
86 | === modified file 'include/CTL/DependencyGraph/Configuration.h' | |||
87 | --- include/CTL/DependencyGraph/Configuration.h 2020-03-10 13:29:26 +0000 | |||
88 | +++ include/CTL/DependencyGraph/Configuration.h 2021-04-02 18:07:40 +0000 | |||
89 | @@ -7,32 +7,29 @@ | |||
90 | 7 | #include <cstdio> | 7 | #include <cstdio> |
91 | 8 | #include <iostream> | 8 | #include <iostream> |
92 | 9 | #include <vector> | 9 | #include <vector> |
93 | 10 | #include <forward_list> | ||
94 | 10 | 11 | ||
95 | 11 | namespace DependencyGraph { | 12 | namespace DependencyGraph { |
96 | 12 | 13 | ||
97 | 13 | class Edge; | 14 | class Edge; |
98 | 14 | 15 | ||
99 | 15 | enum Assignment { | ||
100 | 16 | ONE = 1, UNKNOWN = 0, ZERO = -1, CZERO = -2 | ||
101 | 17 | }; | ||
102 | 18 | |||
103 | 19 | class Configuration | 16 | class Configuration |
104 | 20 | { | 17 | { |
105 | 18 | public: | ||
106 | 19 | std::forward_list<Edge*> dependency_set; | ||
107 | 20 | uint32_t nsuccs = 0; | ||
108 | 21 | private: | ||
109 | 21 | uint32_t distance = 0; | 22 | uint32_t distance = 0; |
110 | 22 | public: | ||
111 | 23 | |||
112 | 24 | uint32_t getDistance() const { return distance; } | ||
113 | 25 | void setDistance(uint32_t value) { distance = value; } | 23 | void setDistance(uint32_t value) { distance = value; } |
115 | 26 | 24 | public: | |
116 | 25 | int8_t assignment = UNKNOWN; | ||
117 | 27 | Configuration() {} | 26 | Configuration() {} |
120 | 28 | virtual ~Configuration(); | 27 | uint32_t getDistance() const { return distance; } |
119 | 29 | |||
121 | 30 | bool isDone() const { return assignment == ONE || assignment == CZERO; } | 28 | bool isDone() const { return assignment == ONE || assignment == CZERO; } |
127 | 31 | 29 | void addDependency(Edge* e); | |
128 | 32 | uint32_t owner = 0; | 30 | void setOwner(uint32_t) { } |
129 | 33 | uint32_t nsuccs = 0; | 31 | uint32_t getOwner() { return 0; } |
130 | 34 | std::vector<Edge*> dependency_set; | 32 | |
126 | 35 | Assignment assignment = UNKNOWN; | ||
131 | 36 | }; | 33 | }; |
132 | 37 | 34 | ||
133 | 38 | 35 | ||
134 | 39 | 36 | ||
135 | === modified file 'include/CTL/DependencyGraph/Edge.h' | |||
136 | --- include/CTL/DependencyGraph/Edge.h 2020-03-02 21:03:24 +0000 | |||
137 | +++ include/CTL/DependencyGraph/Edge.h 2021-04-02 18:07:40 +0000 | |||
138 | @@ -6,13 +6,17 @@ | |||
139 | 6 | #include <string> | 6 | #include <string> |
140 | 7 | #include <algorithm> | 7 | #include <algorithm> |
141 | 8 | #include <cassert> | 8 | #include <cassert> |
142 | 9 | #include <forward_list> | ||
143 | 9 | 10 | ||
144 | 10 | namespace DependencyGraph { | 11 | namespace DependencyGraph { |
145 | 11 | 12 | ||
146 | 12 | class Configuration; | 13 | class Configuration; |
147 | 14 | enum Assignment { | ||
148 | 15 | ONE = 1, UNKNOWN = 0, ZERO = -1, CZERO = -2 | ||
149 | 16 | }; | ||
150 | 13 | 17 | ||
151 | 14 | class Edge { | 18 | class Edge { |
153 | 15 | typedef std::vector<Configuration*> container; | 19 | typedef std::forward_list<Configuration*> container; |
154 | 16 | public: | 20 | public: |
155 | 17 | Edge(){} | 21 | Edge(){} |
156 | 18 | Edge(Configuration &t_source) : source(&t_source) {} | 22 | Edge(Configuration &t_source) : source(&t_source) {} |
157 | @@ -20,17 +24,19 @@ | |||
158 | 20 | void addTarget(Configuration* conf) | 24 | void addTarget(Configuration* conf) |
159 | 21 | { | 25 | { |
160 | 22 | assert(conf); | 26 | assert(conf); |
162 | 23 | targets.push_back(conf); | 27 | targets.push_front(conf); |
163 | 28 | //++children; | ||
164 | 24 | } | 29 | } |
165 | 25 | 30 | ||
166 | 31 | container targets; | ||
167 | 26 | Configuration* source; | 32 | Configuration* source; |
168 | 27 | container targets; | ||
169 | 28 | uint8_t status = 0; | 33 | uint8_t status = 0; |
170 | 29 | bool processed = false; | 34 | bool processed = false; |
171 | 30 | bool is_negated = false; | 35 | bool is_negated = false; |
172 | 36 | bool handled = false; | ||
173 | 31 | int32_t refcnt = 0; | 37 | int32_t refcnt = 0; |
176 | 32 | bool handled = false; | 38 | /*size_t children; |
177 | 33 | uint32_t weight = 0; | 39 | Assignment assignment;*/ |
178 | 34 | }; | 40 | }; |
179 | 35 | } | 41 | } |
180 | 36 | #endif // EDGE_H | 42 | #endif // EDGE_H |
181 | 37 | 43 | ||
182 | === modified file 'include/CTL/PetriNets/PetriConfig.h' | |||
183 | --- include/CTL/PetriNets/PetriConfig.h 2020-03-02 21:03:24 +0000 | |||
184 | +++ include/CTL/PetriNets/PetriConfig.h 2021-04-02 18:07:40 +0000 | |||
185 | @@ -20,8 +20,6 @@ | |||
186 | 20 | DependencyGraph::Configuration(), marking(t_marking), query(t_query) { | 20 | DependencyGraph::Configuration(), marking(t_marking), query(t_query) { |
187 | 21 | } | 21 | } |
188 | 22 | 22 | ||
189 | 23 | virtual ~PetriConfig(){}; | ||
190 | 24 | |||
191 | 25 | size_t marking; | 23 | size_t marking; |
192 | 26 | Condition *query; | 24 | Condition *query; |
193 | 27 | 25 | ||
194 | 28 | 26 | ||
195 | === added directory 'include/LTL' | |||
196 | === added directory 'include/LTL/Algorithm' | |||
197 | === added file 'include/LTL/Algorithm/ModelChecker.h' | |||
198 | --- include/LTL/Algorithm/ModelChecker.h 1970-01-01 00:00:00 +0000 | |||
199 | +++ include/LTL/Algorithm/ModelChecker.h 2021-04-02 18:07:40 +0000 | |||
200 | @@ -0,0 +1,72 @@ | |||
201 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
202 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
203 | 3 | * | ||
204 | 4 | * This program is free software: you can redistribute it and/or modify | ||
205 | 5 | * it under the terms of the GNU General Public License as published by | ||
206 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
207 | 7 | * (at your option) any later version. | ||
208 | 8 | * | ||
209 | 9 | * This program is distributed in the hope that it will be useful, | ||
210 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
211 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
212 | 12 | * GNU General Public License for more details. | ||
213 | 13 | * | ||
214 | 14 | * You should have received a copy of the GNU General Public License | ||
215 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
216 | 16 | */ | ||
217 | 17 | |||
218 | 18 | #ifndef VERIFYPN_MODELCHECKER_H | ||
219 | 19 | #define VERIFYPN_MODELCHECKER_H | ||
220 | 20 | |||
221 | 21 | #include "PetriEngine/PQL/PQL.h" | ||
222 | 22 | #include "LTL/ProductSuccessorGenerator.h" | ||
223 | 23 | #include "LTL/Algorithm/ProductPrinter.h" | ||
224 | 24 | #include "PetriEngine/options.h" | ||
225 | 25 | |||
226 | 26 | namespace LTL { | ||
227 | 27 | |||
228 | 28 | class ModelChecker { | ||
229 | 29 | public: | ||
230 | 30 | ModelChecker(const PetriEngine::PetriNet &net, PetriEngine::PQL::Condition_ptr, const bool shortcircuitweak, | ||
231 | 31 | TraceLevel level = TraceLevel::Transitions); | ||
232 | 32 | |||
233 | 33 | virtual bool isSatisfied() = 0; | ||
234 | 34 | |||
235 | 35 | virtual ~ModelChecker() = default; | ||
236 | 36 | |||
237 | 37 | virtual void printStats(std::ostream &os) = 0; | ||
238 | 38 | |||
239 | 39 | [[nodiscard]] bool isweak() const { return is_weak; } | ||
240 | 40 | |||
241 | 41 | protected: | ||
242 | 42 | struct stats_t { | ||
243 | 43 | size_t explored = 0, expanded = 0; | ||
244 | 44 | }; | ||
245 | 45 | |||
246 | 46 | stats_t stats; | ||
247 | 47 | virtual void _printStats(std::ostream &os, const PetriEngine::Structures::StateSetInterface &stateSet) { | ||
248 | 48 | std::cout << "STATS:\n" | ||
249 | 49 | << "\tdiscovered states: " << stateSet.discovered() << std::endl | ||
250 | 50 | << "\texplored states: " << stats.explored << std::endl | ||
251 | 51 | << "\texpanded states: " << stats.expanded << std::endl | ||
252 | 52 | << "\tmax tokens: " << stateSet.maxTokens() << std::endl; | ||
253 | 53 | } | ||
254 | 54 | |||
255 | 55 | std::unique_ptr<ProductSuccessorGenerator> successorGenerator; | ||
256 | 56 | const PetriEngine::PetriNet &net; | ||
257 | 57 | PetriEngine::PQL::Condition_ptr formula; | ||
258 | 58 | TraceLevel traceLevel; | ||
259 | 59 | |||
260 | 60 | size_t _discovered = 0; | ||
261 | 61 | const bool shortcircuitweak; | ||
262 | 62 | bool weakskip = false; | ||
263 | 63 | bool is_weak = false; | ||
264 | 64 | int maxTransName; | ||
265 | 65 | |||
266 | 66 | std::ostream &printTransition(size_t transition, LTL::Structures::ProductState &state, std::ostream &os); | ||
267 | 67 | |||
268 | 68 | void printLoop(std::ostream &os); | ||
269 | 69 | }; | ||
270 | 70 | } | ||
271 | 71 | |||
272 | 72 | #endif //VERIFYPN_MODELCHECKER_H | ||
273 | 0 | 73 | ||
274 | === added file 'include/LTL/Algorithm/NestedDepthFirstSearch.h' | |||
275 | --- include/LTL/Algorithm/NestedDepthFirstSearch.h 1970-01-01 00:00:00 +0000 | |||
276 | +++ include/LTL/Algorithm/NestedDepthFirstSearch.h 2021-04-02 18:07:40 +0000 | |||
277 | @@ -0,0 +1,91 @@ | |||
278 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
279 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
280 | 3 | * | ||
281 | 4 | * This program is free software: you can redistribute it and/or modify | ||
282 | 5 | * it under the terms of the GNU General Public License as published by | ||
283 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
284 | 7 | * (at your option) any later version. | ||
285 | 8 | * | ||
286 | 9 | * This program is distributed in the hope that it will be useful, | ||
287 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
288 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
289 | 12 | * GNU General Public License for more details. | ||
290 | 13 | * | ||
291 | 14 | * You should have received a copy of the GNU General Public License | ||
292 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
293 | 16 | */ | ||
294 | 17 | |||
295 | 18 | #ifndef VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H | ||
296 | 19 | #define VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H | ||
297 | 20 | |||
298 | 21 | #include "ModelChecker.h" | ||
299 | 22 | #include "PetriEngine/Structures/StateSet.h" | ||
300 | 23 | #include "PetriEngine/Structures/State.h" | ||
301 | 24 | #include "PetriEngine/Structures/Queue.h" | ||
302 | 25 | #include "LTL/Structures/ProductStateFactory.h" | ||
303 | 26 | |||
304 | 27 | #include <ptrie/ptrie_stable.h> | ||
305 | 28 | #include <unordered_set> | ||
306 | 29 | |||
307 | 30 | using namespace PetriEngine; | ||
308 | 31 | |||
309 | 32 | namespace LTL { | ||
310 | 33 | /** | ||
311 | 34 | * Implement the nested DFS algorithm for LTL model checking. Roughly based on versions given in | ||
312 | 35 | * <p> | ||
313 | 36 | * Jaco Geldenhuys & Antti Valmari,<br> | ||
314 | 37 | * More efficient on-the-fly LTL verification with Tarjan's algorithm,<br> | ||
315 | 38 | * https://doi.org/10.1016/j.tcs.2005.07.004 | ||
316 | 39 | * </p> | ||
317 | 40 | * and | ||
318 | 41 | * <p> | ||
319 | 42 | * Gerard J. Holzmann, Doron Peled, and Mihalis Yannakakis<br> | ||
320 | 43 | * On Nested Depth First Search<br> | ||
321 | 44 | * https://spinroot.com/gerard/pdf/inprint/spin96.pdf | ||
322 | 45 | * </p> | ||
323 | 46 | * For most use cases, Tarjan's algorithm (see LTL::TarjanModelChecker) is faster. | ||
324 | 47 | * @tparam W type used for state storage. Use <code>PetriEngine::Structures::TracableStateSet</code> if you want traces, | ||
325 | 48 | * <code>PetriEngine::Structures::StateSet</code> if you don't care (as it is faster). | ||
326 | 49 | */ | ||
327 | 50 | template <typename W> | ||
328 | 51 | class NestedDepthFirstSearch : public ModelChecker { | ||
329 | 52 | public: | ||
330 | 53 | NestedDepthFirstSearch(const PetriNet &net, PetriEngine::PQL::Condition_ptr ptr, const bool shortcircuitweak, TraceLevel level = TraceLevel::Full) | ||
331 | 54 | : ModelChecker(net, ptr, shortcircuitweak, level), factory{net, successorGenerator->initial_buchi_state()}, | ||
332 | 55 | states(net, 0, (int)net.numberOfPlaces() + 1) {} | ||
333 | 56 | |||
334 | 57 | bool isSatisfied() override; | ||
335 | 58 | |||
336 | 59 | void printStats(std::ostream &os) override; | ||
337 | 60 | |||
338 | 61 | private: | ||
339 | 62 | using State = LTL::Structures::ProductState; | ||
340 | 63 | |||
341 | 64 | Structures::ProductStateFactory factory; | ||
342 | 65 | W states; //StateSet | ||
343 | 66 | std::set<size_t> mark1; | ||
344 | 67 | std::set<size_t> mark2; | ||
345 | 68 | |||
346 | 69 | struct StackEntry { | ||
347 | 70 | size_t id; | ||
348 | 71 | successor_info sucinfo; | ||
349 | 72 | }; | ||
350 | 73 | |||
351 | 74 | State *seed; | ||
352 | 75 | bool violation = false; | ||
353 | 76 | |||
354 | 77 | //Used for printing the trace | ||
355 | 78 | std::stack<std::pair<size_t, size_t>> nested_transitions; | ||
356 | 79 | |||
357 | 80 | void dfs(); | ||
358 | 81 | |||
359 | 82 | void ndfs(State &state); | ||
360 | 83 | void printTrace(std::stack<std::pair<size_t, size_t>> &transitions, std::ostream &os = std::cout); | ||
361 | 84 | |||
362 | 85 | static constexpr bool SaveTrace = std::is_same_v<W, PetriEngine::Structures::TracableStateSet>; | ||
363 | 86 | }; | ||
364 | 87 | extern template class NestedDepthFirstSearch<PetriEngine::Structures::StateSet>; | ||
365 | 88 | extern template class NestedDepthFirstSearch<PetriEngine::Structures::TracableStateSet>; | ||
366 | 89 | } | ||
367 | 90 | |||
368 | 91 | #endif //VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H | ||
369 | 0 | 92 | ||
370 | === added file 'include/LTL/Algorithm/ProductPrinter.h' | |||
371 | --- include/LTL/Algorithm/ProductPrinter.h 1970-01-01 00:00:00 +0000 | |||
372 | +++ include/LTL/Algorithm/ProductPrinter.h 2021-04-02 18:07:40 +0000 | |||
373 | @@ -0,0 +1,31 @@ | |||
374 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
375 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
376 | 3 | * | ||
377 | 4 | * This program is free software: you can redistribute it and/or modify | ||
378 | 5 | * it under the terms of the GNU General Public License as published by | ||
379 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
380 | 7 | * (at your option) any later version. | ||
381 | 8 | * | ||
382 | 9 | * This program is distributed in the hope that it will be useful, | ||
383 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
384 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
385 | 12 | * GNU General Public License for more details. | ||
386 | 13 | * | ||
387 | 14 | * You should have received a copy of the GNU General Public License | ||
388 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
389 | 16 | */ | ||
390 | 17 | |||
391 | 18 | #ifndef VERIFYPN_PRODUCTPRINTER_H | ||
392 | 19 | #define VERIFYPN_PRODUCTPRINTER_H | ||
393 | 20 | |||
394 | 21 | #include "LTL/Structures/ProductStateFactory.h" | ||
395 | 22 | #include "LTL/ProductSuccessorGenerator.h" | ||
396 | 23 | #include "PetriEngine/Structures/StateSet.h" | ||
397 | 24 | #include "PetriEngine/Structures/Queue.h" | ||
398 | 25 | #include "PetriEngine/PQL/Contexts.h" | ||
399 | 26 | |||
400 | 27 | namespace LTL::ProductPrinter { | ||
401 | 28 | void printProduct(ProductSuccessorGenerator &successorGenerator, std::ostream &os, const PetriEngine::PetriNet &net, | ||
402 | 29 | PetriEngine::PQL::Condition_ptr formula); | ||
403 | 30 | } | ||
404 | 31 | #endif //VERIFYPN_PRODUCTPRINTER_H | ||
405 | 0 | 32 | ||
406 | === added file 'include/LTL/Algorithm/RandomNDFS.h' | |||
407 | --- include/LTL/Algorithm/RandomNDFS.h 1970-01-01 00:00:00 +0000 | |||
408 | +++ include/LTL/Algorithm/RandomNDFS.h 2021-04-02 18:07:40 +0000 | |||
409 | @@ -0,0 +1,59 @@ | |||
410 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
411 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
412 | 3 | * | ||
413 | 4 | * This program is free software: you can redistribute it and/or modify | ||
414 | 5 | * it under the terms of the GNU General Public License as published by | ||
415 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
416 | 7 | * (at your option) any later version. | ||
417 | 8 | * | ||
418 | 9 | * This program is distributed in the hope that it will be useful, | ||
419 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
420 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
421 | 12 | * GNU General Public License for more details. | ||
422 | 13 | * | ||
423 | 14 | * You should have received a copy of the GNU General Public License | ||
424 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
425 | 16 | */ | ||
426 | 17 | |||
427 | 18 | #ifndef VERIFYPN_RANDOMNDFS_H | ||
428 | 19 | #define VERIFYPN_RANDOMNDFS_H | ||
429 | 20 | |||
430 | 21 | #include "ModelChecker.h" | ||
431 | 22 | #include "PetriEngine/Structures/StateSet.h" | ||
432 | 23 | #include "PetriEngine/Structures/State.h" | ||
433 | 24 | #include "PetriEngine/Structures/Queue.h" | ||
434 | 25 | #include "LTL/Structures/ProductStateFactory.h" | ||
435 | 26 | |||
436 | 27 | #include <ptrie/ptrie_stable.h> | ||
437 | 28 | |||
438 | 29 | using namespace PetriEngine; | ||
439 | 30 | |||
440 | 31 | namespace LTL { | ||
441 | 32 | class RandomNDFS : public ModelChecker { | ||
442 | 33 | public: | ||
443 | 34 | RandomNDFS(const PetriNet &net, PetriEngine::PQL::Condition_ptr ptr) | ||
444 | 35 | : ModelChecker(net, ptr, false), factory{net, successorGenerator->initial_buchi_state()}, | ||
445 | 36 | mark1(net, 0, (int) net.numberOfPlaces() + 1), mark2(net, 0, (int) net.numberOfPlaces() + 1) {} | ||
446 | 37 | |||
447 | 38 | bool isSatisfied() override; | ||
448 | 39 | |||
449 | 40 | void printStats(std::ostream &os) override; | ||
450 | 41 | |||
451 | 42 | private: | ||
452 | 43 | using State = LTL::Structures::ProductState; | ||
453 | 44 | |||
454 | 45 | Structures::ProductStateFactory factory; | ||
455 | 46 | PetriEngine::Structures::StateSet mark1; | ||
456 | 47 | PetriEngine::Structures::StateSet mark2; | ||
457 | 48 | |||
458 | 49 | |||
459 | 50 | State *seed; | ||
460 | 51 | bool violation = false; | ||
461 | 52 | |||
462 | 53 | void dfs(); | ||
463 | 54 | |||
464 | 55 | void ndfs(State &state); | ||
465 | 56 | }; | ||
466 | 57 | } | ||
467 | 58 | |||
468 | 59 | #endif //VERIFYPN_RANDOMNDFS_H | ||
469 | 0 | 60 | ||
470 | === added file 'include/LTL/Algorithm/TarjanModelChecker.h' | |||
471 | --- include/LTL/Algorithm/TarjanModelChecker.h 1970-01-01 00:00:00 +0000 | |||
472 | +++ include/LTL/Algorithm/TarjanModelChecker.h 2021-04-02 18:07:40 +0000 | |||
473 | @@ -0,0 +1,140 @@ | |||
474 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
475 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
476 | 3 | * | ||
477 | 4 | * This program is free software: you can redistribute it and/or modify | ||
478 | 5 | * it under the terms of the GNU General Public License as published by | ||
479 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
480 | 7 | * (at your option) any later version. | ||
481 | 8 | * | ||
482 | 9 | * This program is distributed in the hope that it will be useful, | ||
483 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
484 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
485 | 12 | * GNU General Public License for more details. | ||
486 | 13 | * | ||
487 | 14 | * You should have received a copy of the GNU General Public License | ||
488 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
489 | 16 | */ | ||
490 | 17 | |||
491 | 18 | #ifndef VERIFYPN_TARJANMODELCHECKER_H | ||
492 | 19 | #define VERIFYPN_TARJANMODELCHECKER_H | ||
493 | 20 | |||
494 | 21 | |||
495 | 22 | #include "LTL/Algorithm/ModelChecker.h" | ||
496 | 23 | #include "LTL/Structures/ProductStateFactory.h" | ||
497 | 24 | #include "PetriEngine/Structures/StateSet.h" | ||
498 | 25 | |||
499 | 26 | #include <stack> | ||
500 | 27 | #include <unordered_set> | ||
501 | 28 | |||
502 | 29 | namespace LTL { | ||
503 | 30 | |||
504 | 31 | /** | ||
505 | 32 | * Implements on-the-fly version of Tarjan's algorithm suitable for LTL model checking. | ||
506 | 33 | * The idea is to detect some reachable strongly connected component containing an accepting state, | ||
507 | 34 | * which constitutes a counter-example. | ||
508 | 35 | * For more details see | ||
509 | 36 | * <p> | ||
510 | 37 | * Jaco Geldenhuys & Antti Valmari, | ||
511 | 38 | * More efficient on-the-fly LTL verification with Tarjan's algorithm, | ||
512 | 39 | * https://doi.org/10.1016/j.tcs.2005.07.004 | ||
513 | 40 | * </p> | ||
514 | 41 | * @tparam SaveTrace whether to save and print counter-examples when possible. | ||
515 | 42 | */ | ||
516 | 43 | template<bool SaveTrace> | ||
517 | 44 | class TarjanModelChecker : public ModelChecker { | ||
518 | 45 | public: | ||
519 | 46 | TarjanModelChecker(const PetriEngine::PetriNet &net, const PetriEngine::PQL::Condition_ptr &cond, const bool shortcircuitweak, | ||
520 | 47 | TraceLevel level = TraceLevel::Full) | ||
521 | 48 | : ModelChecker(net, cond, shortcircuitweak, level), factory(net, successorGenerator->initial_buchi_state()), | ||
522 | 49 | seen(net, 0, (int) net.numberOfPlaces() + 1) | ||
523 | 50 | { | ||
524 | 51 | chash.fill(std::numeric_limits<idx_t>::max()); | ||
525 | 52 | } | ||
526 | 53 | |||
527 | 54 | bool isSatisfied() override; | ||
528 | 55 | |||
529 | 56 | void printStats(std::ostream &os) override | ||
530 | 57 | { | ||
531 | 58 | _printStats(os, seen); | ||
532 | 59 | } | ||
533 | 60 | |||
534 | 61 | private: | ||
535 | 62 | using State = LTL::Structures::ProductState; | ||
536 | 63 | using idx_t = size_t; | ||
537 | 64 | // 64 MB hash table | ||
538 | 65 | static constexpr idx_t HashSz = 16777216; | ||
539 | 66 | |||
540 | 67 | LTL::Structures::ProductStateFactory factory; | ||
541 | 68 | |||
542 | 69 | using StateSet = std::conditional_t<SaveTrace, PetriEngine::Structures::TracableStateSet, PetriEngine::Structures::StateSet>; | ||
543 | 70 | |||
544 | 71 | StateSet seen; | ||
545 | 72 | std::unordered_set<idx_t> store; | ||
546 | 73 | |||
547 | 74 | // rudimentary hash table of state IDs. chash[hash(state)] is the top index in cstack | ||
548 | 75 | // corresponding to state. Collisions are resolved using linked list via CEntry::next. | ||
549 | 76 | std::array<idx_t, HashSz> chash; | ||
550 | 77 | static_assert(sizeof(chash) == (1U << 27U)); | ||
551 | 78 | |||
552 | 79 | static inline idx_t hash(idx_t id) | ||
553 | 80 | { | ||
554 | 81 | return id % HashSz; | ||
555 | 82 | } | ||
556 | 83 | |||
557 | 84 | struct PlainCEntry { | ||
558 | 85 | idx_t lowlink; | ||
559 | 86 | idx_t stateid; | ||
560 | 87 | idx_t next = std::numeric_limits<idx_t>::max(); | ||
561 | 88 | |||
562 | 89 | PlainCEntry(idx_t lowlink, idx_t stateid, idx_t next) : lowlink(lowlink), stateid(stateid), next(next) {} | ||
563 | 90 | }; | ||
564 | 91 | |||
565 | 92 | struct TracableCEntry : PlainCEntry { | ||
566 | 93 | idx_t lowsource = std::numeric_limits<idx_t>::max(); | ||
567 | 94 | idx_t sourcetrans; | ||
568 | 95 | |||
569 | 96 | TracableCEntry(idx_t lowlink, idx_t stateid, idx_t next) : PlainCEntry(lowlink, stateid, next) {} | ||
570 | 97 | }; | ||
571 | 98 | |||
572 | 99 | using CEntry = std::conditional_t<SaveTrace, | ||
573 | 100 | TracableCEntry, | ||
574 | 101 | PlainCEntry>; | ||
575 | 102 | |||
576 | 103 | |||
577 | 104 | struct DEntry { | ||
578 | 105 | idx_t pos; // position in cstack. | ||
579 | 106 | successor_info sucinfo; | ||
580 | 107 | }; | ||
581 | 108 | |||
582 | 109 | // master list of state information. | ||
583 | 110 | std::vector<CEntry> cstack; | ||
584 | 111 | // depth-first search stack, contains current search path. | ||
585 | 112 | std::stack<DEntry> dstack; | ||
586 | 113 | // cstack positions of accepting states in current search path, for quick access. | ||
587 | 114 | std::stack<idx_t> astack; | ||
588 | 115 | bool violation = false; | ||
589 | 116 | size_t loopstate = std::numeric_limits<size_t>::max(); | ||
590 | 117 | size_t looptrans = std::numeric_limits<size_t>::max(); | ||
591 | 118 | |||
592 | 119 | void push(State &state, size_t stateid); | ||
593 | 120 | |||
594 | 121 | void pop(); | ||
595 | 122 | |||
596 | 123 | void update(idx_t to); | ||
597 | 124 | |||
598 | 125 | bool nexttrans(State &state, State &parent, DEntry &delem); | ||
599 | 126 | |||
600 | 127 | void popCStack(); | ||
601 | 128 | |||
602 | 129 | void printTrace(std::stack<DEntry> &&dstack, std::ostream &os = std::cout); | ||
603 | 130 | |||
604 | 131 | }; | ||
605 | 132 | |||
606 | 133 | extern template | ||
607 | 134 | class TarjanModelChecker<true>; | ||
608 | 135 | |||
609 | 136 | extern template | ||
610 | 137 | class TarjanModelChecker<false>; | ||
611 | 138 | } | ||
612 | 139 | |||
613 | 140 | #endif //VERIFYPN_TARJANMODELCHECKER_H | ||
614 | 0 | 141 | ||
615 | === added file 'include/LTL/AlgorithmTypes.h' | |||
616 | --- include/LTL/AlgorithmTypes.h 1970-01-01 00:00:00 +0000 | |||
617 | +++ include/LTL/AlgorithmTypes.h 2021-04-02 18:07:40 +0000 | |||
618 | @@ -0,0 +1,40 @@ | |||
619 | 1 | /* Copyright (C) 2021 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
620 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
621 | 3 | * | ||
622 | 4 | * This program is free software: you can redistribute it and/or modify | ||
623 | 5 | * it under the terms of the GNU General Public License as published by | ||
624 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
625 | 7 | * (at your option) any later version. | ||
626 | 8 | * | ||
627 | 9 | * This program is distributed in the hope that it will be useful, | ||
628 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
629 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
630 | 12 | * GNU General Public License for more details. | ||
631 | 13 | * | ||
632 | 14 | * You should have received a copy of the GNU General Public License | ||
633 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
634 | 16 | */ | ||
635 | 17 | |||
636 | 18 | #ifndef VERIFYPN_ALGORITHMTYPES_H | ||
637 | 19 | #define VERIFYPN_ALGORITHMTYPES_H | ||
638 | 20 | |||
639 | 21 | namespace LTL { | ||
640 | 22 | enum class Algorithm { | ||
641 | 23 | NDFS, Tarjan, None=-1 | ||
642 | 24 | }; | ||
643 | 25 | inline auto to_string(Algorithm alg) { | ||
644 | 26 | switch (alg) { | ||
645 | 27 | case Algorithm::NDFS: | ||
646 | 28 | return "NDFS"; | ||
647 | 29 | case Algorithm::Tarjan: | ||
648 | 30 | return "TARJAN"; | ||
649 | 31 | case Algorithm::None: | ||
650 | 32 | default: | ||
651 | 33 | std::cerr << "to_string: Invalid LTL Algorithm " << static_cast<int>(alg) << '\n'; | ||
652 | 34 | assert(false); | ||
653 | 35 | return "None"; | ||
654 | 36 | } | ||
655 | 37 | } | ||
656 | 38 | } | ||
657 | 39 | |||
658 | 40 | #endif //VERIFYPN_ALGORITHMTYPES_H | ||
659 | 0 | 41 | ||
660 | === added file 'include/LTL/BuchiSuccessorGenerator.h' | |||
661 | --- include/LTL/BuchiSuccessorGenerator.h 1970-01-01 00:00:00 +0000 | |||
662 | +++ include/LTL/BuchiSuccessorGenerator.h 2021-04-02 18:07:40 +0000 | |||
663 | @@ -0,0 +1,95 @@ | |||
664 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
665 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
666 | 3 | * | ||
667 | 4 | * This program is free software: you can redistribute it and/or modify | ||
668 | 5 | * it under the terms of the GNU General Public License as published by | ||
669 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
670 | 7 | * (at your option) any later version. | ||
671 | 8 | * | ||
672 | 9 | * This program is distributed in the hope that it will be useful, | ||
673 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
674 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
675 | 12 | * GNU General Public License for more details. | ||
676 | 13 | * | ||
677 | 14 | * You should have received a copy of the GNU General Public License | ||
678 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
679 | 16 | */ | ||
680 | 17 | |||
681 | 18 | #ifndef VERIFYPN_BUCHISUCCESSORGENERATOR_H | ||
682 | 19 | #define VERIFYPN_BUCHISUCCESSORGENERATOR_H | ||
683 | 20 | |||
684 | 21 | #include "PetriEngine/SuccessorGenerator.h" | ||
685 | 22 | #include "LTL/Structures/BuchiAutomaton.h" | ||
686 | 23 | |||
687 | 24 | #include <spot/twa/twagraph.hh> | ||
688 | 25 | #include <utility> | ||
689 | 26 | #include <memory> | ||
690 | 27 | |||
691 | 28 | namespace LTL { | ||
692 | 29 | class BuchiSuccessorGenerator { | ||
693 | 30 | public: | ||
694 | 31 | explicit BuchiSuccessorGenerator(Structures::BuchiAutomaton automaton) | ||
695 | 32 | : aut(std::move(automaton)) | ||
696 | 33 | { | ||
697 | 34 | deleter = SuccIterDeleter{&aut}; | ||
698 | 35 | } | ||
699 | 36 | |||
700 | 37 | void prepare(size_t state) | ||
701 | 38 | { | ||
702 | 39 | auto curstate = aut.buchi->state_from_number(state); | ||
703 | 40 | succ = _succ_iter{aut.buchi->succ_iter(curstate), SuccIterDeleter{&aut}}; | ||
704 | 41 | succ->first(); | ||
705 | 42 | } | ||
706 | 43 | |||
707 | 44 | bool next(size_t &state, bdd &cond) | ||
708 | 45 | { | ||
709 | 46 | if (!succ->done()) { | ||
710 | 47 | auto dst = succ->dst(); | ||
711 | 48 | state = aut.buchi->state_number(dst); | ||
712 | 49 | cond = succ->cond(); | ||
713 | 50 | succ->next(); | ||
714 | 51 | dst->destroy(); | ||
715 | 52 | return true; | ||
716 | 53 | } | ||
717 | 54 | return false; | ||
718 | 55 | } | ||
719 | 56 | |||
720 | 57 | [[nodiscard]] bool is_accepting(size_t state) const | ||
721 | 58 | { | ||
722 | 59 | return aut.buchi->state_is_accepting(state); | ||
723 | 60 | } | ||
724 | 61 | |||
725 | 62 | [[nodiscard]] size_t initial_state_number() const | ||
726 | 63 | { | ||
727 | 64 | return aut.buchi->get_init_state_number(); | ||
728 | 65 | } | ||
729 | 66 | |||
730 | 67 | [[nodiscard]] PetriEngine::PQL::Condition_ptr getExpression(size_t i) const | ||
731 | 68 | { | ||
732 | 69 | return aut.ap_info.at(i).expression; | ||
733 | 70 | } | ||
734 | 71 | |||
735 | 72 | [[nodiscard]] bool is_weak() const | ||
736 | 73 | { | ||
737 | 74 | return (bool) aut.buchi->prop_weak(); | ||
738 | 75 | } | ||
739 | 76 | |||
740 | 77 | private: | ||
741 | 78 | Structures::BuchiAutomaton aut; | ||
742 | 79 | |||
743 | 80 | struct SuccIterDeleter { | ||
744 | 81 | Structures::BuchiAutomaton *aut; | ||
745 | 82 | |||
746 | 83 | void operator()(spot::twa_succ_iterator *iter) const | ||
747 | 84 | { | ||
748 | 85 | aut->buchi->release_iter(iter); | ||
749 | 86 | } | ||
750 | 87 | }; | ||
751 | 88 | |||
752 | 89 | SuccIterDeleter deleter{}; | ||
753 | 90 | |||
754 | 91 | using _succ_iter = std::unique_ptr<spot::twa_succ_iterator, SuccIterDeleter>; | ||
755 | 92 | _succ_iter succ = nullptr; | ||
756 | 93 | }; | ||
757 | 94 | } | ||
758 | 95 | #endif //VERIFYPN_BUCHISUCCESSORGENERATOR_H | ||
759 | 0 | 96 | ||
760 | === added file 'include/LTL/LTL.h' | |||
761 | --- include/LTL/LTL.h 1970-01-01 00:00:00 +0000 | |||
762 | +++ include/LTL/LTL.h 2021-04-02 18:07:40 +0000 | |||
763 | @@ -0,0 +1,34 @@ | |||
764 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
765 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
766 | 3 | * | ||
767 | 4 | * This program is free software: you can redistribute it and/or modify | ||
768 | 5 | * it under the terms of the GNU General Public License as published by | ||
769 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
770 | 7 | * (at your option) any later version. | ||
771 | 8 | * | ||
772 | 9 | * This program is distributed in the hope that it will be useful, | ||
773 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
774 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
775 | 12 | * GNU General Public License for more details. | ||
776 | 13 | * | ||
777 | 14 | * You should have received a copy of the GNU General Public License | ||
778 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
779 | 16 | */ | ||
780 | 17 | |||
781 | 18 | #ifndef VERIFYPN_LTLALGORITHM_H | ||
782 | 19 | #define VERIFYPN_LTLALGORITHM_H | ||
783 | 20 | |||
784 | 21 | #include "LTL/LTLValidator.h" | ||
785 | 22 | #include "LTL/Algorithm/TarjanModelChecker.h" | ||
786 | 23 | #include "LTL/Algorithm/NestedDepthFirstSearch.h" | ||
787 | 24 | #include "LTL/Algorithm/RandomNDFS.h" | ||
788 | 25 | #include "LTL/Simplification/SpotToPQL.h" | ||
789 | 26 | #include "LTL/LTLToBuchi.h" | ||
790 | 27 | |||
791 | 28 | namespace LTL { | ||
792 | 29 | |||
793 | 30 | |||
794 | 31 | std::pair<Condition_ptr, bool> to_ltl(const Condition_ptr &formula); | ||
795 | 32 | } | ||
796 | 33 | |||
797 | 34 | #endif | ||
798 | 0 | \ No newline at end of file | 35 | \ No newline at end of file |
799 | 1 | 36 | ||
800 | === added file 'include/LTL/LTLToBuchi.h' | |||
801 | --- include/LTL/LTLToBuchi.h 1970-01-01 00:00:00 +0000 | |||
802 | +++ include/LTL/LTLToBuchi.h 2021-04-02 18:07:40 +0000 | |||
803 | @@ -0,0 +1,131 @@ | |||
804 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
805 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
806 | 3 | * | ||
807 | 4 | * This program is free software: you can redistribute it and/or modify | ||
808 | 5 | * it under the terms of the GNU General Public License as published by | ||
809 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
810 | 7 | * (at your option) any later version. | ||
811 | 8 | * | ||
812 | 9 | * This program is distributed in the hope that it will be useful, | ||
813 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
814 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
815 | 12 | * GNU General Public License for more details. | ||
816 | 13 | * | ||
817 | 14 | * You should have received a copy of the GNU General Public License | ||
818 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
819 | 16 | */ | ||
820 | 17 | |||
821 | 18 | #ifndef VERIFYPN_LTLTOBUCHI_H | ||
822 | 19 | #define VERIFYPN_LTLTOBUCHI_H | ||
823 | 20 | |||
824 | 21 | #include "PetriParse/QueryParser.h" | ||
825 | 22 | #include "PetriEngine/PQL/QueryPrinter.h" | ||
826 | 23 | |||
827 | 24 | #include <iostream> | ||
828 | 25 | #include <string> | ||
829 | 26 | |||
830 | 27 | #include <spot/tl/formula.hh> | ||
831 | 28 | |||
832 | 29 | namespace LTL { | ||
833 | 30 | struct AtomicProposition { | ||
834 | 31 | PetriEngine::PQL::Condition_ptr expression; | ||
835 | 32 | std::string text; | ||
836 | 33 | }; | ||
837 | 34 | |||
838 | 35 | using APInfo = std::vector<AtomicProposition>; | ||
839 | 36 | std::string toSpotFormat(const QueryItem &query); | ||
840 | 37 | void toSpotFormat(const QueryItem &query, std::ostream &os); | ||
841 | 38 | std::pair<spot::formula, APInfo> to_spot_formula(const PetriEngine::PQL::Condition_ptr& query); | ||
842 | 39 | |||
843 | 40 | class BuchiSuccessorGenerator; | ||
844 | 41 | BuchiSuccessorGenerator makeBuchiAutomaton(const PetriEngine::PQL::Condition_ptr &query); | ||
845 | 42 | |||
846 | 43 | |||
847 | 44 | class FormulaToSpotSyntax : public PetriEngine::PQL::QueryPrinter { | ||
848 | 45 | protected: | ||
849 | 46 | void _accept(const PetriEngine::PQL::ACondition *condition) override; | ||
850 | 47 | |||
851 | 48 | void _accept(const PetriEngine::PQL::ECondition *condition) override; | ||
852 | 49 | |||
853 | 50 | void _accept(const PetriEngine::PQL::NotCondition *element) override; | ||
854 | 51 | |||
855 | 52 | void _accept(const PetriEngine::PQL::AndCondition *element) override; | ||
856 | 53 | |||
857 | 54 | void _accept(const PetriEngine::PQL::OrCondition *element) override; | ||
858 | 55 | |||
859 | 56 | void _accept(const PetriEngine::PQL::LessThanCondition *element) override; | ||
860 | 57 | |||
861 | 58 | void _accept(const PetriEngine::PQL::LessThanOrEqualCondition *element) override; | ||
862 | 59 | |||
863 | 60 | void _accept(const PetriEngine::PQL::EqualCondition *element) override; | ||
864 | 61 | |||
865 | 62 | void _accept(const PetriEngine::PQL::NotEqualCondition *element) override; | ||
866 | 63 | |||
867 | 64 | void _accept(const PetriEngine::PQL::UnfoldedFireableCondition *element) override; | ||
868 | 65 | |||
869 | 66 | void _accept(const PetriEngine::PQL::FireableCondition *element) override; | ||
870 | 67 | |||
871 | 68 | void _accept(const PetriEngine::PQL::BooleanCondition *element) override; | ||
872 | 69 | |||
873 | 70 | void _accept(const PetriEngine::PQL::LiteralExpr *element) override; | ||
874 | 71 | |||
875 | 72 | void _accept(const PetriEngine::PQL::PlusExpr *element) override; | ||
876 | 73 | |||
877 | 74 | void _accept(const PetriEngine::PQL::MultiplyExpr *element) override; | ||
878 | 75 | |||
879 | 76 | void _accept(const PetriEngine::PQL::MinusExpr *element) override; | ||
880 | 77 | |||
881 | 78 | void _accept(const PetriEngine::PQL::SubtractExpr *element) override; | ||
882 | 79 | |||
883 | 80 | void _accept(const PetriEngine::PQL::IdentifierExpr *element) override; | ||
884 | 81 | |||
885 | 82 | void _accept(const PetriEngine::PQL::CompareConjunction *element) override; | ||
886 | 83 | |||
887 | 84 | public: | ||
888 | 85 | |||
889 | 86 | explicit FormulaToSpotSyntax(std::ostream &os = std::cout) | ||
890 | 87 | : PetriEngine::PQL::QueryPrinter(os), compress(true) {} | ||
891 | 88 | |||
892 | 89 | auto begin() const { | ||
893 | 90 | return std::begin(ap_info); | ||
894 | 91 | } | ||
895 | 92 | |||
896 | 93 | auto end() const { | ||
897 | 94 | return std::end(ap_info); | ||
898 | 95 | } | ||
899 | 96 | |||
900 | 97 | const APInfo &apInfo() const { | ||
901 | 98 | return ap_info; | ||
902 | 99 | } | ||
903 | 100 | |||
904 | 101 | private: | ||
905 | 102 | APInfo ap_info; | ||
906 | 103 | bool is_quoted = false; | ||
907 | 104 | bool compress; | ||
908 | 105 | |||
909 | 106 | void make_atomic_prop(const PetriEngine::PQL::Condition_constptr &element) | ||
910 | 107 | { | ||
911 | 108 | auto cond = | ||
912 | 109 | const_cast<PetriEngine::PQL::Condition *>(element.get())->shared_from_this(); | ||
913 | 110 | std::stringstream ss; | ||
914 | 111 | ss << "\""; | ||
915 | 112 | if (compress) { | ||
916 | 113 | // FIXME Very naive; this completely removes APs being in multiple places in the query, | ||
917 | 114 | // leading to some query not being answered as is. The net gain is large in the firebaility category, | ||
918 | 115 | // but ideally it would be possible to make a smarter approach that looks at previously stored APs | ||
919 | 116 | // and efficiently checks for repeat APs such that we can reuse APs. | ||
920 | 117 | ss << ap_info.size(); | ||
921 | 118 | } | ||
922 | 119 | else { | ||
923 | 120 | PetriEngine::PQL::QueryPrinter _printer{ss}; | ||
924 | 121 | cond->visit(_printer); | ||
925 | 122 | } | ||
926 | 123 | ss << "\""; | ||
927 | 124 | os << ss.str(); | ||
928 | 125 | ap_info.push_back(AtomicProposition{cond, ss.str().substr(1, ss.str().size() - 2)}); | ||
929 | 126 | } | ||
930 | 127 | }; | ||
931 | 128 | |||
932 | 129 | } | ||
933 | 130 | |||
934 | 131 | #endif //VERIFYPN_LTLTOBUCHI_H | ||
935 | 0 | 132 | ||
936 | === added file 'include/LTL/LTLValidator.h' | |||
937 | --- include/LTL/LTLValidator.h 1970-01-01 00:00:00 +0000 | |||
938 | +++ include/LTL/LTLValidator.h 2021-04-02 18:07:40 +0000 | |||
939 | @@ -0,0 +1,201 @@ | |||
940 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
941 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
942 | 3 | * | ||
943 | 4 | * This program is free software: you can redistribute it and/or modify | ||
944 | 5 | * it under the terms of the GNU General Public License as published by | ||
945 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
946 | 7 | * (at your option) any later version. | ||
947 | 8 | * | ||
948 | 9 | * This program is distributed in the hope that it will be useful, | ||
949 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
950 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
951 | 12 | * GNU General Public License for more details. | ||
952 | 13 | * | ||
953 | 14 | * You should have received a copy of the GNU General Public License | ||
954 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
955 | 16 | */ | ||
956 | 17 | |||
957 | 18 | #ifndef VERIFYPN_LTLVALIDATOR_H | ||
958 | 19 | #define VERIFYPN_LTLVALIDATOR_H | ||
959 | 20 | |||
960 | 21 | #include "PetriEngine/PQL/Visitor.h" | ||
961 | 22 | |||
962 | 23 | namespace LTL { | ||
963 | 24 | using namespace PetriEngine::PQL; | ||
964 | 25 | class LTLValidator : public PetriEngine::PQL::Visitor { | ||
965 | 26 | public: | ||
966 | 27 | bool bad() const { return _bad; } | ||
967 | 28 | |||
968 | 29 | operator bool() const { return !bad(); } | ||
969 | 30 | |||
970 | 31 | bool isLTL(const Condition_ptr& condition) { | ||
971 | 32 | std::shared_ptr<SimpleQuantifierCondition> quantifierCondition; | ||
972 | 33 | if ((quantifierCondition = std::dynamic_pointer_cast<ACondition>(condition)) != nullptr || | ||
973 | 34 | (quantifierCondition = std::dynamic_pointer_cast<ECondition>(condition)) != nullptr ){ | ||
974 | 35 | (*quantifierCondition)[0]->visit(*this); | ||
975 | 36 | } else { | ||
976 | 37 | condition->visit(*this); | ||
977 | 38 | } | ||
978 | 39 | return !bad(); | ||
979 | 40 | } | ||
980 | 41 | |||
981 | 42 | protected: | ||
982 | 43 | |||
983 | 44 | void _visitNary(const LogicalCondition *condition) { | ||
984 | 45 | for (const auto &cond : *condition) { | ||
985 | 46 | cond->visit(*this); | ||
986 | 47 | } | ||
987 | 48 | }; | ||
988 | 49 | |||
989 | 50 | void _accept(const PetriEngine::PQL::EFCondition *condition) override { | ||
990 | 51 | setBad(); | ||
991 | 52 | std::cerr << "found EFCondition" << std::endl; | ||
992 | 53 | } | ||
993 | 54 | |||
994 | 55 | void _accept(const PetriEngine::PQL::EGCondition *condition) override { | ||
995 | 56 | setBad(); | ||
996 | 57 | std::cerr << "found EGCondition" << std::endl; | ||
997 | 58 | } | ||
998 | 59 | |||
999 | 60 | void _accept(const PetriEngine::PQL::AGCondition *condition) override { | ||
1000 | 61 | setBad(); | ||
1001 | 62 | std::cerr << "found AGCondition" << std::endl; | ||
1002 | 63 | } | ||
1003 | 64 | |||
1004 | 65 | void _accept(const PetriEngine::PQL::AFCondition *condition) override { | ||
1005 | 66 | setBad(); | ||
1006 | 67 | std::cerr << "found AFCondition" << std::endl; | ||
1007 | 68 | } | ||
1008 | 69 | |||
1009 | 70 | void _accept(const PetriEngine::PQL::EXCondition *condition) override { | ||
1010 | 71 | setBad(); | ||
1011 | 72 | std::cerr << "found EXCondition" << std::endl; | ||
1012 | 73 | } | ||
1013 | 74 | |||
1014 | 75 | void _accept(const PetriEngine::PQL::AXCondition *condition) override { | ||
1015 | 76 | setBad(); | ||
1016 | 77 | std::cerr << "found AXCondition" << std::endl; | ||
1017 | 78 | } | ||
1018 | 79 | |||
1019 | 80 | void _accept(const PetriEngine::PQL::EUCondition *condition) override { | ||
1020 | 81 | setBad(); | ||
1021 | 82 | std::cerr << "found EUCondition" << std::endl; | ||
1022 | 83 | } | ||
1023 | 84 | |||
1024 | 85 | void _accept(const PetriEngine::PQL::AUCondition *condition) override { | ||
1025 | 86 | setBad(); | ||
1026 | 87 | std::cerr << "found AUCondition" << std::endl; | ||
1027 | 88 | } | ||
1028 | 89 | |||
1029 | 90 | void _accept(const PetriEngine::PQL::ACondition *condition) override { | ||
1030 | 91 | setBad(); | ||
1031 | 92 | } | ||
1032 | 93 | |||
1033 | 94 | void _accept(const PetriEngine::PQL::ECondition *condition) override { | ||
1034 | 95 | setBad(); | ||
1035 | 96 | } | ||
1036 | 97 | |||
1037 | 98 | void _accept(const PetriEngine::PQL::NotCondition *element) override { | ||
1038 | 99 | (*element)[0]->visit(*this); | ||
1039 | 100 | } | ||
1040 | 101 | |||
1041 | 102 | void _accept(const PetriEngine::PQL::AndCondition *element) override { | ||
1042 | 103 | _visitNary(element); | ||
1043 | 104 | } | ||
1044 | 105 | |||
1045 | 106 | void _accept(const PetriEngine::PQL::OrCondition *element) override { | ||
1046 | 107 | _visitNary(element); | ||
1047 | 108 | } | ||
1048 | 109 | |||
1049 | 110 | void _accept(const PetriEngine::PQL::LessThanCondition *element) override { | ||
1050 | 111 | (*element)[0]->visit(*this); | ||
1051 | 112 | (*element)[1]->visit(*this); | ||
1052 | 113 | } | ||
1053 | 114 | |||
1054 | 115 | void _accept(const PetriEngine::PQL::LessThanOrEqualCondition *element) override { | ||
1055 | 116 | (*element)[0]->visit(*this); | ||
1056 | 117 | (*element)[1]->visit(*this); | ||
1057 | 118 | } | ||
1058 | 119 | |||
1059 | 120 | void _accept(const PetriEngine::PQL::EqualCondition *element) override { | ||
1060 | 121 | (*element)[0]->visit(*this); | ||
1061 | 122 | (*element)[1]->visit(*this); | ||
1062 | 123 | } | ||
1063 | 124 | |||
1064 | 125 | void _accept(const PetriEngine::PQL::NotEqualCondition *element) override { | ||
1065 | 126 | (*element)[0]->visit(*this); | ||
1066 | 127 | (*element)[1]->visit(*this); | ||
1067 | 128 | } | ||
1068 | 129 | |||
1069 | 130 | void _accept(const PetriEngine::PQL::DeadlockCondition *element) override { | ||
1070 | 131 | |||
1071 | 132 | } | ||
1072 | 133 | |||
1073 | 134 | void _accept(const PetriEngine::PQL::CompareConjunction *element) override { | ||
1074 | 135 | |||
1075 | 136 | } | ||
1076 | 137 | |||
1077 | 138 | void _accept(const PetriEngine::PQL::UnfoldedUpperBoundsCondition *element) override { | ||
1078 | 139 | |||
1079 | 140 | } | ||
1080 | 141 | |||
1081 | 142 | void _accept(const PetriEngine::PQL::GCondition *condition) override { | ||
1082 | 143 | (*condition)[0]->visit(*this); | ||
1083 | 144 | } | ||
1084 | 145 | |||
1085 | 146 | void _accept(const PetriEngine::PQL::FCondition *condition) override { | ||
1086 | 147 | (*condition)[0]->visit(*this); | ||
1087 | 148 | } | ||
1088 | 149 | |||
1089 | 150 | void _accept(const PetriEngine::PQL::XCondition *condition) override { | ||
1090 | 151 | (*condition)[0]->visit(*this); | ||
1091 | 152 | } | ||
1092 | 153 | |||
1093 | 154 | void _accept(const PetriEngine::PQL::UntilCondition *condition) override { | ||
1094 | 155 | (*condition)[0]->visit(*this); | ||
1095 | 156 | } | ||
1096 | 157 | |||
1097 | 158 | void _accept(const PetriEngine::PQL::UnfoldedFireableCondition *element) override { | ||
1098 | 159 | } | ||
1099 | 160 | |||
1100 | 161 | void _accept(const PetriEngine::PQL::FireableCondition *element) override { | ||
1101 | 162 | } | ||
1102 | 163 | |||
1103 | 164 | void _accept(const PetriEngine::PQL::UpperBoundsCondition *element) override { | ||
1104 | 165 | } | ||
1105 | 166 | |||
1106 | 167 | void _accept(const PetriEngine::PQL::LivenessCondition *element) override { | ||
1107 | 168 | } | ||
1108 | 169 | |||
1109 | 170 | void _accept(const PetriEngine::PQL::KSafeCondition *element) override { | ||
1110 | 171 | } | ||
1111 | 172 | |||
1112 | 173 | void _accept(const PetriEngine::PQL::QuasiLivenessCondition *element) override { | ||
1113 | 174 | } | ||
1114 | 175 | |||
1115 | 176 | void _accept(const PetriEngine::PQL::StableMarkingCondition *element) override { | ||
1116 | 177 | } | ||
1117 | 178 | |||
1118 | 179 | void _accept(const PetriEngine::PQL::BooleanCondition *element) override {} | ||
1119 | 180 | |||
1120 | 181 | void _accept(const PetriEngine::PQL::UnfoldedIdentifierExpr *element) override {} | ||
1121 | 182 | |||
1122 | 183 | void _accept(const PetriEngine::PQL::LiteralExpr *element) override {} | ||
1123 | 184 | |||
1124 | 185 | void _accept(const PetriEngine::PQL::PlusExpr *element) override {} | ||
1125 | 186 | |||
1126 | 187 | void _accept(const PetriEngine::PQL::MultiplyExpr *element) override {} | ||
1127 | 188 | |||
1128 | 189 | void _accept(const PetriEngine::PQL::MinusExpr *element) override {} | ||
1129 | 190 | |||
1130 | 191 | void _accept(const PetriEngine::PQL::SubtractExpr *element) override {} | ||
1131 | 192 | |||
1132 | 193 | void _accept(const PetriEngine::PQL::IdentifierExpr *element) override {} | ||
1133 | 194 | |||
1134 | 195 | private: | ||
1135 | 196 | bool _bad = false; | ||
1136 | 197 | |||
1137 | 198 | void setBad() { _bad = true; } | ||
1138 | 199 | }; | ||
1139 | 200 | } | ||
1140 | 201 | #endif //VERIFYPN_LTLVALIDATOR_H | ||
1141 | 0 | 202 | ||
1142 | === added file 'include/LTL/ProductSuccessorGenerator.h' | |||
1143 | --- include/LTL/ProductSuccessorGenerator.h 1970-01-01 00:00:00 +0000 | |||
1144 | +++ include/LTL/ProductSuccessorGenerator.h 2021-04-02 18:07:40 +0000 | |||
1145 | @@ -0,0 +1,146 @@ | |||
1146 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
1147 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
1148 | 3 | * | ||
1149 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1150 | 5 | * it under the terms of the GNU General Public License as published by | ||
1151 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
1152 | 7 | * (at your option) any later version. | ||
1153 | 8 | * | ||
1154 | 9 | * This program is distributed in the hope that it will be useful, | ||
1155 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1156 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1157 | 12 | * GNU General Public License for more details. | ||
1158 | 13 | * | ||
1159 | 14 | * You should have received a copy of the GNU General Public License | ||
1160 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1161 | 16 | */ | ||
1162 | 17 | |||
1163 | 18 | #ifndef VERIFYPN_PRODUCTSUCCESSORGENERATOR_H | ||
1164 | 19 | #define VERIFYPN_PRODUCTSUCCESSORGENERATOR_H | ||
1165 | 20 | |||
1166 | 21 | #include "PetriEngine/SuccessorGenerator.h" | ||
1167 | 22 | #include "PetriEngine/PQL/PQL.h" | ||
1168 | 23 | #include "LTL/Structures/ProductState.h" | ||
1169 | 24 | #include "LTL/BuchiSuccessorGenerator.h" | ||
1170 | 25 | #include "LTL/LTLToBuchi.h" | ||
1171 | 26 | |||
1172 | 27 | |||
1173 | 28 | namespace LTL { | ||
1174 | 29 | /** | ||
1175 | 30 | * type holding sufficient information to resume successor generation for a state from a given point. | ||
1176 | 31 | */ | ||
1177 | 32 | struct successor_info { | ||
1178 | 33 | uint32_t pcounter; | ||
1179 | 34 | uint32_t tcounter; | ||
1180 | 35 | size_t buchi_state; | ||
1181 | 36 | size_t last_state; | ||
1182 | 37 | |||
1183 | 38 | friend bool operator==(const successor_info &lhs, const successor_info &rhs) { | ||
1184 | 39 | return lhs.pcounter == rhs.pcounter && | ||
1185 | 40 | lhs.tcounter == rhs.tcounter && | ||
1186 | 41 | lhs.buchi_state == rhs.buchi_state && | ||
1187 | 42 | lhs.last_state == rhs.last_state; | ||
1188 | 43 | } | ||
1189 | 44 | |||
1190 | 45 | friend bool operator!=(const successor_info &lhs, const successor_info &rhs) { | ||
1191 | 46 | return !(rhs == lhs); | ||
1192 | 47 | } | ||
1193 | 48 | |||
1194 | 49 | inline bool has_pcounter() const { | ||
1195 | 50 | return pcounter != NoPCounter; | ||
1196 | 51 | } | ||
1197 | 52 | |||
1198 | 53 | inline bool has_tcounter() const { | ||
1199 | 54 | return tcounter != NoTCounter; | ||
1200 | 55 | } | ||
1201 | 56 | |||
1202 | 57 | inline bool has_buchistate() const { | ||
1203 | 58 | return buchi_state != NoBuchiState; | ||
1204 | 59 | } | ||
1205 | 60 | |||
1206 | 61 | inline bool has_prev_state() const { | ||
1207 | 62 | return last_state != NoLastState; | ||
1208 | 63 | } | ||
1209 | 64 | |||
1210 | 65 | static constexpr auto NoPCounter = 0; | ||
1211 | 66 | static constexpr auto NoTCounter = std::numeric_limits<uint32_t>::max(); | ||
1212 | 67 | static constexpr auto NoBuchiState = std::numeric_limits<size_t>::max(); | ||
1213 | 68 | static constexpr auto NoLastState = std::numeric_limits<size_t>::max(); | ||
1214 | 69 | }; | ||
1215 | 70 | |||
1216 | 71 | constexpr successor_info initial_suc_info{ | ||
1217 | 72 | successor_info::NoPCounter, | ||
1218 | 73 | successor_info::NoTCounter, | ||
1219 | 74 | successor_info::NoBuchiState, | ||
1220 | 75 | successor_info::NoLastState | ||
1221 | 76 | }; | ||
1222 | 77 | |||
1223 | 78 | class ProductSuccessorGenerator : public PetriEngine::SuccessorGenerator { | ||
1224 | 79 | public: | ||
1225 | 80 | |||
1226 | 81 | ProductSuccessorGenerator(const PetriEngine::PetriNet &net, | ||
1227 | 82 | const PetriEngine::PQL::Condition_ptr &cond) | ||
1228 | 83 | : PetriEngine::SuccessorGenerator(net), buchi(makeBuchiAutomaton(cond)) {} | ||
1229 | 84 | |||
1230 | 85 | [[nodiscard]] size_t initial_buchi_state() const { return buchi.initial_state_number(); }; | ||
1231 | 86 | |||
1232 | 87 | void prepare(const LTL::Structures::ProductState *state); | ||
1233 | 88 | |||
1234 | 89 | bool next(LTL::Structures::ProductState &state); | ||
1235 | 90 | |||
1236 | 91 | bool isAccepting(const LTL::Structures::ProductState &state); | ||
1237 | 92 | |||
1238 | 93 | void makeInitialState(std::vector<LTL::Structures::ProductState> &states) { | ||
1239 | 94 | auto buf = new PetriEngine::MarkVal[_net.numberOfPlaces() + 1]; | ||
1240 | 95 | std::copy(_net.initial(), _net.initial() + _net.numberOfPlaces(), buf); | ||
1241 | 96 | buf[_net.numberOfPlaces()] = 0; | ||
1242 | 97 | LTL::Structures::ProductState state; | ||
1243 | 98 | state.setMarking(buf, _net.numberOfPlaces()); | ||
1244 | 99 | state.setBuchiState(initial_buchi_state()); | ||
1245 | 100 | buchi.prepare(state.getBuchiState()); | ||
1246 | 101 | while (next_buchi_succ(state)) { | ||
1247 | 102 | states.emplace_back(); | ||
1248 | 103 | states.back().setMarking(new PetriEngine::MarkVal[_net.numberOfPlaces() + 1], _net.numberOfPlaces()); | ||
1249 | 104 | std::copy(state.marking(), state.marking() + _net.numberOfPlaces(), states.back().marking()); | ||
1250 | 105 | states.back().setBuchiState(state.getBuchiState()); | ||
1251 | 106 | } | ||
1252 | 107 | } | ||
1253 | 108 | |||
1254 | 109 | [[nodiscard]] bool isInitialState(const LTL::Structures::ProductState &state) const { | ||
1255 | 110 | return state.markingEqual(_net.initial()); | ||
1256 | 111 | } | ||
1257 | 112 | |||
1258 | 113 | /** | ||
1259 | 114 | * prepare a state for successor generation, starting from specific point in iteration | ||
1260 | 115 | * @param state the source state to generate successors from | ||
1261 | 116 | * @param sucinfo the point in the iteration to start from, as returned by `next`. | ||
1262 | 117 | */ | ||
1263 | 118 | void prepare(const LTL::Structures::ProductState *state, const successor_info &sucinfo); | ||
1264 | 119 | |||
1265 | 120 | /** | ||
1266 | 121 | * compute the next successor from the last state that was sent to `prepare`. | ||
1267 | 122 | * @param[out] state the state to write | ||
1268 | 123 | * @param[out] sucinfo checkpoint information from which iteration can later be resumed. | ||
1269 | 124 | * @return `true` if a successor was successfully generated, `false` otherwise. | ||
1270 | 125 | * @warning do not use the same State for both prepare and next, this will cause wildly incorrect behaviour! | ||
1271 | 126 | */ | ||
1272 | 127 | bool next(Structures::ProductState &state, successor_info &sucinfo); | ||
1273 | 128 | |||
1274 | 129 | [[nodiscard]] bool is_weak() const { | ||
1275 | 130 | return buchi.is_weak(); | ||
1276 | 131 | } | ||
1277 | 132 | |||
1278 | 133 | private: | ||
1279 | 134 | BuchiSuccessorGenerator buchi; | ||
1280 | 135 | bdd cond; | ||
1281 | 136 | size_t buchi_parent; | ||
1282 | 137 | bool fresh_marking = true; | ||
1283 | 138 | |||
1284 | 139 | bool guard_valid(const PetriEngine::Structures::State &state, bdd bdd); | ||
1285 | 140 | |||
1286 | 141 | bool next_buchi_succ(LTL::Structures::ProductState &state); | ||
1287 | 142 | }; | ||
1288 | 143 | |||
1289 | 144 | } | ||
1290 | 145 | |||
1291 | 146 | #endif //VERIFYPN_PRODUCTSUCCESSORGENERATOR_H | ||
1292 | 0 | 147 | ||
1293 | === added directory 'include/LTL/Simplification' | |||
1294 | === added file 'include/LTL/Simplification/SpotToPQL.h' | |||
1295 | --- include/LTL/Simplification/SpotToPQL.h 1970-01-01 00:00:00 +0000 | |||
1296 | +++ include/LTL/Simplification/SpotToPQL.h 2021-04-02 18:07:40 +0000 | |||
1297 | @@ -0,0 +1,42 @@ | |||
1298 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
1299 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
1300 | 3 | * | ||
1301 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1302 | 5 | * it under the terms of the GNU General Public License as published by | ||
1303 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
1304 | 7 | * (at your option) any later version. | ||
1305 | 8 | * | ||
1306 | 9 | * This program is distributed in the hope that it will be useful, | ||
1307 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1308 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1309 | 12 | * GNU General Public License for more details. | ||
1310 | 13 | * | ||
1311 | 14 | * You should have received a copy of the GNU General Public License | ||
1312 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1313 | 16 | */ | ||
1314 | 17 | |||
1315 | 18 | #ifndef VERIFYPN_SPOTTOPQL_H | ||
1316 | 19 | #define VERIFYPN_SPOTTOPQL_H | ||
1317 | 20 | |||
1318 | 21 | #include "PetriEngine/PQL/Expressions.h" | ||
1319 | 22 | #include "LTL/LTLToBuchi.h" | ||
1320 | 23 | #include <spot/tl/formula.hh> | ||
1321 | 24 | |||
1322 | 25 | namespace LTL { | ||
1323 | 26 | /** | ||
1324 | 27 | * Transform a Spot formula back into the PQL expression tree form. | ||
1325 | 28 | * @param formula The formula to translate to PQL | ||
1326 | 29 | * @param apinfo List of atomic propositions in the formula. This should have been created by {@link LTL::to_spot_formula}. | ||
1327 | 30 | * @return A PQL formula equivalent to the passed spot formula. | ||
1328 | 31 | */ | ||
1329 | 32 | PetriEngine::PQL::Condition_ptr toPQL(const spot::formula &formula, const APInfo &apinfo); | ||
1330 | 33 | |||
1331 | 34 | /** | ||
1332 | 35 | * Simplify an LTL formula using Spot's formula simplifier. Throws if formula is not valid LTL. | ||
1333 | 36 | * @param formula The formula to simplify. | ||
1334 | 37 | * @return the simplified formula. | ||
1335 | 38 | */ | ||
1336 | 39 | PetriEngine::PQL::Condition_ptr simplify(const PetriEngine::PQL::Condition_ptr &formula); | ||
1337 | 40 | } | ||
1338 | 41 | |||
1339 | 42 | #endif // VERIFYPN_SPOTTOPQL_H | ||
1340 | 0 | 43 | ||
1341 | === added directory 'include/LTL/Structures' | |||
1342 | === added file 'include/LTL/Structures/BuchiAutomaton.h' | |||
1343 | --- include/LTL/Structures/BuchiAutomaton.h 1970-01-01 00:00:00 +0000 | |||
1344 | +++ include/LTL/Structures/BuchiAutomaton.h 2021-04-02 18:07:40 +0000 | |||
1345 | @@ -0,0 +1,31 @@ | |||
1346 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
1347 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
1348 | 3 | * | ||
1349 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1350 | 5 | * it under the terms of the GNU General Public License as published by | ||
1351 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
1352 | 7 | * (at your option) any later version. | ||
1353 | 8 | * | ||
1354 | 9 | * This program is distributed in the hope that it will be useful, | ||
1355 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1356 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1357 | 12 | * GNU General Public License for more details. | ||
1358 | 13 | * | ||
1359 | 14 | * You should have received a copy of the GNU General Public License | ||
1360 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1361 | 16 | */ | ||
1362 | 17 | |||
1363 | 18 | #ifndef VERIFYPN_BUCHIAUTOMATON_H | ||
1364 | 19 | #define VERIFYPN_BUCHIAUTOMATON_H | ||
1365 | 20 | |||
1366 | 21 | #include "LTL/LTLToBuchi.h" | ||
1367 | 22 | #include <spot/twa/twagraph.hh> | ||
1368 | 23 | |||
1369 | 24 | namespace LTL::Structures { | ||
1370 | 25 | struct BuchiAutomaton { | ||
1371 | 26 | spot::twa_graph_ptr buchi; | ||
1372 | 27 | const std::unordered_map<int, AtomicProposition> ap_info; | ||
1373 | 28 | }; | ||
1374 | 29 | } | ||
1375 | 30 | |||
1376 | 31 | #endif //VERIFYPN_BUCHIAUTOMATON_H | ||
1377 | 0 | 32 | ||
1378 | === added file 'include/LTL/Structures/ProductState.h' | |||
1379 | --- include/LTL/Structures/ProductState.h 1970-01-01 00:00:00 +0000 | |||
1380 | +++ include/LTL/Structures/ProductState.h 2021-04-02 18:07:40 +0000 | |||
1381 | @@ -0,0 +1,81 @@ | |||
1382 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
1383 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
1384 | 3 | * | ||
1385 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1386 | 5 | * it under the terms of the GNU General Public License as published by | ||
1387 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
1388 | 7 | * (at your option) any later version. | ||
1389 | 8 | * | ||
1390 | 9 | * This program is distributed in the hope that it will be useful, | ||
1391 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1392 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1393 | 12 | * GNU General Public License for more details. | ||
1394 | 13 | * | ||
1395 | 14 | * You should have received a copy of the GNU General Public License | ||
1396 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1397 | 16 | */ | ||
1398 | 17 | |||
1399 | 18 | #ifndef VERIFYPN_PRODUCTSTATE_H | ||
1400 | 19 | #define VERIFYPN_PRODUCTSTATE_H | ||
1401 | 20 | |||
1402 | 21 | #include "PetriEngine/Structures/State.h" | ||
1403 | 22 | |||
1404 | 23 | namespace LTL { | ||
1405 | 24 | class ProductSuccessorGenerator; | ||
1406 | 25 | } | ||
1407 | 26 | namespace LTL::Structures { | ||
1408 | 27 | /** | ||
1409 | 28 | * State on the form (M, q) for marking M and NBA state q. | ||
1410 | 29 | * Represented as array of size nplaces + 1, where the last element is the number | ||
1411 | 30 | * of NBA state q, and the first nplaces elements are the actual marking. | ||
1412 | 31 | */ | ||
1413 | 32 | class ProductState : public PetriEngine::Structures::State { | ||
1414 | 33 | public: | ||
1415 | 34 | ProductState() : PetriEngine::Structures::State() {} | ||
1416 | 35 | |||
1417 | 36 | void setMarking(PetriEngine::MarkVal* marking, size_t nplaces) | ||
1418 | 37 | { | ||
1419 | 38 | State::setMarking(marking); | ||
1420 | 39 | // because zero-indexing | ||
1421 | 40 | buchi_state_idx = nplaces; | ||
1422 | 41 | } | ||
1423 | 42 | |||
1424 | 43 | //TODO override equality operators to handle both marking and NBA state | ||
1425 | 44 | size_t getBuchiState() const { | ||
1426 | 45 | return marking()[buchi_state_idx]; | ||
1427 | 46 | } | ||
1428 | 47 | |||
1429 | 48 | void setBuchiState(size_t state) { | ||
1430 | 49 | marking()[buchi_state_idx] = state; | ||
1431 | 50 | } | ||
1432 | 51 | |||
1433 | 52 | [[nodiscard]] bool markingEqual(const PetriEngine::MarkVal *rhs) const { | ||
1434 | 53 | for (size_t i = 0; i < buchi_state_idx; ++i) { | ||
1435 | 54 | if (marking()[i] != rhs[i]) { | ||
1436 | 55 | return false; | ||
1437 | 56 | } | ||
1438 | 57 | } | ||
1439 | 58 | return true; | ||
1440 | 59 | } | ||
1441 | 60 | |||
1442 | 61 | bool operator==(const ProductState &rhs) const { | ||
1443 | 62 | for (size_t i = 0; i <= buchi_state_idx; ++i) { | ||
1444 | 63 | if (marking()[i] != rhs.marking()[i]) { | ||
1445 | 64 | return false; | ||
1446 | 65 | } | ||
1447 | 66 | } | ||
1448 | 67 | return true; | ||
1449 | 68 | } | ||
1450 | 69 | |||
1451 | 70 | size_t size() const { return buchi_state_idx + 1; } | ||
1452 | 71 | |||
1453 | 72 | bool operator!=(const ProductState &rhs) const { | ||
1454 | 73 | return !(rhs == *this); | ||
1455 | 74 | } | ||
1456 | 75 | private: | ||
1457 | 76 | friend class LTL::ProductSuccessorGenerator; | ||
1458 | 77 | size_t buchi_state_idx; | ||
1459 | 78 | }; | ||
1460 | 79 | } | ||
1461 | 80 | |||
1462 | 81 | #endif //VERIFYPN_PRODUCTSTATE_H | ||
1463 | 0 | 82 | ||
1464 | === added file 'include/LTL/Structures/ProductStateFactory.h' | |||
1465 | --- include/LTL/Structures/ProductStateFactory.h 1970-01-01 00:00:00 +0000 | |||
1466 | +++ include/LTL/Structures/ProductStateFactory.h 2021-04-02 18:07:40 +0000 | |||
1467 | @@ -0,0 +1,46 @@ | |||
1468 | 1 | /* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>, | ||
1469 | 2 | * Simon M. Virenfeldt <simon@simwir.dk> | ||
1470 | 3 | * | ||
1471 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1472 | 5 | * it under the terms of the GNU General Public License as published by | ||
1473 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
1474 | 7 | * (at your option) any later version. | ||
1475 | 8 | * | ||
1476 | 9 | * This program is distributed in the hope that it will be useful, | ||
1477 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1478 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1479 | 12 | * GNU General Public License for more details. | ||
1480 | 13 | * | ||
1481 | 14 | * You should have received a copy of the GNU General Public License | ||
1482 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1483 | 16 | */ | ||
1484 | 17 | |||
1485 | 18 | #ifndef VERIFYPN_PRODUCTSTATEFACTORY_H | ||
1486 | 19 | #define VERIFYPN_PRODUCTSTATEFACTORY_H | ||
1487 | 20 | |||
1488 | 21 | #include "LTL/Structures/ProductState.h" | ||
1489 | 22 | |||
1490 | 23 | #include <memory> | ||
1491 | 24 | |||
1492 | 25 | namespace LTL::Structures{ | ||
1493 | 26 | class ProductStateFactory { | ||
1494 | 27 | public: | ||
1495 | 28 | ProductStateFactory(const PetriEngine::PetriNet &net, size_t initial_buchi_state) | ||
1496 | 29 | : net(net), buchi_init(initial_buchi_state) {} | ||
1497 | 30 | |||
1498 | 31 | ProductState newState() { | ||
1499 | 32 | auto buf = new PetriEngine::MarkVal[net.numberOfPlaces()+1]; | ||
1500 | 33 | std::copy(net.initial(), net.initial() + net.numberOfPlaces(), buf); | ||
1501 | 34 | buf[net.numberOfPlaces()] = 0; | ||
1502 | 35 | ProductState state; | ||
1503 | 36 | state.setMarking(buf, net.numberOfPlaces()); | ||
1504 | 37 | state.setBuchiState(buchi_init); | ||
1505 | 38 | return state; | ||
1506 | 39 | } | ||
1507 | 40 | |||
1508 | 41 | private: | ||
1509 | 42 | const PetriEngine::PetriNet &net; | ||
1510 | 43 | const size_t buchi_init; | ||
1511 | 44 | }; | ||
1512 | 45 | } | ||
1513 | 46 | #endif //VERIFYPN_PRODUCTSTATEFACTORY_H | ||
1514 | 0 | 47 | ||
1515 | === added file 'include/PetriEngine/Colored/ArcIntervals.h' | |||
1516 | --- include/PetriEngine/Colored/ArcIntervals.h 1970-01-01 00:00:00 +0000 | |||
1517 | +++ include/PetriEngine/Colored/ArcIntervals.h 2021-04-02 18:07:40 +0000 | |||
1518 | @@ -0,0 +1,108 @@ | |||
1519 | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, | ||
1520 | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, | ||
1521 | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> | ||
1522 | 4 | * | ||
1523 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1524 | 6 | * it under the terms of the GNU General Public License as published by | ||
1525 | 7 | * the Free Software Foundation, either version 3 of the License, or | ||
1526 | 8 | * (at your option) any later version. | ||
1527 | 9 | * | ||
1528 | 10 | * This program is distributed in the hope that it will be useful, | ||
1529 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1530 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1531 | 13 | * GNU General Public License for more details. | ||
1532 | 14 | * | ||
1533 | 15 | * You should have received a copy of the GNU General Public License | ||
1534 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1535 | 17 | */ | ||
1536 | 18 | |||
1537 | 19 | #ifndef ARCINTERVALS_H | ||
1538 | 20 | #define ARCINTERVALS_H | ||
1539 | 21 | |||
1540 | 22 | #include "Colors.h" | ||
1541 | 23 | |||
1542 | 24 | namespace PetriEngine { | ||
1543 | 25 | namespace Colored { | ||
1544 | 26 | |||
1545 | 27 | struct ArcIntervals { | ||
1546 | 28 | std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>> _varIndexModMap; | ||
1547 | 29 | std::vector<Colored::intervalTuple_t> _intervalTupleVec; | ||
1548 | 30 | Colored::ColorFixpoint * _source; | ||
1549 | 31 | |||
1550 | 32 | ~ArcIntervals() {_varIndexModMap.clear();} | ||
1551 | 33 | ArcIntervals() { | ||
1552 | 34 | } | ||
1553 | 35 | |||
1554 | 36 | ArcIntervals(Colored::ColorFixpoint * source) : _source(source){ | ||
1555 | 37 | } | ||
1556 | 38 | |||
1557 | 39 | ArcIntervals(Colored::ColorFixpoint * source, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>> varIndexModMap) : _varIndexModMap(varIndexModMap), _source(source) { | ||
1558 | 40 | }; | ||
1559 | 41 | |||
1560 | 42 | ArcIntervals(Colored::ColorFixpoint * source, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>> varIndexModMap, std::vector<Colored::intervalTuple_t> ranges) : _varIndexModMap(varIndexModMap), _intervalTupleVec(ranges), _source(source) { | ||
1561 | 43 | }; | ||
1562 | 44 | |||
1563 | 45 | size_t size() { | ||
1564 | 46 | return _intervalTupleVec.size(); | ||
1565 | 47 | } | ||
1566 | 48 | |||
1567 | 49 | Colored::intervalTuple_t& operator[] (size_t index) { | ||
1568 | 50 | return _intervalTupleVec[index]; | ||
1569 | 51 | } | ||
1570 | 52 | |||
1571 | 53 | Colored::intervalTuple_t& operator[] (int index) { | ||
1572 | 54 | return _intervalTupleVec[index]; | ||
1573 | 55 | } | ||
1574 | 56 | |||
1575 | 57 | Colored::intervalTuple_t& operator[] (uint32_t index) { | ||
1576 | 58 | assert(index < _intervalTupleVec.size()); | ||
1577 | 59 | return _intervalTupleVec[index]; | ||
1578 | 60 | } | ||
1579 | 61 | |||
1580 | 62 | Colored::intervalTuple_t& back(){ | ||
1581 | 63 | return _intervalTupleVec.back(); | ||
1582 | 64 | } | ||
1583 | 65 | |||
1584 | 66 | bool hasValidIntervals(){ | ||
1585 | 67 | for(auto intervalTuple : _intervalTupleVec){ | ||
1586 | 68 | if (intervalTuple.hasValidIntervals()){ | ||
1587 | 69 | return true; | ||
1588 | 70 | } | ||
1589 | 71 | } | ||
1590 | 72 | return false; | ||
1591 | 73 | } | ||
1592 | 74 | |||
1593 | 75 | bool containsVariable(Colored::Variable * var){ | ||
1594 | 76 | for (auto varModPair : _varIndexModMap){ | ||
1595 | 77 | if(varModPair.first == var){ | ||
1596 | 78 | return true; | ||
1597 | 79 | } | ||
1598 | 80 | } | ||
1599 | 81 | return false; | ||
1600 | 82 | } | ||
1601 | 83 | |||
1602 | 84 | std::set<const Colored::Variable *> getVariables(){ | ||
1603 | 85 | std::set<const Colored::Variable *> res; | ||
1604 | 86 | for (auto varModPair : _varIndexModMap){ | ||
1605 | 87 | res.insert(varModPair.first); | ||
1606 | 88 | } | ||
1607 | 89 | return res; | ||
1608 | 90 | } | ||
1609 | 91 | |||
1610 | 92 | void print() { | ||
1611 | 93 | std::cout << "[ "; | ||
1612 | 94 | for(auto varModifierPair : _varIndexModMap){ | ||
1613 | 95 | std::cout << "(" << varModifierPair.first->name << ", " << varModifierPair.first->colorType->productSize() << ") "; | ||
1614 | 96 | } | ||
1615 | 97 | std::cout << "]" << std::endl; | ||
1616 | 98 | for(auto intervalTuple: _intervalTupleVec){ | ||
1617 | 99 | std::cout << "--------------------------------------------------------------------" << std::endl; | ||
1618 | 100 | intervalTuple.print(); | ||
1619 | 101 | std::cout << "--------------------------------------------------------------------" << std::endl; | ||
1620 | 102 | } | ||
1621 | 103 | } | ||
1622 | 104 | }; | ||
1623 | 105 | } | ||
1624 | 106 | } | ||
1625 | 107 | |||
1626 | 108 | #endif /* INTERVALGENERATOR_H */ | ||
1627 | 0 | \ No newline at end of file | 109 | \ No newline at end of file |
1628 | 1 | 110 | ||
1629 | === added file 'include/PetriEngine/Colored/BindingGenerator.h' | |||
1630 | --- include/PetriEngine/Colored/BindingGenerator.h 1970-01-01 00:00:00 +0000 | |||
1631 | +++ include/PetriEngine/Colored/BindingGenerator.h 2021-04-02 18:07:40 +0000 | |||
1632 | @@ -0,0 +1,71 @@ | |||
1633 | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, | ||
1634 | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, | ||
1635 | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> | ||
1636 | 4 | * Andreas H. Klostergaard | ||
1637 | 5 | * | ||
1638 | 6 | * This program is free software: you can redistribute it and/or modify | ||
1639 | 7 | * it under the terms of the GNU General Public License as published by | ||
1640 | 8 | * the Free Software Foundation, either version 3 of the License, or | ||
1641 | 9 | * (at your option) any later version. | ||
1642 | 10 | * | ||
1643 | 11 | * This program is distributed in the hope that it will be useful, | ||
1644 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1645 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1646 | 14 | * GNU General Public License for more details. | ||
1647 | 15 | * | ||
1648 | 16 | * You should have received a copy of the GNU General Public License | ||
1649 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1650 | 18 | */ | ||
1651 | 19 | |||
1652 | 20 | #include <vector> | ||
1653 | 21 | #include <unordered_map> | ||
1654 | 22 | |||
1655 | 23 | #include "ColoredNetStructures.h" | ||
1656 | 24 | |||
1657 | 25 | namespace PetriEngine { | ||
1658 | 26 | |||
1659 | 27 | typedef std::unordered_map<std::string, Colored::ColorType*> ColorTypeMap; | ||
1660 | 28 | |||
1661 | 29 | class FixpointBindingGenerator { | ||
1662 | 30 | public: | ||
1663 | 31 | class Iterator { | ||
1664 | 32 | private: | ||
1665 | 33 | FixpointBindingGenerator* _generator; | ||
1666 | 34 | |||
1667 | 35 | public: | ||
1668 | 36 | Iterator(FixpointBindingGenerator* generator); | ||
1669 | 37 | |||
1670 | 38 | bool operator==(Iterator& other); | ||
1671 | 39 | bool operator!=(Iterator& other); | ||
1672 | 40 | Iterator& operator++(); | ||
1673 | 41 | const Colored::ExpressionContext::BindingMap operator++(int); | ||
1674 | 42 | Colored::ExpressionContext::BindingMap& operator*(); | ||
1675 | 43 | }; | ||
1676 | 44 | private: | ||
1677 | 45 | Colored::GuardExpression_ptr _expr; | ||
1678 | 46 | Colored::ExpressionContext::BindingMap _bindings; | ||
1679 | 47 | ColorTypeMap& _colorTypes; | ||
1680 | 48 | Colored::Transition &_transition; | ||
1681 | 49 | bool _isDone; | ||
1682 | 50 | bool _noValidBindings; | ||
1683 | 51 | uint32_t _nextIndex = 0; | ||
1684 | 52 | |||
1685 | 53 | bool eval(); | ||
1686 | 54 | |||
1687 | 55 | public: | ||
1688 | 56 | FixpointBindingGenerator(Colored::Transition& transition, | ||
1689 | 57 | ColorTypeMap& colorTypes); | ||
1690 | 58 | |||
1691 | 59 | FixpointBindingGenerator(const FixpointBindingGenerator& ) = default; | ||
1692 | 60 | |||
1693 | 61 | FixpointBindingGenerator operator= (const FixpointBindingGenerator& b) { | ||
1694 | 62 | return FixpointBindingGenerator(b); | ||
1695 | 63 | } | ||
1696 | 64 | |||
1697 | 65 | Colored::ExpressionContext::BindingMap& nextBinding(); | ||
1698 | 66 | Colored::ExpressionContext::BindingMap& currentBinding(); | ||
1699 | 67 | bool isInitial() const; | ||
1700 | 68 | Iterator begin(); | ||
1701 | 69 | Iterator end(); | ||
1702 | 70 | }; | ||
1703 | 71 | } | ||
1704 | 0 | \ No newline at end of file | 72 | \ No newline at end of file |
1705 | 1 | 73 | ||
1706 | === modified file 'include/PetriEngine/Colored/ColoredNetStructures.h' | |||
1707 | --- include/PetriEngine/Colored/ColoredNetStructures.h 2020-03-02 21:03:24 +0000 | |||
1708 | +++ include/PetriEngine/Colored/ColoredNetStructures.h 2021-04-02 18:07:40 +0000 | |||
1709 | @@ -1,14 +1,20 @@ | |||
1721 | 1 | /* | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, |
1722 | 2 | * To change this license header, choose License Headers in Project Properties. | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, |
1723 | 3 | * To change this template file, choose Tools | Templates | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> |
1724 | 4 | * and open the template in the editor. | 4 | * Andreas H. Klostergaard |
1725 | 5 | */ | 5 | * |
1726 | 6 | 6 | * This program is free software: you can redistribute it and/or modify | |
1727 | 7 | /* | 7 | * it under the terms of the GNU General Public License as published by |
1728 | 8 | * File: ColoredNetStructures.h | 8 | * the Free Software Foundation, either version 3 of the License, or |
1729 | 9 | * Author: Klostergaard | 9 | * (at your option) any later version. |
1730 | 10 | * | 10 | * |
1731 | 11 | * Created on 17. februar 2018, 17:07 | 11 | * This program is distributed in the hope that it will be useful, |
1732 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1733 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1734 | 14 | * GNU General Public License for more details. | ||
1735 | 15 | * | ||
1736 | 16 | * You should have received a copy of the GNU General Public License | ||
1737 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1738 | 12 | */ | 18 | */ |
1739 | 13 | 19 | ||
1740 | 14 | #ifndef COLOREDNETSTRUCTURES_H | 20 | #ifndef COLOREDNETSTRUCTURES_H |
1741 | @@ -16,6 +22,7 @@ | |||
1742 | 16 | 22 | ||
1743 | 17 | #include <vector> | 23 | #include <vector> |
1744 | 18 | #include <set> | 24 | #include <set> |
1745 | 25 | #include <assert.h> | ||
1746 | 19 | #include "Colors.h" | 26 | #include "Colors.h" |
1747 | 20 | #include "Expressions.h" | 27 | #include "Expressions.h" |
1748 | 21 | #include "Multiset.h" | 28 | #include "Multiset.h" |
1749 | @@ -33,7 +40,10 @@ | |||
1750 | 33 | struct Transition { | 40 | struct Transition { |
1751 | 34 | std::string name; | 41 | std::string name; |
1752 | 35 | GuardExpression_ptr guard; | 42 | GuardExpression_ptr guard; |
1754 | 36 | std::vector<Arc> arcs; | 43 | std::vector<Arc> input_arcs; |
1755 | 44 | std::vector<Arc> output_arcs; | ||
1756 | 45 | std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>> variableMaps; | ||
1757 | 46 | bool considered; | ||
1758 | 37 | }; | 47 | }; |
1759 | 38 | 48 | ||
1760 | 39 | struct Place { | 49 | struct Place { |
1761 | 40 | 50 | ||
1762 | === modified file 'include/PetriEngine/Colored/ColoredPetriNetBuilder.h' | |||
1763 | --- include/PetriEngine/Colored/ColoredPetriNetBuilder.h 2020-03-02 21:03:24 +0000 | |||
1764 | +++ include/PetriEngine/Colored/ColoredPetriNetBuilder.h 2021-04-02 18:07:40 +0000 | |||
1765 | @@ -1,8 +1,20 @@ | |||
1771 | 1 | /* | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, |
1772 | 2 | * File: ColoredPetriNetBuilder.h | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, |
1773 | 3 | * Author: Klostergaard | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> |
1774 | 4 | * | 4 | * Andreas H. Klostergaard |
1775 | 5 | * Created on 17. februar 2018, 16:25 | 5 | * |
1776 | 6 | * This program is free software: you can redistribute it and/or modify | ||
1777 | 7 | * it under the terms of the GNU General Public License as published by | ||
1778 | 8 | * the Free Software Foundation, either version 3 of the License, or | ||
1779 | 9 | * (at your option) any later version. | ||
1780 | 10 | * | ||
1781 | 11 | * This program is distributed in the hope that it will be useful, | ||
1782 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1783 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1784 | 14 | * GNU General Public License for more details. | ||
1785 | 15 | * | ||
1786 | 16 | * You should have received a copy of the GNU General Public License | ||
1787 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1788 | 6 | */ | 18 | */ |
1789 | 7 | 19 | ||
1790 | 8 | #ifndef COLOREDPETRINETBUILDER_H | 20 | #ifndef COLOREDPETRINETBUILDER_H |
1791 | @@ -11,14 +23,16 @@ | |||
1792 | 11 | #include <vector> | 23 | #include <vector> |
1793 | 12 | #include <unordered_map> | 24 | #include <unordered_map> |
1794 | 13 | 25 | ||
1795 | 14 | #include "ColoredNetStructures.h" | ||
1796 | 15 | #include "../AbstractPetriNetBuilder.h" | 26 | #include "../AbstractPetriNetBuilder.h" |
1797 | 16 | #include "../PetriNetBuilder.h" | 27 | #include "../PetriNetBuilder.h" |
1798 | 28 | #include "BindingGenerator.h" | ||
1799 | 29 | #include "IntervalGenerator.h" | ||
1800 | 30 | #include "ArcIntervals.h" | ||
1801 | 17 | 31 | ||
1802 | 18 | namespace PetriEngine { | 32 | namespace PetriEngine { |
1803 | 33 | |||
1804 | 19 | class ColoredPetriNetBuilder : public AbstractPetriNetBuilder { | 34 | class ColoredPetriNetBuilder : public AbstractPetriNetBuilder { |
1805 | 20 | public: | 35 | public: |
1806 | 21 | typedef std::unordered_map<std::string, Colored::ColorType*> ColorTypeMap; | ||
1807 | 22 | typedef std::unordered_map<std::string, std::unordered_map<uint32_t , std::string>> PTPlaceMap; | 36 | typedef std::unordered_map<std::string, std::unordered_map<uint32_t , std::string>> PTPlaceMap; |
1808 | 23 | typedef std::unordered_map<std::string, std::vector<std::string>> PTTransitionMap; | 37 | typedef std::unordered_map<std::string, std::vector<std::string>> PTTransitionMap; |
1809 | 24 | 38 | ||
1810 | @@ -66,10 +80,18 @@ | |||
1811 | 66 | return _time; | 80 | return _time; |
1812 | 67 | } | 81 | } |
1813 | 68 | 82 | ||
1814 | 83 | double getFixpointTime() const { | ||
1815 | 84 | return _fixPointCreationTime; | ||
1816 | 85 | } | ||
1817 | 86 | |||
1818 | 69 | uint32_t getPlaceCount() const { | 87 | uint32_t getPlaceCount() const { |
1819 | 70 | return _places.size(); | 88 | return _places.size(); |
1820 | 71 | } | 89 | } |
1821 | 72 | 90 | ||
1822 | 91 | uint32_t getMaxIntervals() const { | ||
1823 | 92 | return _maxIntervals; | ||
1824 | 93 | } | ||
1825 | 94 | |||
1826 | 73 | uint32_t getTransitionCount() const { | 95 | uint32_t getTransitionCount() const { |
1827 | 74 | return _transitions.size(); | 96 | return _transitions.size(); |
1828 | 75 | } | 97 | } |
1829 | @@ -77,7 +99,8 @@ | |||
1830 | 77 | uint32_t getArcCount() const { | 99 | uint32_t getArcCount() const { |
1831 | 78 | uint32_t sum = 0; | 100 | uint32_t sum = 0; |
1832 | 79 | for (auto& t : _transitions) { | 101 | for (auto& t : _transitions) { |
1834 | 80 | sum += t.arcs.size(); | 102 | sum += t.input_arcs.size(); |
1835 | 103 | sum += t.output_arcs.size(); | ||
1836 | 81 | } | 104 | } |
1837 | 82 | return sum; | 105 | return sum; |
1838 | 83 | } | 106 | } |
1839 | @@ -109,71 +132,69 @@ | |||
1840 | 109 | 132 | ||
1841 | 110 | PetriNetBuilder& unfold(); | 133 | PetriNetBuilder& unfold(); |
1842 | 111 | PetriNetBuilder& stripColors(); | 134 | PetriNetBuilder& stripColors(); |
1843 | 135 | void computePlaceColorFixpoint(uint32_t maxIntervals, uint32_t maxIntervalsReduced, int32_t timeout); | ||
1844 | 136 | |||
1845 | 112 | private: | 137 | private: |
1846 | 113 | std::unordered_map<std::string,uint32_t> _placenames; | 138 | std::unordered_map<std::string,uint32_t> _placenames; |
1847 | 114 | std::unordered_map<std::string,uint32_t> _transitionnames; | 139 | std::unordered_map<std::string,uint32_t> _transitionnames; |
1848 | 140 | std::unordered_map<uint32_t, std::unordered_map<uint32_t, Colored::ArcIntervals>> _arcIntervals; | ||
1849 | 141 | std::unordered_map<uint32_t,std::vector<uint32_t>> _placePostTransitionMap; | ||
1850 | 142 | std::unordered_map<uint32_t,FixpointBindingGenerator> _bindings; | ||
1851 | 115 | PTPlaceMap _ptplacenames; | 143 | PTPlaceMap _ptplacenames; |
1852 | 116 | PTTransitionMap _pttransitionnames; | 144 | PTTransitionMap _pttransitionnames; |
1853 | 117 | uint32_t _nptplaces = 0; | 145 | uint32_t _nptplaces = 0; |
1854 | 118 | uint32_t _npttransitions = 0; | 146 | uint32_t _npttransitions = 0; |
1855 | 119 | uint32_t _nptarcs = 0; | 147 | uint32_t _nptarcs = 0; |
1856 | 148 | uint32_t _maxIntervals = 0; | ||
1857 | 149 | PetriEngine::IntervalGenerator intervalGenerator; | ||
1858 | 120 | 150 | ||
1859 | 121 | std::vector<Colored::Place> _places; | 151 | std::vector<Colored::Place> _places; |
1860 | 122 | std::vector<Colored::Transition> _transitions; | 152 | std::vector<Colored::Transition> _transitions; |
1861 | 123 | std::vector<Colored::Arc> _arcs; | 153 | std::vector<Colored::Arc> _arcs; |
1862 | 154 | std::vector<Colored::ColorFixpoint> _placeColorFixpoints; | ||
1863 | 124 | ColorTypeMap _colors; | 155 | ColorTypeMap _colors; |
1864 | 125 | PetriNetBuilder _ptBuilder; | 156 | PetriNetBuilder _ptBuilder; |
1865 | 126 | bool _unfolded = false; | 157 | bool _unfolded = false; |
1866 | 127 | bool _stripped = false; | 158 | bool _stripped = false; |
1867 | 128 | 159 | ||
1868 | 160 | std::vector<uint32_t> _placeFixpointQueue; | ||
1869 | 161 | |||
1870 | 129 | double _time; | 162 | double _time; |
1871 | 163 | double _fixPointCreationTime; | ||
1872 | 164 | |||
1873 | 165 | double _timer; | ||
1874 | 130 | 166 | ||
1875 | 131 | std::string arcToString(Colored::Arc& arc) const ; | 167 | std::string arcToString(Colored::Arc& arc) const ; |
1876 | 168 | |||
1877 | 169 | void printPlaceTable(); | ||
1878 | 170 | |||
1879 | 171 | std::unordered_map<uint32_t, Colored::ArcIntervals> setupTransitionVars(Colored::Transition transition); | ||
1880 | 132 | 172 | ||
1881 | 133 | void addArc(const std::string& place, | 173 | void addArc(const std::string& place, |
1882 | 134 | const std::string& transition, | 174 | const std::string& transition, |
1883 | 135 | const Colored::ArcExpression_ptr& expr, | 175 | const Colored::ArcExpression_ptr& expr, |
1884 | 136 | bool input); | 176 | bool input); |
1885 | 177 | |||
1886 | 178 | |||
1887 | 179 | void getArcIntervals(Colored::Transition& transition, bool &transitionActivated, uint32_t max_intervals, uint32_t transitionId); | ||
1888 | 180 | void processInputArcs(Colored::Transition& transition, uint32_t currentPlaceId, uint32_t transitionId, bool &transitionActivated, uint32_t max_intervals); | ||
1889 | 181 | void processOutputArcs(Colored::Transition& transition); | ||
1890 | 137 | 182 | ||
1892 | 138 | void unfoldPlace(Colored::Place& place); | 183 | void unfoldPlace(const Colored::Place* place, const PetriEngine::Colored::Color *color); |
1893 | 139 | void unfoldTransition(Colored::Transition& transition); | 184 | void unfoldTransition(Colored::Transition& transition); |
1895 | 140 | void unfoldArc(Colored::Arc& arc, Colored::ExpressionContext::BindingMap& binding, std::string& name); | 185 | void handleOrphanPlace(Colored::Place& place, std::unordered_map<std::string, uint32_t> unfoldedPlaceMap); |
1896 | 186 | |||
1897 | 187 | void unfoldArc(Colored::Arc& arc, Colored::ExpressionContext::BindingMap& binding, std::string& name, bool input); | ||
1898 | 141 | }; | 188 | }; |
1899 | 142 | 189 | ||
1926 | 143 | class BindingGenerator { | 190 | //Used for checking if a variable is inside either a succ or pred expression |
1927 | 144 | public: | 191 | enum ExpressionType { |
1928 | 145 | class Iterator { | 192 | None, |
1929 | 146 | private: | 193 | Pred, |
1930 | 147 | BindingGenerator* _generator; | 194 | Succ |
1931 | 148 | 195 | }; | |
1932 | 149 | public: | 196 | |
1907 | 150 | Iterator(BindingGenerator* generator); | ||
1908 | 151 | |||
1909 | 152 | bool operator==(Iterator& other); | ||
1910 | 153 | bool operator!=(Iterator& other); | ||
1911 | 154 | Iterator& operator++(); | ||
1912 | 155 | const Colored::ExpressionContext::BindingMap operator++(int); | ||
1913 | 156 | Colored::ExpressionContext::BindingMap& operator*(); | ||
1914 | 157 | }; | ||
1915 | 158 | private: | ||
1916 | 159 | Colored::GuardExpression_ptr _expr; | ||
1917 | 160 | Colored::ExpressionContext::BindingMap _bindings; | ||
1918 | 161 | ColoredPetriNetBuilder::ColorTypeMap& _colorTypes; | ||
1919 | 162 | |||
1920 | 163 | bool eval(); | ||
1921 | 164 | |||
1922 | 165 | public: | ||
1923 | 166 | BindingGenerator(Colored::Transition& transition, | ||
1924 | 167 | const std::vector<Colored::Arc>& arcs, | ||
1925 | 168 | ColoredPetriNetBuilder::ColorTypeMap& colorTypes); | ||
1933 | 169 | 197 | ||
1934 | 170 | Colored::ExpressionContext::BindingMap& nextBinding(); | ||
1935 | 171 | Colored::ExpressionContext::BindingMap& currentBinding(); | ||
1936 | 172 | bool isInitial() const; | ||
1937 | 173 | Iterator begin(); | ||
1938 | 174 | Iterator end(); | ||
1939 | 175 | }; | ||
1940 | 176 | } | 198 | } |
1941 | 177 | 199 | ||
1942 | 178 | #endif /* COLOREDPETRINETBUILDER_H */ | 200 | #endif /* COLOREDPETRINETBUILDER_H */ |
1943 | 179 | |||
1944 | 180 | 201 | ||
1945 | === modified file 'include/PetriEngine/Colored/Colors.h' | |||
1946 | --- include/PetriEngine/Colored/Colors.h 2020-03-02 22:05:53 +0000 | |||
1947 | +++ include/PetriEngine/Colored/Colors.h 2021-04-02 18:07:40 +0000 | |||
1948 | @@ -1,14 +1,20 @@ | |||
1960 | 1 | /* | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, |
1961 | 2 | * To change this license header, choose License Headers in Project Properties. | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, |
1962 | 3 | * To change this template file, choose Tools | Templates | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> |
1963 | 4 | * and open the template in the editor. | 4 | * Andreas H. Klostergaard |
1964 | 5 | */ | 5 | * |
1965 | 6 | 6 | * This program is free software: you can redistribute it and/or modify | |
1966 | 7 | /* | 7 | * it under the terms of the GNU General Public License as published by |
1967 | 8 | * File: Colors.h | 8 | * the Free Software Foundation, either version 3 of the License, or |
1968 | 9 | * Author: andreas | 9 | * (at your option) any later version. |
1969 | 10 | * | 10 | * |
1970 | 11 | * Created on February 19, 2018, 8:22 PM | 11 | * This program is distributed in the hope that it will be useful, |
1971 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1972 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1973 | 14 | * GNU General Public License for more details. | ||
1974 | 15 | * | ||
1975 | 16 | * You should have received a copy of the GNU General Public License | ||
1976 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1977 | 12 | */ | 18 | */ |
1978 | 13 | 19 | ||
1979 | 14 | #ifndef COLORS_H | 20 | #ifndef COLORS_H |
1980 | @@ -21,6 +27,10 @@ | |||
1981 | 21 | #include <utility> | 27 | #include <utility> |
1982 | 22 | #include <vector> | 28 | #include <vector> |
1983 | 23 | #include <unordered_map> | 29 | #include <unordered_map> |
1984 | 30 | #include <iostream> | ||
1985 | 31 | #include <cassert> | ||
1986 | 32 | |||
1987 | 33 | #include "Intervals.h" | ||
1988 | 24 | 34 | ||
1989 | 25 | namespace PetriEngine { | 35 | namespace PetriEngine { |
1990 | 26 | namespace Colored { | 36 | namespace Colored { |
1991 | @@ -44,7 +54,15 @@ | |||
1992 | 44 | bool isTuple() const { | 54 | bool isTuple() const { |
1993 | 45 | return _tuple.size() > 1; | 55 | return _tuple.size() > 1; |
1994 | 46 | } | 56 | } |
1995 | 57 | |||
1996 | 58 | void getColorConstraints(Colored::interval_t *constraintsVector, uint32_t *index) const; | ||
1997 | 47 | 59 | ||
1998 | 60 | std::vector<const Color*> getTupleColors() const { | ||
1999 | 61 | return _tuple; | ||
2000 | 62 | } | ||
2001 | 63 | |||
2002 | 64 | void getTupleId(std::vector<uint32_t> *idVector) const; | ||
2003 | 65 | |||
2004 | 48 | const std::string& getColorName() const { | 66 | const std::string& getColorName() const { |
2005 | 49 | if (this->isTuple()) { | 67 | if (this->isTuple()) { |
2006 | 50 | throw "Cannot get color from a tuple color."; | 68 | throw "Cannot get color from a tuple color."; |
2007 | @@ -90,9 +108,11 @@ | |||
2008 | 90 | DotConstant(); | 108 | DotConstant(); |
2009 | 91 | 109 | ||
2010 | 92 | public: | 110 | public: |
2012 | 93 | static const Color* dotConstant() { | 111 | static const Color* dotConstant(ColorType *ct) { |
2013 | 94 | static DotConstant _instance; | 112 | static DotConstant _instance; |
2015 | 95 | 113 | if(ct != nullptr){ | |
2016 | 114 | _instance._colorType = ct; | ||
2017 | 115 | } | ||
2018 | 96 | return &_instance; | 116 | return &_instance; |
2019 | 97 | } | 117 | } |
2020 | 98 | 118 | ||
2021 | @@ -160,12 +180,33 @@ | |||
2022 | 160 | virtual void addColor(const char* colorName); | 180 | virtual void addColor(const char* colorName); |
2023 | 161 | virtual void addColor(std::vector<const Color*>& colors); | 181 | virtual void addColor(std::vector<const Color*>& colors); |
2024 | 162 | virtual void addDot() { | 182 | virtual void addDot() { |
2026 | 163 | _colors.push_back(*DotConstant::dotConstant()); | 183 | _colors.push_back(*DotConstant::dotConstant(this)); |
2027 | 164 | } | 184 | } |
2028 | 165 | 185 | ||
2029 | 166 | virtual size_t size() const { | 186 | virtual size_t size() const { |
2030 | 167 | return _colors.size(); | 187 | return _colors.size(); |
2031 | 168 | } | 188 | } |
2032 | 189 | |||
2033 | 190 | virtual size_t productSize() { | ||
2034 | 191 | return 1; | ||
2035 | 192 | } | ||
2036 | 193 | |||
2037 | 194 | virtual std::vector<size_t> getConstituentsSizes(){ | ||
2038 | 195 | std::vector<size_t> result; | ||
2039 | 196 | result.push_back(_colors.size()); | ||
2040 | 197 | |||
2041 | 198 | return result; | ||
2042 | 199 | } | ||
2043 | 200 | |||
2044 | 201 | virtual Colored::interval_t getFullInterval(){ | ||
2045 | 202 | Colored::interval_t interval; | ||
2046 | 203 | interval.addRange(Reachability::range_t(0, size()-1)); | ||
2047 | 204 | return interval; | ||
2048 | 205 | } | ||
2049 | 206 | |||
2050 | 207 | virtual void getColortypes(std::vector<ColorType *> &colorTypes){ | ||
2051 | 208 | colorTypes.push_back(this); | ||
2052 | 209 | } | ||
2053 | 169 | 210 | ||
2054 | 170 | virtual const Color& operator[] (size_t index) { | 211 | virtual const Color& operator[] (size_t index) { |
2055 | 171 | return _colors[index]; | 212 | return _colors[index]; |
2056 | @@ -176,6 +217,7 @@ | |||
2057 | 176 | } | 217 | } |
2058 | 177 | 218 | ||
2059 | 178 | virtual const Color& operator[] (uint32_t index) { | 219 | virtual const Color& operator[] (uint32_t index) { |
2060 | 220 | assert(index < _colors.size()); | ||
2061 | 179 | return _colors[index]; | 221 | return _colors[index]; |
2062 | 180 | } | 222 | } |
2063 | 181 | 223 | ||
2064 | @@ -184,6 +226,11 @@ | |||
2065 | 184 | virtual const Color* operator[] (const std::string& index) { | 226 | virtual const Color* operator[] (const std::string& index) { |
2066 | 185 | return (*this)[index.c_str()]; | 227 | return (*this)[index.c_str()]; |
2067 | 186 | } | 228 | } |
2068 | 229 | |||
2069 | 230 | virtual const Color* getColor(std::vector<uint32_t> ids){ | ||
2070 | 231 | assert(ids.size() == 1); | ||
2071 | 232 | return &_colors[ids[0]]; | ||
2072 | 233 | } | ||
2073 | 187 | 234 | ||
2074 | 188 | bool operator== (const ColorType& other) const { | 235 | bool operator== (const ColorType& other) const { |
2075 | 189 | return _id == other._id; | 236 | return _id == other._id; |
2076 | @@ -233,6 +280,36 @@ | |||
2077 | 233 | return product; | 280 | return product; |
2078 | 234 | } | 281 | } |
2079 | 235 | 282 | ||
2080 | 283 | virtual size_t productSize() { | ||
2081 | 284 | size_t size = 0; | ||
2082 | 285 | for (auto ct : constituents){ | ||
2083 | 286 | size += ct->productSize(); | ||
2084 | 287 | } | ||
2085 | 288 | return size; | ||
2086 | 289 | } | ||
2087 | 290 | |||
2088 | 291 | std::vector<size_t> getConstituentsSizes() override{ | ||
2089 | 292 | std::vector<size_t> result; | ||
2090 | 293 | for (auto ct : constituents) { | ||
2091 | 294 | result.push_back(ct->size()); | ||
2092 | 295 | } | ||
2093 | 296 | return result; | ||
2094 | 297 | } | ||
2095 | 298 | |||
2096 | 299 | Colored::interval_t getFullInterval() override{ | ||
2097 | 300 | Colored::interval_t interval; | ||
2098 | 301 | for(auto ct : constituents) { | ||
2099 | 302 | interval.addRange(Reachability::range_t(0, ct->size()-1)); | ||
2100 | 303 | } | ||
2101 | 304 | return interval; | ||
2102 | 305 | } | ||
2103 | 306 | |||
2104 | 307 | void getColortypes(std::vector<ColorType *> &colorTypes) override{ | ||
2105 | 308 | for(auto ct : constituents){ | ||
2106 | 309 | ct->getColortypes(colorTypes); | ||
2107 | 310 | } | ||
2108 | 311 | } | ||
2109 | 312 | |||
2110 | 236 | bool containsTypes(const std::vector<const ColorType*>& types) const { | 313 | bool containsTypes(const std::vector<const ColorType*>& types) const { |
2111 | 237 | if (constituents.size() != types.size()) return false; | 314 | if (constituents.size() != types.size()) return false; |
2112 | 238 | 315 | ||
2113 | @@ -245,6 +322,19 @@ | |||
2114 | 245 | return true; | 322 | return true; |
2115 | 246 | } | 323 | } |
2116 | 247 | 324 | ||
2117 | 325 | const ColorType* getNestedColorType(size_t index) { | ||
2118 | 326 | return constituents[index]; | ||
2119 | 327 | } | ||
2120 | 328 | |||
2121 | 329 | const Color* getColor(std::vector<uint32_t> ids){ | ||
2122 | 330 | assert(ids.size() == constituents.size()); | ||
2123 | 331 | std::vector<const Color *> colors; | ||
2124 | 332 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
2125 | 333 | colors.push_back(&constituents[i]->operator[](i)); | ||
2126 | 334 | } | ||
2127 | 335 | return getColor(colors); | ||
2128 | 336 | } | ||
2129 | 337 | |||
2130 | 248 | const Color* getColor(const std::vector<const Color*>& colors); | 338 | const Color* getColor(const std::vector<const Color*>& colors); |
2131 | 249 | 339 | ||
2132 | 250 | const Color& operator[](size_t index) override; | 340 | const Color& operator[](size_t index) override; |
2133 | @@ -263,13 +353,29 @@ | |||
2134 | 263 | std::string name; | 353 | std::string name; |
2135 | 264 | ColorType* colorType; | 354 | ColorType* colorType; |
2136 | 265 | }; | 355 | }; |
2144 | 266 | 356 | ||
2145 | 267 | struct Binding { | 357 | struct ColorFixpoint { |
2146 | 268 | Variable* var; | 358 | Colored::intervalTuple_t constraints; |
2147 | 269 | const Color* color; | 359 | bool inQueue; |
2148 | 270 | 360 | uint32_t productSize; | |
2149 | 271 | bool operator==(Binding& other) { | 361 | |
2150 | 272 | return var->name.compare(other.var->name); | 362 | bool constainsColor(std::pair<const PetriEngine::Colored::Color *const, std::vector<uint32_t>> constPair) { |
2151 | 363 | std::unordered_map<uint32_t, bool> contained; | ||
2152 | 364 | for(auto interval : constraints._intervals) { | ||
2153 | 365 | for(uint32_t id : constPair.second){ | ||
2154 | 366 | |||
2155 | 367 | if(contained[id] != true){ | ||
2156 | 368 | contained[id] = interval[id].contains(constPair.first->getId()); | ||
2157 | 369 | } | ||
2158 | 370 | } | ||
2159 | 371 | } | ||
2160 | 372 | |||
2161 | 373 | for(auto pair : contained){ | ||
2162 | 374 | if (!pair.second){ | ||
2163 | 375 | return false; | ||
2164 | 376 | } | ||
2165 | 377 | } | ||
2166 | 378 | return true; | ||
2167 | 273 | } | 379 | } |
2168 | 274 | }; | 380 | }; |
2169 | 275 | } | 381 | } |
2170 | 276 | 382 | ||
2171 | === modified file 'include/PetriEngine/Colored/Expressions.h' | |||
2172 | --- include/PetriEngine/Colored/Expressions.h 2020-03-02 21:03:24 +0000 | |||
2173 | +++ include/PetriEngine/Colored/Expressions.h 2021-04-02 18:07:40 +0000 | |||
2174 | @@ -1,14 +1,20 @@ | |||
2186 | 1 | /* | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, |
2187 | 2 | * To change this license header, choose License Headers in Project Properties. | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, |
2188 | 3 | * To change this template file, choose Tools | Templates | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> |
2189 | 4 | * and open the template in the editor. | 4 | * Andreas H. Klostergaard |
2190 | 5 | */ | 5 | * |
2191 | 6 | 6 | * This program is free software: you can redistribute it and/or modify | |
2192 | 7 | /* | 7 | * it under the terms of the GNU General Public License as published by |
2193 | 8 | * File: Expressions.h | 8 | * the Free Software Foundation, either version 3 of the License, or |
2194 | 9 | * Author: andreas | 9 | * (at your option) any later version. |
2195 | 10 | * | 10 | * |
2196 | 11 | * Created on February 19, 2018, 7:00 PM | 11 | * This program is distributed in the hope that it will be useful, |
2197 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2198 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2199 | 14 | * GNU General Public License for more details. | ||
2200 | 15 | * | ||
2201 | 16 | * You should have received a copy of the GNU General Public License | ||
2202 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2203 | 12 | */ | 18 | */ |
2204 | 13 | 19 | ||
2205 | 14 | #ifndef COLORED_EXPRESSIONS_H | 20 | #ifndef COLORED_EXPRESSIONS_H |
2206 | @@ -25,6 +31,8 @@ | |||
2207 | 25 | 31 | ||
2208 | 26 | #include "Colors.h" | 32 | #include "Colors.h" |
2209 | 27 | #include "Multiset.h" | 33 | #include "Multiset.h" |
2210 | 34 | #include "ArcIntervals.h" | ||
2211 | 35 | #include "GuardRestrictor.h" | ||
2212 | 28 | #include "../errorcodes.h" | 36 | #include "../errorcodes.h" |
2213 | 29 | 37 | ||
2214 | 30 | namespace PetriEngine { | 38 | namespace PetriEngine { |
2215 | @@ -32,14 +40,14 @@ | |||
2216 | 32 | 40 | ||
2217 | 33 | namespace Colored { | 41 | namespace Colored { |
2218 | 34 | struct ExpressionContext { | 42 | struct ExpressionContext { |
2220 | 35 | typedef std::unordered_map<std::string, const Color*> BindingMap; | 43 | typedef std::unordered_map<const Colored::Variable *, const PetriEngine::Colored::Color *> BindingMap; |
2221 | 36 | 44 | ||
2222 | 37 | BindingMap& binding; | 45 | BindingMap& binding; |
2223 | 38 | std::unordered_map<std::string, ColorType*>& colorTypes; | 46 | std::unordered_map<std::string, ColorType*>& colorTypes; |
2224 | 39 | 47 | ||
2225 | 40 | const Color* findColor(const std::string& color) const { | 48 | const Color* findColor(const std::string& color) const { |
2226 | 41 | if (color.compare("dot") == 0) | 49 | if (color.compare("dot") == 0) |
2228 | 42 | return DotConstant::dotConstant(); | 50 | return DotConstant::dotConstant(nullptr); |
2229 | 43 | for (auto& elem : colorTypes) { | 51 | for (auto& elem : colorTypes) { |
2230 | 44 | auto col = (*elem.second)[color]; | 52 | auto col = (*elem.second)[color]; |
2231 | 45 | if (col) | 53 | if (col) |
2232 | @@ -74,8 +82,29 @@ | |||
2233 | 74 | class Expression { | 82 | class Expression { |
2234 | 75 | public: | 83 | public: |
2235 | 76 | Expression() {} | 84 | Expression() {} |
2238 | 77 | 85 | ||
2239 | 78 | virtual void getVariables(std::set<Variable*>& variables) const { | 86 | virtual void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const {} |
2240 | 87 | |||
2241 | 88 | virtual void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap) const { | ||
2242 | 89 | uint32_t index = 0; | ||
2243 | 90 | getVariables(variables, varPositions, varModifierMap, &index); | ||
2244 | 91 | } | ||
2245 | 92 | |||
2246 | 93 | virtual void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions) const { | ||
2247 | 94 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMap; | ||
2248 | 95 | uint32_t index = 0; | ||
2249 | 96 | getVariables(variables, varPositions, varModifierMap, &index); | ||
2250 | 97 | } | ||
2251 | 98 | |||
2252 | 99 | virtual bool isTuple() const { | ||
2253 | 100 | return false; | ||
2254 | 101 | } | ||
2255 | 102 | |||
2256 | 103 | virtual void getVariables(std::set<const Colored::Variable*>& variables) const { | ||
2257 | 104 | std::unordered_map<uint32_t, const Colored::Variable *> varPositions; | ||
2258 | 105 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMap; | ||
2259 | 106 | |||
2260 | 107 | getVariables(variables, varPositions, varModifierMap); | ||
2261 | 79 | } | 108 | } |
2262 | 80 | 109 | ||
2263 | 81 | virtual void expressionType() { | 110 | virtual void expressionType() { |
2264 | @@ -93,12 +122,55 @@ | |||
2265 | 93 | virtual ~ColorExpression() {} | 122 | virtual ~ColorExpression() {} |
2266 | 94 | 123 | ||
2267 | 95 | virtual const Color* eval(ExpressionContext& context) const = 0; | 124 | virtual const Color* eval(ExpressionContext& context) const = 0; |
2268 | 125 | |||
2269 | 126 | virtual void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const = 0; | ||
2270 | 127 | |||
2271 | 128 | virtual bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const = 0; | ||
2272 | 129 | |||
2273 | 130 | virtual ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const = 0; | ||
2274 | 131 | |||
2275 | 132 | virtual Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const { | ||
2276 | 133 | return Colored::intervalTuple_t(); | ||
2277 | 134 | } | ||
2278 | 135 | |||
2279 | 96 | }; | 136 | }; |
2280 | 97 | 137 | ||
2281 | 98 | class DotConstantExpression : public ColorExpression { | 138 | class DotConstantExpression : public ColorExpression { |
2282 | 99 | public: | 139 | public: |
2283 | 100 | const Color* eval(ExpressionContext& context) const override { | 140 | const Color* eval(ExpressionContext& context) const override { |
2285 | 101 | return DotConstant::dotConstant(); | 141 | return DotConstant::dotConstant(nullptr); |
2286 | 142 | } | ||
2287 | 143 | |||
2288 | 144 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
2289 | 145 | if (arcIntervals._intervalTupleVec.empty()) { | ||
2290 | 146 | //We can add all place tokens when considering the dot constant as, that must be present | ||
2291 | 147 | arcIntervals._intervalTupleVec.push_back(cfp.constraints); | ||
2292 | 148 | } | ||
2293 | 149 | return !cfp.constraints._intervals.empty(); | ||
2294 | 150 | } | ||
2295 | 151 | |||
2296 | 152 | Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
2297 | 153 | Colored::interval_t interval; | ||
2298 | 154 | Colored::intervalTuple_t tupleInterval; | ||
2299 | 155 | const Color *dotColor = DotConstant::dotConstant(nullptr); | ||
2300 | 156 | |||
2301 | 157 | colortypes->push_back(dotColor->getColorType()); | ||
2302 | 158 | |||
2303 | 159 | interval.addRange(dotColor->getId(), dotColor->getId()); | ||
2304 | 160 | tupleInterval.addInterval(interval); | ||
2305 | 161 | return tupleInterval; | ||
2306 | 162 | } | ||
2307 | 163 | |||
2308 | 164 | void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override { | ||
2309 | 165 | const Color *dotColor = DotConstant::dotConstant(nullptr); | ||
2310 | 166 | constantMap[index] = dotColor; | ||
2311 | 167 | } | ||
2312 | 168 | ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{ | ||
2313 | 169 | return DotConstant::dotConstant(nullptr)->getColorType(); | ||
2314 | 170 | } | ||
2315 | 171 | |||
2316 | 172 | std::string toString() const override { | ||
2317 | 173 | return "dot"; | ||
2318 | 102 | } | 174 | } |
2319 | 103 | }; | 175 | }; |
2320 | 104 | 176 | ||
2321 | @@ -110,17 +182,74 @@ | |||
2322 | 110 | 182 | ||
2323 | 111 | public: | 183 | public: |
2324 | 112 | const Color* eval(ExpressionContext& context) const override { | 184 | const Color* eval(ExpressionContext& context) const override { |
2326 | 113 | return context.binding[_variable->name]; | 185 | return context.binding[_variable]; |
2327 | 114 | } | 186 | } |
2328 | 115 | 187 | ||
2330 | 116 | void getVariables(std::set<Variable*>& variables) const override { | 188 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2331 | 117 | variables.insert(_variable); | 189 | variables.insert(_variable); |
2332 | 190 | varPositions[*index] = _variable; | ||
2333 | 191 | if(varModifierMap.count(_variable) == 0){ | ||
2334 | 192 | std::vector<std::unordered_map<uint32_t, int32_t>> newVec; | ||
2335 | 193 | |||
2336 | 194 | for(auto pair : varModifierMap){ | ||
2337 | 195 | for(uint32_t i = 0; i < pair.second.size()-1; i++){ | ||
2338 | 196 | std::unordered_map<uint32_t, int32_t> emptyMap; | ||
2339 | 197 | newVec.push_back(emptyMap); | ||
2340 | 198 | } | ||
2341 | 199 | break; | ||
2342 | 200 | } | ||
2343 | 201 | std::unordered_map<uint32_t, int32_t> newMap; | ||
2344 | 202 | newMap[*index] = 0; | ||
2345 | 203 | newVec.push_back(newMap); | ||
2346 | 204 | varModifierMap[_variable] = newVec; | ||
2347 | 205 | } else { | ||
2348 | 206 | varModifierMap[_variable].back()[*index] = 0; | ||
2349 | 207 | } | ||
2350 | 208 | } | ||
2351 | 209 | |||
2352 | 210 | Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
2353 | 211 | Colored::intervalTuple_t varInterval; | ||
2354 | 212 | |||
2355 | 213 | // If we see a new variable on an out arc, it gets its full interval | ||
2356 | 214 | if (varMap.count(_variable) == 0){ | ||
2357 | 215 | Colored::intervalTuple_t intervalTuple; | ||
2358 | 216 | intervalTuple.addInterval(_variable->colorType->getFullInterval()); | ||
2359 | 217 | varMap[_variable] = intervalTuple; | ||
2360 | 218 | } | ||
2361 | 219 | |||
2362 | 220 | for(auto interval : varMap[_variable]._intervals){ | ||
2363 | 221 | varInterval.addInterval(interval); | ||
2364 | 222 | } | ||
2365 | 223 | |||
2366 | 224 | std::vector<ColorType*> varColorTypes; | ||
2367 | 225 | _variable->colorType->getColortypes(varColorTypes); | ||
2368 | 226 | |||
2369 | 227 | for(auto ct : varColorTypes){ | ||
2370 | 228 | colortypes->push_back(ct); | ||
2371 | 229 | } | ||
2372 | 230 | |||
2373 | 231 | return varInterval; | ||
2374 | 232 | } | ||
2375 | 233 | |||
2376 | 234 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
2377 | 235 | if (arcIntervals._intervalTupleVec.empty()){ | ||
2378 | 236 | //As variables does not restrict the values before the guard we include all tokens | ||
2379 | 237 | arcIntervals._intervalTupleVec.push_back(cfp.constraints); | ||
2380 | 238 | } | ||
2381 | 239 | return !cfp.constraints._intervals.empty(); | ||
2382 | 240 | } | ||
2383 | 241 | |||
2384 | 242 | void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override { | ||
2385 | 118 | } | 243 | } |
2386 | 119 | 244 | ||
2387 | 120 | std::string toString() const override { | 245 | std::string toString() const override { |
2388 | 121 | return _variable->name; | 246 | return _variable->name; |
2389 | 122 | } | 247 | } |
2390 | 123 | 248 | ||
2391 | 249 | ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{ | ||
2392 | 250 | return _variable->colorType; | ||
2393 | 251 | } | ||
2394 | 252 | |||
2395 | 124 | VariableExpression(Variable* variable) | 253 | VariableExpression(Variable* variable) |
2396 | 125 | : _variable(variable) {} | 254 | : _variable(variable) {} |
2397 | 126 | }; | 255 | }; |
2398 | @@ -134,10 +263,63 @@ | |||
2399 | 134 | return _userOperator; | 263 | return _userOperator; |
2400 | 135 | } | 264 | } |
2401 | 136 | 265 | ||
2402 | 266 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
2403 | 267 | uint32_t colorId = _userOperator->getId() + modifier; | ||
2404 | 268 | while(colorId < 0){ | ||
2405 | 269 | colorId += _userOperator->getColorType()->size(); | ||
2406 | 270 | } | ||
2407 | 271 | colorId = colorId % _userOperator->getColorType()->size(); | ||
2408 | 272 | |||
2409 | 273 | if(arcIntervals._intervalTupleVec.empty()){ | ||
2410 | 274 | Colored::intervalTuple_t newIntervalTuple; | ||
2411 | 275 | bool colorInFixpoint = false; | ||
2412 | 276 | for (auto interval : cfp.constraints._intervals){ | ||
2413 | 277 | if(interval[*index].contains(colorId)){ | ||
2414 | 278 | newIntervalTuple.addInterval(interval); | ||
2415 | 279 | colorInFixpoint = true; | ||
2416 | 280 | } | ||
2417 | 281 | } | ||
2418 | 282 | arcIntervals._intervalTupleVec.push_back(newIntervalTuple); | ||
2419 | 283 | return colorInFixpoint; | ||
2420 | 284 | } else { | ||
2421 | 285 | std::vector<uint32_t> intervalsToRemove; | ||
2422 | 286 | for(auto& intervalTuple : arcIntervals._intervalTupleVec){ | ||
2423 | 287 | for (uint32_t i = 0; i < intervalTuple._intervals.size(); i++){ | ||
2424 | 288 | if(!intervalTuple[i][*index].contains(colorId)){ | ||
2425 | 289 | intervalsToRemove.push_back(i); | ||
2426 | 290 | } | ||
2427 | 291 | } | ||
2428 | 292 | |||
2429 | 293 | for (auto i = intervalsToRemove.rbegin(); i != intervalsToRemove.rend(); ++i) { | ||
2430 | 294 | intervalTuple.removeInterval(*i); | ||
2431 | 295 | } | ||
2432 | 296 | } | ||
2433 | 297 | return !arcIntervals._intervalTupleVec[0]._intervals.empty(); | ||
2434 | 298 | } | ||
2435 | 299 | } | ||
2436 | 300 | |||
2437 | 137 | std::string toString() const override { | 301 | std::string toString() const override { |
2438 | 138 | return _userOperator->toString(); | 302 | return _userOperator->toString(); |
2439 | 139 | } | 303 | } |
2440 | 140 | 304 | ||
2441 | 305 | void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override { | ||
2442 | 306 | constantMap[index] = _userOperator; | ||
2443 | 307 | } | ||
2444 | 308 | ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{ | ||
2445 | 309 | return _userOperator->getColorType(); | ||
2446 | 310 | } | ||
2447 | 311 | |||
2448 | 312 | Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
2449 | 313 | Colored::interval_t interval; | ||
2450 | 314 | Colored::intervalTuple_t tupleInterval; | ||
2451 | 315 | |||
2452 | 316 | colortypes->push_back(_userOperator->getColorType()); | ||
2453 | 317 | |||
2454 | 318 | interval.addRange(_userOperator->getId(), _userOperator->getId()); | ||
2455 | 319 | tupleInterval.addInterval(interval); | ||
2456 | 320 | return tupleInterval; | ||
2457 | 321 | } | ||
2458 | 322 | |||
2459 | 141 | UserOperatorExpression(const Color* userOperator) | 323 | UserOperatorExpression(const Color* userOperator) |
2460 | 142 | : _userOperator(userOperator) {} | 324 | : _userOperator(userOperator) {} |
2461 | 143 | }; | 325 | }; |
2462 | @@ -185,14 +367,47 @@ | |||
2463 | 185 | return &++(*_color->eval(context)); | 367 | return &++(*_color->eval(context)); |
2464 | 186 | } | 368 | } |
2465 | 187 | 369 | ||
2468 | 188 | void getVariables(std::set<Variable*>& variables) const override { | 370 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2469 | 189 | _color->getVariables(variables); | 371 | //save index before evaluating nested expression to decrease all the correct modifiers |
2470 | 372 | uint32_t indexBefore = *index; | ||
2471 | 373 | _color->getVariables(variables, varPositions, varModifierMap, index); | ||
2472 | 374 | for(auto& varModifierPair : varModifierMap){ | ||
2473 | 375 | for(auto& idModPair : varModifierPair.second.back()){ | ||
2474 | 376 | if(idModPair.first <= *index && idModPair.first >= indexBefore){ | ||
2475 | 377 | idModPair.second--; | ||
2476 | 378 | } | ||
2477 | 379 | } | ||
2478 | 380 | } | ||
2479 | 381 | } | ||
2480 | 382 | |||
2481 | 383 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
2482 | 384 | return _color->getArcIntervals(arcIntervals, cfp, index, modifier+1); | ||
2483 | 385 | } | ||
2484 | 386 | |||
2485 | 387 | Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
2486 | 388 | //store the number of colortyps already in colortypes vector and use that as offset when indexing it | ||
2487 | 389 | auto colortypesBefore = colortypes->size(); | ||
2488 | 390 | |||
2489 | 391 | auto nestedInterval = _color->getOutputIntervals(varMap, colortypes); | ||
2490 | 392 | Colored::GuardRestrictor guardRestrictor = Colored::GuardRestrictor(); | ||
2491 | 393 | return guardRestrictor.shiftIntervals(colortypes, &nestedInterval, 1, colortypesBefore); | ||
2492 | 394 | } | ||
2493 | 395 | |||
2494 | 396 | void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override { | ||
2495 | 397 | _color->getConstants(constantMap, index); | ||
2496 | 398 | for(auto& constIndexPair : constantMap){ | ||
2497 | 399 | constIndexPair.second = &constIndexPair.second->operator++(); | ||
2498 | 400 | } | ||
2499 | 190 | } | 401 | } |
2500 | 191 | 402 | ||
2501 | 192 | std::string toString() const override { | 403 | std::string toString() const override { |
2502 | 193 | return _color->toString() + "++"; | 404 | return _color->toString() + "++"; |
2503 | 194 | } | 405 | } |
2504 | 195 | 406 | ||
2505 | 407 | ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{ | ||
2506 | 408 | return _color->getColorType(colorTypes); | ||
2507 | 409 | } | ||
2508 | 410 | |||
2509 | 196 | SuccessorExpression(ColorExpression_ptr&& color) | 411 | SuccessorExpression(ColorExpression_ptr&& color) |
2510 | 197 | : _color(std::move(color)) {} | 412 | : _color(std::move(color)) {} |
2511 | 198 | }; | 413 | }; |
2512 | @@ -206,14 +421,47 @@ | |||
2513 | 206 | return &--(*_color->eval(context)); | 421 | return &--(*_color->eval(context)); |
2514 | 207 | } | 422 | } |
2515 | 208 | 423 | ||
2518 | 209 | void getVariables(std::set<Variable*>& variables) const override { | 424 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2519 | 210 | _color->getVariables(variables); | 425 | //save index before evaluating nested expression to decrease all the correct modifiers |
2520 | 426 | uint32_t indexBefore = *index; | ||
2521 | 427 | _color->getVariables(variables, varPositions, varModifierMap, index); | ||
2522 | 428 | for(auto& varModifierPair : varModifierMap){ | ||
2523 | 429 | for(auto& idModPair : varModifierPair.second.back()){ | ||
2524 | 430 | if(idModPair.first <= *index && idModPair.first >= indexBefore){ | ||
2525 | 431 | idModPair.second++; | ||
2526 | 432 | } | ||
2527 | 433 | } | ||
2528 | 434 | } | ||
2529 | 435 | } | ||
2530 | 436 | |||
2531 | 437 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
2532 | 438 | return _color->getArcIntervals(arcIntervals, cfp, index, modifier-1); | ||
2533 | 439 | } | ||
2534 | 440 | |||
2535 | 441 | Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
2536 | 442 | //store the number of colortyps already in colortypes vector and use that as offset when indexing it | ||
2537 | 443 | auto colortypesBefore = colortypes->size(); | ||
2538 | 444 | |||
2539 | 445 | auto nestedInterval = _color->getOutputIntervals(varMap, colortypes); | ||
2540 | 446 | Colored::GuardRestrictor guardRestrictor; | ||
2541 | 447 | return guardRestrictor.shiftIntervals(colortypes, &nestedInterval, -1, colortypesBefore); | ||
2542 | 448 | } | ||
2543 | 449 | |||
2544 | 450 | void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override { | ||
2545 | 451 | _color->getConstants(constantMap, index); | ||
2546 | 452 | for(auto& constIndexPair : constantMap){ | ||
2547 | 453 | constIndexPair.second = &constIndexPair.second->operator--(); | ||
2548 | 454 | } | ||
2549 | 211 | } | 455 | } |
2550 | 212 | 456 | ||
2551 | 213 | std::string toString() const override { | 457 | std::string toString() const override { |
2552 | 214 | return _color->toString() + "--"; | 458 | return _color->toString() + "--"; |
2553 | 215 | } | 459 | } |
2554 | 216 | 460 | ||
2555 | 461 | ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{ | ||
2556 | 462 | return _color->getColorType(colorTypes); | ||
2557 | 463 | } | ||
2558 | 464 | |||
2559 | 217 | PredecessorExpression(ColorExpression_ptr&& color) | 465 | PredecessorExpression(ColorExpression_ptr&& color) |
2560 | 218 | : _color(std::move(color)) {} | 466 | : _color(std::move(color)) {} |
2561 | 219 | }; | 467 | }; |
2562 | @@ -221,6 +469,7 @@ | |||
2563 | 221 | class TupleExpression : public ColorExpression { | 469 | class TupleExpression : public ColorExpression { |
2564 | 222 | private: | 470 | private: |
2565 | 223 | std::vector<ColorExpression_ptr> _colors; | 471 | std::vector<ColorExpression_ptr> _colors; |
2566 | 472 | ColorType* _colorType; | ||
2567 | 224 | 473 | ||
2568 | 225 | public: | 474 | public: |
2569 | 226 | const Color* eval(ExpressionContext& context) const override { | 475 | const Color* eval(ExpressionContext& context) const override { |
2570 | @@ -236,10 +485,77 @@ | |||
2571 | 236 | assert(col != nullptr); | 485 | assert(col != nullptr); |
2572 | 237 | return col; | 486 | return col; |
2573 | 238 | } | 487 | } |
2574 | 488 | |||
2575 | 489 | bool isTuple() const override { | ||
2576 | 490 | return true; | ||
2577 | 491 | } | ||
2578 | 492 | |||
2579 | 493 | Colored::intervalTuple_t getOutputIntervals(std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>& varMap, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
2580 | 494 | Colored::intervalTuple_t intervals; | ||
2581 | 495 | Colored::intervalTuple_t intervalHolder; | ||
2582 | 496 | |||
2583 | 497 | for(auto colorExp : _colors) { | ||
2584 | 498 | Colored::intervalTuple_t intervalHolder; | ||
2585 | 499 | auto nested_intervals = colorExp->getOutputIntervals(varMap, colortypes); | ||
2586 | 500 | |||
2587 | 501 | if(intervals._intervals.empty()){ | ||
2588 | 502 | intervals = nested_intervals; | ||
2589 | 503 | } else { | ||
2590 | 504 | for(auto nested_interval : nested_intervals._intervals){ | ||
2591 | 505 | Colored::intervalTuple_t newIntervals; | ||
2592 | 506 | for(auto interval : intervals._intervals){ | ||
2593 | 507 | for(auto nestedRange : nested_interval._ranges) { | ||
2594 | 508 | interval.addRange(nestedRange); | ||
2595 | 509 | } | ||
2596 | 510 | newIntervals.addInterval(interval); | ||
2597 | 511 | } | ||
2598 | 512 | for(auto newInterval : newIntervals._intervals){ | ||
2599 | 513 | intervalHolder.addInterval(newInterval); | ||
2600 | 514 | } | ||
2601 | 515 | } | ||
2602 | 516 | intervals = intervalHolder; | ||
2603 | 517 | } | ||
2604 | 518 | } | ||
2605 | 519 | return intervals; | ||
2606 | 520 | } | ||
2607 | 521 | |||
2608 | 522 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
2609 | 523 | for (auto expr : _colors) { | ||
2610 | 524 | bool res = expr->getArcIntervals(arcIntervals, cfp, index, modifier); | ||
2611 | 525 | if(!res){ | ||
2612 | 526 | return false; | ||
2613 | 527 | } | ||
2614 | 528 | (*index)++; | ||
2615 | 529 | } | ||
2616 | 530 | return true; | ||
2617 | 531 | } | ||
2618 | 239 | 532 | ||
2622 | 240 | void getVariables(std::set<Variable*>& variables) const override { | 533 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2623 | 241 | for (auto elem : _colors) { | 534 | for (auto elem : _colors) { |
2624 | 242 | elem->getVariables(variables); | 535 | elem->getVariables(variables, varPositions, varModifierMap, index); |
2625 | 536 | (*index)++; | ||
2626 | 537 | } | ||
2627 | 538 | } | ||
2628 | 539 | |||
2629 | 540 | ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{ | ||
2630 | 541 | std::vector<const ColorType*> types; | ||
2631 | 542 | for (auto color : _colors) { | ||
2632 | 543 | types.push_back(color->getColorType(colorTypes)); | ||
2633 | 544 | } | ||
2634 | 545 | for (auto& elem : colorTypes) { | ||
2635 | 546 | auto* pt = dynamic_cast<ProductType*>(elem.second); | ||
2636 | 547 | if (pt && pt->containsTypes(types)) { | ||
2637 | 548 | return pt; | ||
2638 | 549 | } | ||
2639 | 550 | } | ||
2640 | 551 | std::cout << "COULD NOT FIND PRODUCT TYPE" << std::endl; | ||
2641 | 552 | return nullptr; | ||
2642 | 553 | } | ||
2643 | 554 | |||
2644 | 555 | void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override { | ||
2645 | 556 | for (auto elem : _colors) { | ||
2646 | 557 | elem->getConstants(constantMap, index); | ||
2647 | 558 | index++; | ||
2648 | 243 | } | 559 | } |
2649 | 244 | } | 560 | } |
2650 | 245 | 561 | ||
2651 | @@ -252,6 +568,10 @@ | |||
2652 | 252 | return res; | 568 | return res; |
2653 | 253 | } | 569 | } |
2654 | 254 | 570 | ||
2655 | 571 | void setColorType(ColorType* ct){ | ||
2656 | 572 | _colorType = ct; | ||
2657 | 573 | } | ||
2658 | 574 | |||
2659 | 255 | TupleExpression(std::vector<ColorExpression_ptr>&& colors) | 575 | TupleExpression(std::vector<ColorExpression_ptr>&& colors) |
2660 | 256 | : _colors(std::move(colors)) {} | 576 | : _colors(std::move(colors)) {} |
2661 | 257 | }; | 577 | }; |
2662 | @@ -262,6 +582,8 @@ | |||
2663 | 262 | virtual ~GuardExpression() {} | 582 | virtual ~GuardExpression() {} |
2664 | 263 | 583 | ||
2665 | 264 | virtual bool eval(ExpressionContext& context) const = 0; | 584 | virtual bool eval(ExpressionContext& context) const = 0; |
2666 | 585 | |||
2667 | 586 | virtual void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const = 0; | ||
2668 | 265 | }; | 587 | }; |
2669 | 266 | 588 | ||
2670 | 267 | typedef std::shared_ptr<GuardExpression> GuardExpression_ptr; | 589 | typedef std::shared_ptr<GuardExpression> GuardExpression_ptr; |
2671 | @@ -275,11 +597,40 @@ | |||
2672 | 275 | bool eval(ExpressionContext& context) const override { | 597 | bool eval(ExpressionContext& context) const override { |
2673 | 276 | return _left->eval(context) < _right->eval(context); | 598 | return _left->eval(context) < _right->eval(context); |
2674 | 277 | } | 599 | } |
2675 | 600 | |||
2676 | 601 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { | ||
2677 | 602 | _left->getVariables(variables, varPositions, varModifierMap); | ||
2678 | 603 | _right->getVariables(variables, varPositions, varModifierMap); | ||
2679 | 604 | } | ||
2680 | 605 | |||
2681 | 606 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2682 | 607 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL; | ||
2683 | 608 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR; | ||
2684 | 609 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL; | ||
2685 | 610 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR; | ||
2686 | 611 | std::unordered_map<uint32_t, const Color*> constantMapL; | ||
2687 | 612 | std::unordered_map<uint32_t, const Color*> constantMapR; | ||
2688 | 613 | std::set<const Variable *> leftVars; | ||
2689 | 614 | std::set<const Variable *> rightVars; | ||
2690 | 615 | uint32_t index = 0; | ||
2691 | 616 | _left->getVariables(leftVars, varPositionsL, varModifierMapL); | ||
2692 | 617 | _right->getVariables(rightVars, varPositionsR, varModifierMapR); | ||
2693 | 618 | _left->getConstants(constantMapL, index); | ||
2694 | 619 | index = 0; | ||
2695 | 620 | _right->getConstants(constantMapR, index); | ||
2696 | 621 | |||
2697 | 622 | if(leftVars.empty() && rightVars.empty()){ | ||
2698 | 623 | return; | ||
2699 | 624 | } | ||
2700 | 625 | Colored::GuardRestrictor guardRestrictor; | ||
2701 | 626 | guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, true, true); | ||
2702 | 627 | } | ||
2703 | 278 | 628 | ||
2707 | 279 | void getVariables(std::set<Variable*>& variables) const override { | 629 | std::string toString() const override { |
2708 | 280 | _left->getVariables(variables); | 630 | std::string res = _left->toString() + " < " + _right->toString(); |
2709 | 281 | _right->getVariables(variables); | 631 | return res; |
2710 | 282 | } | 632 | } |
2711 | 633 | |||
2712 | 283 | 634 | ||
2713 | 284 | LessThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) | 635 | LessThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) |
2714 | 285 | : _left(std::move(left)), _right(std::move(right)) {} | 636 | : _left(std::move(left)), _right(std::move(right)) {} |
2715 | @@ -295,9 +646,38 @@ | |||
2716 | 295 | return _left->eval(context) > _right->eval(context); | 646 | return _left->eval(context) > _right->eval(context); |
2717 | 296 | } | 647 | } |
2718 | 297 | 648 | ||
2722 | 298 | void getVariables(std::set<Variable*>& variables) const override { | 649 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2723 | 299 | _left->getVariables(variables); | 650 | _left->getVariables(variables, varPositions, varModifierMap); |
2724 | 300 | _right->getVariables(variables); | 651 | _right->getVariables(variables, varPositions, varModifierMap); |
2725 | 652 | } | ||
2726 | 653 | |||
2727 | 654 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2728 | 655 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL; | ||
2729 | 656 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR; | ||
2730 | 657 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL; | ||
2731 | 658 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR; | ||
2732 | 659 | std::unordered_map<uint32_t, const Color*> constantMapL; | ||
2733 | 660 | std::unordered_map<uint32_t, const Color*> constantMapR; | ||
2734 | 661 | std::set<const Colored::Variable *> leftVars; | ||
2735 | 662 | std::set<const Colored::Variable *> rightVars; | ||
2736 | 663 | uint32_t index = 0; | ||
2737 | 664 | _left->getVariables(leftVars, varPositionsL, varModifierMapL); | ||
2738 | 665 | _right->getVariables(rightVars, varPositionsR, varModifierMapR); | ||
2739 | 666 | _left->getConstants(constantMapL, index); | ||
2740 | 667 | index = 0; | ||
2741 | 668 | _right->getConstants(constantMapR, index); | ||
2742 | 669 | |||
2743 | 670 | if(leftVars.empty() && rightVars.empty()){ | ||
2744 | 671 | return; | ||
2745 | 672 | } | ||
2746 | 673 | |||
2747 | 674 | Colored::GuardRestrictor guardRestrictor; | ||
2748 | 675 | guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, false, true); | ||
2749 | 676 | } | ||
2750 | 677 | |||
2751 | 678 | std::string toString() const override { | ||
2752 | 679 | std::string res = _left->toString() + " > " + _right->toString(); | ||
2753 | 680 | return res; | ||
2754 | 301 | } | 681 | } |
2755 | 302 | 682 | ||
2756 | 303 | GreaterThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) | 683 | GreaterThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) |
2757 | @@ -314,10 +694,40 @@ | |||
2758 | 314 | return _left->eval(context) <= _right->eval(context); | 694 | return _left->eval(context) <= _right->eval(context); |
2759 | 315 | } | 695 | } |
2760 | 316 | 696 | ||
2765 | 317 | void getVariables(std::set<Variable*>& variables) const override { | 697 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2766 | 318 | _left->getVariables(variables); | 698 | _left->getVariables(variables, varPositions, varModifierMap); |
2767 | 319 | _right->getVariables(variables); | 699 | _right->getVariables(variables, varPositions, varModifierMap); |
2768 | 320 | } | 700 | } |
2769 | 701 | |||
2770 | 702 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2771 | 703 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL; | ||
2772 | 704 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR; | ||
2773 | 705 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL; | ||
2774 | 706 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR; | ||
2775 | 707 | std::unordered_map<uint32_t, const Color*> constantMapL; | ||
2776 | 708 | std::unordered_map<uint32_t, const Color*> constantMapR; | ||
2777 | 709 | std::set<const Colored::Variable *> leftVars; | ||
2778 | 710 | std::set<const Colored::Variable *> rightVars; | ||
2779 | 711 | uint32_t index = 0; | ||
2780 | 712 | _left->getVariables(leftVars, varPositionsL, varModifierMapL); | ||
2781 | 713 | _right->getVariables(rightVars, varPositionsR, varModifierMapR); | ||
2782 | 714 | _left->getConstants(constantMapL, index); | ||
2783 | 715 | index = 0; | ||
2784 | 716 | _right->getConstants(constantMapR, index); | ||
2785 | 717 | |||
2786 | 718 | if(leftVars.empty() && rightVars.empty()){ | ||
2787 | 719 | return; | ||
2788 | 720 | } | ||
2789 | 721 | |||
2790 | 722 | Colored::GuardRestrictor guardRestrictor; | ||
2791 | 723 | guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, true, false); | ||
2792 | 724 | } | ||
2793 | 725 | |||
2794 | 726 | std::string toString() const override { | ||
2795 | 727 | std::string res = _left->toString() + " <= " + _right->toString(); | ||
2796 | 728 | return res; | ||
2797 | 729 | } | ||
2798 | 730 | |||
2799 | 321 | 731 | ||
2800 | 322 | LessThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) | 732 | LessThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) |
2801 | 323 | : _left(std::move(left)), _right(std::move(right)) {} | 733 | : _left(std::move(left)), _right(std::move(right)) {} |
2802 | @@ -333,11 +743,40 @@ | |||
2803 | 333 | return _left->eval(context) >= _right->eval(context); | 743 | return _left->eval(context) >= _right->eval(context); |
2804 | 334 | } | 744 | } |
2805 | 335 | 745 | ||
2809 | 336 | void getVariables(std::set<Variable*>& variables) const override { | 746 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2810 | 337 | _left->getVariables(variables); | 747 | _left->getVariables(variables, varPositions, varModifierMap); |
2811 | 338 | _right->getVariables(variables); | 748 | _right->getVariables(variables, varPositions, varModifierMap); |
2812 | 749 | } | ||
2813 | 750 | |||
2814 | 751 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2815 | 752 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL; | ||
2816 | 753 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR; | ||
2817 | 754 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL; | ||
2818 | 755 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR; | ||
2819 | 756 | std::unordered_map<uint32_t, const Color*> constantMapL; | ||
2820 | 757 | std::unordered_map<uint32_t, const Color*> constantMapR; | ||
2821 | 758 | std::set<const Colored::Variable *> leftVars; | ||
2822 | 759 | std::set<const Colored::Variable *> rightVars; | ||
2823 | 760 | uint32_t index = 0; | ||
2824 | 761 | _left->getVariables(leftVars, varPositionsL, varModifierMapL); | ||
2825 | 762 | _right->getVariables(rightVars, varPositionsR, varModifierMapR); | ||
2826 | 763 | _left->getConstants(constantMapL, index); | ||
2827 | 764 | index = 0; | ||
2828 | 765 | _right->getConstants(constantMapR, index); | ||
2829 | 766 | |||
2830 | 767 | if(leftVars.empty() && rightVars.empty()){ | ||
2831 | 768 | return; | ||
2832 | 769 | } | ||
2833 | 770 | |||
2834 | 771 | Colored::GuardRestrictor guardRestrictor; | ||
2835 | 772 | guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, false, false); | ||
2836 | 339 | } | 773 | } |
2837 | 340 | 774 | ||
2838 | 775 | std::string toString() const override { | ||
2839 | 776 | std::string res = _left->toString() + " >= " + _right->toString(); | ||
2840 | 777 | return res; | ||
2841 | 778 | } | ||
2842 | 779 | |||
2843 | 341 | GreaterThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) | 780 | GreaterThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) |
2844 | 342 | : _left(std::move(left)), _right(std::move(right)) {} | 781 | : _left(std::move(left)), _right(std::move(right)) {} |
2845 | 343 | }; | 782 | }; |
2846 | @@ -352,11 +791,41 @@ | |||
2847 | 352 | return _left->eval(context) == _right->eval(context); | 791 | return _left->eval(context) == _right->eval(context); |
2848 | 353 | } | 792 | } |
2849 | 354 | 793 | ||
2853 | 355 | void getVariables(std::set<Variable*>& variables) const override { | 794 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2854 | 356 | _left->getVariables(variables); | 795 | _left->getVariables(variables, varPositions, varModifierMap); |
2855 | 357 | _right->getVariables(variables); | 796 | _right->getVariables(variables, varPositions, varModifierMap); |
2856 | 358 | } | 797 | } |
2857 | 359 | 798 | ||
2858 | 799 | |||
2859 | 800 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2860 | 801 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL; | ||
2861 | 802 | std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR; | ||
2862 | 803 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL; | ||
2863 | 804 | std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR; | ||
2864 | 805 | std::unordered_map<uint32_t, const Color*> constantMapL; | ||
2865 | 806 | std::unordered_map<uint32_t, const Color*> constantMapR; | ||
2866 | 807 | std::set<const Colored::Variable *> leftVars; | ||
2867 | 808 | std::set<const Colored::Variable *> rightVars; | ||
2868 | 809 | uint32_t index = 0; | ||
2869 | 810 | _left->getVariables(leftVars, varPositionsL, varModifierMapL); | ||
2870 | 811 | _right->getVariables(rightVars, varPositionsR, varModifierMapR); | ||
2871 | 812 | _left->getConstants(constantMapL, index); | ||
2872 | 813 | index = 0; | ||
2873 | 814 | _right->getConstants(constantMapR, index); | ||
2874 | 815 | |||
2875 | 816 | if(leftVars.empty() && rightVars.empty()){ | ||
2876 | 817 | return; | ||
2877 | 818 | } | ||
2878 | 819 | |||
2879 | 820 | Colored::GuardRestrictor guardRestrictor; | ||
2880 | 821 | guardRestrictor.restrictEquality(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR); | ||
2881 | 822 | } | ||
2882 | 823 | |||
2883 | 824 | std::string toString() const override { | ||
2884 | 825 | std::string res = _left->toString() + " == " + _right->toString(); | ||
2885 | 826 | return res; | ||
2886 | 827 | } | ||
2887 | 828 | |||
2888 | 360 | EqualityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) | 829 | EqualityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) |
2889 | 361 | : _left(std::move(left)), _right(std::move(right)) {} | 830 | : _left(std::move(left)), _right(std::move(right)) {} |
2890 | 362 | }; | 831 | }; |
2891 | @@ -371,9 +840,18 @@ | |||
2892 | 371 | return _left->eval(context) != _right->eval(context); | 840 | return _left->eval(context) != _right->eval(context); |
2893 | 372 | } | 841 | } |
2894 | 373 | 842 | ||
2898 | 374 | void getVariables(std::set<Variable*>& variables) const override { | 843 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2899 | 375 | _left->getVariables(variables); | 844 | _left->getVariables(variables, varPositions, varModifierMap); |
2900 | 376 | _right->getVariables(variables); | 845 | _right->getVariables(variables, varPositions, varModifierMap); |
2901 | 846 | } | ||
2902 | 847 | |||
2903 | 848 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2904 | 849 | |||
2905 | 850 | } | ||
2906 | 851 | |||
2907 | 852 | std::string toString() const override { | ||
2908 | 853 | std::string res = _left->toString() + " != " + _right->toString(); | ||
2909 | 854 | return res; | ||
2910 | 377 | } | 855 | } |
2911 | 378 | 856 | ||
2912 | 379 | InequalityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) | 857 | InequalityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right) |
2913 | @@ -389,8 +867,28 @@ | |||
2914 | 389 | return !_expr->eval(context); | 867 | return !_expr->eval(context); |
2915 | 390 | } | 868 | } |
2916 | 391 | 869 | ||
2918 | 392 | void getVariables(std::set<Variable*>& variables) const override { | 870 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2919 | 871 | _expr->getVariables(variables, varPositions, varModifierMap, index); | ||
2920 | 872 | } | ||
2921 | 873 | |||
2922 | 874 | std::string toString() const override { | ||
2923 | 875 | std::string res = "!" + _expr->toString(); | ||
2924 | 876 | return res; | ||
2925 | 877 | } | ||
2926 | 878 | |||
2927 | 879 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2928 | 880 | std::set<const Colored::Variable *> variables; | ||
2929 | 393 | _expr->getVariables(variables); | 881 | _expr->getVariables(variables); |
2930 | 882 | //TODO: invert the var intervals here instead of using the full intervals | ||
2931 | 883 | |||
2932 | 884 | for(auto var : variables){ | ||
2933 | 885 | auto fullInterval = var->colorType->getFullInterval(); | ||
2934 | 886 | Colored::intervalTuple_t fullTuple; | ||
2935 | 887 | fullTuple.addInterval(fullInterval); | ||
2936 | 888 | for(auto& varMap : variableMap){ | ||
2937 | 889 | varMap[var] = fullTuple; | ||
2938 | 890 | } | ||
2939 | 891 | } | ||
2940 | 394 | } | 892 | } |
2941 | 395 | 893 | ||
2942 | 396 | NotExpression(GuardExpression_ptr&& expr) : _expr(std::move(expr)) {} | 894 | NotExpression(GuardExpression_ptr&& expr) : _expr(std::move(expr)) {} |
2943 | @@ -406,11 +904,21 @@ | |||
2944 | 406 | return _left->eval(context) && _right->eval(context); | 904 | return _left->eval(context) && _right->eval(context); |
2945 | 407 | } | 905 | } |
2946 | 408 | 906 | ||
2952 | 409 | void getVariables(std::set<Variable*>& variables) const override { | 907 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2953 | 410 | _left->getVariables(variables); | 908 | _left->getVariables(variables, varPositions, varModifierMap); |
2954 | 411 | _right->getVariables(variables); | 909 | _right->getVariables(variables, varPositions, varModifierMap); |
2955 | 412 | } | 910 | } |
2956 | 413 | 911 | ||
2957 | 912 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override { | ||
2958 | 913 | _left->restrictVars(variableMap); | ||
2959 | 914 | _right->restrictVars(variableMap); | ||
2960 | 915 | } | ||
2961 | 916 | |||
2962 | 917 | std::string toString() const override { | ||
2963 | 918 | std::string res = _left->toString() + " && " + _right->toString(); | ||
2964 | 919 | return res; | ||
2965 | 920 | } | ||
2966 | 921 | |||
2967 | 414 | AndExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right) | 922 | AndExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right) |
2968 | 415 | : _left(left), _right(right) {} | 923 | : _left(left), _right(right) {} |
2969 | 416 | }; | 924 | }; |
2970 | @@ -425,11 +933,30 @@ | |||
2971 | 425 | return _left->eval(context) || _right->eval(context); | 933 | return _left->eval(context) || _right->eval(context); |
2972 | 426 | } | 934 | } |
2973 | 427 | 935 | ||
2979 | 428 | void getVariables(std::set<Variable*>& variables) const override { | 936 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
2980 | 429 | _left->getVariables(variables); | 937 | _left->getVariables(variables, varPositions, varModifierMap); |
2981 | 430 | _right->getVariables(variables); | 938 | _right->getVariables(variables, varPositions, varModifierMap); |
2982 | 431 | } | 939 | } |
2983 | 432 | 940 | ||
2984 | 941 | void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override{ | ||
2985 | 942 | auto varMapCopy = variableMap; | ||
2986 | 943 | _left->restrictVars(variableMap); | ||
2987 | 944 | _right->restrictVars(varMapCopy); | ||
2988 | 945 | |||
2989 | 946 | for(size_t i = 0; i < variableMap.size(); i++){ | ||
2990 | 947 | for(auto& varPair : varMapCopy[i]){ | ||
2991 | 948 | for(auto& interval : varPair.second._intervals){ | ||
2992 | 949 | variableMap[i][varPair.first].addInterval(std::move(interval)); | ||
2993 | 950 | } | ||
2994 | 951 | } | ||
2995 | 952 | } | ||
2996 | 953 | } | ||
2997 | 954 | |||
2998 | 955 | std::string toString() const override { | ||
2999 | 956 | std::string res = _left->toString() + " || " + _right->toString(); | ||
3000 | 957 | return res; | ||
3001 | 958 | } | ||
3002 | 959 | |||
3003 | 433 | OrExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right) | 960 | OrExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right) |
3004 | 434 | : _left(std::move(left)), _right(std::move(right)) {} | 961 | : _left(std::move(left)), _right(std::move(right)) {} |
3005 | 435 | }; | 962 | }; |
3006 | @@ -444,8 +971,21 @@ | |||
3007 | 444 | virtual void expressionType() override { | 971 | virtual void expressionType() override { |
3008 | 445 | std::cout << "ArcExpression" << std::endl; | 972 | std::cout << "ArcExpression" << std::endl; |
3009 | 446 | } | 973 | } |
3010 | 974 | virtual void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const = 0; | ||
3011 | 975 | |||
3012 | 976 | virtual bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const = 0; | ||
3013 | 447 | 977 | ||
3014 | 448 | virtual uint32_t weight() const = 0; | 978 | virtual uint32_t weight() const = 0; |
3015 | 979 | |||
3016 | 980 | virtual Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec) const { | ||
3017 | 981 | std::vector<const Colored::ColorType *> colortypes; | ||
3018 | 982 | |||
3019 | 983 | return getOutputIntervals(varMapVec, &colortypes); | ||
3020 | 984 | } | ||
3021 | 985 | |||
3022 | 986 | virtual Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec, std::vector<const Colored::ColorType *> *colortypes) const { | ||
3023 | 987 | return Colored::intervalTuple_t(); | ||
3024 | 988 | } | ||
3025 | 449 | }; | 989 | }; |
3026 | 450 | 990 | ||
3027 | 451 | typedef std::shared_ptr<ArcExpression> ArcExpression_ptr; | 991 | typedef std::shared_ptr<ArcExpression> ArcExpression_ptr; |
3028 | @@ -465,6 +1005,45 @@ | |||
3029 | 465 | return colors; | 1005 | return colors; |
3030 | 466 | } | 1006 | } |
3031 | 467 | 1007 | ||
3032 | 1008 | void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const { | ||
3033 | 1009 | for (size_t i = 0; i < _sort->size(); i++) { | ||
3034 | 1010 | constantMap[index].push_back(&(*_sort)[i]); | ||
3035 | 1011 | } | ||
3036 | 1012 | } | ||
3037 | 1013 | |||
3038 | 1014 | Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec, std::vector<const Colored::ColorType *> *colortypes) const { | ||
3039 | 1015 | Colored::intervalTuple_t newIntervalTuple; | ||
3040 | 1016 | newIntervalTuple.addInterval(_sort->getFullInterval()); | ||
3041 | 1017 | return newIntervalTuple; | ||
3042 | 1018 | } | ||
3043 | 1019 | |||
3044 | 1020 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const { | ||
3045 | 1021 | |||
3046 | 1022 | if(arcIntervals._intervalTupleVec.empty()){ | ||
3047 | 1023 | bool colorsInFixpoint = false; | ||
3048 | 1024 | Colored::intervalTuple_t newIntervalTuple; | ||
3049 | 1025 | cfp.constraints.simplify(); | ||
3050 | 1026 | if(cfp.constraints.getContainedColors() == _sort->size()){ | ||
3051 | 1027 | colorsInFixpoint = true; | ||
3052 | 1028 | for(auto interval : cfp.constraints._intervals){ | ||
3053 | 1029 | newIntervalTuple.addInterval(interval); | ||
3054 | 1030 | } | ||
3055 | 1031 | } | ||
3056 | 1032 | arcIntervals._intervalTupleVec.push_back(newIntervalTuple); | ||
3057 | 1033 | return colorsInFixpoint; | ||
3058 | 1034 | } else { | ||
3059 | 1035 | std::vector<Colored::intervalTuple_t> newIntervalTupleVec; | ||
3060 | 1036 | for(uint32_t i = 0; i < arcIntervals._intervalTupleVec.size(); i++){ | ||
3061 | 1037 | auto& intervalTuple = arcIntervals._intervalTupleVec[i]; | ||
3062 | 1038 | if(intervalTuple.getContainedColors() == _sort->size()){ | ||
3063 | 1039 | newIntervalTupleVec.push_back(intervalTuple); | ||
3064 | 1040 | } | ||
3065 | 1041 | } | ||
3066 | 1042 | arcIntervals._intervalTupleVec = std::move(newIntervalTupleVec); | ||
3067 | 1043 | return !arcIntervals._intervalTupleVec.empty(); | ||
3068 | 1044 | } | ||
3069 | 1045 | } | ||
3070 | 1046 | |||
3071 | 468 | size_t size() const { | 1047 | size_t size() const { |
3072 | 469 | return _sort->size(); | 1048 | return _sort->size(); |
3073 | 470 | } | 1049 | } |
3074 | @@ -503,12 +1082,64 @@ | |||
3075 | 503 | } | 1082 | } |
3076 | 504 | return Multiset(col); | 1083 | return Multiset(col); |
3077 | 505 | } | 1084 | } |
3080 | 506 | 1085 | ||
3081 | 507 | void getVariables(std::set<Variable*>& variables) const override { | 1086 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
3082 | 508 | if (_all != nullptr) | 1087 | if (_all != nullptr) |
3083 | 509 | return; | 1088 | return; |
3084 | 510 | for (auto elem : _color) { | 1089 | for (auto elem : _color) { |
3086 | 511 | elem->getVariables(variables); | 1090 | //TODO: can there be more than one element in a number of expression? |
3087 | 1091 | elem->getVariables(variables, varPositions, varModifierMap, index); | ||
3088 | 1092 | //(*index)++; | ||
3089 | 1093 | } | ||
3090 | 1094 | } | ||
3091 | 1095 | |||
3092 | 1096 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
3093 | 1097 | if (_all != nullptr) { | ||
3094 | 1098 | return _all->getArcIntervals(arcIntervals, cfp, index, modifier); | ||
3095 | 1099 | } | ||
3096 | 1100 | uint32_t i = 0; | ||
3097 | 1101 | for (auto elem : _color) { | ||
3098 | 1102 | (*index) += i; | ||
3099 | 1103 | if(!elem->getArcIntervals(arcIntervals, cfp, index, modifier)){ | ||
3100 | 1104 | return false; | ||
3101 | 1105 | } | ||
3102 | 1106 | i++; | ||
3103 | 1107 | } | ||
3104 | 1108 | return true; | ||
3105 | 1109 | } | ||
3106 | 1110 | |||
3107 | 1111 | Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
3108 | 1112 | Colored::intervalTuple_t intervals; | ||
3109 | 1113 | if (_all == nullptr) { | ||
3110 | 1114 | for (auto elem : _color) { | ||
3111 | 1115 | for(auto& varMap : varMapVec){ | ||
3112 | 1116 | auto nestedIntervals = elem->getOutputIntervals(varMap, colortypes); | ||
3113 | 1117 | |||
3114 | 1118 | if (intervals._intervals.empty()) { | ||
3115 | 1119 | intervals = nestedIntervals; | ||
3116 | 1120 | } else { | ||
3117 | 1121 | for(auto interval : nestedIntervals._intervals) { | ||
3118 | 1122 | intervals.addInterval(interval); | ||
3119 | 1123 | } | ||
3120 | 1124 | } | ||
3121 | 1125 | } | ||
3122 | 1126 | } | ||
3123 | 1127 | } else { | ||
3124 | 1128 | return _all->getOutputIntervals(varMapVec, colortypes); | ||
3125 | 1129 | } | ||
3126 | 1130 | return intervals; | ||
3127 | 1131 | } | ||
3128 | 1132 | |||
3129 | 1133 | void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override { | ||
3130 | 1134 | if (_all != nullptr) | ||
3131 | 1135 | _all->getConstants(constantMap, index); | ||
3132 | 1136 | else for (auto elem : _color) { | ||
3133 | 1137 | std::unordered_map<uint32_t, const Color*> elemMap; | ||
3134 | 1138 | elem->getConstants(elemMap, index); | ||
3135 | 1139 | for(auto pair : elemMap){ | ||
3136 | 1140 | constantMap[pair.first].push_back(pair.second); | ||
3137 | 1141 | } | ||
3138 | 1142 | index++;//not sure if index should be increased here, but no number expression have multiple elements | ||
3139 | 512 | } | 1143 | } |
3140 | 513 | } | 1144 | } |
3141 | 514 | 1145 | ||
3142 | @@ -563,9 +1194,57 @@ | |||
3143 | 563 | return ms; | 1194 | return ms; |
3144 | 564 | } | 1195 | } |
3145 | 565 | 1196 | ||
3149 | 566 | void getVariables(std::set<Variable*>& variables) const override { | 1197 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
3150 | 567 | for (auto elem : _constituents) { | 1198 | for (auto elem : _constituents) { |
3151 | 568 | elem->getVariables(variables); | 1199 | for(auto& pair : varModifierMap){ |
3152 | 1200 | std::unordered_map<uint32_t, int32_t> newMap; | ||
3153 | 1201 | pair.second.push_back(newMap); | ||
3154 | 1202 | } | ||
3155 | 1203 | elem->getVariables(variables, varPositions, varModifierMap); | ||
3156 | 1204 | } | ||
3157 | 1205 | } | ||
3158 | 1206 | |||
3159 | 1207 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
3160 | 1208 | for (auto elem : _constituents) { | ||
3161 | 1209 | uint32_t newIndex = 0; | ||
3162 | 1210 | Colored::ArcIntervals newArcIntervals; | ||
3163 | 1211 | std::vector<uint32_t> intervalsForRemoval; | ||
3164 | 1212 | std::vector<Colored::interval_t> newIntervals; | ||
3165 | 1213 | if(!elem->getArcIntervals(newArcIntervals, cfp, &newIndex, modifier)){ | ||
3166 | 1214 | return false; | ||
3167 | 1215 | } | ||
3168 | 1216 | |||
3169 | 1217 | if(newArcIntervals._intervalTupleVec.empty()){ | ||
3170 | 1218 | return false; | ||
3171 | 1219 | } | ||
3172 | 1220 | |||
3173 | 1221 | arcIntervals._intervalTupleVec.insert(arcIntervals._intervalTupleVec.end(), newArcIntervals._intervalTupleVec.begin(), newArcIntervals._intervalTupleVec.end()); | ||
3174 | 1222 | } | ||
3175 | 1223 | return true; | ||
3176 | 1224 | } | ||
3177 | 1225 | |||
3178 | 1226 | Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
3179 | 1227 | Colored::intervalTuple_t intervals; | ||
3180 | 1228 | |||
3181 | 1229 | for (auto elem : _constituents) { | ||
3182 | 1230 | auto nestedIntervals = elem->getOutputIntervals(varMapVec, colortypes); | ||
3183 | 1231 | |||
3184 | 1232 | if (intervals._intervals.empty()) { | ||
3185 | 1233 | intervals = nestedIntervals; | ||
3186 | 1234 | } else { | ||
3187 | 1235 | for(auto interval : nestedIntervals._intervals) { | ||
3188 | 1236 | intervals.addInterval(interval); | ||
3189 | 1237 | } | ||
3190 | 1238 | } | ||
3191 | 1239 | } | ||
3192 | 1240 | return intervals; | ||
3193 | 1241 | } | ||
3194 | 1242 | |||
3195 | 1243 | void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override { | ||
3196 | 1244 | uint32_t indexCopy = index; | ||
3197 | 1245 | for (auto elem : _constituents) { | ||
3198 | 1246 | uint32_t localIndex = indexCopy; | ||
3199 | 1247 | elem->getConstants(constantMap, localIndex); | ||
3200 | 569 | } | 1248 | } |
3201 | 570 | } | 1249 | } |
3202 | 571 | 1250 | ||
3203 | @@ -599,9 +1278,29 @@ | |||
3204 | 599 | return _left->eval(context) - _right->eval(context); | 1278 | return _left->eval(context) - _right->eval(context); |
3205 | 600 | } | 1279 | } |
3206 | 601 | 1280 | ||
3210 | 602 | void getVariables(std::set<Variable*>& variables) const override { | 1281 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
3211 | 603 | _left->getVariables(variables); | 1282 | _left->getVariables(variables, varPositions, varModifierMap); |
3212 | 604 | _right->getVariables(variables); | 1283 | //We ignore the restrictions imposed by the subtraction for now |
3213 | 1284 | //_right->getVariables(variables, varPositions, varModifierMap); | ||
3214 | 1285 | } | ||
3215 | 1286 | |||
3216 | 1287 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
3217 | 1288 | return _left->getArcIntervals(arcIntervals, cfp, index, modifier); | ||
3218 | 1289 | //We ignore the restrictions imposed by the subtraction for now | ||
3219 | 1290 | //_right->getArcIntervals(arcIntervals, cfp, &rightIndex); | ||
3220 | 1291 | } | ||
3221 | 1292 | |||
3222 | 1293 | Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
3223 | 1294 | //We could maybe reduce the intervals slightly by checking if the upper or lower bound is being subtracted | ||
3224 | 1295 | auto leftIntervals = _left->getOutputIntervals(varMapVec, colortypes); | ||
3225 | 1296 | |||
3226 | 1297 | return leftIntervals; | ||
3227 | 1298 | } | ||
3228 | 1299 | |||
3229 | 1300 | void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override { | ||
3230 | 1301 | uint32_t rIndex = index; | ||
3231 | 1302 | _left->getConstants(constantMap, index); | ||
3232 | 1303 | _right->getConstants(constantMap, rIndex); | ||
3233 | 605 | } | 1304 | } |
3234 | 606 | 1305 | ||
3235 | 607 | uint32_t weight() const override { | 1306 | uint32_t weight() const override { |
3236 | @@ -636,8 +1335,20 @@ | |||
3237 | 636 | return _expr->eval(context) * _scalar; | 1335 | return _expr->eval(context) * _scalar; |
3238 | 637 | } | 1336 | } |
3239 | 638 | 1337 | ||
3242 | 639 | void getVariables(std::set<Variable*>& variables) const override { | 1338 | void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions, std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>>& varModifierMap, uint32_t *index) const override { |
3243 | 640 | _expr->getVariables(variables); | 1339 | _expr->getVariables(variables, varPositions,varModifierMap); |
3244 | 1340 | } | ||
3245 | 1341 | |||
3246 | 1342 | bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override { | ||
3247 | 1343 | return _expr ->getArcIntervals(arcIntervals, cfp, index, modifier); | ||
3248 | 1344 | } | ||
3249 | 1345 | |||
3250 | 1346 | Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec, std::vector<const Colored::ColorType *> *colortypes) const override { | ||
3251 | 1347 | return _expr->getOutputIntervals(varMapVec, colortypes); | ||
3252 | 1348 | } | ||
3253 | 1349 | |||
3254 | 1350 | void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override { | ||
3255 | 1351 | _expr->getConstants(constantMap, index); | ||
3256 | 641 | } | 1352 | } |
3257 | 642 | 1353 | ||
3258 | 643 | uint32_t weight() const override { | 1354 | uint32_t weight() const override { |
3259 | 644 | 1355 | ||
3260 | === added file 'include/PetriEngine/Colored/GuardRestrictor.h' | |||
3261 | --- include/PetriEngine/Colored/GuardRestrictor.h 1970-01-01 00:00:00 +0000 | |||
3262 | +++ include/PetriEngine/Colored/GuardRestrictor.h 2021-04-02 18:07:40 +0000 | |||
3263 | @@ -0,0 +1,83 @@ | |||
3264 | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, | ||
3265 | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, | ||
3266 | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> | ||
3267 | 4 | * | ||
3268 | 5 | * This program is free software: you can redistribute it and/or modify | ||
3269 | 6 | * it under the terms of the GNU General Public License as published by | ||
3270 | 7 | * the Free Software Foundation, either version 3 of the License, or | ||
3271 | 8 | * (at your option) any later version. | ||
3272 | 9 | * | ||
3273 | 10 | * This program is distributed in the hope that it will be useful, | ||
3274 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3275 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3276 | 13 | * GNU General Public License for more details. | ||
3277 | 14 | * | ||
3278 | 15 | * You should have received a copy of the GNU General Public License | ||
3279 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3280 | 17 | */ | ||
3281 | 18 | |||
3282 | 19 | #ifndef GuardRestrictions_H | ||
3283 | 20 | #define GuardRestrictions_H | ||
3284 | 21 | |||
3285 | 22 | #include "Colors.h" | ||
3286 | 23 | #include "Multiset.h" | ||
3287 | 24 | #include <unordered_map> | ||
3288 | 25 | #include <set> | ||
3289 | 26 | #include <stdlib.h> | ||
3290 | 27 | |||
3291 | 28 | namespace PetriEngine { | ||
3292 | 29 | namespace Colored { | ||
3293 | 30 | |||
3294 | 31 | class GuardRestrictor { | ||
3295 | 32 | public: | ||
3296 | 33 | |||
3297 | 34 | GuardRestrictor(); | ||
3298 | 35 | |||
3299 | 36 | void restrictDiagonal(std::vector<std::unordered_map<const Variable *, intervalTuple_t>> *variableMap, | ||
3300 | 37 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapL, | ||
3301 | 38 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapR, | ||
3302 | 39 | std::unordered_map<uint32_t, const Variable *> *varPositionsL, | ||
3303 | 40 | std::unordered_map<uint32_t, const Variable *> *varPositionsR, | ||
3304 | 41 | std::unordered_map<uint32_t, const Color*> *constantMapL, | ||
3305 | 42 | std::unordered_map<uint32_t, const Color*> *constantMapR, | ||
3306 | 43 | bool lessthan, bool strict); | ||
3307 | 44 | |||
3308 | 45 | void restrictEquality(std::vector<std::unordered_map<const Variable *, intervalTuple_t>> *variableMap, | ||
3309 | 46 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapL, | ||
3310 | 47 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapR, | ||
3311 | 48 | std::unordered_map<uint32_t, const Variable *> *varPositionsL, | ||
3312 | 49 | std::unordered_map<uint32_t, const Variable *> *varPositionsR, | ||
3313 | 50 | std::unordered_map<uint32_t, const Color*> *constantMapL, | ||
3314 | 51 | std::unordered_map<uint32_t, const Color*> *constantMapR); | ||
3315 | 52 | |||
3316 | 53 | intervalTuple_t shiftIntervals(std::vector<const ColorType *> *colortypes, | ||
3317 | 54 | intervalTuple_t *intervals, | ||
3318 | 55 | int32_t modifier, | ||
3319 | 56 | uint32_t ctSizeBefore) const; | ||
3320 | 57 | |||
3321 | 58 | private: | ||
3322 | 59 | int32_t getVarModifier(std::unordered_map<uint32_t, int32_t> *modPairMap, uint32_t index); | ||
3323 | 60 | interval_t getIntervalFromIds(std::vector<uint32_t> *idVec, uint32_t ctSize, int32_t modifier); | ||
3324 | 61 | intervalTuple_t getIntervalOverlap(std::vector<interval_t> *intervals1, std::vector<interval_t> *intervals2); | ||
3325 | 62 | |||
3326 | 63 | void expandIdVec(std::unordered_map<const Variable *, intervalTuple_t> *varMap, | ||
3327 | 64 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *mainVarModifierMap, | ||
3328 | 65 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *otherVarModifierMap, | ||
3329 | 66 | std::unordered_map<uint32_t, const Variable *> *varPositions, | ||
3330 | 67 | std::unordered_map<uint32_t, const Color*> *constantMap, | ||
3331 | 68 | const Variable *otherVar, | ||
3332 | 69 | std::vector<uint32_t> &idVec, size_t targetSize, uint32_t index); | ||
3333 | 70 | |||
3334 | 71 | void expandIntervalVec(std::unordered_map<const Variable *, intervalTuple_t> *varMap, | ||
3335 | 72 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *mainVarModifierMap, | ||
3336 | 73 | std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *otherVarModifierMap, | ||
3337 | 74 | std::unordered_map<uint32_t, const Variable *> *varPositions, | ||
3338 | 75 | std::unordered_map<uint32_t, const Color*> *constantMap, | ||
3339 | 76 | const Variable *otherVar, | ||
3340 | 77 | std::vector<interval_t> &intervalVec, size_t targetSize, uint32_t index); | ||
3341 | 78 | }; | ||
3342 | 79 | } | ||
3343 | 80 | } | ||
3344 | 81 | |||
3345 | 82 | |||
3346 | 83 | #endif /* GuardRestrictions_H */ | ||
3347 | 0 | \ No newline at end of file | 84 | \ No newline at end of file |
3348 | 1 | 85 | ||
3349 | === added file 'include/PetriEngine/Colored/IntervalGenerator.h' | |||
3350 | --- include/PetriEngine/Colored/IntervalGenerator.h 1970-01-01 00:00:00 +0000 | |||
3351 | +++ include/PetriEngine/Colored/IntervalGenerator.h 2021-04-02 18:07:40 +0000 | |||
3352 | @@ -0,0 +1,197 @@ | |||
3353 | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, | ||
3354 | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, | ||
3355 | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> | ||
3356 | 4 | * | ||
3357 | 5 | * This program is free software: you can redistribute it and/or modify | ||
3358 | 6 | * it under the terms of the GNU General Public License as published by | ||
3359 | 7 | * the Free Software Foundation, either version 3 of the License, or | ||
3360 | 8 | * (at your option) any later version. | ||
3361 | 9 | * | ||
3362 | 10 | * This program is distributed in the hope that it will be useful, | ||
3363 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3364 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3365 | 13 | * GNU General Public License for more details. | ||
3366 | 14 | * | ||
3367 | 15 | * You should have received a copy of the GNU General Public License | ||
3368 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3369 | 17 | */ | ||
3370 | 18 | #ifndef INTERVALGENERATOR_H | ||
3371 | 19 | #define INTERVALGENERATOR_H | ||
3372 | 20 | |||
3373 | 21 | #include "ColoredNetStructures.h" | ||
3374 | 22 | |||
3375 | 23 | namespace PetriEngine { | ||
3376 | 24 | struct IntervalGenerator { | ||
3377 | 25 | std::vector<Colored::interval_t> getIntervalsFromInterval(Colored::interval_t *interval, uint32_t varPosition, int32_t varModifier, std::vector<Colored::ColorType*> *varColorTypes){ | ||
3378 | 26 | std::vector<Colored::interval_t> varIntervals; | ||
3379 | 27 | Colored::interval_t firstVarInterval; | ||
3380 | 28 | varIntervals.push_back(firstVarInterval); | ||
3381 | 29 | for(uint32_t i = varPosition; i < varPosition + varColorTypes->size(); i++){ | ||
3382 | 30 | auto ctSize = varColorTypes->operator[](i - varPosition)->size(); | ||
3383 | 31 | int32_t lower_val = ctSize + (interval->operator[](i)._lower + varModifier); | ||
3384 | 32 | int32_t upper_val = ctSize + (interval->operator[](i)._upper + varModifier); | ||
3385 | 33 | uint32_t lower = lower_val % ctSize; | ||
3386 | 34 | uint32_t upper = upper_val % ctSize; | ||
3387 | 35 | |||
3388 | 36 | if(lower > upper ){ | ||
3389 | 37 | if(lower == upper+1){ | ||
3390 | 38 | for (auto& varInterval : varIntervals){ | ||
3391 | 39 | varInterval.addRange(0, ctSize -1); | ||
3392 | 40 | } | ||
3393 | 41 | } else { | ||
3394 | 42 | std::vector<Colored::interval_t> newIntervals; | ||
3395 | 43 | for (auto& varInterval : varIntervals){ | ||
3396 | 44 | Colored::interval_t newVarInterval = varInterval; | ||
3397 | 45 | varInterval.addRange(0, upper); | ||
3398 | 46 | newVarInterval.addRange(lower, ctSize -1); | ||
3399 | 47 | newIntervals.push_back(newVarInterval); | ||
3400 | 48 | } | ||
3401 | 49 | varIntervals.insert(varIntervals.end(), newIntervals.begin(), newIntervals.end()); | ||
3402 | 50 | } | ||
3403 | 51 | } else { | ||
3404 | 52 | for (auto& varInterval : varIntervals){ | ||
3405 | 53 | varInterval.addRange(lower, upper); | ||
3406 | 54 | } | ||
3407 | 55 | } | ||
3408 | 56 | } | ||
3409 | 57 | return varIntervals; | ||
3410 | 58 | } | ||
3411 | 59 | |||
3412 | 60 | void getArcVarIntervals(Colored::intervalTuple_t& varIntervals, std::unordered_map<uint32_t, int32_t> *modIndexMap, Colored::interval_t *interval, std::vector<Colored::ColorType*> *varColorTypes){ | ||
3413 | 61 | for(auto& posModPair : *modIndexMap){ | ||
3414 | 62 | auto intervals = getIntervalsFromInterval(interval, posModPair.first, posModPair.second, varColorTypes); | ||
3415 | 63 | |||
3416 | 64 | if(varIntervals._intervals.empty()){ | ||
3417 | 65 | for(auto& interval : intervals){ | ||
3418 | 66 | varIntervals.addInterval(std::move(interval)); | ||
3419 | 67 | } | ||
3420 | 68 | } else { | ||
3421 | 69 | Colored::intervalTuple_t newVarIntervals; | ||
3422 | 70 | for(uint32_t i = 0; i < varIntervals.size(); i++){ | ||
3423 | 71 | auto varInterval = &varIntervals[i]; | ||
3424 | 72 | for(auto& interval : intervals){ | ||
3425 | 73 | auto overlap = varInterval->getOverlap(std::move(interval)); | ||
3426 | 74 | if(overlap.isSound()){ | ||
3427 | 75 | newVarIntervals.addInterval(std::move(overlap)); | ||
3428 | 76 | //break; | ||
3429 | 77 | } | ||
3430 | 78 | } | ||
3431 | 79 | } | ||
3432 | 80 | varIntervals = std::move(newVarIntervals); | ||
3433 | 81 | } | ||
3434 | 82 | } | ||
3435 | 83 | } | ||
3436 | 84 | |||
3437 | 85 | void populateLocalMap(Colored::ArcIntervals *arcIntervals, | ||
3438 | 86 | std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t> &varMap, | ||
3439 | 87 | std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t> &localVarMap, | ||
3440 | 88 | Colored::interval_t* interval, bool& allVarsAssigned, uint32_t tuplePos){ | ||
3441 | 89 | for(auto& pair : arcIntervals->_varIndexModMap){ | ||
3442 | 90 | Colored::intervalTuple_t varIntervals; | ||
3443 | 91 | std::vector<Colored::ColorType*> varColorTypes; | ||
3444 | 92 | pair.first->colorType->getColortypes(varColorTypes); | ||
3445 | 93 | |||
3446 | 94 | getArcVarIntervals(varIntervals, &pair.second[tuplePos], interval, &varColorTypes); | ||
3447 | 95 | |||
3448 | 96 | if (arcIntervals->_intervalTupleVec.size() > 1 && pair.second[tuplePos].empty()) { | ||
3449 | 97 | //The variable is not on this side of the add expression, so we add a full interval to compare against for the other side | ||
3450 | 98 | varIntervals.addInterval(pair.first->colorType->getFullInterval()); | ||
3451 | 99 | } | ||
3452 | 100 | |||
3453 | 101 | if(varMap.count(pair.first) == 0){ | ||
3454 | 102 | localVarMap[pair.first] = std::move(varIntervals); | ||
3455 | 103 | } else { | ||
3456 | 104 | for(auto& varInterval : varIntervals._intervals){ | ||
3457 | 105 | for(auto& interval : varMap[pair.first]._intervals){ | ||
3458 | 106 | auto overlapInterval = varInterval.getOverlap(interval); | ||
3459 | 107 | |||
3460 | 108 | if(overlapInterval.isSound()){ | ||
3461 | 109 | localVarMap[pair.first].addInterval(overlapInterval); | ||
3462 | 110 | } | ||
3463 | 111 | } | ||
3464 | 112 | } | ||
3465 | 113 | } | ||
3466 | 114 | |||
3467 | 115 | if(localVarMap[pair.first]._intervals.empty()){ | ||
3468 | 116 | allVarsAssigned = false; | ||
3469 | 117 | } | ||
3470 | 118 | } | ||
3471 | 119 | } | ||
3472 | 120 | |||
3473 | 121 | void fillVarMaps(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>> &variableMaps, | ||
3474 | 122 | Colored::ArcIntervals *arcIntervals, | ||
3475 | 123 | uint32_t *intervalTupleSize, | ||
3476 | 124 | uint32_t *tuplePos) | ||
3477 | 125 | { | ||
3478 | 126 | for(uint32_t i = 0; i < *intervalTupleSize; i++){ | ||
3479 | 127 | std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t> localVarMap; | ||
3480 | 128 | bool validInterval = true; | ||
3481 | 129 | auto interval = &arcIntervals->_intervalTupleVec[*tuplePos]._intervals[i]; | ||
3482 | 130 | |||
3483 | 131 | for(auto pair : arcIntervals->_varIndexModMap){ | ||
3484 | 132 | Colored::intervalTuple_t varIntervals; | ||
3485 | 133 | std::vector<Colored::ColorType*> varColorTypes; | ||
3486 | 134 | pair.first->colorType->getColortypes(varColorTypes); | ||
3487 | 135 | getArcVarIntervals(varIntervals, &pair.second[*tuplePos], interval, &varColorTypes); | ||
3488 | 136 | |||
3489 | 137 | if(arcIntervals->_intervalTupleVec.size() > 1 && pair.second[*tuplePos].empty()){ | ||
3490 | 138 | //The variable is not on this side of the add expression, so we add a full interval to compare against for the other side | ||
3491 | 139 | varIntervals.addInterval(pair.first->colorType->getFullInterval()); | ||
3492 | 140 | } else if(varIntervals.size() < 1){ | ||
3493 | 141 | //If any varinterval ends up empty then we were unable to use this arc interval | ||
3494 | 142 | validInterval = false; | ||
3495 | 143 | break; | ||
3496 | 144 | } | ||
3497 | 145 | localVarMap[pair.first] = varIntervals; | ||
3498 | 146 | } | ||
3499 | 147 | |||
3500 | 148 | if(validInterval){ | ||
3501 | 149 | variableMaps.push_back(localVarMap); | ||
3502 | 150 | } | ||
3503 | 151 | } | ||
3504 | 152 | } | ||
3505 | 153 | |||
3506 | 154 | bool getVarIntervals(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMaps, std::unordered_map<uint32_t, Colored::ArcIntervals> placeArcIntervals){ | ||
3507 | 155 | for(auto& placeArcInterval : placeArcIntervals){ | ||
3508 | 156 | for(uint32_t j = 0; j < placeArcInterval.second._intervalTupleVec.size(); j++){ | ||
3509 | 157 | uint32_t intervalTupleSize = placeArcInterval.second._intervalTupleVec[j].size(); | ||
3510 | 158 | //If we have not found intervals for any place yet, we fill the intervals from this place | ||
3511 | 159 | //Else we restrict the intervals we already found to only keep those that can also be matched in this place | ||
3512 | 160 | if(variableMaps.empty()){ | ||
3513 | 161 | fillVarMaps(variableMaps, &placeArcInterval.second, &intervalTupleSize, &j); | ||
3514 | 162 | } else { | ||
3515 | 163 | std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>> newVarMapVec; | ||
3516 | 164 | |||
3517 | 165 | for(auto& varMap : variableMaps){ | ||
3518 | 166 | for(uint32_t i = 0; i < intervalTupleSize; i++){ | ||
3519 | 167 | std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t> localVarMap; | ||
3520 | 168 | bool allVarsAssigned = true; | ||
3521 | 169 | auto interval = &placeArcInterval.second._intervalTupleVec[j]._intervals[i]; | ||
3522 | 170 | |||
3523 | 171 | populateLocalMap(&placeArcInterval.second, varMap, localVarMap, interval, allVarsAssigned, j); | ||
3524 | 172 | |||
3525 | 173 | for(auto& varTuplePair : varMap){ | ||
3526 | 174 | if(localVarMap.count(varTuplePair.first) == 0){ | ||
3527 | 175 | localVarMap[varTuplePair.first] = std::move(varTuplePair.second); | ||
3528 | 176 | } | ||
3529 | 177 | } | ||
3530 | 178 | |||
3531 | 179 | if(allVarsAssigned){ | ||
3532 | 180 | newVarMapVec.push_back(std::move(localVarMap)); | ||
3533 | 181 | } | ||
3534 | 182 | } | ||
3535 | 183 | } | ||
3536 | 184 | variableMaps = std::move(newVarMapVec); | ||
3537 | 185 | } | ||
3538 | 186 | //If we did not find any intervals for an arc, then the transition cannot be activated | ||
3539 | 187 | if(variableMaps.empty()){ | ||
3540 | 188 | return false; | ||
3541 | 189 | } | ||
3542 | 190 | } | ||
3543 | 191 | } | ||
3544 | 192 | return true; | ||
3545 | 193 | } | ||
3546 | 194 | }; | ||
3547 | 195 | } | ||
3548 | 196 | |||
3549 | 197 | #endif /* INTERVALGENERATOR_H */ | ||
3550 | 0 | \ No newline at end of file | 198 | \ No newline at end of file |
3551 | 1 | 199 | ||
3552 | === added file 'include/PetriEngine/Colored/Intervals.h' | |||
3553 | --- include/PetriEngine/Colored/Intervals.h 1970-01-01 00:00:00 +0000 | |||
3554 | +++ include/PetriEngine/Colored/Intervals.h 2021-04-02 18:07:40 +0000 | |||
3555 | @@ -0,0 +1,630 @@ | |||
3556 | 1 | /* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>, | ||
3557 | 2 | * Peter Haar Taankvist <ptaankvist@gmail.com>, | ||
3558 | 3 | * Thomas Pedersen <thomas.pedersen@stofanet.dk> | ||
3559 | 4 | * | ||
3560 | 5 | * This program is free software: you can redistribute it and/or modify | ||
3561 | 6 | * it under the terms of the GNU General Public License as published by | ||
3562 | 7 | * the Free Software Foundation, either version 3 of the License, or | ||
3563 | 8 | * (at your option) any later version. | ||
3564 | 9 | * | ||
3565 | 10 | * This program is distributed in the hope that it will be useful, | ||
3566 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3567 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3568 | 13 | * GNU General Public License for more details. | ||
3569 | 14 | * | ||
3570 | 15 | * You should have received a copy of the GNU General Public License | ||
3571 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3572 | 17 | */ | ||
3573 | 18 | |||
3574 | 19 | #ifndef INTERVALS_H | ||
3575 | 20 | #define INTERVALS_H | ||
3576 | 21 | |||
3577 | 22 | #include "../TAR/range.h" | ||
3578 | 23 | #include <set> | ||
3579 | 24 | #include <unordered_map> | ||
3580 | 25 | #include <chrono> | ||
3581 | 26 | |||
3582 | 27 | |||
3583 | 28 | namespace PetriEngine { | ||
3584 | 29 | namespace Colored { | ||
3585 | 30 | |||
3586 | 31 | struct interval_t { | ||
3587 | 32 | std::vector<Reachability::range_t> _ranges; | ||
3588 | 33 | |||
3589 | 34 | interval_t() { | ||
3590 | 35 | } | ||
3591 | 36 | |||
3592 | 37 | ~interval_t(){} | ||
3593 | 38 | |||
3594 | 39 | interval_t(std::vector<Reachability::range_t> ranges) : _ranges(ranges) { | ||
3595 | 40 | } | ||
3596 | 41 | |||
3597 | 42 | size_t size(){ | ||
3598 | 43 | return _ranges.size(); | ||
3599 | 44 | } | ||
3600 | 45 | |||
3601 | 46 | uint32_t intervalCombinations(){ | ||
3602 | 47 | uint32_t product = 1; | ||
3603 | 48 | for(auto range : _ranges){ | ||
3604 | 49 | product *= range.size(); | ||
3605 | 50 | } | ||
3606 | 51 | if(_ranges.empty()){ | ||
3607 | 52 | return 0; | ||
3608 | 53 | } | ||
3609 | 54 | return product; | ||
3610 | 55 | } | ||
3611 | 56 | |||
3612 | 57 | bool isSound(){ | ||
3613 | 58 | for(auto range: _ranges) { | ||
3614 | 59 | if(!range.isSound()){ | ||
3615 | 60 | return false; | ||
3616 | 61 | } | ||
3617 | 62 | } | ||
3618 | 63 | return true; | ||
3619 | 64 | } | ||
3620 | 65 | |||
3621 | 66 | void addRange(Reachability::range_t newRange) { | ||
3622 | 67 | _ranges.push_back(newRange); | ||
3623 | 68 | } | ||
3624 | 69 | |||
3625 | 70 | void addRange(Reachability::range_t newRange, uint32_t index){ | ||
3626 | 71 | _ranges.insert(_ranges.begin() + index, newRange); | ||
3627 | 72 | } | ||
3628 | 73 | |||
3629 | 74 | void addRange(uint32_t l, uint32_t u) { | ||
3630 | 75 | _ranges.push_back(Reachability::range_t(l, u)); | ||
3631 | 76 | } | ||
3632 | 77 | |||
3633 | 78 | void addRange(uint32_t lower, uint32_t upper, uint32_t index){ | ||
3634 | 79 | _ranges.insert(_ranges.begin() + index, Reachability::range_t(lower, upper)); | ||
3635 | 80 | } | ||
3636 | 81 | |||
3637 | 82 | Reachability::range_t& operator[] (size_t index) { | ||
3638 | 83 | return _ranges[index]; | ||
3639 | 84 | } | ||
3640 | 85 | |||
3641 | 86 | Reachability::range_t& operator[] (int index) { | ||
3642 | 87 | return _ranges[index]; | ||
3643 | 88 | } | ||
3644 | 89 | |||
3645 | 90 | Reachability::range_t& operator[] (uint32_t index) { | ||
3646 | 91 | assert(index < _ranges.size()); | ||
3647 | 92 | return _ranges[index]; | ||
3648 | 93 | } | ||
3649 | 94 | |||
3650 | 95 | Reachability::range_t& getFirst() { | ||
3651 | 96 | return _ranges[0]; | ||
3652 | 97 | } | ||
3653 | 98 | |||
3654 | 99 | Reachability::range_t& getLast() { | ||
3655 | 100 | return _ranges.back(); | ||
3656 | 101 | } | ||
3657 | 102 | |||
3658 | 103 | std::vector<uint32_t> getLowerIds(){ | ||
3659 | 104 | std::vector<uint32_t> ids; | ||
3660 | 105 | for(auto range : _ranges){ | ||
3661 | 106 | ids.push_back(range._lower); | ||
3662 | 107 | } | ||
3663 | 108 | return ids; | ||
3664 | 109 | } | ||
3665 | 110 | |||
3666 | 111 | std::vector<uint32_t> getUpperIds(){ | ||
3667 | 112 | std::vector<uint32_t> ids; | ||
3668 | 113 | for(auto range : _ranges){ | ||
3669 | 114 | ids.push_back(range._upper); | ||
3670 | 115 | } | ||
3671 | 116 | return ids; | ||
3672 | 117 | } | ||
3673 | 118 | |||
3674 | 119 | bool equals(interval_t other){ | ||
3675 | 120 | if(other.size() != size()){ | ||
3676 | 121 | return false; | ||
3677 | 122 | } | ||
3678 | 123 | for(uint32_t i = 0; i < size(); i++){ | ||
3679 | 124 | auto comparisonRes = _ranges[i].compare(other[i]); | ||
3680 | 125 | if(!comparisonRes.first || !comparisonRes.second){ | ||
3681 | 126 | return false; | ||
3682 | 127 | } | ||
3683 | 128 | } | ||
3684 | 129 | return true; | ||
3685 | 130 | } | ||
3686 | 131 | |||
3687 | 132 | uint32_t getContainedColors(){ | ||
3688 | 133 | uint32_t colors = 1; | ||
3689 | 134 | for(auto range: _ranges) { | ||
3690 | 135 | colors *= 1+ range._upper - range._lower; | ||
3691 | 136 | } | ||
3692 | 137 | return colors; | ||
3693 | 138 | } | ||
3694 | 139 | |||
3695 | 140 | bool contains(interval_t other){ | ||
3696 | 141 | if(other.size() != size()){ | ||
3697 | 142 | return false; | ||
3698 | 143 | } | ||
3699 | 144 | for(uint32_t i = 0; i < size(); i++){ | ||
3700 | 145 | if(!_ranges[i].compare(other[i]).first){ | ||
3701 | 146 | return false; | ||
3702 | 147 | } | ||
3703 | 148 | } | ||
3704 | 149 | return true; | ||
3705 | 150 | } | ||
3706 | 151 | |||
3707 | 152 | void constrain(interval_t other){ | ||
3708 | 153 | for(uint32_t i = 0; i < _ranges.size(); i++){ | ||
3709 | 154 | _ranges[i] &= other._ranges[i]; | ||
3710 | 155 | } | ||
3711 | 156 | } | ||
3712 | 157 | |||
3713 | 158 | interval_t getOverlap(interval_t other){ | ||
3714 | 159 | interval_t overlapInterval; | ||
3715 | 160 | if(size() != other.size()){ | ||
3716 | 161 | return overlapInterval; | ||
3717 | 162 | } | ||
3718 | 163 | |||
3719 | 164 | for(uint32_t i = 0; i < size(); i++){ | ||
3720 | 165 | auto rangeCopy = _ranges[i]; | ||
3721 | 166 | overlapInterval.addRange(rangeCopy &= other[i]); | ||
3722 | 167 | } | ||
3723 | 168 | |||
3724 | 169 | return overlapInterval; | ||
3725 | 170 | } | ||
3726 | 171 | |||
3727 | 172 | void print() { | ||
3728 | 173 | for(auto range : _ranges){ | ||
3729 | 174 | std::cout << " " << range._lower << "-" << range._upper << " "; | ||
3730 | 175 | } | ||
3731 | 176 | } | ||
3732 | 177 | }; | ||
3733 | 178 | |||
3734 | 179 | struct closestIntervals { | ||
3735 | 180 | uint32_t intervalId1; | ||
3736 | 181 | uint32_t intervalId2; | ||
3737 | 182 | uint32_t distance; | ||
3738 | 183 | }; | ||
3739 | 184 | |||
3740 | 185 | struct intervalTuple_t { | ||
3741 | 186 | std::vector<interval_t> _intervals; | ||
3742 | 187 | double totalinputtime = 0; | ||
3743 | 188 | |||
3744 | 189 | ~intervalTuple_t() { | ||
3745 | 190 | } | ||
3746 | 191 | |||
3747 | 192 | intervalTuple_t() { | ||
3748 | 193 | } | ||
3749 | 194 | |||
3750 | 195 | intervalTuple_t(std::vector<interval_t> ranges) : _intervals(ranges) { | ||
3751 | 196 | }; | ||
3752 | 197 | |||
3753 | 198 | interval_t& getFirst(){ | ||
3754 | 199 | return _intervals[0]; | ||
3755 | 200 | } | ||
3756 | 201 | |||
3757 | 202 | interval_t& back() { | ||
3758 | 203 | return _intervals.back(); | ||
3759 | 204 | } | ||
3760 | 205 | |||
3761 | 206 | size_t size() { | ||
3762 | 207 | return _intervals.size(); | ||
3763 | 208 | } | ||
3764 | 209 | |||
3765 | 210 | size_t tupleSize() { | ||
3766 | 211 | return _intervals[0].size(); | ||
3767 | 212 | } | ||
3768 | 213 | |||
3769 | 214 | uint32_t getContainedColors(){ | ||
3770 | 215 | uint32_t colors = 0; | ||
3771 | 216 | for (auto interval : _intervals) { | ||
3772 | 217 | colors += interval.getContainedColors(); | ||
3773 | 218 | } | ||
3774 | 219 | return colors; | ||
3775 | 220 | } | ||
3776 | 221 | |||
3777 | 222 | std::pair<uint32_t,uint32_t> shiftInterval(uint32_t lower, uint32_t upper, uint32_t ctSize, int32_t modifier){ | ||
3778 | 223 | int32_t lower_val = ctSize + (lower + modifier); | ||
3779 | 224 | int32_t upper_val = ctSize + (upper + modifier); | ||
3780 | 225 | return std::make_pair(lower_val % ctSize, upper_val % ctSize); | ||
3781 | 226 | } | ||
3782 | 227 | |||
3783 | 228 | uint32_t intervalCombinations(){ | ||
3784 | 229 | uint32_t res = 0; | ||
3785 | 230 | for(auto interval : _intervals){ | ||
3786 | 231 | res += interval.intervalCombinations(); | ||
3787 | 232 | } | ||
3788 | 233 | return res; | ||
3789 | 234 | } | ||
3790 | 235 | |||
3791 | 236 | bool hasValidIntervals(){ | ||
3792 | 237 | for(auto interval : _intervals) { | ||
3793 | 238 | if(interval.isSound()){ | ||
3794 | 239 | return true; | ||
3795 | 240 | } | ||
3796 | 241 | } | ||
3797 | 242 | return false; | ||
3798 | 243 | } | ||
3799 | 244 | |||
3800 | 245 | interval_t& operator[] (size_t index) { | ||
3801 | 246 | return _intervals[index]; | ||
3802 | 247 | } | ||
3803 | 248 | |||
3804 | 249 | interval_t& operator[] (int index) { | ||
3805 | 250 | return _intervals[index]; | ||
3806 | 251 | } | ||
3807 | 252 | |||
3808 | 253 | interval_t& operator[] (uint32_t index) { | ||
3809 | 254 | assert(index < _intervals.size()); | ||
3810 | 255 | return _intervals[index]; | ||
3811 | 256 | } | ||
3812 | 257 | |||
3813 | 258 | interval_t isRangeEnd(std::vector<uint32_t> ids) { | ||
3814 | 259 | for (uint32_t j = 0; j < _intervals.size(); j++) { | ||
3815 | 260 | bool rangeEnd = true; | ||
3816 | 261 | for (uint32_t i = 0; i < _intervals[j].size(); i++) { | ||
3817 | 262 | auto range = _intervals[j][i]; | ||
3818 | 263 | if (range._upper != ids[i]) { | ||
3819 | 264 | rangeEnd = false; | ||
3820 | 265 | break; | ||
3821 | 266 | } | ||
3822 | 267 | } | ||
3823 | 268 | if(rangeEnd) { | ||
3824 | 269 | if(j+1 != _intervals.size()) { | ||
3825 | 270 | return _intervals[j+1]; | ||
3826 | 271 | } else { | ||
3827 | 272 | return getFirst(); | ||
3828 | 273 | } | ||
3829 | 274 | } | ||
3830 | 275 | } | ||
3831 | 276 | return interval_t(); | ||
3832 | 277 | } | ||
3833 | 278 | |||
3834 | 279 | std::vector<Colored::interval_t> shrinkIntervals(uint32_t newSize){ | ||
3835 | 280 | std::vector<Colored::interval_t> resizedIntervals; | ||
3836 | 281 | for(auto interval : _intervals){ | ||
3837 | 282 | Colored::interval_t resizedInterval; | ||
3838 | 283 | for(uint32_t i = 0; i < newSize; i++){ | ||
3839 | 284 | resizedInterval.addRange(interval[i]); | ||
3840 | 285 | } | ||
3841 | 286 | resizedIntervals.push_back(resizedInterval); | ||
3842 | 287 | } | ||
3843 | 288 | return resizedIntervals; | ||
3844 | 289 | } | ||
3845 | 290 | |||
3846 | 291 | void addInterval(interval_t interval) { | ||
3847 | 292 | uint32_t vecIndex = 0; | ||
3848 | 293 | |||
3849 | 294 | if(!_intervals.empty()) { | ||
3850 | 295 | assert(_intervals[0].size() == interval.size()); | ||
3851 | 296 | } else { | ||
3852 | 297 | _intervals.push_back(interval); | ||
3853 | 298 | return; | ||
3854 | 299 | } | ||
3855 | 300 | |||
3856 | 301 | for (auto& localInterval : _intervals) { | ||
3857 | 302 | bool overlap = true; | ||
3858 | 303 | enum FoundPlace {undecided, greater, lower}; | ||
3859 | 304 | FoundPlace foundPlace = undecided; | ||
3860 | 305 | |||
3861 | 306 | for(uint32_t k = 0; k < interval.size(); k++){ | ||
3862 | 307 | if(interval[k]._lower > localInterval[k]._upper || localInterval[k]._lower > interval[k]._upper){ | ||
3863 | 308 | overlap = false; | ||
3864 | 309 | } | ||
3865 | 310 | if(interval[k]._lower < localInterval[k]._lower){ | ||
3866 | 311 | if(foundPlace == undecided){ | ||
3867 | 312 | foundPlace = lower; | ||
3868 | 313 | } | ||
3869 | 314 | } else if (interval[k]._lower > localInterval[k]._lower){ | ||
3870 | 315 | if(foundPlace == undecided){ | ||
3871 | 316 | foundPlace = greater; | ||
3872 | 317 | } | ||
3873 | 318 | } | ||
3874 | 319 | if(!overlap && foundPlace != undecided){ | ||
3875 | 320 | break; | ||
3876 | 321 | } | ||
3877 | 322 | } | ||
3878 | 323 | |||
3879 | 324 | if(overlap) { | ||
3880 | 325 | for(uint32_t k = 0; k < interval.size(); k++){ | ||
3881 | 326 | localInterval[k] |= interval[k]; | ||
3882 | 327 | } | ||
3883 | 328 | return; | ||
3884 | 329 | } else if(foundPlace == lower){ | ||
3885 | 330 | break; | ||
3886 | 331 | } | ||
3887 | 332 | vecIndex++; | ||
3888 | 333 | } | ||
3889 | 334 | |||
3890 | 335 | _intervals.insert(_intervals.begin() + vecIndex, interval); | ||
3891 | 336 | } | ||
3892 | 337 | |||
3893 | 338 | void constrainLower(std::vector<uint32_t> values, bool strict) { | ||
3894 | 339 | for(uint32_t i = 0; i < _intervals.size(); i++) { | ||
3895 | 340 | for(uint32_t j = 0; j < values.size(); j++){ | ||
3896 | 341 | if(strict && _intervals[i][j]._lower <= values[j]){ | ||
3897 | 342 | _intervals[i][j]._lower = values[j]+1; | ||
3898 | 343 | } | ||
3899 | 344 | else if(!strict && _intervals[i][j]._lower < values[j]){ | ||
3900 | 345 | _intervals[i][j]._lower = values[j]; | ||
3901 | 346 | } | ||
3902 | 347 | } | ||
3903 | 348 | } | ||
3904 | 349 | simplify(); | ||
3905 | 350 | } | ||
3906 | 351 | |||
3907 | 352 | void constrainUpper(std::vector<uint32_t> values, bool strict) { | ||
3908 | 353 | for(uint32_t i = 0; i < _intervals.size(); i++) { | ||
3909 | 354 | for(uint32_t j = 0; j < values.size(); j++){ | ||
3910 | 355 | if(strict && _intervals[i][j]._upper >= values[j]){ | ||
3911 | 356 | _intervals[i][j]._upper = values[j]-1; | ||
3912 | 357 | } | ||
3913 | 358 | else if(!strict && _intervals[i][j]._upper > values[j]){ | ||
3914 | 359 | _intervals[i][j]._upper = values[j]; | ||
3915 | 360 | } | ||
3916 | 361 | } | ||
3917 | 362 | } | ||
3918 | 363 | simplify(); | ||
3919 | 364 | } | ||
3920 | 365 | |||
3921 | 366 | void expandLower(std::vector<uint32_t> values) { | ||
3922 | 367 | for(uint32_t i = 0; i < values.size(); i++) { | ||
3923 | 368 | _intervals[0][i]._lower = std::min(values[i],_intervals[0][i]._lower); | ||
3924 | 369 | } | ||
3925 | 370 | } | ||
3926 | 371 | |||
3927 | 372 | void expandUpper(std::vector<uint32_t> values) { | ||
3928 | 373 | for(uint32_t i = 0; i < values.size(); i++) { | ||
3929 | 374 | _intervals[0][i]._upper = std::max(values[i],_intervals[0][i]._upper); | ||
3930 | 375 | } | ||
3931 | 376 | } | ||
3932 | 377 | |||
3933 | 378 | void print() { | ||
3934 | 379 | for (auto interval : _intervals){ | ||
3935 | 380 | std::cout << "["; | ||
3936 | 381 | interval.print(); | ||
3937 | 382 | std::cout << "]" << std::endl; | ||
3938 | 383 | } | ||
3939 | 384 | } | ||
3940 | 385 | |||
3941 | 386 | std::vector<uint32_t> getLowerIds(){ | ||
3942 | 387 | std::vector<uint32_t> ids; | ||
3943 | 388 | for(auto interval : _intervals){ | ||
3944 | 389 | if(ids.empty()){ | ||
3945 | 390 | ids = interval.getLowerIds(); | ||
3946 | 391 | } else { | ||
3947 | 392 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
3948 | 393 | ids[i] = std::min(ids[i], interval[i]._lower); | ||
3949 | 394 | } | ||
3950 | 395 | } | ||
3951 | 396 | } | ||
3952 | 397 | return ids; | ||
3953 | 398 | } | ||
3954 | 399 | |||
3955 | 400 | std::vector<uint32_t> getLowerIds(int32_t modifier, std::vector<size_t> sizes){ | ||
3956 | 401 | std::vector<uint32_t> ids; | ||
3957 | 402 | for(uint32_t j = 0; j < size(); j++){ | ||
3958 | 403 | auto interval = &_intervals[j]; | ||
3959 | 404 | if(ids.empty()){ | ||
3960 | 405 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
3961 | 406 | auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier); | ||
3962 | 407 | if(shiftedInterval.first > shiftedInterval.second){ | ||
3963 | 408 | ids.push_back(0); | ||
3964 | 409 | } else { | ||
3965 | 410 | ids.push_back(shiftedInterval.first); | ||
3966 | 411 | } | ||
3967 | 412 | } | ||
3968 | 413 | } else { | ||
3969 | 414 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
3970 | 415 | if(ids[i] == 0){ | ||
3971 | 416 | continue; | ||
3972 | 417 | } | ||
3973 | 418 | auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier); | ||
3974 | 419 | if(shiftedInterval.first > shiftedInterval.second){ | ||
3975 | 420 | ids[i] = 0; | ||
3976 | 421 | } else { | ||
3977 | 422 | ids[i] = std::max(ids[i], shiftedInterval.first); | ||
3978 | 423 | } | ||
3979 | 424 | } | ||
3980 | 425 | } | ||
3981 | 426 | } | ||
3982 | 427 | return ids; | ||
3983 | 428 | } | ||
3984 | 429 | |||
3985 | 430 | std::vector<uint32_t> getUpperIds(){ | ||
3986 | 431 | std::vector<uint32_t> ids; | ||
3987 | 432 | for(auto interval : _intervals){ | ||
3988 | 433 | if(ids.empty()){ | ||
3989 | 434 | ids = interval.getUpperIds(); | ||
3990 | 435 | } else { | ||
3991 | 436 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
3992 | 437 | ids[i] = std::max(ids[i], interval[i]._upper); | ||
3993 | 438 | } | ||
3994 | 439 | } | ||
3995 | 440 | } | ||
3996 | 441 | return ids; | ||
3997 | 442 | } | ||
3998 | 443 | |||
3999 | 444 | std::vector<uint32_t> getUpperIds(int32_t modifier, std::vector<size_t> sizes){ | ||
4000 | 445 | std::vector<uint32_t> ids; | ||
4001 | 446 | for(uint32_t j = 0; j < size(); j++){ | ||
4002 | 447 | auto interval = &_intervals[j]; | ||
4003 | 448 | if(ids.empty()){ | ||
4004 | 449 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
4005 | 450 | auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier); | ||
4006 | 451 | |||
4007 | 452 | if(shiftedInterval.first > shiftedInterval.second){ | ||
4008 | 453 | ids.push_back(sizes[i]-1); | ||
4009 | 454 | } else { | ||
4010 | 455 | ids.push_back(shiftedInterval.second); | ||
4011 | 456 | } | ||
4012 | 457 | } | ||
4013 | 458 | } else { | ||
4014 | 459 | for(uint32_t i = 0; i < ids.size(); i++){ | ||
4015 | 460 | if(ids[i] == sizes[i]-1){ | ||
4016 | 461 | continue; | ||
4017 | 462 | } | ||
4018 | 463 | auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier); | ||
4019 | 464 | |||
4020 | 465 | if(shiftedInterval.first > shiftedInterval.second){ | ||
4021 | 466 | ids[i] = sizes[i]-1; | ||
4022 | 467 | } else { | ||
4023 | 468 | ids[i] = std::max(ids[i], shiftedInterval.second); | ||
4024 | 469 | } | ||
4025 | 470 | } | ||
4026 | 471 | } | ||
4027 | 472 | } | ||
4028 | 473 | return ids; | ||
4029 | 474 | } | ||
4030 | 475 | |||
4031 | 476 | void applyModifier(int32_t modifier, std::vector<size_t> sizes){ | ||
4032 | 477 | std::vector<interval_t> collectedIntervals; | ||
4033 | 478 | for(auto& interval : _intervals){ | ||
4034 | 479 | std::vector<interval_t> newIntervals; | ||
4035 | 480 | newIntervals.push_back(std::move(interval)); | ||
4036 | 481 | for(uint32_t i = 0; i < interval.size(); i++){ | ||
4037 | 482 | std::vector<interval_t> tempIntervals; | ||
4038 | 483 | for(auto& interval1 : newIntervals){ | ||
4039 | 484 | auto shiftedInterval = shiftInterval(interval1[i]._lower, interval1[i]._upper, sizes[i], modifier); | ||
4040 | 485 | |||
4041 | 486 | if(shiftedInterval.first > shiftedInterval.second){ | ||
4042 | 487 | auto newInterval = interval1; | ||
4043 | 488 | |||
4044 | 489 | interval1[i]._lower = 0; | ||
4045 | 490 | interval1[i]._upper = shiftedInterval.second; | ||
4046 | 491 | |||
4047 | 492 | newInterval[i]._lower = shiftedInterval.first; | ||
4048 | 493 | newInterval[i]._upper = sizes[i]-1; | ||
4049 | 494 | tempIntervals.push_back(std::move(newInterval)); | ||
4050 | 495 | }else { | ||
4051 | 496 | interval1[i]._lower = shiftedInterval.first; | ||
4052 | 497 | interval1[i]._upper = shiftedInterval.second; | ||
4053 | 498 | } | ||
4054 | 499 | } | ||
4055 | 500 | newIntervals.insert(newIntervals.end(), tempIntervals.begin(), tempIntervals.end()); | ||
4056 | 501 | } | ||
4057 | 502 | collectedIntervals.insert(collectedIntervals.end(), newIntervals.begin(), newIntervals.end()); | ||
4058 | 503 | } | ||
4059 | 504 | |||
4060 | 505 | _intervals = std::move(collectedIntervals); | ||
4061 | 506 | } | ||
4062 | 507 | |||
4063 | 508 | bool contains(interval_t interval){ | ||
4064 | 509 | for(auto localInterval : _intervals){ | ||
4065 | 510 | if(localInterval.contains(interval)){ | ||
4066 | 511 | return true; | ||
4067 | 512 | } | ||
4068 | 513 | } | ||
4069 | 514 | return false; | ||
4070 | 515 | } | ||
4071 | 516 | |||
4072 | 517 | void removeInterval(interval_t interval) { | ||
4073 | 518 | for (uint32_t i = 0; i < _intervals.size(); i++) { | ||
4074 | 519 | if(interval.equals(_intervals[i])){ | ||
4075 | 520 | removeInterval(i); | ||
4076 | 521 | return; | ||
4077 | 522 | } | ||
4078 | 523 | } | ||
4079 | 524 | } | ||
4080 | 525 | |||
4081 | 526 | void removeInterval(uint32_t index) { | ||
4082 | 527 | _intervals.erase(_intervals.begin() + index); | ||
4083 | 528 | } | ||
4084 | 529 | |||
4085 | 530 | |||
4086 | 531 | |||
4087 | 532 | void restrict(uint32_t k){ | ||
4088 | 533 | simplify(); | ||
4089 | 534 | if(k == 0){ | ||
4090 | 535 | return; | ||
4091 | 536 | } | ||
4092 | 537 | |||
4093 | 538 | while (size() > k){ | ||
4094 | 539 | closestIntervals closestInterval = getClosestIntervals(); | ||
4095 | 540 | auto interval = &_intervals[closestInterval.intervalId1]; | ||
4096 | 541 | auto otherInterval = &_intervals[closestInterval.intervalId2]; | ||
4097 | 542 | |||
4098 | 543 | for(uint32_t l = 0; l < interval->size(); l++) { | ||
4099 | 544 | interval->operator[](l) |= otherInterval->operator[](l); | ||
4100 | 545 | } | ||
4101 | 546 | |||
4102 | 547 | _intervals.erase(_intervals.begin() + closestInterval.intervalId2); | ||
4103 | 548 | |||
4104 | 549 | } | ||
4105 | 550 | } | ||
4106 | 551 | |||
4107 | 552 | closestIntervals getClosestIntervals(){ | ||
4108 | 553 | closestIntervals currentBest = {0,0, UINT32_MAX}; | ||
4109 | 554 | for (uint32_t i = 0; i < size()-1; i++) { | ||
4110 | 555 | auto interval = &_intervals[i]; | ||
4111 | 556 | for(uint32_t j = i+1; j < size(); j++){ | ||
4112 | 557 | auto otherInterval = &_intervals[j]; | ||
4113 | 558 | uint32_t dist = 0; | ||
4114 | 559 | |||
4115 | 560 | for(uint32_t k = 0; k < interval->size(); k++) { | ||
4116 | 561 | int32_t val1 = otherInterval->operator[](k)._lower - interval->operator[](k)._upper; | ||
4117 | 562 | int32_t val2 = interval->operator[](k)._lower - otherInterval->operator[](k)._upper; | ||
4118 | 563 | dist += std::max(0, std::max(val1, val2)); | ||
4119 | 564 | if(dist >= currentBest.distance){ | ||
4120 | 565 | break; | ||
4121 | 566 | } | ||
4122 | 567 | } | ||
4123 | 568 | |||
4124 | 569 | if(dist < currentBest.distance){ | ||
4125 | 570 | currentBest.distance = dist; | ||
4126 | 571 | currentBest.intervalId1 = i; | ||
4127 | 572 | currentBest.intervalId2 = j; | ||
4128 | 573 | |||
4129 | 574 | //if the distance is 1 we cannot find any intervals that are closer so we stop searching | ||
4130 | 575 | if(currentBest.distance == 1){ | ||
4131 | 576 | return currentBest; | ||
4132 | 577 | } | ||
4133 | 578 | } | ||
4134 | 579 | } | ||
4135 | 580 | } | ||
4136 | 581 | return currentBest; | ||
4137 | 582 | } | ||
4138 | 583 | |||
4139 | 584 | void simplify() { | ||
4140 | 585 | std::set<uint32_t> rangesToRemove; | ||
4141 | 586 | if(_intervals.empty()){ | ||
4142 | 587 | return; | ||
4143 | 588 | } | ||
4144 | 589 | |||
4145 | 590 | for (uint32_t i = 0; i < _intervals.size(); i++) { | ||
4146 | 591 | auto interval = &_intervals[i]; | ||
4147 | 592 | if(!interval->isSound()){ | ||
4148 | 593 | rangesToRemove.insert(i); | ||
4149 | 594 | continue; | ||
4150 | 595 | } | ||
4151 | 596 | for(uint32_t j = i+1; j < _intervals.size(); j++){ | ||
4152 | 597 | auto otherInterval = &_intervals[j]; | ||
4153 | 598 | |||
4154 | 599 | if(!otherInterval->isSound()){ | ||
4155 | 600 | continue; | ||
4156 | 601 | } | ||
4157 | 602 | bool overlap = true; | ||
4158 | 603 | |||
4159 | 604 | if(overlap){ | ||
4160 | 605 | for(uint32_t k = 0; k < interval->size(); k++) { | ||
4161 | 606 | if(interval->operator[](k)._lower > otherInterval->operator[](k)._upper || otherInterval->operator[](k)._lower > interval->operator[](k)._upper) { | ||
4162 | 607 | overlap = false; | ||
4163 | 608 | break; | ||
4164 | 609 | } | ||
4165 | 610 | } | ||
4166 | 611 | } | ||
4167 | 612 | |||
4168 | 613 | if(overlap) { | ||
4169 | 614 | for(uint32_t l = 0; l < interval->size(); l++) { | ||
4170 | 615 | interval->operator[](l) |= otherInterval->operator[](l); | ||
4171 | 616 | } | ||
4172 | 617 | rangesToRemove.insert(j); | ||
4173 | 618 | } | ||
4174 | 619 | } | ||
4175 | 620 | } | ||
4176 | 621 | for (auto i = rangesToRemove.rbegin(); i != rangesToRemove.rend(); ++i) { | ||
4177 | 622 | _intervals.erase(_intervals.begin() + *i); | ||
4178 | 623 | } | ||
4179 | 624 | } | ||
4180 | 625 | }; | ||
4181 | 626 | } | ||
4182 | 627 | } | ||
4183 | 628 | |||
4184 | 629 | |||
4185 | 630 | #endif /* INTERVALS_H */ | ||
4186 | 0 | \ No newline at end of file | 631 | \ No newline at end of file |
4187 | 1 | 632 | ||
4188 | === added file 'include/PetriEngine/PQL/CTLVisitor.h' | |||
4189 | --- include/PetriEngine/PQL/CTLVisitor.h 1970-01-01 00:00:00 +0000 | |||
4190 | +++ include/PetriEngine/PQL/CTLVisitor.h 2021-04-02 18:07:40 +0000 | |||
4191 | @@ -0,0 +1,197 @@ | |||
4192 | 1 | #ifndef VERIFYPN_CTLVISITOR_H | ||
4193 | 2 | #define VERIFYPN_CTLVISITOR_H | ||
4194 | 3 | |||
4195 | 4 | #include "Visitor.h" | ||
4196 | 5 | |||
4197 | 6 | namespace PetriEngine::PQL { | ||
4198 | 7 | |||
4199 | 8 | enum CTLSyntaxType {BOOLEAN, PATH, ERROR = -1}; | ||
4200 | 9 | |||
4201 | 10 | class IsCTLVisitor : public Visitor { | ||
4202 | 11 | public: | ||
4203 | 12 | bool isCTL = true; | ||
4204 | 13 | |||
4205 | 14 | protected: | ||
4206 | 15 | void _accept(const NotCondition *element) override; | ||
4207 | 16 | |||
4208 | 17 | void _accept(const AndCondition *element) override; | ||
4209 | 18 | |||
4210 | 19 | void _accept(const OrCondition *element) override; | ||
4211 | 20 | |||
4212 | 21 | void _accept(const LessThanCondition *element) override; | ||
4213 | 22 | |||
4214 | 23 | void _accept(const LessThanOrEqualCondition *element) override; | ||
4215 | 24 | |||
4216 | 25 | void _accept(const EqualCondition *element) override; | ||
4217 | 26 | |||
4218 | 27 | void _accept(const NotEqualCondition *element) override; | ||
4219 | 28 | |||
4220 | 29 | void _accept(const DeadlockCondition *element) override; | ||
4221 | 30 | |||
4222 | 31 | void _accept(const CompareConjunction *element) override; | ||
4223 | 32 | |||
4224 | 33 | void _accept(const UnfoldedUpperBoundsCondition *element) override; | ||
4225 | 34 | |||
4226 | 35 | void _accept(const EFCondition *condition) override; | ||
4227 | 36 | |||
4228 | 37 | void _accept(const EGCondition *condition) override; | ||
4229 | 38 | |||
4230 | 39 | void _accept(const AGCondition *condition) override; | ||
4231 | 40 | |||
4232 | 41 | void _accept(const AFCondition *condition) override; | ||
4233 | 42 | |||
4234 | 43 | void _accept(const EXCondition *condition) override; | ||
4235 | 44 | |||
4236 | 45 | void _accept(const AXCondition *condition) override; | ||
4237 | 46 | |||
4238 | 47 | void _accept(const EUCondition *condition) override; | ||
4239 | 48 | |||
4240 | 49 | void _accept(const AUCondition *condition) override; | ||
4241 | 50 | |||
4242 | 51 | void _accept(const ACondition *condition) override; | ||
4243 | 52 | |||
4244 | 53 | void _accept(const ECondition *condition) override; | ||
4245 | 54 | |||
4246 | 55 | void _accept(const GCondition *condition) override; | ||
4247 | 56 | |||
4248 | 57 | void _accept(const FCondition *condition) override; | ||
4249 | 58 | |||
4250 | 59 | void _accept(const XCondition *condition) override; | ||
4251 | 60 | |||
4252 | 61 | void _accept(const UntilCondition *condition) override; | ||
4253 | 62 | |||
4254 | 63 | void _accept(const UnfoldedFireableCondition *element) override; | ||
4255 | 64 | |||
4256 | 65 | void _accept(const FireableCondition *element) override; | ||
4257 | 66 | |||
4258 | 67 | void _accept(const UpperBoundsCondition *element) override; | ||
4259 | 68 | |||
4260 | 69 | void _accept(const LivenessCondition *element) override; | ||
4261 | 70 | |||
4262 | 71 | void _accept(const KSafeCondition *element) override; | ||
4263 | 72 | |||
4264 | 73 | void _accept(const QuasiLivenessCondition *element) override; | ||
4265 | 74 | |||
4266 | 75 | void _accept(const StableMarkingCondition *element) override; | ||
4267 | 76 | |||
4268 | 77 | void _accept(const BooleanCondition *element) override; | ||
4269 | 78 | |||
4270 | 79 | void _accept(const UnfoldedIdentifierExpr *element) override; | ||
4271 | 80 | |||
4272 | 81 | void _accept(const LiteralExpr *element) override; | ||
4273 | 82 | |||
4274 | 83 | void _accept(const PlusExpr *element) override; | ||
4275 | 84 | |||
4276 | 85 | void _accept(const MultiplyExpr *element) override; | ||
4277 | 86 | |||
4278 | 87 | void _accept(const MinusExpr *element) override; | ||
4279 | 88 | |||
4280 | 89 | void _accept(const SubtractExpr *element) override; | ||
4281 | 90 | |||
4282 | 91 | void _accept(const IdentifierExpr *element) override; | ||
4283 | 92 | |||
4284 | 93 | private: | ||
4285 | 94 | CTLSyntaxType _cur_type; | ||
4286 | 95 | |||
4287 | 96 | void _accept(const LogicalCondition *element); | ||
4288 | 97 | |||
4289 | 98 | void _accept(const CompareCondition *element); | ||
4290 | 99 | }; | ||
4291 | 100 | |||
4292 | 101 | class AsCTL : public Visitor { | ||
4293 | 102 | public: | ||
4294 | 103 | Condition_ptr _ctl_query = nullptr; | ||
4295 | 104 | Expr_ptr _expression = nullptr; | ||
4296 | 105 | |||
4297 | 106 | protected: | ||
4298 | 107 | void _accept(const NotCondition *element) override; | ||
4299 | 108 | |||
4300 | 109 | void _accept(const AndCondition *element) override; | ||
4301 | 110 | |||
4302 | 111 | void _accept(const OrCondition *element) override; | ||
4303 | 112 | |||
4304 | 113 | void _accept(const LessThanCondition *element) override; | ||
4305 | 114 | |||
4306 | 115 | void _accept(const LessThanOrEqualCondition *element) override; | ||
4307 | 116 | |||
4308 | 117 | void _accept(const EqualCondition *element) override; | ||
4309 | 118 | |||
4310 | 119 | void _accept(const NotEqualCondition *element) override; | ||
4311 | 120 | |||
4312 | 121 | void _accept(const DeadlockCondition *element) override; | ||
4313 | 122 | |||
4314 | 123 | void _accept(const CompareConjunction *element) override; | ||
4315 | 124 | |||
4316 | 125 | void _accept(const UnfoldedUpperBoundsCondition *element) override; | ||
4317 | 126 | |||
4318 | 127 | void _accept(const EFCondition *condition) override; | ||
4319 | 128 | |||
4320 | 129 | void _accept(const EGCondition *condition) override; | ||
4321 | 130 | |||
4322 | 131 | void _accept(const AGCondition *condition) override; | ||
4323 | 132 | |||
4324 | 133 | void _accept(const AFCondition *condition) override; | ||
4325 | 134 | |||
4326 | 135 | void _accept(const EXCondition *condition) override; | ||
4327 | 136 | |||
4328 | 137 | void _accept(const AXCondition *condition) override; | ||
4329 | 138 | |||
4330 | 139 | void _accept(const EUCondition *condition) override; | ||
4331 | 140 | |||
4332 | 141 | void _accept(const AUCondition *condition) override; | ||
4333 | 142 | |||
4334 | 143 | void _accept(const ACondition *condition) override; | ||
4335 | 144 | |||
4336 | 145 | void _accept(const ECondition *condition) override; | ||
4337 | 146 | |||
4338 | 147 | void _accept(const GCondition *condition) override; | ||
4339 | 148 | |||
4340 | 149 | void _accept(const FCondition *condition) override; | ||
4341 | 150 | |||
4342 | 151 | void _accept(const XCondition *condition) override; | ||
4343 | 152 | |||
4344 | 153 | void _accept(const UntilCondition *condition) override; | ||
4345 | 154 | |||
4346 | 155 | void _accept(const UnfoldedFireableCondition *element) override; | ||
4347 | 156 | |||
4348 | 157 | void _accept(const FireableCondition *element) override; | ||
4349 | 158 | |||
4350 | 159 | void _accept(const UpperBoundsCondition *element) override; | ||
4351 | 160 | |||
4352 | 161 | void _accept(const LivenessCondition *element) override; | ||
4353 | 162 | |||
4354 | 163 | void _accept(const KSafeCondition *element) override; | ||
4355 | 164 | |||
4356 | 165 | void _accept(const QuasiLivenessCondition *element) override; | ||
4357 | 166 | |||
4358 | 167 | void _accept(const StableMarkingCondition *element) override; | ||
4359 | 168 | |||
4360 | 169 | void _accept(const BooleanCondition *element) override; | ||
4361 | 170 | |||
4362 | 171 | void _accept(const UnfoldedIdentifierExpr *element) override; | ||
4363 | 172 | |||
4364 | 173 | void _accept(const LiteralExpr *element) override; | ||
4365 | 174 | |||
4366 | 175 | void _accept(const PlusExpr *element) override; | ||
4367 | 176 | |||
4368 | 177 | void _accept(const MultiplyExpr *element) override; | ||
4369 | 178 | |||
4370 | 179 | void _accept(const MinusExpr *element) override; | ||
4371 | 180 | |||
4372 | 181 | void _accept(const SubtractExpr *element) override; | ||
4373 | 182 | |||
4374 | 183 | void _accept(const IdentifierExpr *element) override; | ||
4375 | 184 | |||
4376 | 185 | private: | ||
4377 | 186 | template<typename T> | ||
4378 | 187 | void _acceptNary(const T *element); | ||
4379 | 188 | |||
4380 | 189 | template<typename T> | ||
4381 | 190 | Expr_ptr copy_narry_expr(const T* el); | ||
4382 | 191 | |||
4383 | 192 | template<typename T> | ||
4384 | 193 | std::shared_ptr<T> copy_compare_condition(const T *element); | ||
4385 | 194 | }; | ||
4386 | 195 | } | ||
4387 | 196 | |||
4388 | 197 | #endif //VERIFYPN_CTLVISITOR_H | ||
4389 | 0 | 198 | ||
4390 | === modified file 'include/PetriEngine/PQL/Contexts.h' | |||
4391 | --- include/PetriEngine/PQL/Contexts.h 2020-04-27 14:47:10 +0000 | |||
4392 | +++ include/PetriEngine/PQL/Contexts.h 2021-04-02 18:07:40 +0000 | |||
4393 | @@ -38,8 +38,8 @@ | |||
4394 | 38 | /** Context provided for context analysis */ | 38 | /** Context provided for context analysis */ |
4395 | 39 | class AnalysisContext { | 39 | class AnalysisContext { |
4396 | 40 | protected: | 40 | protected: |
4399 | 41 | const unordered_map<std::string, uint32_t>& _placeNames; | 41 | const std::unordered_map<std::string, uint32_t>& _placeNames; |
4400 | 42 | const unordered_map<std::string, uint32_t>& _transitionNames; | 42 | const std::unordered_map<std::string, uint32_t>& _transitionNames; |
4401 | 43 | const PetriNet* _net; | 43 | const PetriNet* _net; |
4402 | 44 | std::vector<ExprError> _errors; | 44 | std::vector<ExprError> _errors; |
4403 | 45 | public: | 45 | public: |
4404 | @@ -176,7 +176,7 @@ | |||
4405 | 176 | 176 | ||
4406 | 177 | SimplificationContext(const MarkVal* marking, | 177 | SimplificationContext(const MarkVal* marking, |
4407 | 178 | const PetriNet* net, uint32_t queryTimeout, uint32_t lpTimeout, | 178 | const PetriNet* net, uint32_t queryTimeout, uint32_t lpTimeout, |
4409 | 179 | LPCache* cache) | 179 | Simplification::LPCache* cache) |
4410 | 180 | : _queryTimeout(queryTimeout), _lpTimeout(lpTimeout) { | 180 | : _queryTimeout(queryTimeout), _lpTimeout(lpTimeout) { |
4411 | 181 | _negated = false; | 181 | _negated = false; |
4412 | 182 | _marking = marking; | 182 | _marking = marking; |
4413 | @@ -222,8 +222,8 @@ | |||
4414 | 222 | } | 222 | } |
4415 | 223 | 223 | ||
4416 | 224 | uint32_t getLpTimeout() const; | 224 | uint32_t getLpTimeout() const; |
4419 | 225 | 225 | ||
4420 | 226 | LPCache* cache() const | 226 | Simplification::LPCache* cache() const |
4421 | 227 | { | 227 | { |
4422 | 228 | return _cache; | 228 | return _cache; |
4423 | 229 | } | 229 | } |
4424 | @@ -237,7 +237,7 @@ | |||
4425 | 237 | const PetriNet* _net; | 237 | const PetriNet* _net; |
4426 | 238 | uint32_t _queryTimeout, _lpTimeout; | 238 | uint32_t _queryTimeout, _lpTimeout; |
4427 | 239 | std::chrono::high_resolution_clock::time_point _start; | 239 | std::chrono::high_resolution_clock::time_point _start; |
4429 | 240 | LPCache* _cache; | 240 | Simplification::LPCache* _cache; |
4430 | 241 | mutable glp_prob* _base_lp = nullptr; | 241 | mutable glp_prob* _base_lp = nullptr; |
4431 | 242 | 242 | ||
4432 | 243 | glp_prob* buildBase() const; | 243 | glp_prob* buildBase() const; |
4433 | 244 | 244 | ||
4434 | === modified file 'include/PetriEngine/PQL/Expressions.h' | |||
4435 | --- include/PetriEngine/PQL/Expressions.h 2020-06-02 16:20:24 +0000 | |||
4436 | +++ include/PetriEngine/PQL/Expressions.h 2021-04-02 18:07:40 +0000 | |||
4437 | @@ -34,7 +34,7 @@ | |||
4438 | 34 | 34 | ||
4439 | 35 | namespace PetriEngine { | 35 | namespace PetriEngine { |
4440 | 36 | namespace PQL { | 36 | namespace PQL { |
4442 | 37 | 37 | ||
4443 | 38 | std::string generateTabs(uint32_t tabs); | 38 | std::string generateTabs(uint32_t tabs); |
4444 | 39 | class CompareCondition; | 39 | class CompareCondition; |
4445 | 40 | class NotCondition; | 40 | class NotCondition; |
4446 | @@ -55,19 +55,22 @@ | |||
4447 | 55 | for(auto& e : _exprs) sum += e->formulaSize(); | 55 | for(auto& e : _exprs) sum += e->formulaSize(); |
4448 | 56 | return sum + 1; | 56 | return sum + 1; |
4449 | 57 | } | 57 | } |
4450 | 58 | void toString(std::ostream&) const override; | ||
4451 | 59 | bool placeFree() const override; | 58 | bool placeFree() const override; |
4452 | 60 | auto& expressions() const { return _exprs; } | 59 | auto& expressions() const { return _exprs; } |
4453 | 60 | size_t operands() const { return _exprs.size(); } | ||
4454 | 61 | const Expr_ptr &operator[](size_t i) const { | ||
4455 | 62 | return _exprs[i]; | ||
4456 | 63 | } | ||
4457 | 61 | protected: | 64 | protected: |
4458 | 62 | virtual int apply(int v1, int v2) const = 0; | 65 | virtual int apply(int v1, int v2) const = 0; |
4459 | 63 | virtual std::string op() const = 0; | 66 | virtual std::string op() const = 0; |
4460 | 64 | std::vector<Expr_ptr> _exprs; | 67 | std::vector<Expr_ptr> _exprs; |
4461 | 65 | virtual int32_t preOp(const EvaluationContext& context) const; | 68 | virtual int32_t preOp(const EvaluationContext& context) const; |
4462 | 66 | }; | 69 | }; |
4464 | 67 | 70 | ||
4465 | 68 | class PlusExpr; | 71 | class PlusExpr; |
4466 | 69 | class MultiplyExpr; | 72 | class MultiplyExpr; |
4468 | 70 | 73 | ||
4469 | 71 | class CommutativeExpr : public NaryExpr | 74 | class CommutativeExpr : public NaryExpr |
4470 | 72 | { | 75 | { |
4471 | 73 | public: | 76 | public: |
4472 | @@ -80,7 +83,6 @@ | |||
4473 | 80 | for(auto& e : _exprs) sum += e->formulaSize(); | 83 | for(auto& e : _exprs) sum += e->formulaSize(); |
4474 | 81 | return sum + 1; | 84 | return sum + 1; |
4475 | 82 | } | 85 | } |
4476 | 83 | void toString(std::ostream&) const override; | ||
4477 | 84 | bool placeFree() const override; | 86 | bool placeFree() const override; |
4478 | 85 | auto constant() const { return _constant; } | 87 | auto constant() const { return _constant; } |
4479 | 86 | auto& places() const { return _ids; } | 88 | auto& places() const { return _ids; } |
4480 | @@ -98,13 +100,12 @@ | |||
4481 | 98 | public: | 100 | public: |
4482 | 99 | 101 | ||
4483 | 100 | PlusExpr(std::vector<Expr_ptr>&& exprs, bool tk = false); | 102 | PlusExpr(std::vector<Expr_ptr>&& exprs, bool tk = false); |
4485 | 101 | 103 | ||
4486 | 102 | Expr::Types type() const override; | 104 | Expr::Types type() const override; |
4487 | 103 | Member constraint(SimplificationContext& context) const override; | 105 | Member constraint(SimplificationContext& context) const override; |
4488 | 104 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; | 106 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; |
4489 | 105 | bool tk = false; | 107 | bool tk = false; |
4492 | 106 | void incr(ReducingSuccessorGenerator& generator) const override; | 108 | |
4491 | 107 | void decr(ReducingSuccessorGenerator& generator) const override; | ||
4493 | 108 | void visit(Visitor& visitor) const override; | 109 | void visit(Visitor& visitor) const override; |
4494 | 109 | protected: | 110 | protected: |
4495 | 110 | int apply(int v1, int v2) const override; | 111 | int apply(int v1, int v2) const override; |
4496 | @@ -122,8 +123,7 @@ | |||
4497 | 122 | Expr::Types type() const override; | 123 | Expr::Types type() const override; |
4498 | 123 | Member constraint(SimplificationContext& context) const override; | 124 | Member constraint(SimplificationContext& context) const override; |
4499 | 124 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; | 125 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; |
4502 | 125 | void incr(ReducingSuccessorGenerator& generator) const override; | 126 | |
4501 | 126 | void decr(ReducingSuccessorGenerator& generator) const override; | ||
4503 | 127 | void toBinary(std::ostream&) const override; | 127 | void toBinary(std::ostream&) const override; |
4504 | 128 | void visit(Visitor& visitor) const override; | 128 | void visit(Visitor& visitor) const override; |
4505 | 129 | protected: | 129 | protected: |
4506 | @@ -140,8 +140,7 @@ | |||
4507 | 140 | Expr::Types type() const override; | 140 | Expr::Types type() const override; |
4508 | 141 | Member constraint(SimplificationContext& context) const override; | 141 | Member constraint(SimplificationContext& context) const override; |
4509 | 142 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; | 142 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; |
4512 | 143 | void incr(ReducingSuccessorGenerator& generator) const override; | 143 | |
4511 | 144 | void decr(ReducingSuccessorGenerator& generator) const override; | ||
4513 | 145 | void visit(Visitor& visitor) const override; | 144 | void visit(Visitor& visitor) const override; |
4514 | 146 | protected: | 145 | protected: |
4515 | 147 | int apply(int v1, int v2) const override; | 146 | int apply(int v1, int v2) const override; |
4516 | @@ -158,13 +157,11 @@ | |||
4517 | 158 | } | 157 | } |
4518 | 159 | void analyze(AnalysisContext& context) override; | 158 | void analyze(AnalysisContext& context) override; |
4519 | 160 | int evaluate(const EvaluationContext& context) override; | 159 | int evaluate(const EvaluationContext& context) override; |
4520 | 161 | void toString(std::ostream&) const override; | ||
4521 | 162 | Expr::Types type() const override; | 160 | Expr::Types type() const override; |
4522 | 163 | Member constraint(SimplificationContext& context) const override; | 161 | Member constraint(SimplificationContext& context) const override; |
4523 | 164 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; | 162 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; |
4524 | 165 | void toBinary(std::ostream&) const override; | 163 | void toBinary(std::ostream&) const override; |
4527 | 166 | void incr(ReducingSuccessorGenerator& generator) const override; | 164 | |
4526 | 167 | void decr(ReducingSuccessorGenerator& generator) const override; | ||
4528 | 168 | void visit(Visitor& visitor) const override; | 165 | void visit(Visitor& visitor) const override; |
4529 | 169 | int formulaSize() const override{ | 166 | int formulaSize() const override{ |
4530 | 170 | return _expr->formulaSize() + 1; | 167 | return _expr->formulaSize() + 1; |
4531 | @@ -181,14 +178,13 @@ | |||
4532 | 181 | 178 | ||
4533 | 182 | LiteralExpr(int value) : _value(value) { | 179 | LiteralExpr(int value) : _value(value) { |
4534 | 183 | } | 180 | } |
4535 | 181 | LiteralExpr(const LiteralExpr&) = default; | ||
4536 | 184 | void analyze(AnalysisContext& context) override; | 182 | void analyze(AnalysisContext& context) override; |
4537 | 185 | int evaluate(const EvaluationContext& context) override; | 183 | int evaluate(const EvaluationContext& context) override; |
4538 | 186 | void toString(std::ostream&) const override; | ||
4539 | 187 | Expr::Types type() const override; | 184 | Expr::Types type() const override; |
4540 | 188 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; | 185 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; |
4541 | 189 | void toBinary(std::ostream&) const override; | 186 | void toBinary(std::ostream&) const override; |
4544 | 190 | void incr(ReducingSuccessorGenerator& generator) const override; | 187 | |
4543 | 191 | void decr(ReducingSuccessorGenerator& generator) const override; | ||
4545 | 192 | void visit(Visitor& visitor) const override; | 188 | void visit(Visitor& visitor) const override; |
4546 | 193 | int formulaSize() const override{ | 189 | int formulaSize() const override{ |
4547 | 194 | return 1; | 190 | return 1; |
4548 | @@ -206,29 +202,18 @@ | |||
4549 | 206 | class IdentifierExpr : public Expr { | 202 | class IdentifierExpr : public Expr { |
4550 | 207 | public: | 203 | public: |
4551 | 208 | IdentifierExpr(const std::string& name) : _name(name) {} | 204 | IdentifierExpr(const std::string& name) : _name(name) {} |
4552 | 205 | IdentifierExpr(const IdentifierExpr&) = default; | ||
4553 | 209 | void analyze(AnalysisContext& context) override; | 206 | void analyze(AnalysisContext& context) override; |
4554 | 210 | int evaluate(const EvaluationContext& context) override { | 207 | int evaluate(const EvaluationContext& context) override { |
4555 | 211 | return _compiled->evaluate(context); | 208 | return _compiled->evaluate(context); |
4556 | 212 | } | 209 | } |
4564 | 213 | void toString(std::ostream& os) const override { | 210 | [[nodiscard]] Expr::Types type() const override { |
4558 | 214 | if(_compiled) | ||
4559 | 215 | _compiled->toString(os); | ||
4560 | 216 | else | ||
4561 | 217 | os << _name; | ||
4562 | 218 | } | ||
4563 | 219 | Expr::Types type() const override { | ||
4565 | 220 | if(_compiled) return _compiled->type(); | 211 | if(_compiled) return _compiled->type(); |
4566 | 221 | return Expr::IdentifierExpr; | 212 | return Expr::IdentifierExpr; |
4567 | 222 | } | 213 | } |
4568 | 223 | void toXML(std::ostream& os, uint32_t tabs, bool tokencount = false) const override { | 214 | void toXML(std::ostream& os, uint32_t tabs, bool tokencount = false) const override { |
4569 | 224 | _compiled->toXML(os, tabs, tokencount); | 215 | _compiled->toXML(os, tabs, tokencount); |
4570 | 225 | } | 216 | } |
4571 | 226 | void incr(ReducingSuccessorGenerator& generator) const override { | ||
4572 | 227 | _compiled->incr(generator); | ||
4573 | 228 | } | ||
4574 | 229 | void decr(ReducingSuccessorGenerator& generator) const override { | ||
4575 | 230 | _compiled->decr(generator); | ||
4576 | 231 | } | ||
4577 | 232 | int formulaSize() const override { | 217 | int formulaSize() const override { |
4578 | 233 | if(_compiled) return _compiled->formulaSize(); | 218 | if(_compiled) return _compiled->formulaSize(); |
4579 | 234 | return 1; | 219 | return 1; |
4580 | @@ -241,11 +226,20 @@ | |||
4581 | 241 | Member constraint(SimplificationContext& context) const override { | 226 | Member constraint(SimplificationContext& context) const override { |
4582 | 242 | return _compiled->constraint(context); | 227 | return _compiled->constraint(context); |
4583 | 243 | } | 228 | } |
4585 | 244 | 229 | ||
4586 | 245 | void toBinary(std::ostream& s) const override { | 230 | void toBinary(std::ostream& s) const override { |
4587 | 246 | _compiled->toBinary(s); | 231 | _compiled->toBinary(s); |
4588 | 247 | } | 232 | } |
4590 | 248 | void visit(Visitor& visitor) const override; | 233 | void visit(Visitor& visitor) const override; |
4591 | 234 | |||
4592 | 235 | [[nodiscard]] const std::string &name() const { | ||
4593 | 236 | return _name; | ||
4594 | 237 | } | ||
4595 | 238 | |||
4596 | 239 | [[nodiscard]] const Expr_ptr &compiled() const { | ||
4597 | 240 | return _compiled; | ||
4598 | 241 | } | ||
4599 | 242 | |||
4600 | 249 | private: | 243 | private: |
4601 | 250 | std::string _name; | 244 | std::string _name; |
4602 | 251 | Expr_ptr _compiled; | 245 | Expr_ptr _compiled; |
4603 | @@ -257,18 +251,17 @@ | |||
4604 | 257 | UnfoldedIdentifierExpr(const std::string& name, int offest) | 251 | UnfoldedIdentifierExpr(const std::string& name, int offest) |
4605 | 258 | : _offsetInMarking(offest), _name(name) { | 252 | : _offsetInMarking(offest), _name(name) { |
4606 | 259 | } | 253 | } |
4608 | 260 | 254 | ||
4609 | 261 | UnfoldedIdentifierExpr(const std::string& name) : UnfoldedIdentifierExpr(name, -1) { | 255 | UnfoldedIdentifierExpr(const std::string& name) : UnfoldedIdentifierExpr(name, -1) { |
4610 | 262 | } | 256 | } |
4611 | 263 | 257 | ||
4612 | 258 | UnfoldedIdentifierExpr(const UnfoldedIdentifierExpr&) = default; | ||
4613 | 259 | |||
4614 | 264 | void analyze(AnalysisContext& context) override; | 260 | void analyze(AnalysisContext& context) override; |
4615 | 265 | int evaluate(const EvaluationContext& context) override; | 261 | int evaluate(const EvaluationContext& context) override; |
4616 | 266 | void toString(std::ostream&) const override; | ||
4617 | 267 | Expr::Types type() const override; | 262 | Expr::Types type() const override; |
4618 | 268 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; | 263 | void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override; |
4619 | 269 | void toBinary(std::ostream&) const override; | 264 | void toBinary(std::ostream&) const override; |
4620 | 270 | void incr(ReducingSuccessorGenerator& generator) const override; | ||
4621 | 271 | void decr(ReducingSuccessorGenerator& generator) const override; | ||
4622 | 272 | int formulaSize() const override{ | 265 | int formulaSize() const override{ |
4623 | 273 | return 1; | 266 | return 1; |
4624 | 274 | } | 267 | } |
4625 | @@ -276,7 +269,7 @@ | |||
4626 | 276 | int offset() const { | 269 | int offset() const { |
4627 | 277 | return _offsetInMarking; | 270 | return _offsetInMarking; |
4628 | 278 | } | 271 | } |
4630 | 279 | const std::string& name() | 272 | const std::string& name() const |
4631 | 280 | { | 273 | { |
4632 | 281 | return _name; | 274 | return _name; |
4633 | 282 | } | 275 | } |
4634 | @@ -311,18 +304,14 @@ | |||
4635 | 311 | 304 | ||
4636 | 312 | void toXML(std::ostream& out, uint32_t tabs) const override | 305 | void toXML(std::ostream& out, uint32_t tabs) const override |
4637 | 313 | { _compiled->toXML(out, tabs); } | 306 | { _compiled->toXML(out, tabs); } |
4640 | 314 | void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override | 307 | |
4641 | 315 | { _compiled->findInteresting(generator, negated);} | 308 | |
4642 | 316 | Quantifier getQuantifier() const override | 309 | Quantifier getQuantifier() const override |
4643 | 317 | { return _compiled->getQuantifier(); } | 310 | { return _compiled->getQuantifier(); } |
4644 | 318 | Path getPath() const override { return _compiled->getPath(); } | 311 | Path getPath() const override { return _compiled->getPath(); } |
4645 | 319 | CTLType getQueryType() const override { return _compiled->getQueryType(); } | 312 | CTLType getQueryType() const override { return _compiled->getQueryType(); } |
4646 | 320 | bool containsNext() const override { return _compiled->containsNext(); } | 313 | bool containsNext() const override { return _compiled->containsNext(); } |
4647 | 321 | bool nestedDeadlock() const override { return _compiled->nestedDeadlock(); } | 314 | bool nestedDeadlock() const override { return _compiled->nestedDeadlock(); } |
4648 | 322 | #ifdef VERIFYPN_TAR | ||
4649 | 323 | virtual z3::expr encodeSat(const PetriNet& net, z3::context& context, std::vector<int32_t>& uses, std::vector<bool>& incremented) const | ||
4650 | 324 | { return _compiled->encodeSat(net, context, uses, incremented); } | ||
4651 | 325 | #endif | ||
4652 | 326 | int formulaSize() const override{ | 315 | int formulaSize() const override{ |
4653 | 327 | return _compiled->formulaSize(); | 316 | return _compiled->formulaSize(); |
4654 | 328 | } | 317 | } |
4655 | @@ -344,14 +333,13 @@ | |||
4656 | 344 | if (_compiled) _compiled->analyze(context); | 333 | if (_compiled) _compiled->analyze(context); |
4657 | 345 | else _analyze(context); | 334 | else _analyze(context); |
4658 | 346 | } | 335 | } |
4662 | 347 | void toString(std::ostream &out) const { | 336 | public: |
4663 | 348 | if (_compiled) _compiled->toString(out); | 337 | const Condition_ptr &getCompiled() const { |
4664 | 349 | else _toString(out); | 338 | return _compiled; |
4665 | 350 | } | 339 | } |
4666 | 351 | 340 | ||
4667 | 352 | protected: | 341 | protected: |
4668 | 353 | virtual void _analyze(AnalysisContext& context) = 0; | 342 | virtual void _analyze(AnalysisContext& context) = 0; |
4669 | 354 | virtual void _toString(std::ostream& out) const = 0; | ||
4670 | 355 | virtual Condition_ptr clone() = 0; | 343 | virtual Condition_ptr clone() = 0; |
4671 | 356 | Condition_ptr _compiled = nullptr; | 344 | Condition_ptr _compiled = nullptr; |
4672 | 357 | }; | 345 | }; |
4673 | @@ -373,7 +361,6 @@ | |||
4674 | 373 | Result evalAndSet(const EvaluationContext& context) override; | 361 | Result evalAndSet(const EvaluationContext& context) override; |
4675 | 374 | void visit(Visitor&) const override; | 362 | void visit(Visitor&) const override; |
4676 | 375 | uint32_t distance(DistanceContext& context) const override; | 363 | uint32_t distance(DistanceContext& context) const override; |
4677 | 376 | void toString(std::ostream&) const override; | ||
4678 | 377 | void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override; | 364 | void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override; |
4679 | 378 | Retval simplify(SimplificationContext& context) const override; | 365 | Retval simplify(SimplificationContext& context) const override; |
4680 | 379 | bool isReachability(uint32_t depth) const override; | 366 | bool isReachability(uint32_t depth) const override; |
4681 | @@ -381,7 +368,7 @@ | |||
4682 | 381 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | 368 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; |
4683 | 382 | void toXML(std::ostream&, uint32_t tabs) const override; | 369 | void toXML(std::ostream&, uint32_t tabs) const override; |
4684 | 383 | void toBinary(std::ostream&) const override; | 370 | void toBinary(std::ostream&) const override; |
4686 | 384 | void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override; | 371 | |
4687 | 385 | Quantifier getQuantifier() const override { return Quantifier::NEG; } | 372 | Quantifier getQuantifier() const override { return Quantifier::NEG; } |
4688 | 386 | Path getPath() const override { return Path::pError; } | 373 | Path getPath() const override { return Path::pError; } |
4689 | 387 | CTLType getQueryType() const override { return CTLType::LOPERATOR; } | 374 | CTLType getQueryType() const override { return CTLType::LOPERATOR; } |
4690 | @@ -393,18 +380,18 @@ | |||
4691 | 393 | Condition_ptr _cond; | 380 | Condition_ptr _cond; |
4692 | 394 | bool _temporal = false; | 381 | bool _temporal = false; |
4693 | 395 | }; | 382 | }; |
4698 | 396 | 383 | ||
4699 | 397 | 384 | ||
4700 | 398 | /******************** TEMPORAL OPERATORS ********************/ | 385 | /******************** TEMPORAL OPERATORS ********************/ |
4701 | 399 | 386 | ||
4702 | 400 | class QuantifierCondition : public Condition | 387 | class QuantifierCondition : public Condition |
4703 | 401 | { | 388 | { |
4704 | 402 | public: | 389 | public: |
4706 | 403 | virtual bool isTemporal() const override { return true;} | 390 | bool isTemporal() const override { return true;} |
4707 | 404 | CTLType getQueryType() const override { return CTLType::PATHQEURY; } | 391 | CTLType getQueryType() const override { return CTLType::PATHQEURY; } |
4708 | 405 | virtual const Condition_ptr& operator[] (size_t i) const = 0; | 392 | virtual const Condition_ptr& operator[] (size_t i) const = 0; |
4709 | 406 | }; | 393 | }; |
4711 | 407 | 394 | ||
4712 | 408 | class SimpleQuantifierCondition : public QuantifierCondition { | 395 | class SimpleQuantifierCondition : public QuantifierCondition { |
4713 | 409 | public: | 396 | public: |
4714 | 410 | SimpleQuantifierCondition(const Condition_ptr cond) { | 397 | SimpleQuantifierCondition(const Condition_ptr cond) { |
4715 | @@ -414,24 +401,174 @@ | |||
4716 | 414 | int formulaSize() const override{ | 401 | int formulaSize() const override{ |
4717 | 415 | return _cond->formulaSize() + 1; | 402 | return _cond->formulaSize() + 1; |
4718 | 416 | } | 403 | } |
4720 | 417 | 404 | ||
4721 | 418 | void analyze(AnalysisContext& context) override; | 405 | void analyze(AnalysisContext& context) override; |
4722 | 419 | Result evaluate(const EvaluationContext& context) override; | 406 | Result evaluate(const EvaluationContext& context) override; |
4723 | 420 | Result evalAndSet(const EvaluationContext& context) override; | 407 | Result evalAndSet(const EvaluationContext& context) override; |
4724 | 421 | void toString(std::ostream&) const override; | ||
4725 | 422 | void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override; | 408 | void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override; |
4726 | 423 | void toBinary(std::ostream& out) const override; | 409 | void toBinary(std::ostream& out) const override; |
4728 | 424 | void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override; | 410 | |
4729 | 425 | virtual const Condition_ptr& operator[] (size_t i) const override { return _cond;} | 411 | virtual const Condition_ptr& operator[] (size_t i) const override { return _cond;} |
4731 | 426 | virtual bool containsNext() const override { return _cond->containsNext(); } | 412 | bool containsNext() const override { return _cond->containsNext(); } |
4732 | 427 | bool nestedDeadlock() const override { return _cond->nestedDeadlock(); } | 413 | bool nestedDeadlock() const override { return _cond->nestedDeadlock(); } |
4733 | 428 | private: | 414 | private: |
4734 | 429 | virtual std::string op() const = 0; | 415 | virtual std::string op() const = 0; |
4736 | 430 | 416 | ||
4737 | 431 | protected: | 417 | protected: |
4738 | 432 | Condition_ptr _cond; | 418 | Condition_ptr _cond; |
4739 | 433 | }; | 419 | }; |
4741 | 434 | 420 | ||
4742 | 421 | class ECondition : public SimpleQuantifierCondition { | ||
4743 | 422 | public: | ||
4744 | 423 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | ||
4745 | 424 | |||
4746 | 425 | Result evaluate(const EvaluationContext& context) override; | ||
4747 | 426 | |||
4748 | 427 | Retval simplify(SimplificationContext& context) const override; | ||
4749 | 428 | |||
4750 | 429 | bool isReachability(uint32_t depth) const override; | ||
4751 | 430 | Condition_ptr prepareForReachability(bool negated) const override; | ||
4752 | 431 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | ||
4753 | 432 | void toXML(std::ostream&, uint32_t tabs) const override; | ||
4754 | 433 | Quantifier getQuantifier() const override { return Quantifier::E; } | ||
4755 | 434 | Path getPath() const override { return Path::pError; } | ||
4756 | 435 | uint32_t distance(DistanceContext& context) const override { | ||
4757 | 436 | // TODO implement | ||
4758 | 437 | assert(false); std::cerr << "TODO implement" << std::endl; exit(0); | ||
4759 | 438 | } | ||
4760 | 439 | bool isLoopSensitive() const override { | ||
4761 | 440 | // Other LTL Loop sensitivity depend on the outermost quantifier being an A, | ||
4762 | 441 | // so if it is an E we disable loop sensitive reductions. | ||
4763 | 442 | return true; | ||
4764 | 443 | } | ||
4765 | 444 | void visit(Visitor&) const override; | ||
4766 | 445 | private: | ||
4767 | 446 | std::string op() const override; | ||
4768 | 447 | }; | ||
4769 | 448 | |||
4770 | 449 | class ACondition : public SimpleQuantifierCondition { | ||
4771 | 450 | public: | ||
4772 | 451 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | ||
4773 | 452 | |||
4774 | 453 | Result evaluate(const EvaluationContext& context) override; | ||
4775 | 454 | |||
4776 | 455 | Retval simplify(SimplificationContext& context) const override; | ||
4777 | 456 | bool isReachability(uint32_t depth) const override; | ||
4778 | 457 | Condition_ptr prepareForReachability(bool negated) const override; | ||
4779 | 458 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | ||
4780 | 459 | void toXML(std::ostream&, uint32_t tabs) const override; | ||
4781 | 460 | Quantifier getQuantifier() const override { return Quantifier::A; } | ||
4782 | 461 | Path getPath() const override { return Path::pError; } | ||
4783 | 462 | uint32_t distance(DistanceContext& context) const override { | ||
4784 | 463 | uint32_t retval = _cond->distance(context); | ||
4785 | 464 | return retval; | ||
4786 | 465 | } | ||
4787 | 466 | void visit(Visitor&) const override; | ||
4788 | 467 | |||
4789 | 468 | private: | ||
4790 | 469 | std::string op() const override; | ||
4791 | 470 | }; | ||
4792 | 471 | |||
4793 | 472 | class GCondition : public SimpleQuantifierCondition { | ||
4794 | 473 | public: | ||
4795 | 474 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | ||
4796 | 475 | |||
4797 | 476 | Result evaluate(const EvaluationContext &context) override; | ||
4798 | 477 | |||
4799 | 478 | bool isReachability(uint32_t depth) const override { | ||
4800 | 479 | // This could potentially be a reachability formula if the parent is an A. | ||
4801 | 480 | // This case is however already handled by ACondition. | ||
4802 | 481 | return false; | ||
4803 | 482 | } | ||
4804 | 483 | |||
4805 | 484 | Condition_ptr prepareForReachability(bool negated) const override { | ||
4806 | 485 | // TODO implement | ||
4807 | 486 | assert(false); | ||
4808 | 487 | std::cerr << "TODO implement" << std::endl; | ||
4809 | 488 | exit(0); | ||
4810 | 489 | } | ||
4811 | 490 | |||
4812 | 491 | Condition_ptr | ||
4813 | 492 | pushNegation(negstat_t &, const EvaluationContext &context, bool nested, bool negated, bool initrw) override; | ||
4814 | 493 | |||
4815 | 494 | Retval simplify(SimplificationContext &context) const override; | ||
4816 | 495 | |||
4817 | 496 | void toXML(std::ostream &, uint32_t tabs) const override; | ||
4818 | 497 | |||
4819 | 498 | Quantifier getQuantifier() const override { return Quantifier::EMPTY; } | ||
4820 | 499 | |||
4821 | 500 | Path getPath() const override { return Path::G; } | ||
4822 | 501 | |||
4823 | 502 | uint32_t distance(DistanceContext &context) const override { | ||
4824 | 503 | context.negate(); | ||
4825 | 504 | uint32_t retval = _cond->distance(context); | ||
4826 | 505 | context.negate(); | ||
4827 | 506 | return retval; | ||
4828 | 507 | } | ||
4829 | 508 | |||
4830 | 509 | bool isLoopSensitive() const override { return true; } | ||
4831 | 510 | |||
4832 | 511 | void visit(Visitor &) const override; | ||
4833 | 512 | |||
4834 | 513 | private: | ||
4835 | 514 | std::string op() const override; | ||
4836 | 515 | }; | ||
4837 | 516 | |||
4838 | 517 | class FCondition : public SimpleQuantifierCondition { | ||
4839 | 518 | public: | ||
4840 | 519 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | ||
4841 | 520 | |||
4842 | 521 | Result evaluate(const EvaluationContext& context) override; | ||
4843 | 522 | |||
4844 | 523 | Retval simplify(SimplificationContext& context) const override; | ||
4845 | 524 | bool isReachability(uint32_t depth) const override { | ||
4846 | 525 | // This could potentially be a reachability formula if the parent is an E. | ||
4847 | 526 | // This case is however already handled by ECondition. | ||
4848 | 527 | return false; | ||
4849 | 528 | } | ||
4850 | 529 | Condition_ptr prepareForReachability(bool negated) const override { | ||
4851 | 530 | // TODO implement | ||
4852 | 531 | assert(false); std::cerr << "TODO implement" << std::endl; exit(0); | ||
4853 | 532 | } | ||
4854 | 533 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | ||
4855 | 534 | void toXML(std::ostream&, uint32_t tabs) const override; | ||
4856 | 535 | Quantifier getQuantifier() const override { return Quantifier::EMPTY; } | ||
4857 | 536 | Path getPath() const override { return Path::F; } | ||
4858 | 537 | uint32_t distance(DistanceContext& context) const override { | ||
4859 | 538 | return _cond->distance(context); | ||
4860 | 539 | } | ||
4861 | 540 | bool isLoopSensitive() const override { return true; } | ||
4862 | 541 | void visit(Visitor&) const override; | ||
4863 | 542 | private: | ||
4864 | 543 | std::string op() const override; | ||
4865 | 544 | }; | ||
4866 | 545 | |||
4867 | 546 | class XCondition : public SimpleQuantifierCondition { | ||
4868 | 547 | public: | ||
4869 | 548 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | ||
4870 | 549 | |||
4871 | 550 | bool isReachability(uint32_t depth) const override { | ||
4872 | 551 | return false; | ||
4873 | 552 | } | ||
4874 | 553 | Condition_ptr prepareForReachability(bool negated) const override { | ||
4875 | 554 | // TODO implement | ||
4876 | 555 | assert(false); std::cerr << "TODO implement" << std::endl; exit(0); | ||
4877 | 556 | } | ||
4878 | 557 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | ||
4879 | 558 | Retval simplify(SimplificationContext& context) const override; | ||
4880 | 559 | void toXML(std::ostream&, uint32_t tabs) const override; | ||
4881 | 560 | Quantifier getQuantifier() const override { return Quantifier::EMPTY; } | ||
4882 | 561 | Path getPath() const override { return Path::X; } | ||
4883 | 562 | uint32_t distance(DistanceContext& context) const override { | ||
4884 | 563 | return _cond->distance(context); | ||
4885 | 564 | } | ||
4886 | 565 | bool containsNext() const override { return true; } | ||
4887 | 566 | bool isLoopSensitive() const override { return true; } | ||
4888 | 567 | void visit(Visitor&) const override; | ||
4889 | 568 | private: | ||
4890 | 569 | std::string op() const override; | ||
4891 | 570 | }; | ||
4892 | 571 | |||
4893 | 435 | class EXCondition : public SimpleQuantifierCondition { | 572 | class EXCondition : public SimpleQuantifierCondition { |
4894 | 436 | public: | 573 | public: |
4895 | 437 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | 574 | using SimpleQuantifierCondition::SimpleQuantifierCondition; |
4896 | @@ -443,24 +580,24 @@ | |||
4897 | 443 | Quantifier getQuantifier() const override { return Quantifier::E; } | 580 | Quantifier getQuantifier() const override { return Quantifier::E; } |
4898 | 444 | Path getPath() const override { return Path::X; } | 581 | Path getPath() const override { return Path::X; } |
4899 | 445 | uint32_t distance(DistanceContext& context) const override; | 582 | uint32_t distance(DistanceContext& context) const override; |
4901 | 446 | bool containsNext() const override { return true; } | 583 | bool containsNext() const override { return true; } |
4902 | 447 | virtual bool isLoopSensitive() const override { return true; } | 584 | virtual bool isLoopSensitive() const override { return true; } |
4903 | 448 | void visit(Visitor&) const override; | 585 | void visit(Visitor&) const override; |
4904 | 449 | private: | 586 | private: |
4905 | 450 | std::string op() const override; | 587 | std::string op() const override; |
4906 | 451 | }; | 588 | }; |
4908 | 452 | 589 | ||
4909 | 453 | class EGCondition : public SimpleQuantifierCondition { | 590 | class EGCondition : public SimpleQuantifierCondition { |
4910 | 454 | public: | 591 | public: |
4911 | 455 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | 592 | using SimpleQuantifierCondition::SimpleQuantifierCondition; |
4913 | 456 | 593 | ||
4914 | 457 | Retval simplify(SimplificationContext& context) const override; | 594 | Retval simplify(SimplificationContext& context) const override; |
4915 | 458 | bool isReachability(uint32_t depth) const override; | 595 | bool isReachability(uint32_t depth) const override; |
4916 | 459 | Condition_ptr prepareForReachability(bool negated) const override; | 596 | Condition_ptr prepareForReachability(bool negated) const override; |
4917 | 460 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | 597 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; |
4918 | 461 | void toXML(std::ostream&, uint32_t tabs) const override; | 598 | void toXML(std::ostream&, uint32_t tabs) const override; |
4919 | 462 | Quantifier getQuantifier() const override { return Quantifier::E; } | 599 | Quantifier getQuantifier() const override { return Quantifier::E; } |
4921 | 463 | Path getPath() const override { return Path::G; } | 600 | Path getPath() const override { return Path::G; } |
4922 | 464 | uint32_t distance(DistanceContext& context) const override; | 601 | uint32_t distance(DistanceContext& context) const override; |
4923 | 465 | Result evaluate(const EvaluationContext& context) override; | 602 | Result evaluate(const EvaluationContext& context) override; |
4924 | 466 | Result evalAndSet(const EvaluationContext& context) override; | 603 | Result evalAndSet(const EvaluationContext& context) override; |
4925 | @@ -469,18 +606,18 @@ | |||
4926 | 469 | private: | 606 | private: |
4927 | 470 | std::string op() const override; | 607 | std::string op() const override; |
4928 | 471 | }; | 608 | }; |
4930 | 472 | 609 | ||
4931 | 473 | class EFCondition : public SimpleQuantifierCondition { | 610 | class EFCondition : public SimpleQuantifierCondition { |
4932 | 474 | public: | 611 | public: |
4933 | 475 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | 612 | using SimpleQuantifierCondition::SimpleQuantifierCondition; |
4935 | 476 | 613 | ||
4936 | 477 | Retval simplify(SimplificationContext& context) const override; | 614 | Retval simplify(SimplificationContext& context) const override; |
4937 | 478 | bool isReachability(uint32_t depth) const override; | 615 | bool isReachability(uint32_t depth) const override; |
4938 | 479 | Condition_ptr prepareForReachability(bool negated) const override; | 616 | Condition_ptr prepareForReachability(bool negated) const override; |
4939 | 480 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | 617 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; |
4940 | 481 | void toXML(std::ostream&, uint32_t tabs) const override; | 618 | void toXML(std::ostream&, uint32_t tabs) const override; |
4941 | 482 | Quantifier getQuantifier() const override { return Quantifier::E; } | 619 | Quantifier getQuantifier() const override { return Quantifier::E; } |
4943 | 483 | Path getPath() const override { return Path::F; } | 620 | Path getPath() const override { return Path::F; } |
4944 | 484 | uint32_t distance(DistanceContext& context) const override; | 621 | uint32_t distance(DistanceContext& context) const override; |
4945 | 485 | Result evaluate(const EvaluationContext& context) override; | 622 | Result evaluate(const EvaluationContext& context) override; |
4946 | 486 | Result evalAndSet(const EvaluationContext& context) override; | 623 | Result evalAndSet(const EvaluationContext& context) override; |
4947 | @@ -506,7 +643,7 @@ | |||
4948 | 506 | private: | 643 | private: |
4949 | 507 | std::string op() const override; | 644 | std::string op() const override; |
4950 | 508 | }; | 645 | }; |
4952 | 509 | 646 | ||
4953 | 510 | class AGCondition : public SimpleQuantifierCondition { | 647 | class AGCondition : public SimpleQuantifierCondition { |
4954 | 511 | public: | 648 | public: |
4955 | 512 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | 649 | using SimpleQuantifierCondition::SimpleQuantifierCondition; |
4956 | @@ -516,7 +653,7 @@ | |||
4957 | 516 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | 653 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; |
4958 | 517 | void toXML(std::ostream&, uint32_t tabs) const override; | 654 | void toXML(std::ostream&, uint32_t tabs) const override; |
4959 | 518 | Quantifier getQuantifier() const override { return Quantifier::A; } | 655 | Quantifier getQuantifier() const override { return Quantifier::A; } |
4961 | 519 | Path getPath() const override { return Path::G; } | 656 | Path getPath() const override { return Path::G; } |
4962 | 520 | uint32_t distance(DistanceContext& context) const override; | 657 | uint32_t distance(DistanceContext& context) const override; |
4963 | 521 | Result evaluate(const EvaluationContext& context) override; | 658 | Result evaluate(const EvaluationContext& context) override; |
4964 | 522 | Result evalAndSet(const EvaluationContext& context) override; | 659 | Result evalAndSet(const EvaluationContext& context) override; |
4965 | @@ -524,7 +661,7 @@ | |||
4966 | 524 | private: | 661 | private: |
4967 | 525 | std::string op() const override; | 662 | std::string op() const override; |
4968 | 526 | }; | 663 | }; |
4970 | 527 | 664 | ||
4971 | 528 | class AFCondition : public SimpleQuantifierCondition { | 665 | class AFCondition : public SimpleQuantifierCondition { |
4972 | 529 | public: | 666 | public: |
4973 | 530 | using SimpleQuantifierCondition::SimpleQuantifierCondition; | 667 | using SimpleQuantifierCondition::SimpleQuantifierCondition; |
4974 | @@ -534,7 +671,7 @@ | |||
4975 | 534 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; | 671 | Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override; |
4976 | 535 | void toXML(std::ostream&, uint32_t tabs) const override; | 672 | void toXML(std::ostream&, uint32_t tabs) const override; |
4977 | 536 | Quantifier getQuantifier() const override { return Quantifier::A; } | 673 | Quantifier getQuantifier() const override { return Quantifier::A; } |
4979 | 537 | Path getPath() const override { return Path::F; } | 674 | Path getPath() const override { return Path::F; } |
4980 | 538 | uint32_t distance(DistanceContext& context) const override; | 675 | uint32_t distance(DistanceContext& context) const override; |
4981 | 539 | Result evaluate(const EvaluationContext& context) override; | 676 | Result evaluate(const EvaluationContext& context) override; |
4982 | 540 | Result evalAndSet(const EvaluationContext& context) override; | 677 | Result evalAndSet(const EvaluationContext& context) override; |
4983 | @@ -542,8 +679,8 @@ | |||
4984 | 542 | virtual bool isLoopSensitive() const override { return true; } | 679 | virtual bool isLoopSensitive() const override { return true; } |
4985 | 543 | private: | 680 | private: |
4986 | 544 | std::string op() const override; | 681 | std::string op() const override; |
4989 | 545 | }; | 682 | }; |
4990 | 546 | 683 | ||
4991 | 547 | class UntilCondition : public QuantifierCondition { | 684 | class UntilCondition : public QuantifierCondition { |
4992 | 548 | public: | 685 | public: |
4993 | 549 | UntilCondition(const Condition_ptr cond1, const Condition_ptr cond2) { | 686 | UntilCondition(const Condition_ptr cond1, const Condition_ptr cond2) { |
4994 | @@ -554,50 +691,59 @@ | |||
4995 | 554 | int formulaSize() const override{ | 691 | int formulaSize() const override{ |
4996 | 555 | return _cond1->formulaSize() + _cond2->formulaSize() + 1; | 692 | return _cond1->formulaSize() + _cond2->formulaSize() + 1; |
4997 | 556 | } | 693 | } |
4999 | 557 | 694 | ||
5000 | 558 | void analyze(AnalysisContext& context) override; | 695 | void analyze(AnalysisContext& context) override; |
The diff has been truncated for viewing.