Merge lp:~tapaal-ltl/verifypn/mcc2021 into lp:verifypn

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
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.

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
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2020-10-31 18:57:21 +0000
+++ CMakeLists.txt 2021-04-02 18:07:40 +0000
@@ -15,7 +15,7 @@
15set(CMAKE_POSITION_INDEPENDENT_CODE ON)15set(CMAKE_POSITION_INDEPENDENT_CODE ON)
1616
1717
18set(VERIFYPN_VERSION 3.1.1)18set(VERIFYPN_VERSION 4.0.0)
19add_compile_definitions(VERIFYPN_VERSION=\"${VERIFYPN_VERSION}\")19add_compile_definitions(VERIFYPN_VERSION=\"${VERIFYPN_VERSION}\")
2020
21project(verifypn VERSION ${VERIFYPN_VERSION} LANGUAGES CXX C)21project(verifypn VERSION ${VERIFYPN_VERSION} LANGUAGES CXX C)
@@ -32,11 +32,7 @@
32 endif(VERIFYPN_MC_Simplification)32 endif(VERIFYPN_MC_Simplification)
33 if (NOT APPLE)33 if (NOT APPLE)
34 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")34 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
35 else(NOT APPLE)
36 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
37 endif(NOT APPLE)35 endif(NOT APPLE)
38else(VERIFYPN_Static)
39 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
40endif (VERIFYPN_Static)36endif (VERIFYPN_Static)
4137
42if (VERIFYPN_MC_Simplification)38if (VERIFYPN_MC_Simplification)
@@ -47,14 +43,15 @@
47 set(ARCH_TYPE "linux64")43 set(ARCH_TYPE "linux64")
48elseif(APPLE)44elseif(APPLE)
49 set(ARCH_TYPE "osx64")45 set(ARCH_TYPE "osx64")
50 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.8 -m64 ")46 set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
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 ")
48 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m64 ")
52else()49else()
53 set(ARCH_TYPE "win64")50 set(ARCH_TYPE "win64")
54endif ()51endif ()
5552
56set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -pedantic-errors -O3 -DNDEBUG")53set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s -Wall -pedantic-errors -O3 -DNDEBUG")
5754set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -fno-omit-frame-pointer")
58set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -O3 -DNDEBUG")55set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -O3 -DNDEBUG")
59if (VERIFYPN_Static AND NOT APPLE)56if (VERIFYPN_Static AND NOT APPLE)
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")
@@ -81,6 +78,23 @@
81 CONFIGURE_COMMAND mkdir -p ${CMAKE_BINARY_DIR}/external/include78 CONFIGURE_COMMAND mkdir -p ${CMAKE_BINARY_DIR}/external/include
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
83 )80 )
81 if (UNIX AND NOT APPLE)
82 ExternalProject_add(spot-ext
83 URL http://www.lrde.epita.fr/dload/spot/spot-2.9.6.tar.gz
84 URL_HASH SHA512=69ec8a3ce84b2c069bf40b8d2127e5085724c8e4ba88ffdefc3e2225f6334955959afd17bcfcde29fd6826d78d49a7f1303bd07ba756a8695473ff6cc5ade3a2
85 BUILD_COMMAND make
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
87 INSTALL_COMMAND make install
88 )
89 else ()
90 ExternalProject_add(spot-ext
91 URL http://www.lrde.epita.fr/dload/spot/spot-2.9.6.tar.gz
92 URL_HASH SHA512=69ec8a3ce84b2c069bf40b8d2127e5085724c8e4ba88ffdefc3e2225f6334955959afd17bcfcde29fd6826d78d49a7f1303bd07ba756a8695473ff6cc5ade3a2
93 BUILD_COMMAND make
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}
95 INSTALL_COMMAND make install
96 )
97 endif ()
8498
85 if (WIN32) #If windows 32 or 64 99 if (WIN32) #If windows 32 or 64
86 set(GLPK_CFLAGS "-D __WOE__ -O3" )100 set(GLPK_CFLAGS "-D __WOE__ -O3" )
87101
=== modified file 'Scripts/MCC20/competition-scripts/tapaal.sh' (properties changed: -x to +x)
=== modified file 'include/CTL/Algorithm/CertainZeroFPA.h'
--- include/CTL/Algorithm/CertainZeroFPA.h 2020-03-02 21:03:24 +0000
+++ include/CTL/Algorithm/CertainZeroFPA.h 2021-04-02 18:07:40 +0000
@@ -27,9 +27,8 @@
27 27
28 void checkEdge(DependencyGraph::Edge* e, bool only_assign = false);28 void checkEdge(DependencyGraph::Edge* e, bool only_assign = false);
29 void finalAssign(DependencyGraph::Configuration *c, DependencyGraph::Assignment a);29 void finalAssign(DependencyGraph::Configuration *c, DependencyGraph::Assignment a);
30 void finalAssign(DependencyGraph::Edge *e, DependencyGraph::Assignment a);
30 void explore(DependencyGraph::Configuration *c);31 void explore(DependencyGraph::Configuration *c);
31 void addDependency(DependencyGraph::Edge *e,
32 DependencyGraph::Configuration *target);
3332
34};33};
35}34}
3635
=== modified file 'include/CTL/DependencyGraph/Configuration.h'
--- include/CTL/DependencyGraph/Configuration.h 2020-03-10 13:29:26 +0000
+++ include/CTL/DependencyGraph/Configuration.h 2021-04-02 18:07:40 +0000
@@ -7,32 +7,29 @@
7#include <cstdio>7#include <cstdio>
8#include <iostream>8#include <iostream>
9#include <vector>9#include <vector>
10#include <forward_list>
1011
11namespace DependencyGraph {12namespace DependencyGraph {
1213
13class Edge;14class Edge;
1415
15enum Assignment {
16 ONE = 1, UNKNOWN = 0, ZERO = -1, CZERO = -2
17};
18
19class Configuration16class Configuration
20{17{
18public:
19 std::forward_list<Edge*> dependency_set;
20 uint32_t nsuccs = 0;
21private:
21 uint32_t distance = 0;22 uint32_t distance = 0;
22public:
23
24 uint32_t getDistance() const { return distance; }
25 void setDistance(uint32_t value) { distance = value; }23 void setDistance(uint32_t value) { distance = value; }
2624public:
25 int8_t assignment = UNKNOWN;
27 Configuration() {}26 Configuration() {}
28 virtual ~Configuration();27 uint32_t getDistance() const { return distance; }
29
30 bool isDone() const { return assignment == ONE || assignment == CZERO; }28 bool isDone() const { return assignment == ONE || assignment == CZERO; }
3129 void addDependency(Edge* e);
32 uint32_t owner = 0;30 void setOwner(uint32_t) { }
33 uint32_t nsuccs = 0;31 uint32_t getOwner() { return 0; }
34 std::vector<Edge*> dependency_set;32
35 Assignment assignment = UNKNOWN;
36};33};
3734
3835
3936
=== modified file 'include/CTL/DependencyGraph/Edge.h'
--- include/CTL/DependencyGraph/Edge.h 2020-03-02 21:03:24 +0000
+++ include/CTL/DependencyGraph/Edge.h 2021-04-02 18:07:40 +0000
@@ -6,13 +6,17 @@
6#include <string>6#include <string>
7#include <algorithm>7#include <algorithm>
8#include <cassert>8#include <cassert>
9#include <forward_list>
910
10namespace DependencyGraph {11namespace DependencyGraph {
1112
12class Configuration;13class Configuration;
14enum Assignment {
15 ONE = 1, UNKNOWN = 0, ZERO = -1, CZERO = -2
16};
1317
14class Edge {18class Edge {
15 typedef std::vector<Configuration*> container;19 typedef std::forward_list<Configuration*> container;
16public:20public:
17 Edge(){}21 Edge(){}
18 Edge(Configuration &t_source) : source(&t_source) {}22 Edge(Configuration &t_source) : source(&t_source) {}
@@ -20,17 +24,19 @@
20 void addTarget(Configuration* conf)24 void addTarget(Configuration* conf)
21 {25 {
22 assert(conf);26 assert(conf);
23 targets.push_back(conf);27 targets.push_front(conf);
28 //++children;
24 }29 }
25 30
31 container targets;
26 Configuration* source;32 Configuration* source;
27 container targets;
28 uint8_t status = 0;33 uint8_t status = 0;
29 bool processed = false;34 bool processed = false;
30 bool is_negated = false;35 bool is_negated = false;
36 bool handled = false;
31 int32_t refcnt = 0;37 int32_t refcnt = 0;
32 bool handled = false;38 /*size_t children;
33 uint32_t weight = 0;39 Assignment assignment;*/
34};40};
35}41}
36#endif // EDGE_H42#endif // EDGE_H
3743
=== modified file 'include/CTL/PetriNets/PetriConfig.h'
--- include/CTL/PetriNets/PetriConfig.h 2020-03-02 21:03:24 +0000
+++ include/CTL/PetriNets/PetriConfig.h 2021-04-02 18:07:40 +0000
@@ -20,8 +20,6 @@
20 DependencyGraph::Configuration(), marking(t_marking), query(t_query) {20 DependencyGraph::Configuration(), marking(t_marking), query(t_query) {
21 }21 }
2222
23 virtual ~PetriConfig(){};
24
25 size_t marking;23 size_t marking;
26 Condition *query;24 Condition *query;
2725
2826
=== added directory 'include/LTL'
=== added directory 'include/LTL/Algorithm'
=== added file 'include/LTL/Algorithm/ModelChecker.h'
--- include/LTL/Algorithm/ModelChecker.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Algorithm/ModelChecker.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,72 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_MODELCHECKER_H
19#define VERIFYPN_MODELCHECKER_H
20
21#include "PetriEngine/PQL/PQL.h"
22#include "LTL/ProductSuccessorGenerator.h"
23#include "LTL/Algorithm/ProductPrinter.h"
24#include "PetriEngine/options.h"
25
26namespace LTL {
27
28 class ModelChecker {
29 public:
30 ModelChecker(const PetriEngine::PetriNet &net, PetriEngine::PQL::Condition_ptr, const bool shortcircuitweak,
31 TraceLevel level = TraceLevel::Transitions);
32
33 virtual bool isSatisfied() = 0;
34
35 virtual ~ModelChecker() = default;
36
37 virtual void printStats(std::ostream &os) = 0;
38
39 [[nodiscard]] bool isweak() const { return is_weak; }
40
41 protected:
42 struct stats_t {
43 size_t explored = 0, expanded = 0;
44 };
45
46 stats_t stats;
47 virtual void _printStats(std::ostream &os, const PetriEngine::Structures::StateSetInterface &stateSet) {
48 std::cout << "STATS:\n"
49 << "\tdiscovered states: " << stateSet.discovered() << std::endl
50 << "\texplored states: " << stats.explored << std::endl
51 << "\texpanded states: " << stats.expanded << std::endl
52 << "\tmax tokens: " << stateSet.maxTokens() << std::endl;
53 }
54
55 std::unique_ptr<ProductSuccessorGenerator> successorGenerator;
56 const PetriEngine::PetriNet &net;
57 PetriEngine::PQL::Condition_ptr formula;
58 TraceLevel traceLevel;
59
60 size_t _discovered = 0;
61 const bool shortcircuitweak;
62 bool weakskip = false;
63 bool is_weak = false;
64 int maxTransName;
65
66 std::ostream &printTransition(size_t transition, LTL::Structures::ProductState &state, std::ostream &os);
67
68 void printLoop(std::ostream &os);
69 };
70}
71
72#endif //VERIFYPN_MODELCHECKER_H
073
=== added file 'include/LTL/Algorithm/NestedDepthFirstSearch.h'
--- include/LTL/Algorithm/NestedDepthFirstSearch.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Algorithm/NestedDepthFirstSearch.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,91 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H
19#define VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H
20
21#include "ModelChecker.h"
22#include "PetriEngine/Structures/StateSet.h"
23#include "PetriEngine/Structures/State.h"
24#include "PetriEngine/Structures/Queue.h"
25#include "LTL/Structures/ProductStateFactory.h"
26
27#include <ptrie/ptrie_stable.h>
28#include <unordered_set>
29
30using namespace PetriEngine;
31
32namespace LTL {
33 /**
34 * Implement the nested DFS algorithm for LTL model checking. Roughly based on versions given in
35 * <p>
36 * Jaco Geldenhuys & Antti Valmari,<br>
37 * More efficient on-the-fly LTL verification with Tarjan's algorithm,<br>
38 * https://doi.org/10.1016/j.tcs.2005.07.004
39 * </p>
40 * and
41 * <p>
42 * Gerard J. Holzmann, Doron Peled, and Mihalis Yannakakis<br>
43 * On Nested Depth First Search<br>
44 * https://spinroot.com/gerard/pdf/inprint/spin96.pdf
45 * </p>
46 * For most use cases, Tarjan's algorithm (see LTL::TarjanModelChecker) is faster.
47 * @tparam W type used for state storage. Use <code>PetriEngine::Structures::TracableStateSet</code> if you want traces,
48 * <code>PetriEngine::Structures::StateSet</code> if you don't care (as it is faster).
49 */
50 template <typename W>
51 class NestedDepthFirstSearch : public ModelChecker {
52 public:
53 NestedDepthFirstSearch(const PetriNet &net, PetriEngine::PQL::Condition_ptr ptr, const bool shortcircuitweak, TraceLevel level = TraceLevel::Full)
54 : ModelChecker(net, ptr, shortcircuitweak, level), factory{net, successorGenerator->initial_buchi_state()},
55 states(net, 0, (int)net.numberOfPlaces() + 1) {}
56
57 bool isSatisfied() override;
58
59 void printStats(std::ostream &os) override;
60
61 private:
62 using State = LTL::Structures::ProductState;
63
64 Structures::ProductStateFactory factory;
65 W states; //StateSet
66 std::set<size_t> mark1;
67 std::set<size_t> mark2;
68
69 struct StackEntry {
70 size_t id;
71 successor_info sucinfo;
72 };
73
74 State *seed;
75 bool violation = false;
76
77 //Used for printing the trace
78 std::stack<std::pair<size_t, size_t>> nested_transitions;
79
80 void dfs();
81
82 void ndfs(State &state);
83 void printTrace(std::stack<std::pair<size_t, size_t>> &transitions, std::ostream &os = std::cout);
84
85 static constexpr bool SaveTrace = std::is_same_v<W, PetriEngine::Structures::TracableStateSet>;
86 };
87 extern template class NestedDepthFirstSearch<PetriEngine::Structures::StateSet>;
88 extern template class NestedDepthFirstSearch<PetriEngine::Structures::TracableStateSet>;
89}
90
91#endif //VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H
092
=== added file 'include/LTL/Algorithm/ProductPrinter.h'
--- include/LTL/Algorithm/ProductPrinter.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Algorithm/ProductPrinter.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,31 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_PRODUCTPRINTER_H
19#define VERIFYPN_PRODUCTPRINTER_H
20
21#include "LTL/Structures/ProductStateFactory.h"
22#include "LTL/ProductSuccessorGenerator.h"
23#include "PetriEngine/Structures/StateSet.h"
24#include "PetriEngine/Structures/Queue.h"
25#include "PetriEngine/PQL/Contexts.h"
26
27namespace LTL::ProductPrinter {
28 void printProduct(ProductSuccessorGenerator &successorGenerator, std::ostream &os, const PetriEngine::PetriNet &net,
29 PetriEngine::PQL::Condition_ptr formula);
30}
31#endif //VERIFYPN_PRODUCTPRINTER_H
032
=== added file 'include/LTL/Algorithm/RandomNDFS.h'
--- include/LTL/Algorithm/RandomNDFS.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Algorithm/RandomNDFS.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,59 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_RANDOMNDFS_H
19#define VERIFYPN_RANDOMNDFS_H
20
21#include "ModelChecker.h"
22#include "PetriEngine/Structures/StateSet.h"
23#include "PetriEngine/Structures/State.h"
24#include "PetriEngine/Structures/Queue.h"
25#include "LTL/Structures/ProductStateFactory.h"
26
27#include <ptrie/ptrie_stable.h>
28
29using namespace PetriEngine;
30
31namespace LTL {
32 class RandomNDFS : public ModelChecker {
33 public:
34 RandomNDFS(const PetriNet &net, PetriEngine::PQL::Condition_ptr ptr)
35 : ModelChecker(net, ptr, false), factory{net, successorGenerator->initial_buchi_state()},
36 mark1(net, 0, (int) net.numberOfPlaces() + 1), mark2(net, 0, (int) net.numberOfPlaces() + 1) {}
37
38 bool isSatisfied() override;
39
40 void printStats(std::ostream &os) override;
41
42 private:
43 using State = LTL::Structures::ProductState;
44
45 Structures::ProductStateFactory factory;
46 PetriEngine::Structures::StateSet mark1;
47 PetriEngine::Structures::StateSet mark2;
48
49
50 State *seed;
51 bool violation = false;
52
53 void dfs();
54
55 void ndfs(State &state);
56 };
57}
58
59#endif //VERIFYPN_RANDOMNDFS_H
060
=== added file 'include/LTL/Algorithm/TarjanModelChecker.h'
--- include/LTL/Algorithm/TarjanModelChecker.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Algorithm/TarjanModelChecker.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,140 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_TARJANMODELCHECKER_H
19#define VERIFYPN_TARJANMODELCHECKER_H
20
21
22#include "LTL/Algorithm/ModelChecker.h"
23#include "LTL/Structures/ProductStateFactory.h"
24#include "PetriEngine/Structures/StateSet.h"
25
26#include <stack>
27#include <unordered_set>
28
29namespace LTL {
30
31 /**
32 * Implements on-the-fly version of Tarjan's algorithm suitable for LTL model checking.
33 * The idea is to detect some reachable strongly connected component containing an accepting state,
34 * which constitutes a counter-example.
35 * For more details see
36 * <p>
37 * Jaco Geldenhuys & Antti Valmari,
38 * More efficient on-the-fly LTL verification with Tarjan's algorithm,
39 * https://doi.org/10.1016/j.tcs.2005.07.004
40 * </p>
41 * @tparam SaveTrace whether to save and print counter-examples when possible.
42 */
43 template<bool SaveTrace>
44 class TarjanModelChecker : public ModelChecker {
45 public:
46 TarjanModelChecker(const PetriEngine::PetriNet &net, const PetriEngine::PQL::Condition_ptr &cond, const bool shortcircuitweak,
47 TraceLevel level = TraceLevel::Full)
48 : ModelChecker(net, cond, shortcircuitweak, level), factory(net, successorGenerator->initial_buchi_state()),
49 seen(net, 0, (int) net.numberOfPlaces() + 1)
50 {
51 chash.fill(std::numeric_limits<idx_t>::max());
52 }
53
54 bool isSatisfied() override;
55
56 void printStats(std::ostream &os) override
57 {
58 _printStats(os, seen);
59 }
60
61 private:
62 using State = LTL::Structures::ProductState;
63 using idx_t = size_t;
64 // 64 MB hash table
65 static constexpr idx_t HashSz = 16777216;
66
67 LTL::Structures::ProductStateFactory factory;
68
69 using StateSet = std::conditional_t<SaveTrace, PetriEngine::Structures::TracableStateSet, PetriEngine::Structures::StateSet>;
70
71 StateSet seen;
72 std::unordered_set<idx_t> store;
73
74 // rudimentary hash table of state IDs. chash[hash(state)] is the top index in cstack
75 // corresponding to state. Collisions are resolved using linked list via CEntry::next.
76 std::array<idx_t, HashSz> chash;
77 static_assert(sizeof(chash) == (1U << 27U));
78
79 static inline idx_t hash(idx_t id)
80 {
81 return id % HashSz;
82 }
83
84 struct PlainCEntry {
85 idx_t lowlink;
86 idx_t stateid;
87 idx_t next = std::numeric_limits<idx_t>::max();
88
89 PlainCEntry(idx_t lowlink, idx_t stateid, idx_t next) : lowlink(lowlink), stateid(stateid), next(next) {}
90 };
91
92 struct TracableCEntry : PlainCEntry {
93 idx_t lowsource = std::numeric_limits<idx_t>::max();
94 idx_t sourcetrans;
95
96 TracableCEntry(idx_t lowlink, idx_t stateid, idx_t next) : PlainCEntry(lowlink, stateid, next) {}
97 };
98
99 using CEntry = std::conditional_t<SaveTrace,
100 TracableCEntry,
101 PlainCEntry>;
102
103
104 struct DEntry {
105 idx_t pos; // position in cstack.
106 successor_info sucinfo;
107 };
108
109 // master list of state information.
110 std::vector<CEntry> cstack;
111 // depth-first search stack, contains current search path.
112 std::stack<DEntry> dstack;
113 // cstack positions of accepting states in current search path, for quick access.
114 std::stack<idx_t> astack;
115 bool violation = false;
116 size_t loopstate = std::numeric_limits<size_t>::max();
117 size_t looptrans = std::numeric_limits<size_t>::max();
118
119 void push(State &state, size_t stateid);
120
121 void pop();
122
123 void update(idx_t to);
124
125 bool nexttrans(State &state, State &parent, DEntry &delem);
126
127 void popCStack();
128
129 void printTrace(std::stack<DEntry> &&dstack, std::ostream &os = std::cout);
130
131 };
132
133 extern template
134 class TarjanModelChecker<true>;
135
136 extern template
137 class TarjanModelChecker<false>;
138}
139
140#endif //VERIFYPN_TARJANMODELCHECKER_H
0141
=== added file 'include/LTL/AlgorithmTypes.h'
--- include/LTL/AlgorithmTypes.h 1970-01-01 00:00:00 +0000
+++ include/LTL/AlgorithmTypes.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,40 @@
1/* Copyright (C) 2021 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_ALGORITHMTYPES_H
19#define VERIFYPN_ALGORITHMTYPES_H
20
21namespace LTL {
22 enum class Algorithm {
23 NDFS, Tarjan, None=-1
24 };
25 inline auto to_string(Algorithm alg) {
26 switch (alg) {
27 case Algorithm::NDFS:
28 return "NDFS";
29 case Algorithm::Tarjan:
30 return "TARJAN";
31 case Algorithm::None:
32 default:
33 std::cerr << "to_string: Invalid LTL Algorithm " << static_cast<int>(alg) << '\n';
34 assert(false);
35 return "None";
36 }
37 }
38}
39
40#endif //VERIFYPN_ALGORITHMTYPES_H
041
=== added file 'include/LTL/BuchiSuccessorGenerator.h'
--- include/LTL/BuchiSuccessorGenerator.h 1970-01-01 00:00:00 +0000
+++ include/LTL/BuchiSuccessorGenerator.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,95 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_BUCHISUCCESSORGENERATOR_H
19#define VERIFYPN_BUCHISUCCESSORGENERATOR_H
20
21#include "PetriEngine/SuccessorGenerator.h"
22#include "LTL/Structures/BuchiAutomaton.h"
23
24#include <spot/twa/twagraph.hh>
25#include <utility>
26#include <memory>
27
28namespace LTL {
29 class BuchiSuccessorGenerator {
30 public:
31 explicit BuchiSuccessorGenerator(Structures::BuchiAutomaton automaton)
32 : aut(std::move(automaton))
33 {
34 deleter = SuccIterDeleter{&aut};
35 }
36
37 void prepare(size_t state)
38 {
39 auto curstate = aut.buchi->state_from_number(state);
40 succ = _succ_iter{aut.buchi->succ_iter(curstate), SuccIterDeleter{&aut}};
41 succ->first();
42 }
43
44 bool next(size_t &state, bdd &cond)
45 {
46 if (!succ->done()) {
47 auto dst = succ->dst();
48 state = aut.buchi->state_number(dst);
49 cond = succ->cond();
50 succ->next();
51 dst->destroy();
52 return true;
53 }
54 return false;
55 }
56
57 [[nodiscard]] bool is_accepting(size_t state) const
58 {
59 return aut.buchi->state_is_accepting(state);
60 }
61
62 [[nodiscard]] size_t initial_state_number() const
63 {
64 return aut.buchi->get_init_state_number();
65 }
66
67 [[nodiscard]] PetriEngine::PQL::Condition_ptr getExpression(size_t i) const
68 {
69 return aut.ap_info.at(i).expression;
70 }
71
72 [[nodiscard]] bool is_weak() const
73 {
74 return (bool) aut.buchi->prop_weak();
75 }
76
77 private:
78 Structures::BuchiAutomaton aut;
79
80 struct SuccIterDeleter {
81 Structures::BuchiAutomaton *aut;
82
83 void operator()(spot::twa_succ_iterator *iter) const
84 {
85 aut->buchi->release_iter(iter);
86 }
87 };
88
89 SuccIterDeleter deleter{};
90
91 using _succ_iter = std::unique_ptr<spot::twa_succ_iterator, SuccIterDeleter>;
92 _succ_iter succ = nullptr;
93 };
94}
95#endif //VERIFYPN_BUCHISUCCESSORGENERATOR_H
096
=== added file 'include/LTL/LTL.h'
--- include/LTL/LTL.h 1970-01-01 00:00:00 +0000
+++ include/LTL/LTL.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,34 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_LTLALGORITHM_H
19#define VERIFYPN_LTLALGORITHM_H
20
21#include "LTL/LTLValidator.h"
22#include "LTL/Algorithm/TarjanModelChecker.h"
23#include "LTL/Algorithm/NestedDepthFirstSearch.h"
24#include "LTL/Algorithm/RandomNDFS.h"
25#include "LTL/Simplification/SpotToPQL.h"
26#include "LTL/LTLToBuchi.h"
27
28namespace LTL {
29
30
31 std::pair<Condition_ptr, bool> to_ltl(const Condition_ptr &formula);
32}
33
34#endif
0\ No newline at end of file35\ No newline at end of file
136
=== added file 'include/LTL/LTLToBuchi.h'
--- include/LTL/LTLToBuchi.h 1970-01-01 00:00:00 +0000
+++ include/LTL/LTLToBuchi.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,131 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_LTLTOBUCHI_H
19#define VERIFYPN_LTLTOBUCHI_H
20
21#include "PetriParse/QueryParser.h"
22#include "PetriEngine/PQL/QueryPrinter.h"
23
24#include <iostream>
25#include <string>
26
27#include <spot/tl/formula.hh>
28
29namespace LTL {
30 struct AtomicProposition {
31 PetriEngine::PQL::Condition_ptr expression;
32 std::string text;
33 };
34
35 using APInfo = std::vector<AtomicProposition>;
36 std::string toSpotFormat(const QueryItem &query);
37 void toSpotFormat(const QueryItem &query, std::ostream &os);
38 std::pair<spot::formula, APInfo> to_spot_formula(const PetriEngine::PQL::Condition_ptr& query);
39
40 class BuchiSuccessorGenerator;
41 BuchiSuccessorGenerator makeBuchiAutomaton(const PetriEngine::PQL::Condition_ptr &query);
42
43
44 class FormulaToSpotSyntax : public PetriEngine::PQL::QueryPrinter {
45 protected:
46 void _accept(const PetriEngine::PQL::ACondition *condition) override;
47
48 void _accept(const PetriEngine::PQL::ECondition *condition) override;
49
50 void _accept(const PetriEngine::PQL::NotCondition *element) override;
51
52 void _accept(const PetriEngine::PQL::AndCondition *element) override;
53
54 void _accept(const PetriEngine::PQL::OrCondition *element) override;
55
56 void _accept(const PetriEngine::PQL::LessThanCondition *element) override;
57
58 void _accept(const PetriEngine::PQL::LessThanOrEqualCondition *element) override;
59
60 void _accept(const PetriEngine::PQL::EqualCondition *element) override;
61
62 void _accept(const PetriEngine::PQL::NotEqualCondition *element) override;
63
64 void _accept(const PetriEngine::PQL::UnfoldedFireableCondition *element) override;
65
66 void _accept(const PetriEngine::PQL::FireableCondition *element) override;
67
68 void _accept(const PetriEngine::PQL::BooleanCondition *element) override;
69
70 void _accept(const PetriEngine::PQL::LiteralExpr *element) override;
71
72 void _accept(const PetriEngine::PQL::PlusExpr *element) override;
73
74 void _accept(const PetriEngine::PQL::MultiplyExpr *element) override;
75
76 void _accept(const PetriEngine::PQL::MinusExpr *element) override;
77
78 void _accept(const PetriEngine::PQL::SubtractExpr *element) override;
79
80 void _accept(const PetriEngine::PQL::IdentifierExpr *element) override;
81
82 void _accept(const PetriEngine::PQL::CompareConjunction *element) override;
83
84 public:
85
86 explicit FormulaToSpotSyntax(std::ostream &os = std::cout)
87 : PetriEngine::PQL::QueryPrinter(os), compress(true) {}
88
89 auto begin() const {
90 return std::begin(ap_info);
91 }
92
93 auto end() const {
94 return std::end(ap_info);
95 }
96
97 const APInfo &apInfo() const {
98 return ap_info;
99 }
100
101 private:
102 APInfo ap_info;
103 bool is_quoted = false;
104 bool compress;
105
106 void make_atomic_prop(const PetriEngine::PQL::Condition_constptr &element)
107 {
108 auto cond =
109 const_cast<PetriEngine::PQL::Condition *>(element.get())->shared_from_this();
110 std::stringstream ss;
111 ss << "\"";
112 if (compress) {
113 // FIXME Very naive; this completely removes APs being in multiple places in the query,
114 // leading to some query not being answered as is. The net gain is large in the firebaility category,
115 // but ideally it would be possible to make a smarter approach that looks at previously stored APs
116 // and efficiently checks for repeat APs such that we can reuse APs.
117 ss << ap_info.size();
118 }
119 else {
120 PetriEngine::PQL::QueryPrinter _printer{ss};
121 cond->visit(_printer);
122 }
123 ss << "\"";
124 os << ss.str();
125 ap_info.push_back(AtomicProposition{cond, ss.str().substr(1, ss.str().size() - 2)});
126 }
127 };
128
129}
130
131#endif //VERIFYPN_LTLTOBUCHI_H
0132
=== added file 'include/LTL/LTLValidator.h'
--- include/LTL/LTLValidator.h 1970-01-01 00:00:00 +0000
+++ include/LTL/LTLValidator.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,201 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_LTLVALIDATOR_H
19#define VERIFYPN_LTLVALIDATOR_H
20
21#include "PetriEngine/PQL/Visitor.h"
22
23namespace LTL {
24 using namespace PetriEngine::PQL;
25 class LTLValidator : public PetriEngine::PQL::Visitor {
26 public:
27 bool bad() const { return _bad; }
28
29 operator bool() const { return !bad(); }
30
31 bool isLTL(const Condition_ptr& condition) {
32 std::shared_ptr<SimpleQuantifierCondition> quantifierCondition;
33 if ((quantifierCondition = std::dynamic_pointer_cast<ACondition>(condition)) != nullptr ||
34 (quantifierCondition = std::dynamic_pointer_cast<ECondition>(condition)) != nullptr ){
35 (*quantifierCondition)[0]->visit(*this);
36 } else {
37 condition->visit(*this);
38 }
39 return !bad();
40 }
41
42 protected:
43
44 void _visitNary(const LogicalCondition *condition) {
45 for (const auto &cond : *condition) {
46 cond->visit(*this);
47 }
48 };
49
50 void _accept(const PetriEngine::PQL::EFCondition *condition) override {
51 setBad();
52 std::cerr << "found EFCondition" << std::endl;
53 }
54
55 void _accept(const PetriEngine::PQL::EGCondition *condition) override {
56 setBad();
57 std::cerr << "found EGCondition" << std::endl;
58 }
59
60 void _accept(const PetriEngine::PQL::AGCondition *condition) override {
61 setBad();
62 std::cerr << "found AGCondition" << std::endl;
63 }
64
65 void _accept(const PetriEngine::PQL::AFCondition *condition) override {
66 setBad();
67 std::cerr << "found AFCondition" << std::endl;
68 }
69
70 void _accept(const PetriEngine::PQL::EXCondition *condition) override {
71 setBad();
72 std::cerr << "found EXCondition" << std::endl;
73 }
74
75 void _accept(const PetriEngine::PQL::AXCondition *condition) override {
76 setBad();
77 std::cerr << "found AXCondition" << std::endl;
78 }
79
80 void _accept(const PetriEngine::PQL::EUCondition *condition) override {
81 setBad();
82 std::cerr << "found EUCondition" << std::endl;
83 }
84
85 void _accept(const PetriEngine::PQL::AUCondition *condition) override {
86 setBad();
87 std::cerr << "found AUCondition" << std::endl;
88 }
89
90 void _accept(const PetriEngine::PQL::ACondition *condition) override {
91 setBad();
92 }
93
94 void _accept(const PetriEngine::PQL::ECondition *condition) override {
95 setBad();
96 }
97
98 void _accept(const PetriEngine::PQL::NotCondition *element) override {
99 (*element)[0]->visit(*this);
100 }
101
102 void _accept(const PetriEngine::PQL::AndCondition *element) override {
103 _visitNary(element);
104 }
105
106 void _accept(const PetriEngine::PQL::OrCondition *element) override {
107 _visitNary(element);
108 }
109
110 void _accept(const PetriEngine::PQL::LessThanCondition *element) override {
111 (*element)[0]->visit(*this);
112 (*element)[1]->visit(*this);
113 }
114
115 void _accept(const PetriEngine::PQL::LessThanOrEqualCondition *element) override {
116 (*element)[0]->visit(*this);
117 (*element)[1]->visit(*this);
118 }
119
120 void _accept(const PetriEngine::PQL::EqualCondition *element) override {
121 (*element)[0]->visit(*this);
122 (*element)[1]->visit(*this);
123 }
124
125 void _accept(const PetriEngine::PQL::NotEqualCondition *element) override {
126 (*element)[0]->visit(*this);
127 (*element)[1]->visit(*this);
128 }
129
130 void _accept(const PetriEngine::PQL::DeadlockCondition *element) override {
131
132 }
133
134 void _accept(const PetriEngine::PQL::CompareConjunction *element) override {
135
136 }
137
138 void _accept(const PetriEngine::PQL::UnfoldedUpperBoundsCondition *element) override {
139
140 }
141
142 void _accept(const PetriEngine::PQL::GCondition *condition) override {
143 (*condition)[0]->visit(*this);
144 }
145
146 void _accept(const PetriEngine::PQL::FCondition *condition) override {
147 (*condition)[0]->visit(*this);
148 }
149
150 void _accept(const PetriEngine::PQL::XCondition *condition) override {
151 (*condition)[0]->visit(*this);
152 }
153
154 void _accept(const PetriEngine::PQL::UntilCondition *condition) override {
155 (*condition)[0]->visit(*this);
156 }
157
158 void _accept(const PetriEngine::PQL::UnfoldedFireableCondition *element) override {
159 }
160
161 void _accept(const PetriEngine::PQL::FireableCondition *element) override {
162 }
163
164 void _accept(const PetriEngine::PQL::UpperBoundsCondition *element) override {
165 }
166
167 void _accept(const PetriEngine::PQL::LivenessCondition *element) override {
168 }
169
170 void _accept(const PetriEngine::PQL::KSafeCondition *element) override {
171 }
172
173 void _accept(const PetriEngine::PQL::QuasiLivenessCondition *element) override {
174 }
175
176 void _accept(const PetriEngine::PQL::StableMarkingCondition *element) override {
177 }
178
179 void _accept(const PetriEngine::PQL::BooleanCondition *element) override {}
180
181 void _accept(const PetriEngine::PQL::UnfoldedIdentifierExpr *element) override {}
182
183 void _accept(const PetriEngine::PQL::LiteralExpr *element) override {}
184
185 void _accept(const PetriEngine::PQL::PlusExpr *element) override {}
186
187 void _accept(const PetriEngine::PQL::MultiplyExpr *element) override {}
188
189 void _accept(const PetriEngine::PQL::MinusExpr *element) override {}
190
191 void _accept(const PetriEngine::PQL::SubtractExpr *element) override {}
192
193 void _accept(const PetriEngine::PQL::IdentifierExpr *element) override {}
194
195 private:
196 bool _bad = false;
197
198 void setBad() { _bad = true; }
199 };
200}
201#endif //VERIFYPN_LTLVALIDATOR_H
0202
=== added file 'include/LTL/ProductSuccessorGenerator.h'
--- include/LTL/ProductSuccessorGenerator.h 1970-01-01 00:00:00 +0000
+++ include/LTL/ProductSuccessorGenerator.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,146 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_PRODUCTSUCCESSORGENERATOR_H
19#define VERIFYPN_PRODUCTSUCCESSORGENERATOR_H
20
21#include "PetriEngine/SuccessorGenerator.h"
22#include "PetriEngine/PQL/PQL.h"
23#include "LTL/Structures/ProductState.h"
24#include "LTL/BuchiSuccessorGenerator.h"
25#include "LTL/LTLToBuchi.h"
26
27
28namespace LTL {
29 /**
30 * type holding sufficient information to resume successor generation for a state from a given point.
31 */
32 struct successor_info {
33 uint32_t pcounter;
34 uint32_t tcounter;
35 size_t buchi_state;
36 size_t last_state;
37
38 friend bool operator==(const successor_info &lhs, const successor_info &rhs) {
39 return lhs.pcounter == rhs.pcounter &&
40 lhs.tcounter == rhs.tcounter &&
41 lhs.buchi_state == rhs.buchi_state &&
42 lhs.last_state == rhs.last_state;
43 }
44
45 friend bool operator!=(const successor_info &lhs, const successor_info &rhs) {
46 return !(rhs == lhs);
47 }
48
49 inline bool has_pcounter() const {
50 return pcounter != NoPCounter;
51 }
52
53 inline bool has_tcounter() const {
54 return tcounter != NoTCounter;
55 }
56
57 inline bool has_buchistate() const {
58 return buchi_state != NoBuchiState;
59 }
60
61 inline bool has_prev_state() const {
62 return last_state != NoLastState;
63 }
64
65 static constexpr auto NoPCounter = 0;
66 static constexpr auto NoTCounter = std::numeric_limits<uint32_t>::max();
67 static constexpr auto NoBuchiState = std::numeric_limits<size_t>::max();
68 static constexpr auto NoLastState = std::numeric_limits<size_t>::max();
69 };
70
71 constexpr successor_info initial_suc_info{
72 successor_info::NoPCounter,
73 successor_info::NoTCounter,
74 successor_info::NoBuchiState,
75 successor_info::NoLastState
76 };
77
78 class ProductSuccessorGenerator : public PetriEngine::SuccessorGenerator {
79 public:
80
81 ProductSuccessorGenerator(const PetriEngine::PetriNet &net,
82 const PetriEngine::PQL::Condition_ptr &cond)
83 : PetriEngine::SuccessorGenerator(net), buchi(makeBuchiAutomaton(cond)) {}
84
85 [[nodiscard]] size_t initial_buchi_state() const { return buchi.initial_state_number(); };
86
87 void prepare(const LTL::Structures::ProductState *state);
88
89 bool next(LTL::Structures::ProductState &state);
90
91 bool isAccepting(const LTL::Structures::ProductState &state);
92
93 void makeInitialState(std::vector<LTL::Structures::ProductState> &states) {
94 auto buf = new PetriEngine::MarkVal[_net.numberOfPlaces() + 1];
95 std::copy(_net.initial(), _net.initial() + _net.numberOfPlaces(), buf);
96 buf[_net.numberOfPlaces()] = 0;
97 LTL::Structures::ProductState state;
98 state.setMarking(buf, _net.numberOfPlaces());
99 state.setBuchiState(initial_buchi_state());
100 buchi.prepare(state.getBuchiState());
101 while (next_buchi_succ(state)) {
102 states.emplace_back();
103 states.back().setMarking(new PetriEngine::MarkVal[_net.numberOfPlaces() + 1], _net.numberOfPlaces());
104 std::copy(state.marking(), state.marking() + _net.numberOfPlaces(), states.back().marking());
105 states.back().setBuchiState(state.getBuchiState());
106 }
107 }
108
109 [[nodiscard]] bool isInitialState(const LTL::Structures::ProductState &state) const {
110 return state.markingEqual(_net.initial());
111 }
112
113 /**
114 * prepare a state for successor generation, starting from specific point in iteration
115 * @param state the source state to generate successors from
116 * @param sucinfo the point in the iteration to start from, as returned by `next`.
117 */
118 void prepare(const LTL::Structures::ProductState *state, const successor_info &sucinfo);
119
120 /**
121 * compute the next successor from the last state that was sent to `prepare`.
122 * @param[out] state the state to write
123 * @param[out] sucinfo checkpoint information from which iteration can later be resumed.
124 * @return `true` if a successor was successfully generated, `false` otherwise.
125 * @warning do not use the same State for both prepare and next, this will cause wildly incorrect behaviour!
126 */
127 bool next(Structures::ProductState &state, successor_info &sucinfo);
128
129 [[nodiscard]] bool is_weak() const {
130 return buchi.is_weak();
131 }
132
133 private:
134 BuchiSuccessorGenerator buchi;
135 bdd cond;
136 size_t buchi_parent;
137 bool fresh_marking = true;
138
139 bool guard_valid(const PetriEngine::Structures::State &state, bdd bdd);
140
141 bool next_buchi_succ(LTL::Structures::ProductState &state);
142 };
143
144}
145
146#endif //VERIFYPN_PRODUCTSUCCESSORGENERATOR_H
0147
=== added directory 'include/LTL/Simplification'
=== added file 'include/LTL/Simplification/SpotToPQL.h'
--- include/LTL/Simplification/SpotToPQL.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Simplification/SpotToPQL.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,42 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_SPOTTOPQL_H
19#define VERIFYPN_SPOTTOPQL_H
20
21#include "PetriEngine/PQL/Expressions.h"
22#include "LTL/LTLToBuchi.h"
23#include <spot/tl/formula.hh>
24
25namespace LTL {
26 /**
27 * Transform a Spot formula back into the PQL expression tree form.
28 * @param formula The formula to translate to PQL
29 * @param apinfo List of atomic propositions in the formula. This should have been created by {@link LTL::to_spot_formula}.
30 * @return A PQL formula equivalent to the passed spot formula.
31 */
32 PetriEngine::PQL::Condition_ptr toPQL(const spot::formula &formula, const APInfo &apinfo);
33
34 /**
35 * Simplify an LTL formula using Spot's formula simplifier. Throws if formula is not valid LTL.
36 * @param formula The formula to simplify.
37 * @return the simplified formula.
38 */
39 PetriEngine::PQL::Condition_ptr simplify(const PetriEngine::PQL::Condition_ptr &formula);
40}
41
42#endif // VERIFYPN_SPOTTOPQL_H
043
=== added directory 'include/LTL/Structures'
=== added file 'include/LTL/Structures/BuchiAutomaton.h'
--- include/LTL/Structures/BuchiAutomaton.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Structures/BuchiAutomaton.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,31 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_BUCHIAUTOMATON_H
19#define VERIFYPN_BUCHIAUTOMATON_H
20
21#include "LTL/LTLToBuchi.h"
22#include <spot/twa/twagraph.hh>
23
24namespace LTL::Structures {
25 struct BuchiAutomaton {
26 spot::twa_graph_ptr buchi;
27 const std::unordered_map<int, AtomicProposition> ap_info;
28 };
29}
30
31#endif //VERIFYPN_BUCHIAUTOMATON_H
032
=== added file 'include/LTL/Structures/ProductState.h'
--- include/LTL/Structures/ProductState.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Structures/ProductState.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,81 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_PRODUCTSTATE_H
19#define VERIFYPN_PRODUCTSTATE_H
20
21#include "PetriEngine/Structures/State.h"
22
23namespace LTL {
24 class ProductSuccessorGenerator;
25}
26namespace LTL::Structures {
27 /**
28 * State on the form (M, q) for marking M and NBA state q.
29 * Represented as array of size nplaces + 1, where the last element is the number
30 * of NBA state q, and the first nplaces elements are the actual marking.
31 */
32 class ProductState : public PetriEngine::Structures::State {
33 public:
34 ProductState() : PetriEngine::Structures::State() {}
35
36 void setMarking(PetriEngine::MarkVal* marking, size_t nplaces)
37 {
38 State::setMarking(marking);
39 // because zero-indexing
40 buchi_state_idx = nplaces;
41 }
42
43 //TODO override equality operators to handle both marking and NBA state
44 size_t getBuchiState() const {
45 return marking()[buchi_state_idx];
46 }
47
48 void setBuchiState(size_t state) {
49 marking()[buchi_state_idx] = state;
50 }
51
52 [[nodiscard]] bool markingEqual(const PetriEngine::MarkVal *rhs) const {
53 for (size_t i = 0; i < buchi_state_idx; ++i) {
54 if (marking()[i] != rhs[i]) {
55 return false;
56 }
57 }
58 return true;
59 }
60
61 bool operator==(const ProductState &rhs) const {
62 for (size_t i = 0; i <= buchi_state_idx; ++i) {
63 if (marking()[i] != rhs.marking()[i]) {
64 return false;
65 }
66 }
67 return true;
68 }
69
70 size_t size() const { return buchi_state_idx + 1; }
71
72 bool operator!=(const ProductState &rhs) const {
73 return !(rhs == *this);
74 }
75 private:
76 friend class LTL::ProductSuccessorGenerator;
77 size_t buchi_state_idx;
78 };
79}
80
81#endif //VERIFYPN_PRODUCTSTATE_H
082
=== added file 'include/LTL/Structures/ProductStateFactory.h'
--- include/LTL/Structures/ProductStateFactory.h 1970-01-01 00:00:00 +0000
+++ include/LTL/Structures/ProductStateFactory.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,46 @@
1/* Copyright (C) 2020 Nikolaj J. Ulrik <nikolaj@njulrik.dk>,
2 * Simon M. Virenfeldt <simon@simwir.dk>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef VERIFYPN_PRODUCTSTATEFACTORY_H
19#define VERIFYPN_PRODUCTSTATEFACTORY_H
20
21#include "LTL/Structures/ProductState.h"
22
23#include <memory>
24
25namespace LTL::Structures{
26 class ProductStateFactory {
27 public:
28 ProductStateFactory(const PetriEngine::PetriNet &net, size_t initial_buchi_state)
29 : net(net), buchi_init(initial_buchi_state) {}
30
31 ProductState newState() {
32 auto buf = new PetriEngine::MarkVal[net.numberOfPlaces()+1];
33 std::copy(net.initial(), net.initial() + net.numberOfPlaces(), buf);
34 buf[net.numberOfPlaces()] = 0;
35 ProductState state;
36 state.setMarking(buf, net.numberOfPlaces());
37 state.setBuchiState(buchi_init);
38 return state;
39 }
40
41 private:
42 const PetriEngine::PetriNet &net;
43 const size_t buchi_init;
44 };
45}
46#endif //VERIFYPN_PRODUCTSTATEFACTORY_H
047
=== added file 'include/PetriEngine/Colored/ArcIntervals.h'
--- include/PetriEngine/Colored/ArcIntervals.h 1970-01-01 00:00:00 +0000
+++ include/PetriEngine/Colored/ArcIntervals.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,108 @@
1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef ARCINTERVALS_H
20#define ARCINTERVALS_H
21
22#include "Colors.h"
23
24namespace PetriEngine {
25 namespace Colored {
26
27 struct ArcIntervals {
28 std::unordered_map<const Colored::Variable *, std::vector<std::unordered_map<uint32_t, int32_t>>> _varIndexModMap;
29 std::vector<Colored::intervalTuple_t> _intervalTupleVec;
30 Colored::ColorFixpoint * _source;
31
32 ~ArcIntervals() {_varIndexModMap.clear();}
33 ArcIntervals() {
34 }
35
36 ArcIntervals(Colored::ColorFixpoint * source) : _source(source){
37 }
38
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) {
40 };
41
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) {
43 };
44
45 size_t size() {
46 return _intervalTupleVec.size();
47 }
48
49 Colored::intervalTuple_t& operator[] (size_t index) {
50 return _intervalTupleVec[index];
51 }
52
53 Colored::intervalTuple_t& operator[] (int index) {
54 return _intervalTupleVec[index];
55 }
56
57 Colored::intervalTuple_t& operator[] (uint32_t index) {
58 assert(index < _intervalTupleVec.size());
59 return _intervalTupleVec[index];
60 }
61
62 Colored::intervalTuple_t& back(){
63 return _intervalTupleVec.back();
64 }
65
66 bool hasValidIntervals(){
67 for(auto intervalTuple : _intervalTupleVec){
68 if (intervalTuple.hasValidIntervals()){
69 return true;
70 }
71 }
72 return false;
73 }
74
75 bool containsVariable(Colored::Variable * var){
76 for (auto varModPair : _varIndexModMap){
77 if(varModPair.first == var){
78 return true;
79 }
80 }
81 return false;
82 }
83
84 std::set<const Colored::Variable *> getVariables(){
85 std::set<const Colored::Variable *> res;
86 for (auto varModPair : _varIndexModMap){
87 res.insert(varModPair.first);
88 }
89 return res;
90 }
91
92 void print() {
93 std::cout << "[ ";
94 for(auto varModifierPair : _varIndexModMap){
95 std::cout << "(" << varModifierPair.first->name << ", " << varModifierPair.first->colorType->productSize() << ") ";
96 }
97 std::cout << "]" << std::endl;
98 for(auto intervalTuple: _intervalTupleVec){
99 std::cout << "--------------------------------------------------------------------" << std::endl;
100 intervalTuple.print();
101 std::cout << "--------------------------------------------------------------------" << std::endl;
102 }
103 }
104 };
105 }
106}
107
108#endif /* INTERVALGENERATOR_H */
0\ No newline at end of file109\ No newline at end of file
1110
=== added file 'include/PetriEngine/Colored/BindingGenerator.h'
--- include/PetriEngine/Colored/BindingGenerator.h 1970-01-01 00:00:00 +0000
+++ include/PetriEngine/Colored/BindingGenerator.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,71 @@
1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 * Andreas H. Klostergaard
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <vector>
21#include <unordered_map>
22
23#include "ColoredNetStructures.h"
24
25namespace PetriEngine {
26
27 typedef std::unordered_map<std::string, Colored::ColorType*> ColorTypeMap;
28
29 class FixpointBindingGenerator {
30 public:
31 class Iterator {
32 private:
33 FixpointBindingGenerator* _generator;
34
35 public:
36 Iterator(FixpointBindingGenerator* generator);
37
38 bool operator==(Iterator& other);
39 bool operator!=(Iterator& other);
40 Iterator& operator++();
41 const Colored::ExpressionContext::BindingMap operator++(int);
42 Colored::ExpressionContext::BindingMap& operator*();
43 };
44 private:
45 Colored::GuardExpression_ptr _expr;
46 Colored::ExpressionContext::BindingMap _bindings;
47 ColorTypeMap& _colorTypes;
48 Colored::Transition &_transition;
49 bool _isDone;
50 bool _noValidBindings;
51 uint32_t _nextIndex = 0;
52
53 bool eval();
54
55 public:
56 FixpointBindingGenerator(Colored::Transition& transition,
57 ColorTypeMap& colorTypes);
58
59 FixpointBindingGenerator(const FixpointBindingGenerator& ) = default;
60
61 FixpointBindingGenerator operator= (const FixpointBindingGenerator& b) {
62 return FixpointBindingGenerator(b);
63 }
64
65 Colored::ExpressionContext::BindingMap& nextBinding();
66 Colored::ExpressionContext::BindingMap& currentBinding();
67 bool isInitial() const;
68 Iterator begin();
69 Iterator end();
70 };
71}
0\ No newline at end of file72\ No newline at end of file
173
=== modified file 'include/PetriEngine/Colored/ColoredNetStructures.h'
--- include/PetriEngine/Colored/ColoredNetStructures.h 2020-03-02 21:03:24 +0000
+++ include/PetriEngine/Colored/ColoredNetStructures.h 2021-04-02 18:07:40 +0000
@@ -1,14 +1,20 @@
1/*1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * To change this license header, choose License Headers in Project Properties.2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * To change this template file, choose Tools | Templates3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 * and open the template in the editor.4 * Andreas H. Klostergaard
5 */5 *
66 * This program is free software: you can redistribute it and/or modify
7/* 7 * it under the terms of the GNU General Public License as published by
8 * File: ColoredNetStructures.h8 * the Free Software Foundation, either version 3 of the License, or
9 * Author: Klostergaard9 * (at your option) any later version.
10 *10 *
11 * Created on 17. februar 2018, 17:0711 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */18 */
1319
14#ifndef COLOREDNETSTRUCTURES_H20#ifndef COLOREDNETSTRUCTURES_H
@@ -16,6 +22,7 @@
1622
17#include <vector>23#include <vector>
18#include <set>24#include <set>
25#include <assert.h>
19#include "Colors.h"26#include "Colors.h"
20#include "Expressions.h"27#include "Expressions.h"
21#include "Multiset.h"28#include "Multiset.h"
@@ -33,7 +40,10 @@
33 struct Transition {40 struct Transition {
34 std::string name;41 std::string name;
35 GuardExpression_ptr guard;42 GuardExpression_ptr guard;
36 std::vector<Arc> arcs;43 std::vector<Arc> input_arcs;
44 std::vector<Arc> output_arcs;
45 std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>> variableMaps;
46 bool considered;
37 };47 };
38 48
39 struct Place {49 struct Place {
4050
=== modified file 'include/PetriEngine/Colored/ColoredPetriNetBuilder.h'
--- include/PetriEngine/Colored/ColoredPetriNetBuilder.h 2020-03-02 21:03:24 +0000
+++ include/PetriEngine/Colored/ColoredPetriNetBuilder.h 2021-04-02 18:07:40 +0000
@@ -1,8 +1,20 @@
1/*1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * File: ColoredPetriNetBuilder.h2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * Author: Klostergaard3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 *4 * Andreas H. Klostergaard
5 * Created on 17. februar 2018, 16:255 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6 */18 */
719
8#ifndef COLOREDPETRINETBUILDER_H20#ifndef COLOREDPETRINETBUILDER_H
@@ -11,14 +23,16 @@
11#include <vector>23#include <vector>
12#include <unordered_map>24#include <unordered_map>
1325
14#include "ColoredNetStructures.h"
15#include "../AbstractPetriNetBuilder.h"26#include "../AbstractPetriNetBuilder.h"
16#include "../PetriNetBuilder.h"27#include "../PetriNetBuilder.h"
28#include "BindingGenerator.h"
29#include "IntervalGenerator.h"
30#include "ArcIntervals.h"
1731
18namespace PetriEngine {32namespace PetriEngine {
33
19 class ColoredPetriNetBuilder : public AbstractPetriNetBuilder {34 class ColoredPetriNetBuilder : public AbstractPetriNetBuilder {
20 public:35 public:
21 typedef std::unordered_map<std::string, Colored::ColorType*> ColorTypeMap;
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;
23 typedef std::unordered_map<std::string, std::vector<std::string>> PTTransitionMap;37 typedef std::unordered_map<std::string, std::vector<std::string>> PTTransitionMap;
24 38
@@ -66,10 +80,18 @@
66 return _time;80 return _time;
67 }81 }
6882
83 double getFixpointTime() const {
84 return _fixPointCreationTime;
85 }
86
69 uint32_t getPlaceCount() const {87 uint32_t getPlaceCount() const {
70 return _places.size();88 return _places.size();
71 }89 }
7290
91 uint32_t getMaxIntervals() const {
92 return _maxIntervals;
93 }
94
73 uint32_t getTransitionCount() const {95 uint32_t getTransitionCount() const {
74 return _transitions.size();96 return _transitions.size();
75 }97 }
@@ -77,7 +99,8 @@
77 uint32_t getArcCount() const {99 uint32_t getArcCount() const {
78 uint32_t sum = 0;100 uint32_t sum = 0;
79 for (auto& t : _transitions) {101 for (auto& t : _transitions) {
80 sum += t.arcs.size();102 sum += t.input_arcs.size();
103 sum += t.output_arcs.size();
81 }104 }
82 return sum;105 return sum;
83 }106 }
@@ -109,71 +132,69 @@
109 132
110 PetriNetBuilder& unfold();133 PetriNetBuilder& unfold();
111 PetriNetBuilder& stripColors();134 PetriNetBuilder& stripColors();
135 void computePlaceColorFixpoint(uint32_t maxIntervals, uint32_t maxIntervalsReduced, int32_t timeout);
136
112 private:137 private:
113 std::unordered_map<std::string,uint32_t> _placenames;138 std::unordered_map<std::string,uint32_t> _placenames;
114 std::unordered_map<std::string,uint32_t> _transitionnames;139 std::unordered_map<std::string,uint32_t> _transitionnames;
140 std::unordered_map<uint32_t, std::unordered_map<uint32_t, Colored::ArcIntervals>> _arcIntervals;
141 std::unordered_map<uint32_t,std::vector<uint32_t>> _placePostTransitionMap;
142 std::unordered_map<uint32_t,FixpointBindingGenerator> _bindings;
115 PTPlaceMap _ptplacenames;143 PTPlaceMap _ptplacenames;
116 PTTransitionMap _pttransitionnames;144 PTTransitionMap _pttransitionnames;
117 uint32_t _nptplaces = 0;145 uint32_t _nptplaces = 0;
118 uint32_t _npttransitions = 0;146 uint32_t _npttransitions = 0;
119 uint32_t _nptarcs = 0;147 uint32_t _nptarcs = 0;
148 uint32_t _maxIntervals = 0;
149 PetriEngine::IntervalGenerator intervalGenerator;
120 150
121 std::vector<Colored::Place> _places;151 std::vector<Colored::Place> _places;
122 std::vector<Colored::Transition> _transitions;152 std::vector<Colored::Transition> _transitions;
123 std::vector<Colored::Arc> _arcs;153 std::vector<Colored::Arc> _arcs;
154 std::vector<Colored::ColorFixpoint> _placeColorFixpoints;
124 ColorTypeMap _colors;155 ColorTypeMap _colors;
125 PetriNetBuilder _ptBuilder;156 PetriNetBuilder _ptBuilder;
126 bool _unfolded = false;157 bool _unfolded = false;
127 bool _stripped = false;158 bool _stripped = false;
128159
160 std::vector<uint32_t> _placeFixpointQueue;
161
129 double _time;162 double _time;
163 double _fixPointCreationTime;
164
165 double _timer;
130166
131 std::string arcToString(Colored::Arc& arc) const ;167 std::string arcToString(Colored::Arc& arc) const ;
168
169 void printPlaceTable();
170
171 std::unordered_map<uint32_t, Colored::ArcIntervals> setupTransitionVars(Colored::Transition transition);
132 172
133 void addArc(const std::string& place,173 void addArc(const std::string& place,
134 const std::string& transition,174 const std::string& transition,
135 const Colored::ArcExpression_ptr& expr,175 const Colored::ArcExpression_ptr& expr,
136 bool input);176 bool input);
177
178
179 void getArcIntervals(Colored::Transition& transition, bool &transitionActivated, uint32_t max_intervals, uint32_t transitionId);
180 void processInputArcs(Colored::Transition& transition, uint32_t currentPlaceId, uint32_t transitionId, bool &transitionActivated, uint32_t max_intervals);
181 void processOutputArcs(Colored::Transition& transition);
137 182
138 void unfoldPlace(Colored::Place& place);183 void unfoldPlace(const Colored::Place* place, const PetriEngine::Colored::Color *color);
139 void unfoldTransition(Colored::Transition& transition);184 void unfoldTransition(Colored::Transition& transition);
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);
186
187 void unfoldArc(Colored::Arc& arc, Colored::ExpressionContext::BindingMap& binding, std::string& name, bool input);
141 };188 };
142 189
143 class BindingGenerator {190 //Used for checking if a variable is inside either a succ or pred expression
144 public:191 enum ExpressionType {
145 class Iterator {192 None,
146 private:193 Pred,
147 BindingGenerator* _generator;194 Succ
148 195 };
149 public:196
150 Iterator(BindingGenerator* generator);
151
152 bool operator==(Iterator& other);
153 bool operator!=(Iterator& other);
154 Iterator& operator++();
155 const Colored::ExpressionContext::BindingMap operator++(int);
156 Colored::ExpressionContext::BindingMap& operator*();
157 };
158 private:
159 Colored::GuardExpression_ptr _expr;
160 Colored::ExpressionContext::BindingMap _bindings;
161 ColoredPetriNetBuilder::ColorTypeMap& _colorTypes;
162
163 bool eval();
164
165 public:
166 BindingGenerator(Colored::Transition& transition,
167 const std::vector<Colored::Arc>& arcs,
168 ColoredPetriNetBuilder::ColorTypeMap& colorTypes);
169197
170 Colored::ExpressionContext::BindingMap& nextBinding();
171 Colored::ExpressionContext::BindingMap& currentBinding();
172 bool isInitial() const;
173 Iterator begin();
174 Iterator end();
175 };
176}198}
177199
178#endif /* COLOREDPETRINETBUILDER_H */200#endif /* COLOREDPETRINETBUILDER_H */
179
180201
=== modified file 'include/PetriEngine/Colored/Colors.h'
--- include/PetriEngine/Colored/Colors.h 2020-03-02 22:05:53 +0000
+++ include/PetriEngine/Colored/Colors.h 2021-04-02 18:07:40 +0000
@@ -1,14 +1,20 @@
1/*1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * To change this license header, choose License Headers in Project Properties.2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * To change this template file, choose Tools | Templates3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 * and open the template in the editor.4 * Andreas H. Klostergaard
5 */5 *
66 * This program is free software: you can redistribute it and/or modify
7/* 7 * it under the terms of the GNU General Public License as published by
8 * File: Colors.h8 * the Free Software Foundation, either version 3 of the License, or
9 * Author: andreas9 * (at your option) any later version.
10 *10 *
11 * Created on February 19, 2018, 8:22 PM11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */18 */
1319
14#ifndef COLORS_H20#ifndef COLORS_H
@@ -21,6 +27,10 @@
21#include <utility>27#include <utility>
22#include <vector>28#include <vector>
23#include <unordered_map>29#include <unordered_map>
30#include <iostream>
31#include <cassert>
32
33#include "Intervals.h"
2434
25namespace PetriEngine {35namespace PetriEngine {
26 namespace Colored {36 namespace Colored {
@@ -44,7 +54,15 @@
44 bool isTuple() const {54 bool isTuple() const {
45 return _tuple.size() > 1;55 return _tuple.size() > 1;
46 }56 }
57
58 void getColorConstraints(Colored::interval_t *constraintsVector, uint32_t *index) const;
47 59
60 std::vector<const Color*> getTupleColors() const {
61 return _tuple;
62 }
63
64 void getTupleId(std::vector<uint32_t> *idVector) const;
65
48 const std::string& getColorName() const {66 const std::string& getColorName() const {
49 if (this->isTuple()) {67 if (this->isTuple()) {
50 throw "Cannot get color from a tuple color.";68 throw "Cannot get color from a tuple color.";
@@ -90,9 +108,11 @@
90 DotConstant();108 DotConstant();
91 109
92 public:110 public:
93 static const Color* dotConstant() {111 static const Color* dotConstant(ColorType *ct) {
94 static DotConstant _instance;112 static DotConstant _instance;
95 113 if(ct != nullptr){
114 _instance._colorType = ct;
115 }
96 return &_instance;116 return &_instance;
97 }117 }
98 118
@@ -160,12 +180,33 @@
160 virtual void addColor(const char* colorName);180 virtual void addColor(const char* colorName);
161 virtual void addColor(std::vector<const Color*>& colors);181 virtual void addColor(std::vector<const Color*>& colors);
162 virtual void addDot() {182 virtual void addDot() {
163 _colors.push_back(*DotConstant::dotConstant());183 _colors.push_back(*DotConstant::dotConstant(this));
164 }184 }
165 185
166 virtual size_t size() const {186 virtual size_t size() const {
167 return _colors.size();187 return _colors.size();
168 }188 }
189
190 virtual size_t productSize() {
191 return 1;
192 }
193
194 virtual std::vector<size_t> getConstituentsSizes(){
195 std::vector<size_t> result;
196 result.push_back(_colors.size());
197
198 return result;
199 }
200
201 virtual Colored::interval_t getFullInterval(){
202 Colored::interval_t interval;
203 interval.addRange(Reachability::range_t(0, size()-1));
204 return interval;
205 }
206
207 virtual void getColortypes(std::vector<ColorType *> &colorTypes){
208 colorTypes.push_back(this);
209 }
169 210
170 virtual const Color& operator[] (size_t index) {211 virtual const Color& operator[] (size_t index) {
171 return _colors[index];212 return _colors[index];
@@ -176,6 +217,7 @@
176 }217 }
177 218
178 virtual const Color& operator[] (uint32_t index) {219 virtual const Color& operator[] (uint32_t index) {
220 assert(index < _colors.size());
179 return _colors[index];221 return _colors[index];
180 }222 }
181 223
@@ -184,6 +226,11 @@
184 virtual const Color* operator[] (const std::string& index) {226 virtual const Color* operator[] (const std::string& index) {
185 return (*this)[index.c_str()];227 return (*this)[index.c_str()];
186 }228 }
229
230 virtual const Color* getColor(std::vector<uint32_t> ids){
231 assert(ids.size() == 1);
232 return &_colors[ids[0]];
233 }
187 234
188 bool operator== (const ColorType& other) const {235 bool operator== (const ColorType& other) const {
189 return _id == other._id;236 return _id == other._id;
@@ -233,6 +280,36 @@
233 return product;280 return product;
234 }281 }
235282
283 virtual size_t productSize() {
284 size_t size = 0;
285 for (auto ct : constituents){
286 size += ct->productSize();
287 }
288 return size;
289 }
290
291 std::vector<size_t> getConstituentsSizes() override{
292 std::vector<size_t> result;
293 for (auto ct : constituents) {
294 result.push_back(ct->size());
295 }
296 return result;
297 }
298
299 Colored::interval_t getFullInterval() override{
300 Colored::interval_t interval;
301 for(auto ct : constituents) {
302 interval.addRange(Reachability::range_t(0, ct->size()-1));
303 }
304 return interval;
305 }
306
307 void getColortypes(std::vector<ColorType *> &colorTypes) override{
308 for(auto ct : constituents){
309 ct->getColortypes(colorTypes);
310 }
311 }
312
236 bool containsTypes(const std::vector<const ColorType*>& types) const {313 bool containsTypes(const std::vector<const ColorType*>& types) const {
237 if (constituents.size() != types.size()) return false;314 if (constituents.size() != types.size()) return false;
238315
@@ -245,6 +322,19 @@
245 return true;322 return true;
246 }323 }
247324
325 const ColorType* getNestedColorType(size_t index) {
326 return constituents[index];
327 }
328
329 const Color* getColor(std::vector<uint32_t> ids){
330 assert(ids.size() == constituents.size());
331 std::vector<const Color *> colors;
332 for(uint32_t i = 0; i < ids.size(); i++){
333 colors.push_back(&constituents[i]->operator[](i));
334 }
335 return getColor(colors);
336 }
337
248 const Color* getColor(const std::vector<const Color*>& colors);338 const Color* getColor(const std::vector<const Color*>& colors);
249339
250 const Color& operator[](size_t index) override;340 const Color& operator[](size_t index) override;
@@ -263,13 +353,29 @@
263 std::string name;353 std::string name;
264 ColorType* colorType;354 ColorType* colorType;
265 };355 };
266 356
267 struct Binding {357 struct ColorFixpoint {
268 Variable* var;358 Colored::intervalTuple_t constraints;
269 const Color* color;359 bool inQueue;
270 360 uint32_t productSize;
271 bool operator==(Binding& other) {361
272 return var->name.compare(other.var->name);362 bool constainsColor(std::pair<const PetriEngine::Colored::Color *const, std::vector<uint32_t>> constPair) {
363 std::unordered_map<uint32_t, bool> contained;
364 for(auto interval : constraints._intervals) {
365 for(uint32_t id : constPair.second){
366
367 if(contained[id] != true){
368 contained[id] = interval[id].contains(constPair.first->getId());
369 }
370 }
371 }
372
373 for(auto pair : contained){
374 if (!pair.second){
375 return false;
376 }
377 }
378 return true;
273 }379 }
274 };380 };
275 }381 }
276382
=== modified file 'include/PetriEngine/Colored/Expressions.h'
--- include/PetriEngine/Colored/Expressions.h 2020-03-02 21:03:24 +0000
+++ include/PetriEngine/Colored/Expressions.h 2021-04-02 18:07:40 +0000
@@ -1,14 +1,20 @@
1/*1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * To change this license header, choose License Headers in Project Properties.2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * To change this template file, choose Tools | Templates3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 * and open the template in the editor.4 * Andreas H. Klostergaard
5 */5 *
66 * This program is free software: you can redistribute it and/or modify
7/* 7 * it under the terms of the GNU General Public License as published by
8 * File: Expressions.h8 * the Free Software Foundation, either version 3 of the License, or
9 * Author: andreas9 * (at your option) any later version.
10 *10 *
11 * Created on February 19, 2018, 7:00 PM11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */18 */
1319
14#ifndef COLORED_EXPRESSIONS_H20#ifndef COLORED_EXPRESSIONS_H
@@ -25,6 +31,8 @@
2531
26#include "Colors.h"32#include "Colors.h"
27#include "Multiset.h"33#include "Multiset.h"
34#include "ArcIntervals.h"
35#include "GuardRestrictor.h"
28#include "../errorcodes.h"36#include "../errorcodes.h"
2937
30namespace PetriEngine {38namespace PetriEngine {
@@ -32,14 +40,14 @@
32 40
33 namespace Colored {41 namespace Colored {
34 struct ExpressionContext {42 struct ExpressionContext {
35 typedef std::unordered_map<std::string, const Color*> BindingMap;43 typedef std::unordered_map<const Colored::Variable *, const PetriEngine::Colored::Color *> BindingMap;
3644
37 BindingMap& binding;45 BindingMap& binding;
38 std::unordered_map<std::string, ColorType*>& colorTypes;46 std::unordered_map<std::string, ColorType*>& colorTypes;
39 47
40 const Color* findColor(const std::string& color) const {48 const Color* findColor(const std::string& color) const {
41 if (color.compare("dot") == 0)49 if (color.compare("dot") == 0)
42 return DotConstant::dotConstant();50 return DotConstant::dotConstant(nullptr);
43 for (auto& elem : colorTypes) {51 for (auto& elem : colorTypes) {
44 auto col = (*elem.second)[color];52 auto col = (*elem.second)[color];
45 if (col)53 if (col)
@@ -74,8 +82,29 @@
74 class Expression {82 class Expression {
75 public:83 public:
76 Expression() {}84 Expression() {}
77 85
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 {}
87
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 {
89 uint32_t index = 0;
90 getVariables(variables, varPositions, varModifierMap, &index);
91 }
92
93 virtual void getVariables(std::set<const Colored::Variable*>& variables, std::unordered_map<uint32_t, const Colored::Variable *>& varPositions) const {
94 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMap;
95 uint32_t index = 0;
96 getVariables(variables, varPositions, varModifierMap, &index);
97 }
98
99 virtual bool isTuple() const {
100 return false;
101 }
102
103 virtual void getVariables(std::set<const Colored::Variable*>& variables) const {
104 std::unordered_map<uint32_t, const Colored::Variable *> varPositions;
105 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMap;
106
107 getVariables(variables, varPositions, varModifierMap);
79 }108 }
80 109
81 virtual void expressionType() {110 virtual void expressionType() {
@@ -93,12 +122,55 @@
93 virtual ~ColorExpression() {}122 virtual ~ColorExpression() {}
94 123
95 virtual const Color* eval(ExpressionContext& context) const = 0;124 virtual const Color* eval(ExpressionContext& context) const = 0;
125
126 virtual void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const = 0;
127
128 virtual bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const = 0;
129
130 virtual ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const = 0;
131
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 {
133 return Colored::intervalTuple_t();
134 }
135
96 };136 };
97 137
98 class DotConstantExpression : public ColorExpression {138 class DotConstantExpression : public ColorExpression {
99 public:139 public:
100 const Color* eval(ExpressionContext& context) const override {140 const Color* eval(ExpressionContext& context) const override {
101 return DotConstant::dotConstant();141 return DotConstant::dotConstant(nullptr);
142 }
143
144 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
145 if (arcIntervals._intervalTupleVec.empty()) {
146 //We can add all place tokens when considering the dot constant as, that must be present
147 arcIntervals._intervalTupleVec.push_back(cfp.constraints);
148 }
149 return !cfp.constraints._intervals.empty();
150 }
151
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 {
153 Colored::interval_t interval;
154 Colored::intervalTuple_t tupleInterval;
155 const Color *dotColor = DotConstant::dotConstant(nullptr);
156
157 colortypes->push_back(dotColor->getColorType());
158
159 interval.addRange(dotColor->getId(), dotColor->getId());
160 tupleInterval.addInterval(interval);
161 return tupleInterval;
162 }
163
164 void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override {
165 const Color *dotColor = DotConstant::dotConstant(nullptr);
166 constantMap[index] = dotColor;
167 }
168 ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{
169 return DotConstant::dotConstant(nullptr)->getColorType();
170 }
171
172 std::string toString() const override {
173 return "dot";
102 }174 }
103 };175 };
104176
@@ -110,17 +182,74 @@
110 182
111 public:183 public:
112 const Color* eval(ExpressionContext& context) const override {184 const Color* eval(ExpressionContext& context) const override {
113 return context.binding[_variable->name];185 return context.binding[_variable];
114 }186 }
115 187
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 {
117 variables.insert(_variable);189 variables.insert(_variable);
190 varPositions[*index] = _variable;
191 if(varModifierMap.count(_variable) == 0){
192 std::vector<std::unordered_map<uint32_t, int32_t>> newVec;
193
194 for(auto pair : varModifierMap){
195 for(uint32_t i = 0; i < pair.second.size()-1; i++){
196 std::unordered_map<uint32_t, int32_t> emptyMap;
197 newVec.push_back(emptyMap);
198 }
199 break;
200 }
201 std::unordered_map<uint32_t, int32_t> newMap;
202 newMap[*index] = 0;
203 newVec.push_back(newMap);
204 varModifierMap[_variable] = newVec;
205 } else {
206 varModifierMap[_variable].back()[*index] = 0;
207 }
208 }
209
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 {
211 Colored::intervalTuple_t varInterval;
212
213 // If we see a new variable on an out arc, it gets its full interval
214 if (varMap.count(_variable) == 0){
215 Colored::intervalTuple_t intervalTuple;
216 intervalTuple.addInterval(_variable->colorType->getFullInterval());
217 varMap[_variable] = intervalTuple;
218 }
219
220 for(auto interval : varMap[_variable]._intervals){
221 varInterval.addInterval(interval);
222 }
223
224 std::vector<ColorType*> varColorTypes;
225 _variable->colorType->getColortypes(varColorTypes);
226
227 for(auto ct : varColorTypes){
228 colortypes->push_back(ct);
229 }
230
231 return varInterval;
232 }
233
234 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
235 if (arcIntervals._intervalTupleVec.empty()){
236 //As variables does not restrict the values before the guard we include all tokens
237 arcIntervals._intervalTupleVec.push_back(cfp.constraints);
238 }
239 return !cfp.constraints._intervals.empty();
240 }
241
242 void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override {
118 }243 }
119244
120 std::string toString() const override {245 std::string toString() const override {
121 return _variable->name;246 return _variable->name;
122 }247 }
123248
249 ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{
250 return _variable->colorType;
251 }
252
124 VariableExpression(Variable* variable)253 VariableExpression(Variable* variable)
125 : _variable(variable) {}254 : _variable(variable) {}
126 };255 };
@@ -134,10 +263,63 @@
134 return _userOperator;263 return _userOperator;
135 }264 }
136265
266 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
267 uint32_t colorId = _userOperator->getId() + modifier;
268 while(colorId < 0){
269 colorId += _userOperator->getColorType()->size();
270 }
271 colorId = colorId % _userOperator->getColorType()->size();
272
273 if(arcIntervals._intervalTupleVec.empty()){
274 Colored::intervalTuple_t newIntervalTuple;
275 bool colorInFixpoint = false;
276 for (auto interval : cfp.constraints._intervals){
277 if(interval[*index].contains(colorId)){
278 newIntervalTuple.addInterval(interval);
279 colorInFixpoint = true;
280 }
281 }
282 arcIntervals._intervalTupleVec.push_back(newIntervalTuple);
283 return colorInFixpoint;
284 } else {
285 std::vector<uint32_t> intervalsToRemove;
286 for(auto& intervalTuple : arcIntervals._intervalTupleVec){
287 for (uint32_t i = 0; i < intervalTuple._intervals.size(); i++){
288 if(!intervalTuple[i][*index].contains(colorId)){
289 intervalsToRemove.push_back(i);
290 }
291 }
292
293 for (auto i = intervalsToRemove.rbegin(); i != intervalsToRemove.rend(); ++i) {
294 intervalTuple.removeInterval(*i);
295 }
296 }
297 return !arcIntervals._intervalTupleVec[0]._intervals.empty();
298 }
299 }
300
137 std::string toString() const override {301 std::string toString() const override {
138 return _userOperator->toString();302 return _userOperator->toString();
139 }303 }
140304
305 void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override {
306 constantMap[index] = _userOperator;
307 }
308 ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{
309 return _userOperator->getColorType();
310 }
311
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 {
313 Colored::interval_t interval;
314 Colored::intervalTuple_t tupleInterval;
315
316 colortypes->push_back(_userOperator->getColorType());
317
318 interval.addRange(_userOperator->getId(), _userOperator->getId());
319 tupleInterval.addInterval(interval);
320 return tupleInterval;
321 }
322
141 UserOperatorExpression(const Color* userOperator)323 UserOperatorExpression(const Color* userOperator)
142 : _userOperator(userOperator) {}324 : _userOperator(userOperator) {}
143 };325 };
@@ -185,14 +367,47 @@
185 return &++(*_color->eval(context));367 return &++(*_color->eval(context));
186 }368 }
187 369
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 {
189 _color->getVariables(variables);371 //save index before evaluating nested expression to decrease all the correct modifiers
372 uint32_t indexBefore = *index;
373 _color->getVariables(variables, varPositions, varModifierMap, index);
374 for(auto& varModifierPair : varModifierMap){
375 for(auto& idModPair : varModifierPair.second.back()){
376 if(idModPair.first <= *index && idModPair.first >= indexBefore){
377 idModPair.second--;
378 }
379 }
380 }
381 }
382
383 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
384 return _color->getArcIntervals(arcIntervals, cfp, index, modifier+1);
385 }
386
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 {
388 //store the number of colortyps already in colortypes vector and use that as offset when indexing it
389 auto colortypesBefore = colortypes->size();
390
391 auto nestedInterval = _color->getOutputIntervals(varMap, colortypes);
392 Colored::GuardRestrictor guardRestrictor = Colored::GuardRestrictor();
393 return guardRestrictor.shiftIntervals(colortypes, &nestedInterval, 1, colortypesBefore);
394 }
395
396 void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override {
397 _color->getConstants(constantMap, index);
398 for(auto& constIndexPair : constantMap){
399 constIndexPair.second = &constIndexPair.second->operator++();
400 }
190 }401 }
191402
192 std::string toString() const override {403 std::string toString() const override {
193 return _color->toString() + "++";404 return _color->toString() + "++";
194 }405 }
195406
407 ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{
408 return _color->getColorType(colorTypes);
409 }
410
196 SuccessorExpression(ColorExpression_ptr&& color)411 SuccessorExpression(ColorExpression_ptr&& color)
197 : _color(std::move(color)) {}412 : _color(std::move(color)) {}
198 };413 };
@@ -206,14 +421,47 @@
206 return &--(*_color->eval(context));421 return &--(*_color->eval(context));
207 }422 }
208 423
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 {
210 _color->getVariables(variables);425 //save index before evaluating nested expression to decrease all the correct modifiers
426 uint32_t indexBefore = *index;
427 _color->getVariables(variables, varPositions, varModifierMap, index);
428 for(auto& varModifierPair : varModifierMap){
429 for(auto& idModPair : varModifierPair.second.back()){
430 if(idModPair.first <= *index && idModPair.first >= indexBefore){
431 idModPair.second++;
432 }
433 }
434 }
435 }
436
437 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
438 return _color->getArcIntervals(arcIntervals, cfp, index, modifier-1);
439 }
440
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 {
442 //store the number of colortyps already in colortypes vector and use that as offset when indexing it
443 auto colortypesBefore = colortypes->size();
444
445 auto nestedInterval = _color->getOutputIntervals(varMap, colortypes);
446 Colored::GuardRestrictor guardRestrictor;
447 return guardRestrictor.shiftIntervals(colortypes, &nestedInterval, -1, colortypesBefore);
448 }
449
450 void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override {
451 _color->getConstants(constantMap, index);
452 for(auto& constIndexPair : constantMap){
453 constIndexPair.second = &constIndexPair.second->operator--();
454 }
211 }455 }
212456
213 std::string toString() const override {457 std::string toString() const override {
214 return _color->toString() + "--";458 return _color->toString() + "--";
215 }459 }
216460
461 ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{
462 return _color->getColorType(colorTypes);
463 }
464
217 PredecessorExpression(ColorExpression_ptr&& color)465 PredecessorExpression(ColorExpression_ptr&& color)
218 : _color(std::move(color)) {}466 : _color(std::move(color)) {}
219 };467 };
@@ -221,6 +469,7 @@
221 class TupleExpression : public ColorExpression {469 class TupleExpression : public ColorExpression {
222 private:470 private:
223 std::vector<ColorExpression_ptr> _colors;471 std::vector<ColorExpression_ptr> _colors;
472 ColorType* _colorType;
224 473
225 public:474 public:
226 const Color* eval(ExpressionContext& context) const override {475 const Color* eval(ExpressionContext& context) const override {
@@ -236,10 +485,77 @@
236 assert(col != nullptr);485 assert(col != nullptr);
237 return col;486 return col;
238 }487 }
488
489 bool isTuple() const override {
490 return true;
491 }
492
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 {
494 Colored::intervalTuple_t intervals;
495 Colored::intervalTuple_t intervalHolder;
496
497 for(auto colorExp : _colors) {
498 Colored::intervalTuple_t intervalHolder;
499 auto nested_intervals = colorExp->getOutputIntervals(varMap, colortypes);
500
501 if(intervals._intervals.empty()){
502 intervals = nested_intervals;
503 } else {
504 for(auto nested_interval : nested_intervals._intervals){
505 Colored::intervalTuple_t newIntervals;
506 for(auto interval : intervals._intervals){
507 for(auto nestedRange : nested_interval._ranges) {
508 interval.addRange(nestedRange);
509 }
510 newIntervals.addInterval(interval);
511 }
512 for(auto newInterval : newIntervals._intervals){
513 intervalHolder.addInterval(newInterval);
514 }
515 }
516 intervals = intervalHolder;
517 }
518 }
519 return intervals;
520 }
521
522 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
523 for (auto expr : _colors) {
524 bool res = expr->getArcIntervals(arcIntervals, cfp, index, modifier);
525 if(!res){
526 return false;
527 }
528 (*index)++;
529 }
530 return true;
531 }
239 532
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 {
241 for (auto elem : _colors) {534 for (auto elem : _colors) {
242 elem->getVariables(variables);535 elem->getVariables(variables, varPositions, varModifierMap, index);
536 (*index)++;
537 }
538 }
539
540 ColorType* getColorType(std::unordered_map<std::string, Colored::ColorType*>& colorTypes) const override{
541 std::vector<const ColorType*> types;
542 for (auto color : _colors) {
543 types.push_back(color->getColorType(colorTypes));
544 }
545 for (auto& elem : colorTypes) {
546 auto* pt = dynamic_cast<ProductType*>(elem.second);
547 if (pt && pt->containsTypes(types)) {
548 return pt;
549 }
550 }
551 std::cout << "COULD NOT FIND PRODUCT TYPE" << std::endl;
552 return nullptr;
553 }
554
555 void getConstants(std::unordered_map<uint32_t, const Color*> &constantMap, uint32_t &index) const override {
556 for (auto elem : _colors) {
557 elem->getConstants(constantMap, index);
558 index++;
243 }559 }
244 }560 }
245561
@@ -252,6 +568,10 @@
252 return res;568 return res;
253 }569 }
254570
571 void setColorType(ColorType* ct){
572 _colorType = ct;
573 }
574
255 TupleExpression(std::vector<ColorExpression_ptr>&& colors)575 TupleExpression(std::vector<ColorExpression_ptr>&& colors)
256 : _colors(std::move(colors)) {}576 : _colors(std::move(colors)) {}
257 };577 };
@@ -262,6 +582,8 @@
262 virtual ~GuardExpression() {}582 virtual ~GuardExpression() {}
263 583
264 virtual bool eval(ExpressionContext& context) const = 0;584 virtual bool eval(ExpressionContext& context) const = 0;
585
586 virtual void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const = 0;
265 };587 };
266588
267 typedef std::shared_ptr<GuardExpression> GuardExpression_ptr;589 typedef std::shared_ptr<GuardExpression> GuardExpression_ptr;
@@ -275,11 +597,40 @@
275 bool eval(ExpressionContext& context) const override {597 bool eval(ExpressionContext& context) const override {
276 return _left->eval(context) < _right->eval(context);598 return _left->eval(context) < _right->eval(context);
277 }599 }
600
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 {
602 _left->getVariables(variables, varPositions, varModifierMap);
603 _right->getVariables(variables, varPositions, varModifierMap);
604 }
605
606 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
607 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL;
608 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR;
609 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL;
610 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR;
611 std::unordered_map<uint32_t, const Color*> constantMapL;
612 std::unordered_map<uint32_t, const Color*> constantMapR;
613 std::set<const Variable *> leftVars;
614 std::set<const Variable *> rightVars;
615 uint32_t index = 0;
616 _left->getVariables(leftVars, varPositionsL, varModifierMapL);
617 _right->getVariables(rightVars, varPositionsR, varModifierMapR);
618 _left->getConstants(constantMapL, index);
619 index = 0;
620 _right->getConstants(constantMapR, index);
621
622 if(leftVars.empty() && rightVars.empty()){
623 return;
624 }
625 Colored::GuardRestrictor guardRestrictor;
626 guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, true, true);
627 }
278 628
279 void getVariables(std::set<Variable*>& variables) const override {629 std::string toString() const override {
280 _left->getVariables(variables);630 std::string res = _left->toString() + " < " + _right->toString();
281 _right->getVariables(variables);631 return res;
282 }632 }
633
283 634
284 LessThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)635 LessThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)
285 : _left(std::move(left)), _right(std::move(right)) {}636 : _left(std::move(left)), _right(std::move(right)) {}
@@ -295,9 +646,38 @@
295 return _left->eval(context) > _right->eval(context);646 return _left->eval(context) > _right->eval(context);
296 }647 }
297 648
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 {
299 _left->getVariables(variables);650 _left->getVariables(variables, varPositions, varModifierMap);
300 _right->getVariables(variables);651 _right->getVariables(variables, varPositions, varModifierMap);
652 }
653
654 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
655 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL;
656 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR;
657 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL;
658 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR;
659 std::unordered_map<uint32_t, const Color*> constantMapL;
660 std::unordered_map<uint32_t, const Color*> constantMapR;
661 std::set<const Colored::Variable *> leftVars;
662 std::set<const Colored::Variable *> rightVars;
663 uint32_t index = 0;
664 _left->getVariables(leftVars, varPositionsL, varModifierMapL);
665 _right->getVariables(rightVars, varPositionsR, varModifierMapR);
666 _left->getConstants(constantMapL, index);
667 index = 0;
668 _right->getConstants(constantMapR, index);
669
670 if(leftVars.empty() && rightVars.empty()){
671 return;
672 }
673
674 Colored::GuardRestrictor guardRestrictor;
675 guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, false, true);
676 }
677
678 std::string toString() const override {
679 std::string res = _left->toString() + " > " + _right->toString();
680 return res;
301 }681 }
302 682
303 GreaterThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)683 GreaterThanExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)
@@ -314,10 +694,40 @@
314 return _left->eval(context) <= _right->eval(context);694 return _left->eval(context) <= _right->eval(context);
315 }695 }
316 696
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 {
318 _left->getVariables(variables);698 _left->getVariables(variables, varPositions, varModifierMap);
319 _right->getVariables(variables);699 _right->getVariables(variables, varPositions, varModifierMap);
320 }700 }
701
702 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
703 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL;
704 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR;
705 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL;
706 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR;
707 std::unordered_map<uint32_t, const Color*> constantMapL;
708 std::unordered_map<uint32_t, const Color*> constantMapR;
709 std::set<const Colored::Variable *> leftVars;
710 std::set<const Colored::Variable *> rightVars;
711 uint32_t index = 0;
712 _left->getVariables(leftVars, varPositionsL, varModifierMapL);
713 _right->getVariables(rightVars, varPositionsR, varModifierMapR);
714 _left->getConstants(constantMapL, index);
715 index = 0;
716 _right->getConstants(constantMapR, index);
717
718 if(leftVars.empty() && rightVars.empty()){
719 return;
720 }
721
722 Colored::GuardRestrictor guardRestrictor;
723 guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, true, false);
724 }
725
726 std::string toString() const override {
727 std::string res = _left->toString() + " <= " + _right->toString();
728 return res;
729 }
730
321 731
322 LessThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)732 LessThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)
323 : _left(std::move(left)), _right(std::move(right)) {}733 : _left(std::move(left)), _right(std::move(right)) {}
@@ -333,11 +743,40 @@
333 return _left->eval(context) >= _right->eval(context);743 return _left->eval(context) >= _right->eval(context);
334 }744 }
335 745
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 {
337 _left->getVariables(variables);747 _left->getVariables(variables, varPositions, varModifierMap);
338 _right->getVariables(variables);748 _right->getVariables(variables, varPositions, varModifierMap);
749 }
750
751 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
752 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL;
753 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR;
754 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL;
755 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR;
756 std::unordered_map<uint32_t, const Color*> constantMapL;
757 std::unordered_map<uint32_t, const Color*> constantMapR;
758 std::set<const Colored::Variable *> leftVars;
759 std::set<const Colored::Variable *> rightVars;
760 uint32_t index = 0;
761 _left->getVariables(leftVars, varPositionsL, varModifierMapL);
762 _right->getVariables(rightVars, varPositionsR, varModifierMapR);
763 _left->getConstants(constantMapL, index);
764 index = 0;
765 _right->getConstants(constantMapR, index);
766
767 if(leftVars.empty() && rightVars.empty()){
768 return;
769 }
770
771 Colored::GuardRestrictor guardRestrictor;
772 guardRestrictor.restrictDiagonal(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR, false, false);
339 }773 }
340 774
775 std::string toString() const override {
776 std::string res = _left->toString() + " >= " + _right->toString();
777 return res;
778 }
779
341 GreaterThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)780 GreaterThanEqExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)
342 : _left(std::move(left)), _right(std::move(right)) {}781 : _left(std::move(left)), _right(std::move(right)) {}
343 };782 };
@@ -352,11 +791,41 @@
352 return _left->eval(context) == _right->eval(context);791 return _left->eval(context) == _right->eval(context);
353 }792 }
354 793
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 {
356 _left->getVariables(variables);795 _left->getVariables(variables, varPositions, varModifierMap);
357 _right->getVariables(variables);796 _right->getVariables(variables, varPositions, varModifierMap);
358 }797 }
359 798
799
800 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
801 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapL;
802 std::unordered_map<const Colored::Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> varModifierMapR;
803 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsL;
804 std::unordered_map<uint32_t, const Colored::Variable *> varPositionsR;
805 std::unordered_map<uint32_t, const Color*> constantMapL;
806 std::unordered_map<uint32_t, const Color*> constantMapR;
807 std::set<const Colored::Variable *> leftVars;
808 std::set<const Colored::Variable *> rightVars;
809 uint32_t index = 0;
810 _left->getVariables(leftVars, varPositionsL, varModifierMapL);
811 _right->getVariables(rightVars, varPositionsR, varModifierMapR);
812 _left->getConstants(constantMapL, index);
813 index = 0;
814 _right->getConstants(constantMapR, index);
815
816 if(leftVars.empty() && rightVars.empty()){
817 return;
818 }
819
820 Colored::GuardRestrictor guardRestrictor;
821 guardRestrictor.restrictEquality(&variableMap, &varModifierMapL, &varModifierMapR, &varPositionsL, &varPositionsR, &constantMapL, &constantMapR);
822 }
823
824 std::string toString() const override {
825 std::string res = _left->toString() + " == " + _right->toString();
826 return res;
827 }
828
360 EqualityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)829 EqualityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)
361 : _left(std::move(left)), _right(std::move(right)) {}830 : _left(std::move(left)), _right(std::move(right)) {}
362 };831 };
@@ -371,9 +840,18 @@
371 return _left->eval(context) != _right->eval(context);840 return _left->eval(context) != _right->eval(context);
372 }841 }
373 842
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 {
375 _left->getVariables(variables);844 _left->getVariables(variables, varPositions, varModifierMap);
376 _right->getVariables(variables);845 _right->getVariables(variables, varPositions, varModifierMap);
846 }
847
848 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
849
850 }
851
852 std::string toString() const override {
853 std::string res = _left->toString() + " != " + _right->toString();
854 return res;
377 }855 }
378 856
379 InequalityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)857 InequalityExpression(ColorExpression_ptr&& left, ColorExpression_ptr&& right)
@@ -389,8 +867,28 @@
389 return !_expr->eval(context);867 return !_expr->eval(context);
390 }868 }
391 869
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 {
871 _expr->getVariables(variables, varPositions, varModifierMap, index);
872 }
873
874 std::string toString() const override {
875 std::string res = "!" + _expr->toString();
876 return res;
877 }
878
879 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
880 std::set<const Colored::Variable *> variables;
393 _expr->getVariables(variables);881 _expr->getVariables(variables);
882 //TODO: invert the var intervals here instead of using the full intervals
883
884 for(auto var : variables){
885 auto fullInterval = var->colorType->getFullInterval();
886 Colored::intervalTuple_t fullTuple;
887 fullTuple.addInterval(fullInterval);
888 for(auto& varMap : variableMap){
889 varMap[var] = fullTuple;
890 }
891 }
394 }892 }
395 893
396 NotExpression(GuardExpression_ptr&& expr) : _expr(std::move(expr)) {}894 NotExpression(GuardExpression_ptr&& expr) : _expr(std::move(expr)) {}
@@ -406,11 +904,21 @@
406 return _left->eval(context) && _right->eval(context);904 return _left->eval(context) && _right->eval(context);
407 }905 }
408 906
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 {
410 _left->getVariables(variables);908 _left->getVariables(variables, varPositions, varModifierMap);
411 _right->getVariables(variables);909 _right->getVariables(variables, varPositions, varModifierMap);
412 }910 }
413 911
912 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override {
913 _left->restrictVars(variableMap);
914 _right->restrictVars(variableMap);
915 }
916
917 std::string toString() const override {
918 std::string res = _left->toString() + " && " + _right->toString();
919 return res;
920 }
921
414 AndExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right)922 AndExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right)
415 : _left(left), _right(right) {}923 : _left(left), _right(right) {}
416 };924 };
@@ -425,11 +933,30 @@
425 return _left->eval(context) || _right->eval(context);933 return _left->eval(context) || _right->eval(context);
426 }934 }
427 935
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 {
429 _left->getVariables(variables);937 _left->getVariables(variables, varPositions, varModifierMap);
430 _right->getVariables(variables);938 _right->getVariables(variables, varPositions, varModifierMap);
431 }939 }
432 940
941 void restrictVars(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMap) const override{
942 auto varMapCopy = variableMap;
943 _left->restrictVars(variableMap);
944 _right->restrictVars(varMapCopy);
945
946 for(size_t i = 0; i < variableMap.size(); i++){
947 for(auto& varPair : varMapCopy[i]){
948 for(auto& interval : varPair.second._intervals){
949 variableMap[i][varPair.first].addInterval(std::move(interval));
950 }
951 }
952 }
953 }
954
955 std::string toString() const override {
956 std::string res = _left->toString() + " || " + _right->toString();
957 return res;
958 }
959
433 OrExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right)960 OrExpression(GuardExpression_ptr&& left, GuardExpression_ptr&& right)
434 : _left(std::move(left)), _right(std::move(right)) {}961 : _left(std::move(left)), _right(std::move(right)) {}
435 };962 };
@@ -444,8 +971,21 @@
444 virtual void expressionType() override {971 virtual void expressionType() override {
445 std::cout << "ArcExpression" << std::endl;972 std::cout << "ArcExpression" << std::endl;
446 }973 }
974 virtual void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const = 0;
975
976 virtual bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const = 0;
447977
448 virtual uint32_t weight() const = 0;978 virtual uint32_t weight() const = 0;
979
980 virtual Colored::intervalTuple_t getOutputIntervals(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>>& varMapVec) const {
981 std::vector<const Colored::ColorType *> colortypes;
982
983 return getOutputIntervals(varMapVec, &colortypes);
984 }
985
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 {
987 return Colored::intervalTuple_t();
988 }
449 };989 };
450990
451 typedef std::shared_ptr<ArcExpression> ArcExpression_ptr;991 typedef std::shared_ptr<ArcExpression> ArcExpression_ptr;
@@ -465,6 +1005,45 @@
465 return colors;1005 return colors;
466 }1006 }
4671007
1008 void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const {
1009 for (size_t i = 0; i < _sort->size(); i++) {
1010 constantMap[index].push_back(&(*_sort)[i]);
1011 }
1012 }
1013
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 {
1015 Colored::intervalTuple_t newIntervalTuple;
1016 newIntervalTuple.addInterval(_sort->getFullInterval());
1017 return newIntervalTuple;
1018 }
1019
1020 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const {
1021
1022 if(arcIntervals._intervalTupleVec.empty()){
1023 bool colorsInFixpoint = false;
1024 Colored::intervalTuple_t newIntervalTuple;
1025 cfp.constraints.simplify();
1026 if(cfp.constraints.getContainedColors() == _sort->size()){
1027 colorsInFixpoint = true;
1028 for(auto interval : cfp.constraints._intervals){
1029 newIntervalTuple.addInterval(interval);
1030 }
1031 }
1032 arcIntervals._intervalTupleVec.push_back(newIntervalTuple);
1033 return colorsInFixpoint;
1034 } else {
1035 std::vector<Colored::intervalTuple_t> newIntervalTupleVec;
1036 for(uint32_t i = 0; i < arcIntervals._intervalTupleVec.size(); i++){
1037 auto& intervalTuple = arcIntervals._intervalTupleVec[i];
1038 if(intervalTuple.getContainedColors() == _sort->size()){
1039 newIntervalTupleVec.push_back(intervalTuple);
1040 }
1041 }
1042 arcIntervals._intervalTupleVec = std::move(newIntervalTupleVec);
1043 return !arcIntervals._intervalTupleVec.empty();
1044 }
1045 }
1046
468 size_t size() const {1047 size_t size() const {
469 return _sort->size();1048 return _sort->size();
470 }1049 }
@@ -503,12 +1082,64 @@
503 }1082 }
504 return Multiset(col);1083 return Multiset(col);
505 }1084 }
506 1085
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 {
508 if (_all != nullptr)1087 if (_all != nullptr)
509 return;1088 return;
510 for (auto elem : _color) {1089 for (auto elem : _color) {
511 elem->getVariables(variables);1090 //TODO: can there be more than one element in a number of expression?
1091 elem->getVariables(variables, varPositions, varModifierMap, index);
1092 //(*index)++;
1093 }
1094 }
1095
1096 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
1097 if (_all != nullptr) {
1098 return _all->getArcIntervals(arcIntervals, cfp, index, modifier);
1099 }
1100 uint32_t i = 0;
1101 for (auto elem : _color) {
1102 (*index) += i;
1103 if(!elem->getArcIntervals(arcIntervals, cfp, index, modifier)){
1104 return false;
1105 }
1106 i++;
1107 }
1108 return true;
1109 }
1110
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 {
1112 Colored::intervalTuple_t intervals;
1113 if (_all == nullptr) {
1114 for (auto elem : _color) {
1115 for(auto& varMap : varMapVec){
1116 auto nestedIntervals = elem->getOutputIntervals(varMap, colortypes);
1117
1118 if (intervals._intervals.empty()) {
1119 intervals = nestedIntervals;
1120 } else {
1121 for(auto interval : nestedIntervals._intervals) {
1122 intervals.addInterval(interval);
1123 }
1124 }
1125 }
1126 }
1127 } else {
1128 return _all->getOutputIntervals(varMapVec, colortypes);
1129 }
1130 return intervals;
1131 }
1132
1133 void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override {
1134 if (_all != nullptr)
1135 _all->getConstants(constantMap, index);
1136 else for (auto elem : _color) {
1137 std::unordered_map<uint32_t, const Color*> elemMap;
1138 elem->getConstants(elemMap, index);
1139 for(auto pair : elemMap){
1140 constantMap[pair.first].push_back(pair.second);
1141 }
1142 index++;//not sure if index should be increased here, but no number expression have multiple elements
512 }1143 }
513 }1144 }
5141145
@@ -563,9 +1194,57 @@
563 return ms;1194 return ms;
564 }1195 }
565 1196
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 {
567 for (auto elem : _constituents) {1198 for (auto elem : _constituents) {
568 elem->getVariables(variables);1199 for(auto& pair : varModifierMap){
1200 std::unordered_map<uint32_t, int32_t> newMap;
1201 pair.second.push_back(newMap);
1202 }
1203 elem->getVariables(variables, varPositions, varModifierMap);
1204 }
1205 }
1206
1207 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
1208 for (auto elem : _constituents) {
1209 uint32_t newIndex = 0;
1210 Colored::ArcIntervals newArcIntervals;
1211 std::vector<uint32_t> intervalsForRemoval;
1212 std::vector<Colored::interval_t> newIntervals;
1213 if(!elem->getArcIntervals(newArcIntervals, cfp, &newIndex, modifier)){
1214 return false;
1215 }
1216
1217 if(newArcIntervals._intervalTupleVec.empty()){
1218 return false;
1219 }
1220
1221 arcIntervals._intervalTupleVec.insert(arcIntervals._intervalTupleVec.end(), newArcIntervals._intervalTupleVec.begin(), newArcIntervals._intervalTupleVec.end());
1222 }
1223 return true;
1224 }
1225
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 {
1227 Colored::intervalTuple_t intervals;
1228
1229 for (auto elem : _constituents) {
1230 auto nestedIntervals = elem->getOutputIntervals(varMapVec, colortypes);
1231
1232 if (intervals._intervals.empty()) {
1233 intervals = nestedIntervals;
1234 } else {
1235 for(auto interval : nestedIntervals._intervals) {
1236 intervals.addInterval(interval);
1237 }
1238 }
1239 }
1240 return intervals;
1241 }
1242
1243 void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override {
1244 uint32_t indexCopy = index;
1245 for (auto elem : _constituents) {
1246 uint32_t localIndex = indexCopy;
1247 elem->getConstants(constantMap, localIndex);
569 }1248 }
570 }1249 }
5711250
@@ -599,9 +1278,29 @@
599 return _left->eval(context) - _right->eval(context);1278 return _left->eval(context) - _right->eval(context);
600 }1279 }
601 1280
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 {
603 _left->getVariables(variables);1282 _left->getVariables(variables, varPositions, varModifierMap);
604 _right->getVariables(variables);1283 //We ignore the restrictions imposed by the subtraction for now
1284 //_right->getVariables(variables, varPositions, varModifierMap);
1285 }
1286
1287 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
1288 return _left->getArcIntervals(arcIntervals, cfp, index, modifier);
1289 //We ignore the restrictions imposed by the subtraction for now
1290 //_right->getArcIntervals(arcIntervals, cfp, &rightIndex);
1291 }
1292
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 {
1294 //We could maybe reduce the intervals slightly by checking if the upper or lower bound is being subtracted
1295 auto leftIntervals = _left->getOutputIntervals(varMapVec, colortypes);
1296
1297 return leftIntervals;
1298 }
1299
1300 void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override {
1301 uint32_t rIndex = index;
1302 _left->getConstants(constantMap, index);
1303 _right->getConstants(constantMap, rIndex);
605 }1304 }
6061305
607 uint32_t weight() const override {1306 uint32_t weight() const override {
@@ -636,8 +1335,20 @@
636 return _expr->eval(context) * _scalar;1335 return _expr->eval(context) * _scalar;
637 }1336 }
638 1337
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 {
640 _expr->getVariables(variables);1339 _expr->getVariables(variables, varPositions,varModifierMap);
1340 }
1341
1342 bool getArcIntervals(Colored::ArcIntervals& arcIntervals, PetriEngine::Colored::ColorFixpoint& cfp, uint32_t *index, int32_t modifier) const override {
1343 return _expr ->getArcIntervals(arcIntervals, cfp, index, modifier);
1344 }
1345
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 {
1347 return _expr->getOutputIntervals(varMapVec, colortypes);
1348 }
1349
1350 void getConstants(std::unordered_map<uint32_t, std::vector<const Color*>> &constantMap, uint32_t &index) const override {
1351 _expr->getConstants(constantMap, index);
641 }1352 }
6421353
643 uint32_t weight() const override {1354 uint32_t weight() const override {
6441355
=== added file 'include/PetriEngine/Colored/GuardRestrictor.h'
--- include/PetriEngine/Colored/GuardRestrictor.h 1970-01-01 00:00:00 +0000
+++ include/PetriEngine/Colored/GuardRestrictor.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,83 @@
1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef GuardRestrictions_H
20#define GuardRestrictions_H
21
22#include "Colors.h"
23#include "Multiset.h"
24#include <unordered_map>
25#include <set>
26#include <stdlib.h>
27
28namespace PetriEngine {
29 namespace Colored {
30
31 class GuardRestrictor {
32 public:
33
34 GuardRestrictor();
35
36 void restrictDiagonal(std::vector<std::unordered_map<const Variable *, intervalTuple_t>> *variableMap,
37 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapL,
38 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapR,
39 std::unordered_map<uint32_t, const Variable *> *varPositionsL,
40 std::unordered_map<uint32_t, const Variable *> *varPositionsR,
41 std::unordered_map<uint32_t, const Color*> *constantMapL,
42 std::unordered_map<uint32_t, const Color*> *constantMapR,
43 bool lessthan, bool strict);
44
45 void restrictEquality(std::vector<std::unordered_map<const Variable *, intervalTuple_t>> *variableMap,
46 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapL,
47 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *varModifierMapR,
48 std::unordered_map<uint32_t, const Variable *> *varPositionsL,
49 std::unordered_map<uint32_t, const Variable *> *varPositionsR,
50 std::unordered_map<uint32_t, const Color*> *constantMapL,
51 std::unordered_map<uint32_t, const Color*> *constantMapR);
52
53 intervalTuple_t shiftIntervals(std::vector<const ColorType *> *colortypes,
54 intervalTuple_t *intervals,
55 int32_t modifier,
56 uint32_t ctSizeBefore) const;
57
58 private:
59 int32_t getVarModifier(std::unordered_map<uint32_t, int32_t> *modPairMap, uint32_t index);
60 interval_t getIntervalFromIds(std::vector<uint32_t> *idVec, uint32_t ctSize, int32_t modifier);
61 intervalTuple_t getIntervalOverlap(std::vector<interval_t> *intervals1, std::vector<interval_t> *intervals2);
62
63 void expandIdVec(std::unordered_map<const Variable *, intervalTuple_t> *varMap,
64 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *mainVarModifierMap,
65 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *otherVarModifierMap,
66 std::unordered_map<uint32_t, const Variable *> *varPositions,
67 std::unordered_map<uint32_t, const Color*> *constantMap,
68 const Variable *otherVar,
69 std::vector<uint32_t> &idVec, size_t targetSize, uint32_t index);
70
71 void expandIntervalVec(std::unordered_map<const Variable *, intervalTuple_t> *varMap,
72 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *mainVarModifierMap,
73 std::unordered_map<const Variable *,std::vector<std::unordered_map<uint32_t, int32_t>>> *otherVarModifierMap,
74 std::unordered_map<uint32_t, const Variable *> *varPositions,
75 std::unordered_map<uint32_t, const Color*> *constantMap,
76 const Variable *otherVar,
77 std::vector<interval_t> &intervalVec, size_t targetSize, uint32_t index);
78 };
79 }
80}
81
82
83#endif /* GuardRestrictions_H */
0\ No newline at end of file84\ No newline at end of file
185
=== added file 'include/PetriEngine/Colored/IntervalGenerator.h'
--- include/PetriEngine/Colored/IntervalGenerator.h 1970-01-01 00:00:00 +0000
+++ include/PetriEngine/Colored/IntervalGenerator.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,197 @@
1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef INTERVALGENERATOR_H
19#define INTERVALGENERATOR_H
20
21#include "ColoredNetStructures.h"
22
23namespace PetriEngine {
24 struct IntervalGenerator {
25 std::vector<Colored::interval_t> getIntervalsFromInterval(Colored::interval_t *interval, uint32_t varPosition, int32_t varModifier, std::vector<Colored::ColorType*> *varColorTypes){
26 std::vector<Colored::interval_t> varIntervals;
27 Colored::interval_t firstVarInterval;
28 varIntervals.push_back(firstVarInterval);
29 for(uint32_t i = varPosition; i < varPosition + varColorTypes->size(); i++){
30 auto ctSize = varColorTypes->operator[](i - varPosition)->size();
31 int32_t lower_val = ctSize + (interval->operator[](i)._lower + varModifier);
32 int32_t upper_val = ctSize + (interval->operator[](i)._upper + varModifier);
33 uint32_t lower = lower_val % ctSize;
34 uint32_t upper = upper_val % ctSize;
35
36 if(lower > upper ){
37 if(lower == upper+1){
38 for (auto& varInterval : varIntervals){
39 varInterval.addRange(0, ctSize -1);
40 }
41 } else {
42 std::vector<Colored::interval_t> newIntervals;
43 for (auto& varInterval : varIntervals){
44 Colored::interval_t newVarInterval = varInterval;
45 varInterval.addRange(0, upper);
46 newVarInterval.addRange(lower, ctSize -1);
47 newIntervals.push_back(newVarInterval);
48 }
49 varIntervals.insert(varIntervals.end(), newIntervals.begin(), newIntervals.end());
50 }
51 } else {
52 for (auto& varInterval : varIntervals){
53 varInterval.addRange(lower, upper);
54 }
55 }
56 }
57 return varIntervals;
58 }
59
60 void getArcVarIntervals(Colored::intervalTuple_t& varIntervals, std::unordered_map<uint32_t, int32_t> *modIndexMap, Colored::interval_t *interval, std::vector<Colored::ColorType*> *varColorTypes){
61 for(auto& posModPair : *modIndexMap){
62 auto intervals = getIntervalsFromInterval(interval, posModPair.first, posModPair.second, varColorTypes);
63
64 if(varIntervals._intervals.empty()){
65 for(auto& interval : intervals){
66 varIntervals.addInterval(std::move(interval));
67 }
68 } else {
69 Colored::intervalTuple_t newVarIntervals;
70 for(uint32_t i = 0; i < varIntervals.size(); i++){
71 auto varInterval = &varIntervals[i];
72 for(auto& interval : intervals){
73 auto overlap = varInterval->getOverlap(std::move(interval));
74 if(overlap.isSound()){
75 newVarIntervals.addInterval(std::move(overlap));
76 //break;
77 }
78 }
79 }
80 varIntervals = std::move(newVarIntervals);
81 }
82 }
83 }
84
85 void populateLocalMap(Colored::ArcIntervals *arcIntervals,
86 std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t> &varMap,
87 std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t> &localVarMap,
88 Colored::interval_t* interval, bool& allVarsAssigned, uint32_t tuplePos){
89 for(auto& pair : arcIntervals->_varIndexModMap){
90 Colored::intervalTuple_t varIntervals;
91 std::vector<Colored::ColorType*> varColorTypes;
92 pair.first->colorType->getColortypes(varColorTypes);
93
94 getArcVarIntervals(varIntervals, &pair.second[tuplePos], interval, &varColorTypes);
95
96 if (arcIntervals->_intervalTupleVec.size() > 1 && pair.second[tuplePos].empty()) {
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
98 varIntervals.addInterval(pair.first->colorType->getFullInterval());
99 }
100
101 if(varMap.count(pair.first) == 0){
102 localVarMap[pair.first] = std::move(varIntervals);
103 } else {
104 for(auto& varInterval : varIntervals._intervals){
105 for(auto& interval : varMap[pair.first]._intervals){
106 auto overlapInterval = varInterval.getOverlap(interval);
107
108 if(overlapInterval.isSound()){
109 localVarMap[pair.first].addInterval(overlapInterval);
110 }
111 }
112 }
113 }
114
115 if(localVarMap[pair.first]._intervals.empty()){
116 allVarsAssigned = false;
117 }
118 }
119 }
120
121 void fillVarMaps(std::vector<std::unordered_map<const PetriEngine::Colored::Variable *, PetriEngine::Colored::intervalTuple_t>> &variableMaps,
122 Colored::ArcIntervals *arcIntervals,
123 uint32_t *intervalTupleSize,
124 uint32_t *tuplePos)
125 {
126 for(uint32_t i = 0; i < *intervalTupleSize; i++){
127 std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t> localVarMap;
128 bool validInterval = true;
129 auto interval = &arcIntervals->_intervalTupleVec[*tuplePos]._intervals[i];
130
131 for(auto pair : arcIntervals->_varIndexModMap){
132 Colored::intervalTuple_t varIntervals;
133 std::vector<Colored::ColorType*> varColorTypes;
134 pair.first->colorType->getColortypes(varColorTypes);
135 getArcVarIntervals(varIntervals, &pair.second[*tuplePos], interval, &varColorTypes);
136
137 if(arcIntervals->_intervalTupleVec.size() > 1 && pair.second[*tuplePos].empty()){
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
139 varIntervals.addInterval(pair.first->colorType->getFullInterval());
140 } else if(varIntervals.size() < 1){
141 //If any varinterval ends up empty then we were unable to use this arc interval
142 validInterval = false;
143 break;
144 }
145 localVarMap[pair.first] = varIntervals;
146 }
147
148 if(validInterval){
149 variableMaps.push_back(localVarMap);
150 }
151 }
152 }
153
154 bool getVarIntervals(std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>>& variableMaps, std::unordered_map<uint32_t, Colored::ArcIntervals> placeArcIntervals){
155 for(auto& placeArcInterval : placeArcIntervals){
156 for(uint32_t j = 0; j < placeArcInterval.second._intervalTupleVec.size(); j++){
157 uint32_t intervalTupleSize = placeArcInterval.second._intervalTupleVec[j].size();
158 //If we have not found intervals for any place yet, we fill the intervals from this place
159 //Else we restrict the intervals we already found to only keep those that can also be matched in this place
160 if(variableMaps.empty()){
161 fillVarMaps(variableMaps, &placeArcInterval.second, &intervalTupleSize, &j);
162 } else {
163 std::vector<std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t>> newVarMapVec;
164
165 for(auto& varMap : variableMaps){
166 for(uint32_t i = 0; i < intervalTupleSize; i++){
167 std::unordered_map<const Colored::Variable *, Colored::intervalTuple_t> localVarMap;
168 bool allVarsAssigned = true;
169 auto interval = &placeArcInterval.second._intervalTupleVec[j]._intervals[i];
170
171 populateLocalMap(&placeArcInterval.second, varMap, localVarMap, interval, allVarsAssigned, j);
172
173 for(auto& varTuplePair : varMap){
174 if(localVarMap.count(varTuplePair.first) == 0){
175 localVarMap[varTuplePair.first] = std::move(varTuplePair.second);
176 }
177 }
178
179 if(allVarsAssigned){
180 newVarMapVec.push_back(std::move(localVarMap));
181 }
182 }
183 }
184 variableMaps = std::move(newVarMapVec);
185 }
186 //If we did not find any intervals for an arc, then the transition cannot be activated
187 if(variableMaps.empty()){
188 return false;
189 }
190 }
191 }
192 return true;
193 }
194 };
195}
196
197#endif /* INTERVALGENERATOR_H */
0\ No newline at end of file198\ No newline at end of file
1199
=== added file 'include/PetriEngine/Colored/Intervals.h'
--- include/PetriEngine/Colored/Intervals.h 1970-01-01 00:00:00 +0000
+++ include/PetriEngine/Colored/Intervals.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,630 @@
1/* Copyright (C) 2020 Alexander Bilgram <alexander@bilgram.dk>,
2 * Peter Haar Taankvist <ptaankvist@gmail.com>,
3 * Thomas Pedersen <thomas.pedersen@stofanet.dk>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef INTERVALS_H
20#define INTERVALS_H
21
22#include "../TAR/range.h"
23#include <set>
24#include <unordered_map>
25#include <chrono>
26
27
28namespace PetriEngine {
29 namespace Colored {
30
31 struct interval_t {
32 std::vector<Reachability::range_t> _ranges;
33
34 interval_t() {
35 }
36
37 ~interval_t(){}
38
39 interval_t(std::vector<Reachability::range_t> ranges) : _ranges(ranges) {
40 }
41
42 size_t size(){
43 return _ranges.size();
44 }
45
46 uint32_t intervalCombinations(){
47 uint32_t product = 1;
48 for(auto range : _ranges){
49 product *= range.size();
50 }
51 if(_ranges.empty()){
52 return 0;
53 }
54 return product;
55 }
56
57 bool isSound(){
58 for(auto range: _ranges) {
59 if(!range.isSound()){
60 return false;
61 }
62 }
63 return true;
64 }
65
66 void addRange(Reachability::range_t newRange) {
67 _ranges.push_back(newRange);
68 }
69
70 void addRange(Reachability::range_t newRange, uint32_t index){
71 _ranges.insert(_ranges.begin() + index, newRange);
72 }
73
74 void addRange(uint32_t l, uint32_t u) {
75 _ranges.push_back(Reachability::range_t(l, u));
76 }
77
78 void addRange(uint32_t lower, uint32_t upper, uint32_t index){
79 _ranges.insert(_ranges.begin() + index, Reachability::range_t(lower, upper));
80 }
81
82 Reachability::range_t& operator[] (size_t index) {
83 return _ranges[index];
84 }
85
86 Reachability::range_t& operator[] (int index) {
87 return _ranges[index];
88 }
89
90 Reachability::range_t& operator[] (uint32_t index) {
91 assert(index < _ranges.size());
92 return _ranges[index];
93 }
94
95 Reachability::range_t& getFirst() {
96 return _ranges[0];
97 }
98
99 Reachability::range_t& getLast() {
100 return _ranges.back();
101 }
102
103 std::vector<uint32_t> getLowerIds(){
104 std::vector<uint32_t> ids;
105 for(auto range : _ranges){
106 ids.push_back(range._lower);
107 }
108 return ids;
109 }
110
111 std::vector<uint32_t> getUpperIds(){
112 std::vector<uint32_t> ids;
113 for(auto range : _ranges){
114 ids.push_back(range._upper);
115 }
116 return ids;
117 }
118
119 bool equals(interval_t other){
120 if(other.size() != size()){
121 return false;
122 }
123 for(uint32_t i = 0; i < size(); i++){
124 auto comparisonRes = _ranges[i].compare(other[i]);
125 if(!comparisonRes.first || !comparisonRes.second){
126 return false;
127 }
128 }
129 return true;
130 }
131
132 uint32_t getContainedColors(){
133 uint32_t colors = 1;
134 for(auto range: _ranges) {
135 colors *= 1+ range._upper - range._lower;
136 }
137 return colors;
138 }
139
140 bool contains(interval_t other){
141 if(other.size() != size()){
142 return false;
143 }
144 for(uint32_t i = 0; i < size(); i++){
145 if(!_ranges[i].compare(other[i]).first){
146 return false;
147 }
148 }
149 return true;
150 }
151
152 void constrain(interval_t other){
153 for(uint32_t i = 0; i < _ranges.size(); i++){
154 _ranges[i] &= other._ranges[i];
155 }
156 }
157
158 interval_t getOverlap(interval_t other){
159 interval_t overlapInterval;
160 if(size() != other.size()){
161 return overlapInterval;
162 }
163
164 for(uint32_t i = 0; i < size(); i++){
165 auto rangeCopy = _ranges[i];
166 overlapInterval.addRange(rangeCopy &= other[i]);
167 }
168
169 return overlapInterval;
170 }
171
172 void print() {
173 for(auto range : _ranges){
174 std::cout << " " << range._lower << "-" << range._upper << " ";
175 }
176 }
177 };
178
179 struct closestIntervals {
180 uint32_t intervalId1;
181 uint32_t intervalId2;
182 uint32_t distance;
183 };
184
185 struct intervalTuple_t {
186 std::vector<interval_t> _intervals;
187 double totalinputtime = 0;
188
189 ~intervalTuple_t() {
190 }
191
192 intervalTuple_t() {
193 }
194
195 intervalTuple_t(std::vector<interval_t> ranges) : _intervals(ranges) {
196 };
197
198 interval_t& getFirst(){
199 return _intervals[0];
200 }
201
202 interval_t& back() {
203 return _intervals.back();
204 }
205
206 size_t size() {
207 return _intervals.size();
208 }
209
210 size_t tupleSize() {
211 return _intervals[0].size();
212 }
213
214 uint32_t getContainedColors(){
215 uint32_t colors = 0;
216 for (auto interval : _intervals) {
217 colors += interval.getContainedColors();
218 }
219 return colors;
220 }
221
222 std::pair<uint32_t,uint32_t> shiftInterval(uint32_t lower, uint32_t upper, uint32_t ctSize, int32_t modifier){
223 int32_t lower_val = ctSize + (lower + modifier);
224 int32_t upper_val = ctSize + (upper + modifier);
225 return std::make_pair(lower_val % ctSize, upper_val % ctSize);
226 }
227
228 uint32_t intervalCombinations(){
229 uint32_t res = 0;
230 for(auto interval : _intervals){
231 res += interval.intervalCombinations();
232 }
233 return res;
234 }
235
236 bool hasValidIntervals(){
237 for(auto interval : _intervals) {
238 if(interval.isSound()){
239 return true;
240 }
241 }
242 return false;
243 }
244
245 interval_t& operator[] (size_t index) {
246 return _intervals[index];
247 }
248
249 interval_t& operator[] (int index) {
250 return _intervals[index];
251 }
252
253 interval_t& operator[] (uint32_t index) {
254 assert(index < _intervals.size());
255 return _intervals[index];
256 }
257
258 interval_t isRangeEnd(std::vector<uint32_t> ids) {
259 for (uint32_t j = 0; j < _intervals.size(); j++) {
260 bool rangeEnd = true;
261 for (uint32_t i = 0; i < _intervals[j].size(); i++) {
262 auto range = _intervals[j][i];
263 if (range._upper != ids[i]) {
264 rangeEnd = false;
265 break;
266 }
267 }
268 if(rangeEnd) {
269 if(j+1 != _intervals.size()) {
270 return _intervals[j+1];
271 } else {
272 return getFirst();
273 }
274 }
275 }
276 return interval_t();
277 }
278
279 std::vector<Colored::interval_t> shrinkIntervals(uint32_t newSize){
280 std::vector<Colored::interval_t> resizedIntervals;
281 for(auto interval : _intervals){
282 Colored::interval_t resizedInterval;
283 for(uint32_t i = 0; i < newSize; i++){
284 resizedInterval.addRange(interval[i]);
285 }
286 resizedIntervals.push_back(resizedInterval);
287 }
288 return resizedIntervals;
289 }
290
291 void addInterval(interval_t interval) {
292 uint32_t vecIndex = 0;
293
294 if(!_intervals.empty()) {
295 assert(_intervals[0].size() == interval.size());
296 } else {
297 _intervals.push_back(interval);
298 return;
299 }
300
301 for (auto& localInterval : _intervals) {
302 bool overlap = true;
303 enum FoundPlace {undecided, greater, lower};
304 FoundPlace foundPlace = undecided;
305
306 for(uint32_t k = 0; k < interval.size(); k++){
307 if(interval[k]._lower > localInterval[k]._upper || localInterval[k]._lower > interval[k]._upper){
308 overlap = false;
309 }
310 if(interval[k]._lower < localInterval[k]._lower){
311 if(foundPlace == undecided){
312 foundPlace = lower;
313 }
314 } else if (interval[k]._lower > localInterval[k]._lower){
315 if(foundPlace == undecided){
316 foundPlace = greater;
317 }
318 }
319 if(!overlap && foundPlace != undecided){
320 break;
321 }
322 }
323
324 if(overlap) {
325 for(uint32_t k = 0; k < interval.size(); k++){
326 localInterval[k] |= interval[k];
327 }
328 return;
329 } else if(foundPlace == lower){
330 break;
331 }
332 vecIndex++;
333 }
334
335 _intervals.insert(_intervals.begin() + vecIndex, interval);
336 }
337
338 void constrainLower(std::vector<uint32_t> values, bool strict) {
339 for(uint32_t i = 0; i < _intervals.size(); i++) {
340 for(uint32_t j = 0; j < values.size(); j++){
341 if(strict && _intervals[i][j]._lower <= values[j]){
342 _intervals[i][j]._lower = values[j]+1;
343 }
344 else if(!strict && _intervals[i][j]._lower < values[j]){
345 _intervals[i][j]._lower = values[j];
346 }
347 }
348 }
349 simplify();
350 }
351
352 void constrainUpper(std::vector<uint32_t> values, bool strict) {
353 for(uint32_t i = 0; i < _intervals.size(); i++) {
354 for(uint32_t j = 0; j < values.size(); j++){
355 if(strict && _intervals[i][j]._upper >= values[j]){
356 _intervals[i][j]._upper = values[j]-1;
357 }
358 else if(!strict && _intervals[i][j]._upper > values[j]){
359 _intervals[i][j]._upper = values[j];
360 }
361 }
362 }
363 simplify();
364 }
365
366 void expandLower(std::vector<uint32_t> values) {
367 for(uint32_t i = 0; i < values.size(); i++) {
368 _intervals[0][i]._lower = std::min(values[i],_intervals[0][i]._lower);
369 }
370 }
371
372 void expandUpper(std::vector<uint32_t> values) {
373 for(uint32_t i = 0; i < values.size(); i++) {
374 _intervals[0][i]._upper = std::max(values[i],_intervals[0][i]._upper);
375 }
376 }
377
378 void print() {
379 for (auto interval : _intervals){
380 std::cout << "[";
381 interval.print();
382 std::cout << "]" << std::endl;
383 }
384 }
385
386 std::vector<uint32_t> getLowerIds(){
387 std::vector<uint32_t> ids;
388 for(auto interval : _intervals){
389 if(ids.empty()){
390 ids = interval.getLowerIds();
391 } else {
392 for(uint32_t i = 0; i < ids.size(); i++){
393 ids[i] = std::min(ids[i], interval[i]._lower);
394 }
395 }
396 }
397 return ids;
398 }
399
400 std::vector<uint32_t> getLowerIds(int32_t modifier, std::vector<size_t> sizes){
401 std::vector<uint32_t> ids;
402 for(uint32_t j = 0; j < size(); j++){
403 auto interval = &_intervals[j];
404 if(ids.empty()){
405 for(uint32_t i = 0; i < ids.size(); i++){
406 auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier);
407 if(shiftedInterval.first > shiftedInterval.second){
408 ids.push_back(0);
409 } else {
410 ids.push_back(shiftedInterval.first);
411 }
412 }
413 } else {
414 for(uint32_t i = 0; i < ids.size(); i++){
415 if(ids[i] == 0){
416 continue;
417 }
418 auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier);
419 if(shiftedInterval.first > shiftedInterval.second){
420 ids[i] = 0;
421 } else {
422 ids[i] = std::max(ids[i], shiftedInterval.first);
423 }
424 }
425 }
426 }
427 return ids;
428 }
429
430 std::vector<uint32_t> getUpperIds(){
431 std::vector<uint32_t> ids;
432 for(auto interval : _intervals){
433 if(ids.empty()){
434 ids = interval.getUpperIds();
435 } else {
436 for(uint32_t i = 0; i < ids.size(); i++){
437 ids[i] = std::max(ids[i], interval[i]._upper);
438 }
439 }
440 }
441 return ids;
442 }
443
444 std::vector<uint32_t> getUpperIds(int32_t modifier, std::vector<size_t> sizes){
445 std::vector<uint32_t> ids;
446 for(uint32_t j = 0; j < size(); j++){
447 auto interval = &_intervals[j];
448 if(ids.empty()){
449 for(uint32_t i = 0; i < ids.size(); i++){
450 auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier);
451
452 if(shiftedInterval.first > shiftedInterval.second){
453 ids.push_back(sizes[i]-1);
454 } else {
455 ids.push_back(shiftedInterval.second);
456 }
457 }
458 } else {
459 for(uint32_t i = 0; i < ids.size(); i++){
460 if(ids[i] == sizes[i]-1){
461 continue;
462 }
463 auto shiftedInterval = shiftInterval(interval->operator[](i)._lower, interval->operator[](i)._upper, sizes[i], modifier);
464
465 if(shiftedInterval.first > shiftedInterval.second){
466 ids[i] = sizes[i]-1;
467 } else {
468 ids[i] = std::max(ids[i], shiftedInterval.second);
469 }
470 }
471 }
472 }
473 return ids;
474 }
475
476 void applyModifier(int32_t modifier, std::vector<size_t> sizes){
477 std::vector<interval_t> collectedIntervals;
478 for(auto& interval : _intervals){
479 std::vector<interval_t> newIntervals;
480 newIntervals.push_back(std::move(interval));
481 for(uint32_t i = 0; i < interval.size(); i++){
482 std::vector<interval_t> tempIntervals;
483 for(auto& interval1 : newIntervals){
484 auto shiftedInterval = shiftInterval(interval1[i]._lower, interval1[i]._upper, sizes[i], modifier);
485
486 if(shiftedInterval.first > shiftedInterval.second){
487 auto newInterval = interval1;
488
489 interval1[i]._lower = 0;
490 interval1[i]._upper = shiftedInterval.second;
491
492 newInterval[i]._lower = shiftedInterval.first;
493 newInterval[i]._upper = sizes[i]-1;
494 tempIntervals.push_back(std::move(newInterval));
495 }else {
496 interval1[i]._lower = shiftedInterval.first;
497 interval1[i]._upper = shiftedInterval.second;
498 }
499 }
500 newIntervals.insert(newIntervals.end(), tempIntervals.begin(), tempIntervals.end());
501 }
502 collectedIntervals.insert(collectedIntervals.end(), newIntervals.begin(), newIntervals.end());
503 }
504
505 _intervals = std::move(collectedIntervals);
506 }
507
508 bool contains(interval_t interval){
509 for(auto localInterval : _intervals){
510 if(localInterval.contains(interval)){
511 return true;
512 }
513 }
514 return false;
515 }
516
517 void removeInterval(interval_t interval) {
518 for (uint32_t i = 0; i < _intervals.size(); i++) {
519 if(interval.equals(_intervals[i])){
520 removeInterval(i);
521 return;
522 }
523 }
524 }
525
526 void removeInterval(uint32_t index) {
527 _intervals.erase(_intervals.begin() + index);
528 }
529
530
531
532 void restrict(uint32_t k){
533 simplify();
534 if(k == 0){
535 return;
536 }
537
538 while (size() > k){
539 closestIntervals closestInterval = getClosestIntervals();
540 auto interval = &_intervals[closestInterval.intervalId1];
541 auto otherInterval = &_intervals[closestInterval.intervalId2];
542
543 for(uint32_t l = 0; l < interval->size(); l++) {
544 interval->operator[](l) |= otherInterval->operator[](l);
545 }
546
547 _intervals.erase(_intervals.begin() + closestInterval.intervalId2);
548
549 }
550 }
551
552 closestIntervals getClosestIntervals(){
553 closestIntervals currentBest = {0,0, UINT32_MAX};
554 for (uint32_t i = 0; i < size()-1; i++) {
555 auto interval = &_intervals[i];
556 for(uint32_t j = i+1; j < size(); j++){
557 auto otherInterval = &_intervals[j];
558 uint32_t dist = 0;
559
560 for(uint32_t k = 0; k < interval->size(); k++) {
561 int32_t val1 = otherInterval->operator[](k)._lower - interval->operator[](k)._upper;
562 int32_t val2 = interval->operator[](k)._lower - otherInterval->operator[](k)._upper;
563 dist += std::max(0, std::max(val1, val2));
564 if(dist >= currentBest.distance){
565 break;
566 }
567 }
568
569 if(dist < currentBest.distance){
570 currentBest.distance = dist;
571 currentBest.intervalId1 = i;
572 currentBest.intervalId2 = j;
573
574 //if the distance is 1 we cannot find any intervals that are closer so we stop searching
575 if(currentBest.distance == 1){
576 return currentBest;
577 }
578 }
579 }
580 }
581 return currentBest;
582 }
583
584 void simplify() {
585 std::set<uint32_t> rangesToRemove;
586 if(_intervals.empty()){
587 return;
588 }
589
590 for (uint32_t i = 0; i < _intervals.size(); i++) {
591 auto interval = &_intervals[i];
592 if(!interval->isSound()){
593 rangesToRemove.insert(i);
594 continue;
595 }
596 for(uint32_t j = i+1; j < _intervals.size(); j++){
597 auto otherInterval = &_intervals[j];
598
599 if(!otherInterval->isSound()){
600 continue;
601 }
602 bool overlap = true;
603
604 if(overlap){
605 for(uint32_t k = 0; k < interval->size(); k++) {
606 if(interval->operator[](k)._lower > otherInterval->operator[](k)._upper || otherInterval->operator[](k)._lower > interval->operator[](k)._upper) {
607 overlap = false;
608 break;
609 }
610 }
611 }
612
613 if(overlap) {
614 for(uint32_t l = 0; l < interval->size(); l++) {
615 interval->operator[](l) |= otherInterval->operator[](l);
616 }
617 rangesToRemove.insert(j);
618 }
619 }
620 }
621 for (auto i = rangesToRemove.rbegin(); i != rangesToRemove.rend(); ++i) {
622 _intervals.erase(_intervals.begin() + *i);
623 }
624 }
625 };
626 }
627}
628
629
630#endif /* INTERVALS_H */
0\ No newline at end of file631\ No newline at end of file
1632
=== added file 'include/PetriEngine/PQL/CTLVisitor.h'
--- include/PetriEngine/PQL/CTLVisitor.h 1970-01-01 00:00:00 +0000
+++ include/PetriEngine/PQL/CTLVisitor.h 2021-04-02 18:07:40 +0000
@@ -0,0 +1,197 @@
1#ifndef VERIFYPN_CTLVISITOR_H
2#define VERIFYPN_CTLVISITOR_H
3
4#include "Visitor.h"
5
6namespace PetriEngine::PQL {
7
8 enum CTLSyntaxType {BOOLEAN, PATH, ERROR = -1};
9
10 class IsCTLVisitor : public Visitor {
11 public:
12 bool isCTL = true;
13
14 protected:
15 void _accept(const NotCondition *element) override;
16
17 void _accept(const AndCondition *element) override;
18
19 void _accept(const OrCondition *element) override;
20
21 void _accept(const LessThanCondition *element) override;
22
23 void _accept(const LessThanOrEqualCondition *element) override;
24
25 void _accept(const EqualCondition *element) override;
26
27 void _accept(const NotEqualCondition *element) override;
28
29 void _accept(const DeadlockCondition *element) override;
30
31 void _accept(const CompareConjunction *element) override;
32
33 void _accept(const UnfoldedUpperBoundsCondition *element) override;
34
35 void _accept(const EFCondition *condition) override;
36
37 void _accept(const EGCondition *condition) override;
38
39 void _accept(const AGCondition *condition) override;
40
41 void _accept(const AFCondition *condition) override;
42
43 void _accept(const EXCondition *condition) override;
44
45 void _accept(const AXCondition *condition) override;
46
47 void _accept(const EUCondition *condition) override;
48
49 void _accept(const AUCondition *condition) override;
50
51 void _accept(const ACondition *condition) override;
52
53 void _accept(const ECondition *condition) override;
54
55 void _accept(const GCondition *condition) override;
56
57 void _accept(const FCondition *condition) override;
58
59 void _accept(const XCondition *condition) override;
60
61 void _accept(const UntilCondition *condition) override;
62
63 void _accept(const UnfoldedFireableCondition *element) override;
64
65 void _accept(const FireableCondition *element) override;
66
67 void _accept(const UpperBoundsCondition *element) override;
68
69 void _accept(const LivenessCondition *element) override;
70
71 void _accept(const KSafeCondition *element) override;
72
73 void _accept(const QuasiLivenessCondition *element) override;
74
75 void _accept(const StableMarkingCondition *element) override;
76
77 void _accept(const BooleanCondition *element) override;
78
79 void _accept(const UnfoldedIdentifierExpr *element) override;
80
81 void _accept(const LiteralExpr *element) override;
82
83 void _accept(const PlusExpr *element) override;
84
85 void _accept(const MultiplyExpr *element) override;
86
87 void _accept(const MinusExpr *element) override;
88
89 void _accept(const SubtractExpr *element) override;
90
91 void _accept(const IdentifierExpr *element) override;
92
93 private:
94 CTLSyntaxType _cur_type;
95
96 void _accept(const LogicalCondition *element);
97
98 void _accept(const CompareCondition *element);
99 };
100
101 class AsCTL : public Visitor {
102 public:
103 Condition_ptr _ctl_query = nullptr;
104 Expr_ptr _expression = nullptr;
105
106 protected:
107 void _accept(const NotCondition *element) override;
108
109 void _accept(const AndCondition *element) override;
110
111 void _accept(const OrCondition *element) override;
112
113 void _accept(const LessThanCondition *element) override;
114
115 void _accept(const LessThanOrEqualCondition *element) override;
116
117 void _accept(const EqualCondition *element) override;
118
119 void _accept(const NotEqualCondition *element) override;
120
121 void _accept(const DeadlockCondition *element) override;
122
123 void _accept(const CompareConjunction *element) override;
124
125 void _accept(const UnfoldedUpperBoundsCondition *element) override;
126
127 void _accept(const EFCondition *condition) override;
128
129 void _accept(const EGCondition *condition) override;
130
131 void _accept(const AGCondition *condition) override;
132
133 void _accept(const AFCondition *condition) override;
134
135 void _accept(const EXCondition *condition) override;
136
137 void _accept(const AXCondition *condition) override;
138
139 void _accept(const EUCondition *condition) override;
140
141 void _accept(const AUCondition *condition) override;
142
143 void _accept(const ACondition *condition) override;
144
145 void _accept(const ECondition *condition) override;
146
147 void _accept(const GCondition *condition) override;
148
149 void _accept(const FCondition *condition) override;
150
151 void _accept(const XCondition *condition) override;
152
153 void _accept(const UntilCondition *condition) override;
154
155 void _accept(const UnfoldedFireableCondition *element) override;
156
157 void _accept(const FireableCondition *element) override;
158
159 void _accept(const UpperBoundsCondition *element) override;
160
161 void _accept(const LivenessCondition *element) override;
162
163 void _accept(const KSafeCondition *element) override;
164
165 void _accept(const QuasiLivenessCondition *element) override;
166
167 void _accept(const StableMarkingCondition *element) override;
168
169 void _accept(const BooleanCondition *element) override;
170
171 void _accept(const UnfoldedIdentifierExpr *element) override;
172
173 void _accept(const LiteralExpr *element) override;
174
175 void _accept(const PlusExpr *element) override;
176
177 void _accept(const MultiplyExpr *element) override;
178
179 void _accept(const MinusExpr *element) override;
180
181 void _accept(const SubtractExpr *element) override;
182
183 void _accept(const IdentifierExpr *element) override;
184
185 private:
186 template<typename T>
187 void _acceptNary(const T *element);
188
189 template<typename T>
190 Expr_ptr copy_narry_expr(const T* el);
191
192 template<typename T>
193 std::shared_ptr<T> copy_compare_condition(const T *element);
194 };
195}
196
197#endif //VERIFYPN_CTLVISITOR_H
0198
=== modified file 'include/PetriEngine/PQL/Contexts.h'
--- include/PetriEngine/PQL/Contexts.h 2020-04-27 14:47:10 +0000
+++ include/PetriEngine/PQL/Contexts.h 2021-04-02 18:07:40 +0000
@@ -38,8 +38,8 @@
38 /** Context provided for context analysis */38 /** Context provided for context analysis */
39 class AnalysisContext {39 class AnalysisContext {
40 protected:40 protected:
41 const unordered_map<std::string, uint32_t>& _placeNames;41 const std::unordered_map<std::string, uint32_t>& _placeNames;
42 const unordered_map<std::string, uint32_t>& _transitionNames;42 const std::unordered_map<std::string, uint32_t>& _transitionNames;
43 const PetriNet* _net;43 const PetriNet* _net;
44 std::vector<ExprError> _errors;44 std::vector<ExprError> _errors;
45 public:45 public:
@@ -176,7 +176,7 @@
176176
177 SimplificationContext(const MarkVal* marking,177 SimplificationContext(const MarkVal* marking,
178 const PetriNet* net, uint32_t queryTimeout, uint32_t lpTimeout,178 const PetriNet* net, uint32_t queryTimeout, uint32_t lpTimeout,
179 LPCache* cache)179 Simplification::LPCache* cache)
180 : _queryTimeout(queryTimeout), _lpTimeout(lpTimeout) {180 : _queryTimeout(queryTimeout), _lpTimeout(lpTimeout) {
181 _negated = false;181 _negated = false;
182 _marking = marking;182 _marking = marking;
@@ -222,8 +222,8 @@
222 }222 }
223 223
224 uint32_t getLpTimeout() const;224 uint32_t getLpTimeout() const;
225 225
226 LPCache* cache() const226 Simplification::LPCache* cache() const
227 {227 {
228 return _cache;228 return _cache;
229 }229 }
@@ -237,7 +237,7 @@
237 const PetriNet* _net;237 const PetriNet* _net;
238 uint32_t _queryTimeout, _lpTimeout;238 uint32_t _queryTimeout, _lpTimeout;
239 std::chrono::high_resolution_clock::time_point _start;239 std::chrono::high_resolution_clock::time_point _start;
240 LPCache* _cache;240 Simplification::LPCache* _cache;
241 mutable glp_prob* _base_lp = nullptr;241 mutable glp_prob* _base_lp = nullptr;
242242
243 glp_prob* buildBase() const;243 glp_prob* buildBase() const;
244244
=== modified file 'include/PetriEngine/PQL/Expressions.h'
--- include/PetriEngine/PQL/Expressions.h 2020-06-02 16:20:24 +0000
+++ include/PetriEngine/PQL/Expressions.h 2021-04-02 18:07:40 +0000
@@ -34,7 +34,7 @@
3434
35namespace PetriEngine {35namespace PetriEngine {
36 namespace PQL {36 namespace PQL {
37 37
38 std::string generateTabs(uint32_t tabs);38 std::string generateTabs(uint32_t tabs);
39 class CompareCondition;39 class CompareCondition;
40 class NotCondition;40 class NotCondition;
@@ -55,19 +55,22 @@
55 for(auto& e : _exprs) sum += e->formulaSize();55 for(auto& e : _exprs) sum += e->formulaSize();
56 return sum + 1;56 return sum + 1;
57 }57 }
58 void toString(std::ostream&) const override;
59 bool placeFree() const override;58 bool placeFree() const override;
60 auto& expressions() const { return _exprs; }59 auto& expressions() const { return _exprs; }
60 size_t operands() const { return _exprs.size(); }
61 const Expr_ptr &operator[](size_t i) const {
62 return _exprs[i];
63 }
61 protected:64 protected:
62 virtual int apply(int v1, int v2) const = 0;65 virtual int apply(int v1, int v2) const = 0;
63 virtual std::string op() const = 0;66 virtual std::string op() const = 0;
64 std::vector<Expr_ptr> _exprs;67 std::vector<Expr_ptr> _exprs;
65 virtual int32_t preOp(const EvaluationContext& context) const;68 virtual int32_t preOp(const EvaluationContext& context) const;
66 };69 };
67 70
68 class PlusExpr;71 class PlusExpr;
69 class MultiplyExpr;72 class MultiplyExpr;
70 73
71 class CommutativeExpr : public NaryExpr74 class CommutativeExpr : public NaryExpr
72 {75 {
73 public:76 public:
@@ -80,7 +83,6 @@
80 for(auto& e : _exprs) sum += e->formulaSize();83 for(auto& e : _exprs) sum += e->formulaSize();
81 return sum + 1;84 return sum + 1;
82 }85 }
83 void toString(std::ostream&) const override;
84 bool placeFree() const override;86 bool placeFree() const override;
85 auto constant() const { return _constant; }87 auto constant() const { return _constant; }
86 auto& places() const { return _ids; }88 auto& places() const { return _ids; }
@@ -98,13 +100,12 @@
98 public:100 public:
99101
100 PlusExpr(std::vector<Expr_ptr>&& exprs, bool tk = false);102 PlusExpr(std::vector<Expr_ptr>&& exprs, bool tk = false);
101 103
102 Expr::Types type() const override;104 Expr::Types type() const override;
103 Member constraint(SimplificationContext& context) const override;105 Member constraint(SimplificationContext& context) const override;
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;
105 bool tk = false;107 bool tk = false;
106 void incr(ReducingSuccessorGenerator& generator) const override;108
107 void decr(ReducingSuccessorGenerator& generator) const override;
108 void visit(Visitor& visitor) const override;109 void visit(Visitor& visitor) const override;
109 protected:110 protected:
110 int apply(int v1, int v2) const override;111 int apply(int v1, int v2) const override;
@@ -122,8 +123,7 @@
122 Expr::Types type() const override;123 Expr::Types type() const override;
123 Member constraint(SimplificationContext& context) const override;124 Member constraint(SimplificationContext& context) const override;
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;
125 void incr(ReducingSuccessorGenerator& generator) const override;126
126 void decr(ReducingSuccessorGenerator& generator) const override;
127 void toBinary(std::ostream&) const override;127 void toBinary(std::ostream&) const override;
128 void visit(Visitor& visitor) const override;128 void visit(Visitor& visitor) const override;
129 protected:129 protected:
@@ -140,8 +140,7 @@
140 Expr::Types type() const override;140 Expr::Types type() const override;
141 Member constraint(SimplificationContext& context) const override;141 Member constraint(SimplificationContext& context) const override;
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;
143 void incr(ReducingSuccessorGenerator& generator) const override;143
144 void decr(ReducingSuccessorGenerator& generator) const override;
145 void visit(Visitor& visitor) const override;144 void visit(Visitor& visitor) const override;
146 protected:145 protected:
147 int apply(int v1, int v2) const override;146 int apply(int v1, int v2) const override;
@@ -158,13 +157,11 @@
158 }157 }
159 void analyze(AnalysisContext& context) override;158 void analyze(AnalysisContext& context) override;
160 int evaluate(const EvaluationContext& context) override;159 int evaluate(const EvaluationContext& context) override;
161 void toString(std::ostream&) const override;
162 Expr::Types type() const override;160 Expr::Types type() const override;
163 Member constraint(SimplificationContext& context) const override;161 Member constraint(SimplificationContext& context) const override;
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;
165 void toBinary(std::ostream&) const override;163 void toBinary(std::ostream&) const override;
166 void incr(ReducingSuccessorGenerator& generator) const override;164
167 void decr(ReducingSuccessorGenerator& generator) const override;
168 void visit(Visitor& visitor) const override;165 void visit(Visitor& visitor) const override;
169 int formulaSize() const override{166 int formulaSize() const override{
170 return _expr->formulaSize() + 1;167 return _expr->formulaSize() + 1;
@@ -181,14 +178,13 @@
181178
182 LiteralExpr(int value) : _value(value) {179 LiteralExpr(int value) : _value(value) {
183 }180 }
181 LiteralExpr(const LiteralExpr&) = default;
184 void analyze(AnalysisContext& context) override;182 void analyze(AnalysisContext& context) override;
185 int evaluate(const EvaluationContext& context) override;183 int evaluate(const EvaluationContext& context) override;
186 void toString(std::ostream&) const override;
187 Expr::Types type() const override;184 Expr::Types type() const override;
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;
189 void toBinary(std::ostream&) const override;186 void toBinary(std::ostream&) const override;
190 void incr(ReducingSuccessorGenerator& generator) const override;187
191 void decr(ReducingSuccessorGenerator& generator) const override;
192 void visit(Visitor& visitor) const override;188 void visit(Visitor& visitor) const override;
193 int formulaSize() const override{189 int formulaSize() const override{
194 return 1;190 return 1;
@@ -206,29 +202,18 @@
206 class IdentifierExpr : public Expr {202 class IdentifierExpr : public Expr {
207 public:203 public:
208 IdentifierExpr(const std::string& name) : _name(name) {}204 IdentifierExpr(const std::string& name) : _name(name) {}
205 IdentifierExpr(const IdentifierExpr&) = default;
209 void analyze(AnalysisContext& context) override;206 void analyze(AnalysisContext& context) override;
210 int evaluate(const EvaluationContext& context) override {207 int evaluate(const EvaluationContext& context) override {
211 return _compiled->evaluate(context);208 return _compiled->evaluate(context);
212 }209 }
213 void toString(std::ostream& os) const override {210 [[nodiscard]] Expr::Types type() const override {
214 if(_compiled)
215 _compiled->toString(os);
216 else
217 os << _name;
218 }
219 Expr::Types type() const override {
220 if(_compiled) return _compiled->type();211 if(_compiled) return _compiled->type();
221 return Expr::IdentifierExpr;212 return Expr::IdentifierExpr;
222 }213 }
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 {
224 _compiled->toXML(os, tabs, tokencount);215 _compiled->toXML(os, tabs, tokencount);
225 }216 }
226 void incr(ReducingSuccessorGenerator& generator) const override {
227 _compiled->incr(generator);
228 }
229 void decr(ReducingSuccessorGenerator& generator) const override {
230 _compiled->decr(generator);
231 }
232 int formulaSize() const override {217 int formulaSize() const override {
233 if(_compiled) return _compiled->formulaSize();218 if(_compiled) return _compiled->formulaSize();
234 return 1;219 return 1;
@@ -241,11 +226,20 @@
241 Member constraint(SimplificationContext& context) const override {226 Member constraint(SimplificationContext& context) const override {
242 return _compiled->constraint(context);227 return _compiled->constraint(context);
243 }228 }
244 229
245 void toBinary(std::ostream& s) const override {230 void toBinary(std::ostream& s) const override {
246 _compiled->toBinary(s);231 _compiled->toBinary(s);
247 }232 }
248 void visit(Visitor& visitor) const override; 233 void visit(Visitor& visitor) const override;
234
235 [[nodiscard]] const std::string &name() const {
236 return _name;
237 }
238
239 [[nodiscard]] const Expr_ptr &compiled() const {
240 return _compiled;
241 }
242
249 private:243 private:
250 std::string _name;244 std::string _name;
251 Expr_ptr _compiled;245 Expr_ptr _compiled;
@@ -257,18 +251,17 @@
257 UnfoldedIdentifierExpr(const std::string& name, int offest)251 UnfoldedIdentifierExpr(const std::string& name, int offest)
258 : _offsetInMarking(offest), _name(name) {252 : _offsetInMarking(offest), _name(name) {
259 }253 }
260 254
261 UnfoldedIdentifierExpr(const std::string& name) : UnfoldedIdentifierExpr(name, -1) {255 UnfoldedIdentifierExpr(const std::string& name) : UnfoldedIdentifierExpr(name, -1) {
262 }256 }
263 257
258 UnfoldedIdentifierExpr(const UnfoldedIdentifierExpr&) = default;
259
264 void analyze(AnalysisContext& context) override;260 void analyze(AnalysisContext& context) override;
265 int evaluate(const EvaluationContext& context) override;261 int evaluate(const EvaluationContext& context) override;
266 void toString(std::ostream&) const override;
267 Expr::Types type() const override;262 Expr::Types type() const override;
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;
269 void toBinary(std::ostream&) const override;264 void toBinary(std::ostream&) const override;
270 void incr(ReducingSuccessorGenerator& generator) const override;
271 void decr(ReducingSuccessorGenerator& generator) const override;
272 int formulaSize() const override{265 int formulaSize() const override{
273 return 1;266 return 1;
274 }267 }
@@ -276,7 +269,7 @@
276 int offset() const {269 int offset() const {
277 return _offsetInMarking;270 return _offsetInMarking;
278 }271 }
279 const std::string& name()272 const std::string& name() const
280 {273 {
281 return _name;274 return _name;
282 }275 }
@@ -311,18 +304,14 @@
311304
312 void toXML(std::ostream& out, uint32_t tabs) const override305 void toXML(std::ostream& out, uint32_t tabs) const override
313 { _compiled->toXML(out, tabs); }306 { _compiled->toXML(out, tabs); }
314 void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override307
315 { _compiled->findInteresting(generator, negated);}308
316 Quantifier getQuantifier() const override309 Quantifier getQuantifier() const override
317 { return _compiled->getQuantifier(); }310 { return _compiled->getQuantifier(); }
318 Path getPath() const override { return _compiled->getPath(); }311 Path getPath() const override { return _compiled->getPath(); }
319 CTLType getQueryType() const override { return _compiled->getQueryType(); }312 CTLType getQueryType() const override { return _compiled->getQueryType(); }
320 bool containsNext() const override { return _compiled->containsNext(); }313 bool containsNext() const override { return _compiled->containsNext(); }
321 bool nestedDeadlock() const override { return _compiled->nestedDeadlock(); }314 bool nestedDeadlock() const override { return _compiled->nestedDeadlock(); }
322#ifdef VERIFYPN_TAR
323 virtual z3::expr encodeSat(const PetriNet& net, z3::context& context, std::vector<int32_t>& uses, std::vector<bool>& incremented) const
324 { return _compiled->encodeSat(net, context, uses, incremented); }
325#endif
326 int formulaSize() const override{315 int formulaSize() const override{
327 return _compiled->formulaSize();316 return _compiled->formulaSize();
328 }317 }
@@ -344,14 +333,13 @@
344 if (_compiled) _compiled->analyze(context);333 if (_compiled) _compiled->analyze(context);
345 else _analyze(context);334 else _analyze(context);
346 }335 }
347 void toString(std::ostream &out) const {336 public:
348 if (_compiled) _compiled->toString(out);337 const Condition_ptr &getCompiled() const {
349 else _toString(out);338 return _compiled;
350 }339 }
351340
352 protected:341 protected:
353 virtual void _analyze(AnalysisContext& context) = 0;342 virtual void _analyze(AnalysisContext& context) = 0;
354 virtual void _toString(std::ostream& out) const = 0;
355 virtual Condition_ptr clone() = 0;343 virtual Condition_ptr clone() = 0;
356 Condition_ptr _compiled = nullptr;344 Condition_ptr _compiled = nullptr;
357 };345 };
@@ -373,7 +361,6 @@
373 Result evalAndSet(const EvaluationContext& context) override;361 Result evalAndSet(const EvaluationContext& context) override;
374 void visit(Visitor&) const override;362 void visit(Visitor&) const override;
375 uint32_t distance(DistanceContext& context) const override;363 uint32_t distance(DistanceContext& context) const override;
376 void toString(std::ostream&) const override;
377 void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;364 void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
378 Retval simplify(SimplificationContext& context) const override;365 Retval simplify(SimplificationContext& context) const override;
379 bool isReachability(uint32_t depth) const override;366 bool isReachability(uint32_t depth) const override;
@@ -381,7 +368,7 @@
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;
382 void toXML(std::ostream&, uint32_t tabs) const override;369 void toXML(std::ostream&, uint32_t tabs) const override;
383 void toBinary(std::ostream&) const override;370 void toBinary(std::ostream&) const override;
384 void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;371
385 Quantifier getQuantifier() const override { return Quantifier::NEG; }372 Quantifier getQuantifier() const override { return Quantifier::NEG; }
386 Path getPath() const override { return Path::pError; }373 Path getPath() const override { return Path::pError; }
387 CTLType getQueryType() const override { return CTLType::LOPERATOR; }374 CTLType getQueryType() const override { return CTLType::LOPERATOR; }
@@ -393,18 +380,18 @@
393 Condition_ptr _cond;380 Condition_ptr _cond;
394 bool _temporal = false;381 bool _temporal = false;
395 };382 };
396 383
397 384
398 /******************** TEMPORAL OPERATORS ********************/ 385 /******************** TEMPORAL OPERATORS ********************/
399 386
400 class QuantifierCondition : public Condition387 class QuantifierCondition : public Condition
401 {388 {
402 public:389 public:
403 virtual bool isTemporal() const override { return true;}390 bool isTemporal() const override { return true;}
404 CTLType getQueryType() const override { return CTLType::PATHQEURY; }391 CTLType getQueryType() const override { return CTLType::PATHQEURY; }
405 virtual const Condition_ptr& operator[] (size_t i) const = 0;392 virtual const Condition_ptr& operator[] (size_t i) const = 0;
406 };393 };
407 394
408 class SimpleQuantifierCondition : public QuantifierCondition {395 class SimpleQuantifierCondition : public QuantifierCondition {
409 public:396 public:
410 SimpleQuantifierCondition(const Condition_ptr cond) {397 SimpleQuantifierCondition(const Condition_ptr cond) {
@@ -414,24 +401,174 @@
414 int formulaSize() const override{401 int formulaSize() const override{
415 return _cond->formulaSize() + 1;402 return _cond->formulaSize() + 1;
416 }403 }
417 404
418 void analyze(AnalysisContext& context) override;405 void analyze(AnalysisContext& context) override;
419 Result evaluate(const EvaluationContext& context) override;406 Result evaluate(const EvaluationContext& context) override;
420 Result evalAndSet(const EvaluationContext& context) override;407 Result evalAndSet(const EvaluationContext& context) override;
421 void toString(std::ostream&) const override;
422 void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;408 void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
423 void toBinary(std::ostream& out) const override;409 void toBinary(std::ostream& out) const override;
424 void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;410
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;}
426 virtual bool containsNext() const override { return _cond->containsNext(); }412 bool containsNext() const override { return _cond->containsNext(); }
427 bool nestedDeadlock() const override { return _cond->nestedDeadlock(); }413 bool nestedDeadlock() const override { return _cond->nestedDeadlock(); }
428 private:414 private:
429 virtual std::string op() const = 0;415 virtual std::string op() const = 0;
430 416
431 protected:417 protected:
432 Condition_ptr _cond;418 Condition_ptr _cond;
433 };419 };
434 420
421 class ECondition : public SimpleQuantifierCondition {
422 public:
423 using SimpleQuantifierCondition::SimpleQuantifierCondition;
424
425 Result evaluate(const EvaluationContext& context) override;
426
427 Retval simplify(SimplificationContext& context) const override;
428
429 bool isReachability(uint32_t depth) const override;
430 Condition_ptr prepareForReachability(bool negated) const override;
431 Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
432 void toXML(std::ostream&, uint32_t tabs) const override;
433 Quantifier getQuantifier() const override { return Quantifier::E; }
434 Path getPath() const override { return Path::pError; }
435 uint32_t distance(DistanceContext& context) const override {
436 // TODO implement
437 assert(false); std::cerr << "TODO implement" << std::endl; exit(0);
438 }
439 bool isLoopSensitive() const override {
440 // Other LTL Loop sensitivity depend on the outermost quantifier being an A,
441 // so if it is an E we disable loop sensitive reductions.
442 return true;
443 }
444 void visit(Visitor&) const override;
445 private:
446 std::string op() const override;
447 };
448
449 class ACondition : public SimpleQuantifierCondition {
450 public:
451 using SimpleQuantifierCondition::SimpleQuantifierCondition;
452
453 Result evaluate(const EvaluationContext& context) override;
454
455 Retval simplify(SimplificationContext& context) const override;
456 bool isReachability(uint32_t depth) const override;
457 Condition_ptr prepareForReachability(bool negated) const override;
458 Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
459 void toXML(std::ostream&, uint32_t tabs) const override;
460 Quantifier getQuantifier() const override { return Quantifier::A; }
461 Path getPath() const override { return Path::pError; }
462 uint32_t distance(DistanceContext& context) const override {
463 uint32_t retval = _cond->distance(context);
464 return retval;
465 }
466 void visit(Visitor&) const override;
467
468 private:
469 std::string op() const override;
470 };
471
472 class GCondition : public SimpleQuantifierCondition {
473 public:
474 using SimpleQuantifierCondition::SimpleQuantifierCondition;
475
476 Result evaluate(const EvaluationContext &context) override;
477
478 bool isReachability(uint32_t depth) const override {
479 // This could potentially be a reachability formula if the parent is an A.
480 // This case is however already handled by ACondition.
481 return false;
482 }
483
484 Condition_ptr prepareForReachability(bool negated) const override {
485 // TODO implement
486 assert(false);
487 std::cerr << "TODO implement" << std::endl;
488 exit(0);
489 }
490
491 Condition_ptr
492 pushNegation(negstat_t &, const EvaluationContext &context, bool nested, bool negated, bool initrw) override;
493
494 Retval simplify(SimplificationContext &context) const override;
495
496 void toXML(std::ostream &, uint32_t tabs) const override;
497
498 Quantifier getQuantifier() const override { return Quantifier::EMPTY; }
499
500 Path getPath() const override { return Path::G; }
501
502 uint32_t distance(DistanceContext &context) const override {
503 context.negate();
504 uint32_t retval = _cond->distance(context);
505 context.negate();
506 return retval;
507 }
508
509 bool isLoopSensitive() const override { return true; }
510
511 void visit(Visitor &) const override;
512
513 private:
514 std::string op() const override;
515 };
516
517 class FCondition : public SimpleQuantifierCondition {
518 public:
519 using SimpleQuantifierCondition::SimpleQuantifierCondition;
520
521 Result evaluate(const EvaluationContext& context) override;
522
523 Retval simplify(SimplificationContext& context) const override;
524 bool isReachability(uint32_t depth) const override {
525 // This could potentially be a reachability formula if the parent is an E.
526 // This case is however already handled by ECondition.
527 return false;
528 }
529 Condition_ptr prepareForReachability(bool negated) const override {
530 // TODO implement
531 assert(false); std::cerr << "TODO implement" << std::endl; exit(0);
532 }
533 Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
534 void toXML(std::ostream&, uint32_t tabs) const override;
535 Quantifier getQuantifier() const override { return Quantifier::EMPTY; }
536 Path getPath() const override { return Path::F; }
537 uint32_t distance(DistanceContext& context) const override {
538 return _cond->distance(context);
539 }
540 bool isLoopSensitive() const override { return true; }
541 void visit(Visitor&) const override;
542 private:
543 std::string op() const override;
544 };
545
546 class XCondition : public SimpleQuantifierCondition {
547 public:
548 using SimpleQuantifierCondition::SimpleQuantifierCondition;
549
550 bool isReachability(uint32_t depth) const override {
551 return false;
552 }
553 Condition_ptr prepareForReachability(bool negated) const override {
554 // TODO implement
555 assert(false); std::cerr << "TODO implement" << std::endl; exit(0);
556 }
557 Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
558 Retval simplify(SimplificationContext& context) const override;
559 void toXML(std::ostream&, uint32_t tabs) const override;
560 Quantifier getQuantifier() const override { return Quantifier::EMPTY; }
561 Path getPath() const override { return Path::X; }
562 uint32_t distance(DistanceContext& context) const override {
563 return _cond->distance(context);
564 }
565 bool containsNext() const override { return true; }
566 bool isLoopSensitive() const override { return true; }
567 void visit(Visitor&) const override;
568 private:
569 std::string op() const override;
570 };
571
435 class EXCondition : public SimpleQuantifierCondition {572 class EXCondition : public SimpleQuantifierCondition {
436 public:573 public:
437 using SimpleQuantifierCondition::SimpleQuantifierCondition;574 using SimpleQuantifierCondition::SimpleQuantifierCondition;
@@ -443,24 +580,24 @@
443 Quantifier getQuantifier() const override { return Quantifier::E; }580 Quantifier getQuantifier() const override { return Quantifier::E; }
444 Path getPath() const override { return Path::X; }581 Path getPath() const override { return Path::X; }
445 uint32_t distance(DistanceContext& context) const override;582 uint32_t distance(DistanceContext& context) const override;
446 bool containsNext() const override { return true; } 583 bool containsNext() const override { return true; }
447 virtual bool isLoopSensitive() const override { return true; }584 virtual bool isLoopSensitive() const override { return true; }
448 void visit(Visitor&) const override;585 void visit(Visitor&) const override;
449 private:586 private:
450 std::string op() const override;587 std::string op() const override;
451 };588 };
452 589
453 class EGCondition : public SimpleQuantifierCondition {590 class EGCondition : public SimpleQuantifierCondition {
454 public:591 public:
455 using SimpleQuantifierCondition::SimpleQuantifierCondition;592 using SimpleQuantifierCondition::SimpleQuantifierCondition;
456 593
457 Retval simplify(SimplificationContext& context) const override;594 Retval simplify(SimplificationContext& context) const override;
458 bool isReachability(uint32_t depth) const override;595 bool isReachability(uint32_t depth) const override;
459 Condition_ptr prepareForReachability(bool negated) const override;596 Condition_ptr prepareForReachability(bool negated) const override;
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;
461 void toXML(std::ostream&, uint32_t tabs) const override;598 void toXML(std::ostream&, uint32_t tabs) const override;
462 Quantifier getQuantifier() const override { return Quantifier::E; }599 Quantifier getQuantifier() const override { return Quantifier::E; }
463 Path getPath() const override { return Path::G; } 600 Path getPath() const override { return Path::G; }
464 uint32_t distance(DistanceContext& context) const override;601 uint32_t distance(DistanceContext& context) const override;
465 Result evaluate(const EvaluationContext& context) override;602 Result evaluate(const EvaluationContext& context) override;
466 Result evalAndSet(const EvaluationContext& context) override;603 Result evalAndSet(const EvaluationContext& context) override;
@@ -469,18 +606,18 @@
469 private:606 private:
470 std::string op() const override;607 std::string op() const override;
471 };608 };
472 609
473 class EFCondition : public SimpleQuantifierCondition {610 class EFCondition : public SimpleQuantifierCondition {
474 public:611 public:
475 using SimpleQuantifierCondition::SimpleQuantifierCondition;612 using SimpleQuantifierCondition::SimpleQuantifierCondition;
476 613
477 Retval simplify(SimplificationContext& context) const override;614 Retval simplify(SimplificationContext& context) const override;
478 bool isReachability(uint32_t depth) const override;615 bool isReachability(uint32_t depth) const override;
479 Condition_ptr prepareForReachability(bool negated) const override;616 Condition_ptr prepareForReachability(bool negated) const override;
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;
481 void toXML(std::ostream&, uint32_t tabs) const override;618 void toXML(std::ostream&, uint32_t tabs) const override;
482 Quantifier getQuantifier() const override { return Quantifier::E; }619 Quantifier getQuantifier() const override { return Quantifier::E; }
483 Path getPath() const override { return Path::F; } 620 Path getPath() const override { return Path::F; }
484 uint32_t distance(DistanceContext& context) const override;621 uint32_t distance(DistanceContext& context) const override;
485 Result evaluate(const EvaluationContext& context) override;622 Result evaluate(const EvaluationContext& context) override;
486 Result evalAndSet(const EvaluationContext& context) override;623 Result evalAndSet(const EvaluationContext& context) override;
@@ -506,7 +643,7 @@
506 private:643 private:
507 std::string op() const override;644 std::string op() const override;
508 };645 };
509 646
510 class AGCondition : public SimpleQuantifierCondition {647 class AGCondition : public SimpleQuantifierCondition {
511 public:648 public:
512 using SimpleQuantifierCondition::SimpleQuantifierCondition;649 using SimpleQuantifierCondition::SimpleQuantifierCondition;
@@ -516,7 +653,7 @@
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;
517 void toXML(std::ostream&, uint32_t tabs) const override;654 void toXML(std::ostream&, uint32_t tabs) const override;
518 Quantifier getQuantifier() const override { return Quantifier::A; }655 Quantifier getQuantifier() const override { return Quantifier::A; }
519 Path getPath() const override { return Path::G; } 656 Path getPath() const override { return Path::G; }
520 uint32_t distance(DistanceContext& context) const override;657 uint32_t distance(DistanceContext& context) const override;
521 Result evaluate(const EvaluationContext& context) override;658 Result evaluate(const EvaluationContext& context) override;
522 Result evalAndSet(const EvaluationContext& context) override;659 Result evalAndSet(const EvaluationContext& context) override;
@@ -524,7 +661,7 @@
524 private:661 private:
525 std::string op() const override;662 std::string op() const override;
526 };663 };
527 664
528 class AFCondition : public SimpleQuantifierCondition {665 class AFCondition : public SimpleQuantifierCondition {
529 public:666 public:
530 using SimpleQuantifierCondition::SimpleQuantifierCondition;667 using SimpleQuantifierCondition::SimpleQuantifierCondition;
@@ -534,7 +671,7 @@
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;
535 void toXML(std::ostream&, uint32_t tabs) const override;672 void toXML(std::ostream&, uint32_t tabs) const override;
536 Quantifier getQuantifier() const override { return Quantifier::A; }673 Quantifier getQuantifier() const override { return Quantifier::A; }
537 Path getPath() const override { return Path::F; } 674 Path getPath() const override { return Path::F; }
538 uint32_t distance(DistanceContext& context) const override;675 uint32_t distance(DistanceContext& context) const override;
539 Result evaluate(const EvaluationContext& context) override;676 Result evaluate(const EvaluationContext& context) override;
540 Result evalAndSet(const EvaluationContext& context) override;677 Result evalAndSet(const EvaluationContext& context) override;
@@ -542,8 +679,8 @@
542 virtual bool isLoopSensitive() const override { return true; }679 virtual bool isLoopSensitive() const override { return true; }
543 private:680 private:
544 std::string op() const override;681 std::string op() const override;
545 }; 682 };
546 683
547 class UntilCondition : public QuantifierCondition {684 class UntilCondition : public QuantifierCondition {
548 public:685 public:
549 UntilCondition(const Condition_ptr cond1, const Condition_ptr cond2) {686 UntilCondition(const Condition_ptr cond1, const Condition_ptr cond2) {
@@ -554,50 +691,59 @@
554 int formulaSize() const override{691 int formulaSize() const override{
555 return _cond1->formulaSize() + _cond2->formulaSize() + 1;692 return _cond1->formulaSize() + _cond2->formulaSize() + 1;
556 }693 }
557 694
558 void analyze(AnalysisContext& context) override;695 void analyze(AnalysisContext& context) override;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches