LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
spn_siphons.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_SPN_SPN_SIPHONS_H
6#define LINE_API_SPN_SPN_SIPHONS_H
7
8/**
9 * @file
10 * @ingroup api_spn
11 * All minimal siphons of a stochastic Petri net and Commoner's condition
12 * (Murata 1989, sec. VI-A; Silva, Teruel and Colom 1998). A siphon S is a
13 * level set with *S contained in S*: once S is empty it stays empty. The
14 * enumeration is the branch and bound of Cordone, Ferrarini and Piroddi
15 * (2005): a node (I, O) asks for a minimal siphon containing I and avoiding
16 * O, prunes with the largest siphon inside the complement of O (a fixpoint
17 * that drops every level fed by an event taking nothing from the set), and
18 * branches on the first level of that siphon outside I. A net can hold
19 * exponentially many minimal siphons, so time and output are exponential in
20 * the number of levels in the worst case; each node costs O(n^2 E).
21 *
22 * S lists the siphons as 0/1 rows over the levels, sorted by size and then
23 * by their level indices. trapped(i) is true when the largest trap inside
24 * siphon i is marked at m0; commoner = all(trapped). The check is
25 * structural: inhibitor arcs, priorities and the timed/immediate split are
26 * ignored. MATLAB twin: matlab/src/api/spn/spn_siphons.m.
27 */
28
29#include <cstddef>
30#include <vector>
31
33
34namespace line {
35namespace spn {
36
37struct SpnSiphons {
38 std::vector<std::size_t> places; ///< 1-based node indices, in level order
39 std::vector<std::vector<int>> S; ///< one minimal siphon per row (0/1 over levels)
40 std::vector<bool> trapped; ///< largest trap inside S(i) is marked at m0
41 bool commoner = true; ///< every minimal siphon holds a marked trap
42 std::vector<long long> m0;
43};
44
45template <class T>
47 const std::vector<double>& init = std::vector<double>()) {
48 const detail::SpnNet net = detail::spn_build_net(sn, "spn_siphons");
49 SpnSiphons out;
50 out.places = net.places;
51 out.m0 = detail::spn_initmarking(sn, net, init, "spn_siphons");
52 const std::vector<std::vector<bool>> L = detail::spn_minsiphons(net.pre, net.post);
53 out.S = detail::spn_sets_to_int(L);
54 out.trapped.assign(L.size(), false);
55 for (std::size_t i = 0; i < L.size(); ++i) {
56 const std::vector<bool> Q = detail::spn_maxsiphon(net.post, net.pre, L[i]);
57 for (std::size_t l = 0; l < net.n; ++l)
58 if (Q[l] && out.m0[l] > 0) out.trapped[i] = true;
59 out.commoner = out.commoner && out.trapped[i];
60 }
61 return out;
62}
63
64} // namespace spn
65} // namespace line
66
67#endif // LINE_API_SPN_SPN_SIPHONS_H
A network plus its refreshed NetworkStruct.
SpnSiphons spn_siphons(const qn::NetworkStruct< T > &sn, const std::vector< double > &init=std::vector< double >())
Definition spn_siphons.h:46
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
Shared net model of the Petri-net property functions (spn_tinvariants, spn_siphons,...
std::vector< bool > trapped
largest trap inside S(i) is marked at m0
Definition spn_siphons.h:40
bool commoner
every minimal siphon holds a marked trap
Definition spn_siphons.h:41
std::vector< std::size_t > places
1-based node indices, in level order
Definition spn_siphons.h:38
std::vector< long long > m0
Definition spn_siphons.h:42
std::vector< std::vector< int > > S
one minimal siphon per row (0/1 over levels)
Definition spn_siphons.h:39