LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
ldes_spn.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_SOLVERS_LDES_LDES_SPN_H
6
#define LINE_SOLVERS_LDES_LDES_SPN_H
7
8
/**
9
* @file
10
* @ingroup line_solvers
11
* The Petri-net layer of the native LDES engine: Places and Transitions.
12
*
13
* A PLACE holds tokens per class and a TRANSITION moves them. A mode of a
14
* transition is ENABLED when every input place holds at least its enabling
15
* count and no inhibiting count is met; firing consumes the enabling tokens and
16
* deposits the firing counts.
17
*
18
* IMMEDIATE MODES FIRE BEFORE ANY TIMED ONE, and among themselves in priority
19
* order, weighted at equal priority. That is not an optimization: an immediate
20
* transition takes zero time, so a marking that enables one is not a marking
21
* the net ever rests in, and letting a timed mode fire from it would visit a
22
* state the model does not have.
23
*
24
* THE FIRING RATE MAY DEPEND ON THE MARKING. `firingdep` multiplies the mode's
25
* nominal rate by g(marking), and the clock has to be RESAMPLED whenever the
26
* marking changes, not merely scaled: an exponential clock drawn under one
27
* rate and left to run carries the old rate into the new marking.
28
*/
29
30
#include <algorithm>
31
#include <cstddef>
32
#include <functional>
33
#include <limits>
34
#include <vector>
35
36
#include "
line/lang/lang_types.h
"
37
38
namespace
line
{
39
namespace
ldes
{
40
namespace
engine
{
41
42
/**
43
* One mode of a transition, resolved to what the event loop needs.
44
*
45
* THE ARC VECTORS ARE INDEXED BY (place slot, class), flattened `p * K + r`,
46
* and the marking handed to `spn_enabled` and `spn_fire` uses the same layout.
47
* A Petri net whose arcs carry a class is a COLOURED net and its behaviour is
48
* not that of the class-summed one: a mode needing two Class1 tokens must not
49
* be enabled by two Class2 tokens sitting at the same place.
50
*/
51
struct
SpnMode
{
52
std::vector<double>
enabling
;
///< per (place, class), tokens required
53
std::vector<double>
inhibiting
;
///< per (place, class), tokens that block (inf = never)
54
std::vector<double>
firing
;
///< per (place, class), tokens moved on a firing
55
double
servers
= 1.0;
56
double
priority
= 0.0;
57
double
weight
= 1.0;
58
bool
immediate
=
false
;
59
double
rate
= 1.0;
///< nominal firing rate of a timed mode
60
std::function<double(
const
std::vector<double>&)>
dep
;
///< marking multiplier
61
};
62
63
/** One Transition node. */
64
struct
SpnTransition
{
65
std::size_t
node
= 0;
66
std::vector<SpnMode>
modes
;
67
std::vector<std::size_t>
places
;
///< the place NODES its modes reference, in order
68
std::vector<double>
fired
;
///< per mode
69
};
70
71
/**
72
* True when `m` is enabled by the marking `tok`, which is indexed the same way
73
* as the mode's own vectors -- (place slot, class), flattened.
74
*
75
* An INHIBITING arc is a bound, not a requirement: the mode is blocked once the
76
* place reaches the count IN THAT CLASS, and an infinite count never blocks.
77
*/
78
inline
bool
spn_enabled
(
const
SpnMode
& m,
const
std::vector<double>& tok) {
79
for
(std::size_t p = 0; p < m.
enabling
.size() && p < tok.size(); ++p)
80
if
(tok[p] < m.
enabling
[p])
return
false
;
81
for
(std::size_t p = 0; p < m.
inhibiting
.size() && p < tok.size(); ++p)
82
if
(std::isfinite(m.
inhibiting
[p]) && m.
inhibiting
[p] > 0.0 && tok[p] >= m.
inhibiting
[p])
83
return
false
;
84
return
true
;
85
}
86
87
/** The rate of a timed mode under the current marking. */
88
inline
double
spn_rate
(
const
SpnMode
& m,
const
std::vector<double>& tok) {
89
double
r = m.
rate
;
90
if
(m.
dep
) {
91
const
double
g = m.
dep
(tok);
92
r *= (g > 0.0) ? g : 0.0;
93
}
94
return
r;
95
}
96
97
/** Move the tokens of one firing: consume the enabling counts, deposit the firing ones. */
98
inline
void
spn_fire
(
const
SpnMode
& m, std::vector<double>& tok) {
99
for
(std::size_t p = 0; p < m.
enabling
.size() && p < tok.size(); ++p)
100
tok[p] -= m.
enabling
[p];
101
for
(std::size_t p = 0; p < m.
firing
.size() && p < tok.size(); ++p) tok[p] += m.
firing
[p];
102
}
103
104
/**
105
* Pick among the enabled IMMEDIATE modes: the highest priority first (lowest
106
* value), then weighted at random among the ties. Returns -1 when none is
107
* enabled.
108
*/
109
inline
int
spn_pick_immediate
(
const
std::vector<SpnMode>& modes,
const
std::vector<double>& tok,
110
double
u) {
111
double
best_prio = std::numeric_limits<double>::infinity();
112
for
(
const
SpnMode
& m : modes)
113
if
(m.immediate &&
spn_enabled
(m, tok)) best_prio = std::min(best_prio, m.priority);
114
if
(!std::isfinite(best_prio))
return
-1;
115
double
total = 0.0;
116
for
(
const
SpnMode
& m : modes)
117
if
(m.immediate && m.priority == best_prio &&
spn_enabled
(m, tok)) total += m.weight;
118
if
(!(total > 0.0)) {
119
for
(std::size_t k = 0; k < modes.size(); ++k)
120
if
(modes[k].immediate && modes[k].priority == best_prio &&
spn_enabled
(modes[k], tok))
121
return
static_cast<
int
>
(k);
122
return
-1;
123
}
124
double
acc = 0.0;
125
const
double
x = u * total;
126
for
(std::size_t k = 0; k < modes.size(); ++k)
127
if
(modes[k].immediate && modes[k].priority == best_prio &&
spn_enabled
(modes[k], tok)) {
128
acc += modes[k].weight;
129
if
(x < acc)
return
static_cast<
int
>
(k);
130
}
131
return
-1;
132
}
133
134
}
// namespace engine
135
}
// namespace ldes
136
}
// namespace line
137
138
#endif
// LINE_SOLVERS_LDES_LDES_SPN_H
lang_types.h
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
line::ldes::engine
Definition
ldes_busyperiod.h:42
line::ldes::engine::spn_rate
double spn_rate(const SpnMode &m, const std::vector< double > &tok)
The rate of a timed mode under the current marking.
Definition
ldes_spn.h:88
line::ldes::engine::spn_pick_immediate
int spn_pick_immediate(const std::vector< SpnMode > &modes, const std::vector< double > &tok, double u)
Pick among the enabled IMMEDIATE modes: the highest priority first (lowest value),...
Definition
ldes_spn.h:109
line::ldes::engine::spn_enabled
bool spn_enabled(const SpnMode &m, const std::vector< double > &tok)
True when m is enabled by the marking tok, which is indexed the same way as the mode's own vectors – ...
Definition
ldes_spn.h:78
line::ldes::engine::spn_fire
void spn_fire(const SpnMode &m, std::vector< double > &tok)
Move the tokens of one firing: consume the enabling counts, deposit the firing ones.
Definition
ldes_spn.h:98
line::ldes
Definition
ldes_busyperiod.h:41
line
Definition
aoi_dist2ph.h:52
line::ldes::engine::SpnMode
One mode of a transition, resolved to what the event loop needs.
Definition
ldes_spn.h:51
line::ldes::engine::SpnMode::enabling
std::vector< double > enabling
per (place, class), tokens required
Definition
ldes_spn.h:52
line::ldes::engine::SpnMode::servers
double servers
Definition
ldes_spn.h:55
line::ldes::engine::SpnMode::immediate
bool immediate
Definition
ldes_spn.h:58
line::ldes::engine::SpnMode::dep
std::function< double(const std::vector< double > &)> dep
marking multiplier
Definition
ldes_spn.h:60
line::ldes::engine::SpnMode::priority
double priority
Definition
ldes_spn.h:56
line::ldes::engine::SpnMode::rate
double rate
nominal firing rate of a timed mode
Definition
ldes_spn.h:59
line::ldes::engine::SpnMode::weight
double weight
Definition
ldes_spn.h:57
line::ldes::engine::SpnMode::inhibiting
std::vector< double > inhibiting
per (place, class), tokens that block (inf = never)
Definition
ldes_spn.h:53
line::ldes::engine::SpnMode::firing
std::vector< double > firing
per (place, class), tokens moved on a firing
Definition
ldes_spn.h:54
line::ldes::engine::SpnTransition
One Transition node.
Definition
ldes_spn.h:64
line::ldes::engine::SpnTransition::fired
std::vector< double > fired
per mode
Definition
ldes_spn.h:68
line::ldes::engine::SpnTransition::places
std::vector< std::size_t > places
the place NODES its modes reference, in order
Definition
ldes_spn.h:67
line::ldes::engine::SpnTransition::node
std::size_t node
Definition
ldes_spn.h:65
line::ldes::engine::SpnTransition::modes
std::vector< SpnMode > modes
Definition
ldes_spn.h:66
include
line
solvers
ldes
ldes_spn.h
Generated by
1.18.0