5#ifndef LINE_API_SPN_SPN_STRUCTPROPS_H
6#define LINE_API_SPN_SPN_STRUCTPROPS_H
54inline std::vector<bool> spn_cover(
const std::vector<std::vector<long long>>& A, std::size_t N,
57 for (std::size_t j = 0; j < N; ++j) {
63 for (std::size_t i = 0; i < A.size(); ++i) {
64 for (std::size_t j = 0; j < N; ++j)
65 if (A[i][j] != 0) lpm.
row_add(j,
static_cast<double>(A[i][j]));
68 for (std::size_t j = 0; j < N; ++j) {
74 bool fin = sol.
ok() && sol.
x.size() == 2 * N;
75 for (std::size_t j = 0; fin && j < 2 * N; ++j) fin = std::isfinite(sol.
x[j]);
78 "spn_structprops: the covering linear program returned no solution, "
79 "although z = 0 is feasible");
80 std::vector<bool> cov(N);
81 for (std::size_t j = 0; j < N; ++j) cov[j] = sol.
x[N + j] > 0.5;
85inline bool spn_all(
const std::vector<bool>& v) {
86 for (std::size_t i = 0; i < v.size(); ++i)
87 if (!v[i])
return false;
95 const detail::SpnNet net = detail::spn_build_net(
sn,
"spn_structprops");
96 const std::size_t n = net.n, E = net.E;
97 const std::vector<std::vector<long long>> Ct = detail::spn_transpose(net.C, E);
98 std::vector<std::vector<long long>> negC(n, std::vector<long long>(E));
99 for (std::size_t l = 0; l < n; ++l)
100 for (std::size_t e = 0; e < E; ++e) negC[l][e] = -net.C[l][e];
104 sp.
modes = net.modes;
114 bool ordinary =
true;
115 std::vector<std::size_t> intake(E, 0), outfeed(E, 0), lout(n, 0), lin(n, 0);
116 for (std::size_t l = 0; l < n; ++l)
117 for (std::size_t e = 0; e < E; ++e) {
118 if (net.pre[l][e] > 0) {
119 ordinary = ordinary && net.pre[l][e] == 1;
123 if (net.post[l][e] > 0) {
124 ordinary = ordinary && net.post[l][e] == 1;
129 bool smach = ordinary, mgraph = ordinary;
130 for (std::size_t e = 0; e < E; ++e) smach = smach && intake[e] == 1 && outfeed[e] == 1;
131 for (std::size_t l = 0; l < n; ++l) mgraph = mgraph && lout[l] == 1 && lin[l] == 1;
132 bool fc = ordinary, efc = ordinary, ac = ordinary;
133 for (std::size_t p = 0; p < n; ++p) {
135 for (std::size_t e = 0; e < E; ++e)
136 if (net.pre[p][e] > 0 && intake[e] != 1) fc =
false;
137 for (std::size_t q = 0; q < n; ++q) {
138 bool share =
false, aonly =
false, bonly =
false;
139 for (std::size_t e = 0; e < E; ++e) {
140 const bool a = net.pre[p][e] > 0, b = net.pre[q][e] > 0;
141 share = share || (a && b);
142 aonly = aonly || (a && !b);
143 bonly = bonly || (b && !a);
146 if (aonly || bonly) efc =
false;
147 if (aonly && bonly) ac =
false;
NumericError(const std::string &what)
Sparse LP in the natural form, with per-variable bounds.
void set_maximize(bool m)
true to maximize c'x (the default), false to minimize.
void emit(LpSense sense, const T &rhs)
Emit the accumulated row with the given relation and right-hand side.
void set_cost(std::size_t j, const T &v)
void set_bounds(std::size_t j, const T &lo, const T &hi)
void row_add(std::size_t j, const T &v)
row(j) += v, the accumulation the MATLAB reference performs.
A network plus its refreshed NetworkStruct.
A sparse LP backend for line::lp::LpModel, on HiGHS (MIT).
LpSolution< T > lp_solve(const LpModel< T > &model, std::size_t dense_max_cols=512)
Solve, choosing the backend by arithmetic and size.
SpnStructProps spn_structprops(const qn::NetworkStruct< T > &sn)
Conservation laws of a layered queueing network, enumerated from its structure.
Templated primal simplex with Bland's rule.
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< T > x
primal solution in the ORIGINAL variable space
std::vector< bool > repetitiveevents
std::vector< bool > boundedlevels
std::vector< bool > conservedlevels
std::vector< bool > consistentevents
std::vector< std::size_t > transitions
1-based node index of each event
std::vector< std::size_t > places
1-based node indices, in level order
std::vector< std::size_t > modes
0-based mode index of each event
std::vector< std::string > ignored
inhibitor, immediate, priority (when used)