5#ifndef LINE_API_SPN_SPN_REACHGRAPH_H
6#define LINE_API_SPN_SPN_REACHGRAPH_H
47 std::vector<std::vector<long long>>
M;
48 std::vector<std::vector<std::size_t>>
E;
52 std::vector<long long>
m0;
59 for (std::size_t pp = 0; pp < net.places.size(); ++pp) {
60 const std::size_t nd = net.places[pp];
61 const std::size_t ist =
sn.nodes[nd - 1].station;
62 if (ist >= 1 && ist <=
sn.stations.size() &&
65 caller +
": place " +
sn.nodes[nd - 1].name +
66 " is a QUEUEING place: its embedded service is state "
67 "that the marking does not carry");
71inline SpnReachGraph spn_explore(
const SpnNet& net,
const std::vector<long long>& m0,
72 std::size_t maxstates) {
73 const std::size_t n = net.n;
76 g.transitions = net.transitions;
79 g.status =
"complete";
80 g.unboundedlevels.assign(n,
false);
81 std::vector<std::size_t> parent;
82 std::map<std::vector<long long>, std::size_t> key;
86 const bool monotone = net.monotone();
87 for (std::size_t head = 0; head < g.M.size() && g.status ==
"complete"; ++head) {
88 const std::vector<long long> m = g.M[head];
89 const std::vector<bool> f = net.fireable(m);
90 for (std::size_t e = 0; e < net.E; ++e) {
92 std::vector<long long> mp(n);
93 for (std::size_t l = 0; l < n; ++l) mp[l] = m[l] - net.pre[l][e] + net.post[l][e];
94 const std::map<std::vector<long long>, std::size_t>::const_iterator it = key.find(mp);
95 if (it != key.end()) {
96 g.E.push_back(std::vector<std::size_t>{head, it->second, e});
99 if (g.M.size() >= maxstates) {
103 const std::size_t
id = g.M.size();
105 parent.push_back(head);
107 g.E.push_back(std::vector<std::size_t>{head, id, e});
109 std::size_t a = head;
111 bool le =
true, lt =
false;
112 for (std::size_t l = 0; l < n; ++l) {
113 le = le && g.M[a][l] <= mp[l];
114 lt = lt || g.M[a][l] < mp[l];
117 for (std::size_t l = 0; l < n; ++l) g.unboundedlevels[l] = mp[l] > g.M[a][l];
118 g.status =
"unbounded";
124 if (g.status !=
"complete")
break;
128 g.tangible.assign(g.M.size(),
true);
129 for (std::size_t i = 0; i < g.M.size(); ++i) {
130 const std::vector<bool> f = net.fireable(g.M[i]);
131 for (std::size_t e = 0; e < net.E; ++e)
132 if (f[e] && net.immediate[e]) g.tangible[i] =
false;
146 const std::vector<double>& init = std::vector<double>(),
147 std::size_t maxstates = 0) {
148 const detail::SpnNet net = detail::spn_build_net(
sn,
"spn_reachgraph");
149 detail::spn_check_places(
sn, net,
"spn_reachgraph");
150 const std::vector<long long> m0 = detail::spn_initmarking(
sn, net, init,
"spn_reachgraph");
UnsupportedError(const std::string &what)
A network plus its refreshed NetworkStruct.
constexpr std::size_t SPN_REACH_MAXSTATES
Default cap on the number of explored markings.
SpnReachGraph spn_reachgraph(const qn::NetworkStruct< T > &sn, const std::vector< double > &init=std::vector< double >(), std::size_t maxstates=0)
Conservation laws of a layered queueing network, enumerated from its structure.
Shared net model of the Petri-net property functions (spn_tinvariants, spn_siphons,...
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
std::vector< bool > unboundedlevels
std::vector< std::size_t > modes
0-based mode index of each event
std::vector< std::size_t > places
1-based node indices, in level order
std::vector< long long > m0
std::vector< std::size_t > transitions
1-based node index of each event
std::string status
complete, cap or unbounded
std::vector< std::vector< std::size_t > > E
edges (from, to, event), 0-based
std::vector< std::vector< long long > > M
markings, discovery order
std::vector< bool > tangible