5#ifndef LINE_API_SN_SN_PREDICATES_H
6#define LINE_API_SN_SN_PREDICATES_H
51 for (std::size_t i = 0; i < sn.stations.size(); ++i)
52 if (sn.stations[i].sched == s)
return true;
62 return detail::sn_any_sched(
sn, qn::SchedStrategy::DPS);
66 return detail::sn_any_sched(
sn, qn::SchedStrategy::DPSPRIO);
70 return detail::sn_any_sched(
sn, qn::SchedStrategy::FCFS);
74 return detail::sn_any_sched(
sn, qn::SchedStrategy::GPS);
78 return detail::sn_any_sched(
sn, qn::SchedStrategy::GPSPRIO);
82 return detail::sn_any_sched(
sn, qn::SchedStrategy::HOL);
86 return detail::sn_any_sched(
sn, qn::SchedStrategy::INF);
90 return detail::sn_any_sched(
sn, qn::SchedStrategy::LCFS);
94 return detail::sn_any_sched(
sn, qn::SchedStrategy::LCFSPI);
98 return detail::sn_any_sched(
sn, qn::SchedStrategy::LCFSPR);
102 return detail::sn_any_sched(
sn, qn::SchedStrategy::LEPT);
106 return detail::sn_any_sched(
sn, qn::SchedStrategy::LJF);
110 return detail::sn_any_sched(
sn, qn::SchedStrategy::LPS);
114 return detail::sn_any_sched(
sn, qn::SchedStrategy::POLLING);
118 return detail::sn_any_sched(
sn, qn::SchedStrategy::PS);
122 return detail::sn_any_sched(
sn, qn::SchedStrategy::PSPRIO);
126 return detail::sn_any_sched(
sn, qn::SchedStrategy::SEPT);
130 return detail::sn_any_sched(
sn, qn::SchedStrategy::SETF);
134 return detail::sn_any_sched(
sn, qn::SchedStrategy::SIRO);
138 return detail::sn_any_sched(
sn, qn::SchedStrategy::SJF);
142 return detail::sn_any_sched(
sn, qn::SchedStrategy::SRPT);
154 std::size_t count = 0;
155 for (std::size_t i = 0; i <
sn.nstations && i <
sn.stations.size(); ++i)
156 if (
sn.stations[i].sched == strategy) ++count;
157 return count ==
sn.nstations;
169 it =
sn.joindecl.begin();
170 it !=
sn.joindecl.end(); ++it) {
172 if (it->second.quorum > 0.0)
return true;
181 for (std::size_t k = 0; k <
sn.classes.size(); ++k)
182 if (std::isinf(
sn.classes[k].population))
return true;
188 for (std::size_t k = 0; k <
sn.classes.size(); ++k)
189 if (std::isfinite(
sn.classes[k].population))
return true;
196 for (std::size_t k = 0; k <
sn.classes.size(); ++k)
197 if (std::isfinite(
sn.classes[k].population)) ++n;
208 return sn.nchains > 1;
212 return sn.nchains == 1;
216 return sn.nclasses > 1;
220 return sn.nclasses == 1;
224 return sn.nclasses !=
sn.nchains;
230 for (std::size_t k = 0; k <
sn.classes.size(); ++k)
231 if (!std::isinf(
sn.classes[k].population))
return false;
238 for (std::size_t k = 0; k <
sn.classes.size(); ++k)
239 if (!std::isfinite(
sn.classes[k].population))
return false;
252 for (std::size_t k = 0; k <
sn.classes.size(); ++k)
253 if (
sn.classes[k].prio > 0)
return true;
259 for (std::size_t i = 0; i <
sn.stations.size(); ++i)
260 if (std::isfinite(
sn.stations[i].nservers) &&
sn.stations[i].nservers > 1.0)
return true;
267 for (std::size_t k = 0; k <
sn.classes.size(); ++k) {
268 const double n =
sn.classes[k].population;
269 if (std::isfinite(n) && n != std::floor(n + 0.5))
return true;
277 for (std::size_t i = 0; i <
sn.stations.size(); ++i)
278 if (!
sn.stations[i].lldscaling.empty())
return true;
291 return !
sn.fj.empty();
304 for (std::size_t a = 0; a <
sn.nodes.size(); ++a)
305 for (std::size_t r = 0; r <
sn.nodes[a].routing.size(); ++r) {
307 if (s == qn::RoutingStrategy::RROBIN || s == qn::RoutingStrategy::WRROBIN ||
308 s == qn::RoutingStrategy::JSQ || s == qn::RoutingStrategy::SQ ||
309 s == qn::RoutingStrategy::SDR)
319 for (std::size_t i = 0; i <
sn.nstations; ++i) {
320 if (
sn.stations[i].sched != qn::SchedStrategy::FCFS)
continue;
322 for (std::size_t r = 0; r <
sn.nclasses; ++r) {
323 if (!
sn.disabled.empty() &&
sn.disabled[i][r])
continue;
324 if (
sn.rates(i, r) > zero) ++n;
326 if (n > 1)
return true;
342 for (std::size_t i = 0; i <
sn.nstations; ++i) {
343 if (
sn.stations[i].sched != qn::SchedStrategy::FCFS)
continue;
345 double lo = 0.0, hi = 0.0;
346 for (std::size_t r = 0; r <
sn.nclasses; ++r) {
347 if (!
sn.disabled.empty() &&
sn.disabled[i][r])
continue;
349 if (!std::isfinite(v))
continue;
367 for (std::size_t i = 0; i <
sn.nstations; ++i) {
368 if (
sn.stations[i].sched != qn::SchedStrategy::FCFS)
continue;
373 double lo = 0.0, hi = 0.0;
374 for (std::size_t r = 0; r <
sn.nclasses; ++r) {
375 if (!
sn.disabled.empty() &&
sn.disabled[i][r])
continue;
377 if (std::isnan(v))
continue;
386 if (!(any && hi - lo > 0.0))
continue;
390 bool allone =
true, seen =
false;
391 for (std::size_t r = 0; r <
sn.nclasses && allone; ++r) {
392 if (!
sn.disabled.empty() &&
sn.disabled[i][r])
continue;
394 if (std::isnan(c))
continue;
399 if (seen && allone)
return true;
407 for (std::size_t i = 0; i <
sn.stations.size(); ++i) {
409 if (!(s == qn::SchedStrategy::INF || s == qn::SchedStrategy::PS ||
410 s == qn::SchedStrategy::FCFS || s == qn::SchedStrategy::LCFSPR ||
411 s == qn::SchedStrategy::LCFS || s == qn::SchedStrategy::EXT))
448 for (std::size_t i = 0; i <
sn.stations.size(); ++i) {
450 if (!(s == qn::SchedStrategy::INF || s == qn::SchedStrategy::PS ||
451 s == qn::SchedStrategy::FCFS || s == qn::SchedStrategy::LCFSPR ||
452 s == qn::SchedStrategy::EXT))
456 for (std::size_t i = 0; i <
sn.nstations; ++i) {
457 if (
sn.stations[i].sched != qn::SchedStrategy::FCFS)
continue;
470 for (std::size_t r = 0; r <
sn.nclasses; ++r) {
471 if (!
sn.disabled.empty() &&
sn.disabled[i][r])
continue;
473 if (std::isfinite(v) && v > 0.0 &&
477 if (!check_means ||
sn.visits.empty())
continue;
478 const std::size_t isf =
sn.stateful_of_station(i + 1) - 1;
479 double stmin = 0.0, stmax = 0.0;
480 bool anyserved =
false;
481 for (std::size_t c = 0; c <
sn.nchains && c <
sn.visits.size(); ++c) {
482 double num = 0.0, den = 0.0;
483 for (std::size_t r = 0; r <
sn.nclasses; ++r) {
484 if (!
sn.chains.empty() && !
sn.chains[c][r])
continue;
485 if (!
sn.disabled.empty() &&
sn.disabled[i][r])
continue;
494 const double st = num / den;
499 stmin = std::min(stmin, st);
500 stmax = std::max(stmax, st);
515 for (std::size_t i = 0; i <
sn.stations.size(); ++i) {
517 if (!(s == qn::SchedStrategy::INF || s == qn::SchedStrategy::PS ||
518 s == qn::SchedStrategy::PSPRIO || s == qn::SchedStrategy::DPS ||
519 s == qn::SchedStrategy::GPS || s == qn::SchedStrategy::GPSPRIO ||
520 s == qn::SchedStrategy::DPSPRIO || s == qn::SchedStrategy::EXT))
531 if (
sn.nclasses != 1)
return false;
533 for (std::size_t k = 0; k <
sn.classes.size(); ++k) {
534 if (std::isinf(
sn.classes[k].population))
return false;
535 closed +=
sn.classes[k].population;
537 if (!(closed > 0.0))
return false;
542 for (std::size_t i = 0; i <
sn.droprule.size(); ++i)
543 for (std::size_t r = 0; r <
sn.droprule[i].size(); ++r)
544 if (
sn.droprule[i][r] == qn::DropStrategy::BAS)
return true;
554 return sn.is_mm1k_loss();
578 return sn.has_blocking();
587 return sn.is_fluid_node(ind);
597 return sn.has_fluid_places();
A network plus its refreshed NetworkStruct.
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
bool sn_has_siro(const qn::NetworkStruct< T > &sn)
bool sn_has_multi_class_heter_fcfs(const qn::NetworkStruct< T > &sn)
sn_has_multi_class_heter_fcfs: an FCFS station whose per-class rates differ.
bool sn_has_hol(const qn::NetworkStruct< T > &sn)
bool sn_has_mixed_classes(const qn::NetworkStruct< T > &sn)
bool sn_has_ljf(const qn::NetworkStruct< T > &sn)
bool sn_has_multi_chain(const qn::NetworkStruct< T > &sn)
bool sn_has_ps(const qn::NetworkStruct< T > &sn)
bool sn_has_multi_class_fcfs(const qn::NetworkStruct< T > &sn)
sum(sn.rates(i,:)>0)>1 at some FCFS station: more than one class is served there.
bool sn_is_open_model(const qn::NetworkStruct< T > &sn)
all(isinf(sn.njobs)): EVERY class is open, which a mixed model fails.
bool sn_has_lcfs_pi(const qn::NetworkStruct< T > &sn)
bool sn_has_closed_classes(const qn::NetworkStruct< T > &sn)
bool sn_has_product_form(const qn::NetworkStruct< T > &sn)
Port of sn_has_product_form.
bool sn_has_ps_prio(const qn::NetworkStruct< T > &sn)
bool sn_has_sept(const qn::NetworkStruct< T > &sn)
bool sn_has_dps(const qn::NetworkStruct< T > &sn)
bool sn_has_load_dependence(const qn::NetworkStruct< T > &sn)
size(sn.lldscaling,2)>0: some station carries a limited-load scaling row.
bool sn_has_single_class(const qn::NetworkStruct< T > &sn)
bool sn_has_multiple_closed_classes(const qn::NetworkStruct< T > &sn)
bool sn_has_srpt(const qn::NetworkStruct< T > &sn)
bool sn_has_lps(const qn::NetworkStruct< T > &sn)
bool sn_has_sd_routing(const qn::NetworkStruct< T > &sn)
sn_has_sd_routing: some node dispatches on the STATE of the network.
bool sn_is_population_model(const qn::NetworkStruct< T > &sn)
sn_is_population_model: every station is population dependent only, which is what lets the fluid and ...
bool sn_has_class_switching(const qn::NetworkStruct< T > &sn)
bool sn_is_closed_model(const qn::NetworkStruct< T > &sn)
all(isfinite(sn.njobs)): EVERY class is closed.
bool sn_is_mixed_model(const qn::NetworkStruct< T > &sn)
bool sn_has_product_form_not_het_fcfs(const qn::NetworkStruct< T > &sn, bool check_means=true)
Port of sn_has_product_form_not_het_fcfs: LCFS is out, and every enabled FCFS pair with a finite posi...
bool sn_has_sjf(const qn::NetworkStruct< T > &sn)
bool sn_has_homogeneous_scheduling(const qn::NetworkStruct< T > &sn, qn::SchedStrategy strategy)
Port of sn_has_homogeneous_scheduling: true when EVERY station uses strategy, the reference's length(...
bool sn_is_bas_model(const qn::NetworkStruct< T > &sn)
sn_is_bas_model: a single-class closed model with blocking-after-service.
bool sn_has_lcfs_pr(const qn::NetworkStruct< T > &sn)
bool sn_has_fractional_populations(const qn::NetworkStruct< T > &sn)
any(sn.njobs ~= round(sn.njobs)); an infinite population rounds to itself.
bool sn_has_lcfs(const qn::NetworkStruct< T > &sn)
bool sn_has_multi_server(const qn::NetworkStruct< T > &sn)
bool sn_has_multi_class(const qn::NetworkStruct< T > &sn)
bool sn_has_priorities(const qn::NetworkStruct< T > &sn)
bool sn_has_dps_prio(const qn::NetworkStruct< T > &sn)
bool sn_has_quorum_join(const qn::NetworkStruct< T > &sn)
Port of sn_has_quorum_join: true when some Join node declares a non-STD strategy with a positive requ...
bool sn_has_multi_class_heter_exp_fcfs(const qn::NetworkStruct< T > &sn)
An FCFS station with heterogeneous rates whose SCVs are all one (exponential).
bool sn_is_fluid_place(const qn::NetworkStruct< T > &sn, std::size_t ind)
Port of sn_is_fluid_place: node ind (1-based, as in the reference) is a FLUID place (Place....
bool sn_has_fork_join(const qn::NetworkStruct< T > &sn)
any(sn.fj(:) > 0): the model has a Fork closed by a Join.
bool sn_has_blocking(const qn::NetworkStruct< T > &sn)
Defined below, after sn_is_mm1k_loss, which it exempts.
bool sn_has_setf(const qn::NetworkStruct< T > &sn)
bool sn_has_lept(const qn::NetworkStruct< T > &sn)
bool sn_has_fluid_places(const qn::NetworkStruct< T > &sn)
Port of sn_has_fluid_places: the model is a Fluid Stochastic Petri Net, holding a fluid place or a tr...
bool sn_has_gps_prio(const qn::NetworkStruct< T > &sn)
bool sn_has_inf(const qn::NetworkStruct< T > &sn)
bool sn_has_polling(const qn::NetworkStruct< T > &sn)
bool sn_has_single_chain(const qn::NetworkStruct< T > &sn)
bool sn_has_open_classes(const qn::NetworkStruct< T > &sn)
bool sn_has_fcfs(const qn::NetworkStruct< T > &sn)
bool sn_has_gps(const qn::NetworkStruct< T > &sn)
bool sn_sched_is_product_form(const qn::NetworkStruct< T > &sn)
The disciplines the reference admits in sn_has_product_form.
bool sn_is_mm1k_loss(const qn::NetworkStruct< T > &sn)
sn_is_mm1k_loss: the three-node Source/Queue/Sink model of an M/M/1/K with loss, the shape MVA answer...
SchedStrategy
Scheduling disciplines, with the values of MATLAB SchedStrategy.
RoutingStrategy
Routing strategies, with the values of MATLAB RoutingStrategy.
Conservation laws of a layered queueing network, enumerated from its structure.
A queueing network and its refreshed NetworkStruct.
Number-type abstraction for the templated API port.
Physical buffer size of a station, in jobs, the one in service included.
static constexpr double FineTol
static constexpr double Zero
static constexpr double CoarseTol
The DECLARED join rule of a Join node, by 1-based node index.