5#ifndef LINE_SOLVERS_AUTO_AUTO_METHODS_H
6#define LINE_SOLVERS_AUTO_AUTO_METHODS_H
77#include <initializer_list>
120 return {
"mva",
"nc",
"ctmc",
"fld",
"mam",
"ag",
"ba",
"ssa",
"ldes",
"jmt",
"lqns"};
136 if (family ==
"mva")
return {
"amva."};
148 const std::vector<std::string>& declared) {
150 if (name.size() > prefix.size() && name.compare(0, prefix.size(), prefix) == 0 &&
151 std::find(declared.begin(), declared.end(), name.substr(prefix.size())) !=
161inline bool auto_slot_of_family(
const std::string& family,
AutoSolver& out) {
189bool capacity_admits(
const std::string& family,
const qn::NetworkStruct<T>& sn,
190 const std::string& method) {
191 if (family !=
"mva" && family !=
"nc" && family !=
"fld" && family !=
"lqns")
return true;
196 if (family ==
"fld" && fluid::detail::fluid_unqualify(method) ==
"dae")
return true;
197 if (family ==
"nc" && method ==
"mem") {
199 return ms.supported && ms.blocking;
212inline bool declared_feature_set(
const std::string& family,
const std::string& method,
213 qn::FeatureSet& declared, std::string& label) {
214 if (family ==
"mva") { declared =
qn::mva_feature_set(method); label =
"SolverMVA";
return true; }
215 if (family ==
"nc") { declared =
qn::nc_feature_set(method); label =
"SolverNC";
return true; }
216 if (family ==
"mam") { declared =
qn::mam_feature_set(method); label =
"SolverMAM";
return true; }
218 if (family ==
"ssa") { declared =
qn::ssa_feature_set(method); label =
"SolverSSA";
return true; }
219 if (family ==
"ctmc") { declared =
qn::ctmc_feature_set(method); label =
"SolverCTMC";
return true; }
220 if (family ==
"ldes") { declared =
qn::ldes_feature_set(method); label =
"SolverLDES";
return true; }
221 if (family ==
"ag") { declared =
qn::ag_feature_set(method); label =
"SolverAG";
return true; }
222 if (family ==
"ba") { declared =
qn::ba_feature_set(method); label =
"SolverBA";
return true; }
223 if (family ==
"jmt") { declared =
qn::jmt_feature_set(method); label =
"SolverJMT";
return true; }
224 if (family ==
"lqns") {
226 label =
"SolverLQNS";
255 return std::vector<std::string>();
266 const auto lower = [](std::string s) {
267 std::transform(s.begin(), s.end(), s.begin(), [](
unsigned char c) { return std::tolower(c); });
270 const std::string want = lower(name);
275 if (lower(m) == want)
return fam;
277 return std::string();
302 "SolverAUTO: Unrecognized method '" + raw +
"'. Valid tokens are a selection intent (default, "
303 "heur, sim, exact, fast, accurate, bound), a method family (mva, nc, ctmc, fld, mam, ag, ba, ssa, "
304 "ldes, jmt, ln, env, lqns, uq), or a qualified method name such as 'nc.comom'.");
319 const std::string& method) {
324 if (family ==
"nc" && (method ==
"cftp" || method ==
"cftp.approx")) {
326 if (!why.empty())
return why;
330 if (family ==
"mva" || family ==
"fld") {
332 if (!why.empty())
return (family ==
"mva" ?
"SolverMVA: " :
"SolverFLD: ") + why;
334 if (family ==
"mva") {
338 if (method ==
"default") {
340 if (resolved ==
"erlanga" || resolved ==
"mgisrgi")
return auto_family_refusal(family,
sn, resolved);
342 if (method ==
"erlanga") {
344 if (!why.empty())
return "SolverMVA: " + why;
347 if (!detail::capacity_admits(family,
sn, method))
348 return "SolverAUTO: this method ignores the finite station capacity this model sets "
349 "(setCapacity / classCap), so it would report a capped station as unbounded.";
353 std::string gated = method;
354 if (family ==
"fld") {
355 const std::string m = fluid::detail::fluid_unqualify(method);
356 if (m ==
"rmf" || m ==
"refined") gated = fluid::detail::fluid_has_cache(
sn) ?
"rmf" :
"refined";
360 if (!detail::declared_feature_set(family, gated, declared, label))
361 return "SolverAUTO: the '" + family +
"' method family does not solve a flat Network.";
372 if (family ==
"nc") {
374 if (!ncr.empty())
return ncr;
386 if (family ==
"jmt") {
388 if (!why.empty())
return why;
390 if (family ==
"mam") {
392 if (!why.empty())
return why;
398 if (family ==
"ag") {
399 const std::string why = ag::runner_detail::method_refusal(
sn, method);
400 if (!why.empty())
return why;
405 if (family ==
"lqns") {
407 if (!why.empty())
return why;
417 if (family ==
"ba") {
419 if (!why.empty())
return "SolverBA: " + why;
421 if (family ==
"ctmc") {
424 const std::string why =
426 if (!why.empty())
return why;
435 if (family ==
"ctmc" || family ==
"ssa") {
437 if (!why.empty())
return why;
445 if (family ==
"ssa" && method ==
"nrm") {
446 const std::string why = ssa::detail::ssa_nrm_supports(
sn);
447 if (!why.empty())
return why;
451 if (family ==
"ssa") {
455 if (family ==
"fld") {
460 if (!why.empty())
return why;
464 const std::string
fj = fluid::detail::fluid_forkjoin_supports(
sn, method);
465 if (!
fj.empty())
return fj;
473 if (detail::auto_slot_of_family(family, slot)) {
476 ": no engine for this solver is available in this build.";
480 ": 'exact' needs a product-form model, and this one has no product-form "
483 return "SolverCTMC: the state space of this model is too large to enumerate.";
484 return label +
": this solver refuses the model through its own structural check.";
492 const std::string& method) {
516 const std::string& method) {
520 if (family ==
"jmt") {
522 for (
char ch : method) low +=
static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
523 return low ==
"default" ? std::string(
"jsim") : method;
525 if (family ==
"fld") {
526 const std::string m = fluid::detail::fluid_unqualify(method);
529 if (m ==
"default" && fluid::detail::fluid_is_petri_net(
sn))
return "dae";
530 if (m !=
"default" && m !=
"mfq" && m !=
"rmf" && m !=
"refined")
return method;
531 const std::string r = fluid::detail::fluid_resolve_method(
sn, method);
532 return r == m ? method : r;
552 const std::string& method) {
593 return {
"avg",
"tran",
"cdf",
"prob",
"tranprob",
"sample",
594 "cache",
"loss",
"orbit",
"moment",
"sens"};
599inline bool name_in(
const std::string& n, std::initializer_list<const char*> names) {
600 for (
const char* c : names)
601 if (n == c)
return true;
605inline bool starts_with(
const std::string& s,
const std::string& p) {
606 return s.size() >= p.size() && s.compare(0, p.size(), p) == 0;
624 if (name.empty())
return "";
626 if (g == name)
return g;
627 if (name ==
"any" || name ==
"all")
return "";
628 if (detail::name_in(name, {
"getTranAvg",
"getTranAvgVar",
"tranAvg"}))
return "tran";
629 if (detail::name_in(name, {
"getCdfRespT",
"getCdfPassT",
"getPerctRespT",
"getTranCdfPassT",
630 "getTranCdfRespT",
"getCdfSysRespT"}))
632 if (detail::name_in(name, {
"getTranProb",
"getTranProbSys",
"getTranProbAggr",
633 "getTranProbSysAggr"}))
635 if (detail::name_in(name, {
"getProb",
"getProbAggr",
"getProbSys",
"getProbSysAggr",
636 "getProbMarg",
"getProbNormConstAggr"}))
638 if (detail::name_in(name, {
"sample",
"sampleSys",
"sampleAggr",
"sampleSysAggr"}))
640 if (detail::name_in(name, {
"getAvgCacheTable",
"getAvgCacheT",
"getAvgItemTable",
641 "getAvgItemT",
"cacheAvgT",
"itemAvgT",
"aCaT",
"aIT"}))
643 if (detail::name_in(name, {
"getAvgLossTable",
"getAvgLossT",
"getAvgRegionLossTable",
644 "getAvgRegionLossT",
"lossAvgT",
"regionLossAvgT",
"aLT",
"aRLT"}))
646 if (detail::name_in(name, {
"getAvgOrbitTable",
"getAvgOrbitT",
"getAvgOrbit",
"orbitAvgT",
649 if (detail::name_in(name, {
"getMomentTable",
"getMomentChainTable",
"getMomentStationTable",
650 "getMomentT",
"getMomentChainT",
"getMomentStationT",
"momentT",
651 "momentChainT",
"momentStationT",
"mT",
"mCT",
"mST"}))
653 if (detail::name_in(name, {
"getSensitivityTable",
"getSensitivityT",
"sensitivityT",
"sT",
654 "getSensitivity",
"getSensitivityRanking"}))
658 if (detail::starts_with(name,
"getAvg") || detail::starts_with(name,
"avg") ||
659 detail::name_in(name, {
"getAvgSysRespT",
"getAvgSysTput",
"aT",
"aNT",
"aCT",
"aST",
686 if (family ==
"mva")
return {
"avg",
"prob",
"cache",
"orbit",
"moment",
"sens"};
687 if (family ==
"nc")
return {
"avg",
"cdf",
"prob",
"cache",
"moment",
"sens"};
688 if (family ==
"ctmc")
689 return {
"avg",
"tran",
"cdf",
"prob",
"tranprob",
"sample",
"cache",
"loss",
"orbit",
691 if (family ==
"fld")
return {
"avg",
"tran",
"cdf",
"prob",
"cache",
"sens"};
692 if (family ==
"mam")
return {
"avg",
"cdf"};
695 if (family ==
"ag")
return {
"avg"};
697 if (family ==
"ba")
return {
"avg"};
698 if (family ==
"ssa")
return {
"avg",
"cdf",
"prob",
"sample",
"loss"};
699 if (family ==
"ldes")
700 return {
"avg",
"tran",
"cdf",
"prob",
"sample",
"cache",
"loss",
"orbit"};
701 if (family ==
"jmt")
return {
"avg",
"tran",
"cdf",
"prob",
"tranprob",
"sample"};
716 if (family ==
"ssa" || family ==
"ldes")
return true;
718 if (family ==
"jmt") {
720 std::vector<std::string> toks;
721 for (
char ch : method) {
722 if (ch ==
'.' || ch ==
'/') {
726 tok +=
static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
731 for (
const std::string& t : toks)
732 if (t ==
"jmva") jmva =
true;
733 if (!jmva)
return true;
734 for (
const std::string& t : toks)
735 if (t ==
"ls" || t ==
"mci" || t ==
"imci" || t ==
"sampling")
return true;
742inline std::string exact_if(
bool cond) {
return cond ?
"exact" :
"approx"; }
773 bool is_stochastic,
bool is_product_form,
774 bool is_qbd_shape,
bool has_cache =
false) {
777 if (family ==
"ba")
return "bound";
778 if (is_stochastic)
return "simulation";
779 if (family ==
"ctmc") {
783 if (method ==
"mdd")
return detail::exact_if(is_product_form);
786 if (family ==
"nc") {
793 if (detail::name_in(method, {
"exact",
"divdiff",
"ca",
"comom",
"comomld",
"rec",
"ms",
794 "cub",
"rgf",
"cftp"}))
795 return detail::exact_if(is_product_form && !has_cache);
798 if (family ==
"mva") {
801 if (detail::name_in(method, {
"exact",
"mva"}))
802 return detail::exact_if(is_product_form && !has_cache);
805 if (family ==
"jmt") {
808 if (detail::name_in(method, {
"jmva.mva",
"jmva.recal",
"jmva.comom",
"jmva.treeconv"}))
809 return detail::exact_if(is_product_form && !has_cache);
812 if (family ==
"mam") {
816 if (detail::name_in(method, {
"default",
"mna",
"ldqbd",
"bgchain",
"retrial"}))
817 return detail::exact_if(is_qbd_shape);
820 if (family ==
"ag") {
851 const std::string& metric = std::string(),
852 bool show_all =
false) {
854 if (group.empty() && !metric.empty() && metric !=
"any" && metric !=
"all") {
857 if (!groups.empty()) groups +=
", ";
864 throw InputError(
"'" + metric +
"' names no measure. Pass a group (" + groups +
865 ") or the accessor that returns it, e.g. 'getCdfRespT'.");
870 const bool is_product_form =
sn.has_product_form();
871 std::size_t nsources = 0;
874 const std::vector<double> njobs =
sn.njobs();
875 bool all_open = !njobs.empty();
876 for (
double n : njobs)
877 if (!std::isinf(n)) all_open =
false;
878 const bool is_qbd_shape = all_open && (
sn.nstations - nsources) == 1;
879 bool has_cache =
false;
881 if (nd.
nodetype == qn::NodeType::Cache) has_cache =
true;
883 std::vector<SolverCandidate> rows;
886 if (!group.empty() &&
887 std::find(groups.begin(), groups.end(), group) == groups.end())
889 std::string metric_list;
890 for (
const std::string& g : groups) {
891 if (!metric_list.empty()) metric_list +=
",";
895 for (
const std::string& name : declared) {
897 if (family ==
"ssa" && name ==
"mlmc")
continue;
898 if (detail::starts_with(name, family +
".")) {
919 const bool ok = v.
ok;
920 std::string reason = ok ? std::string() : v.
reason;
922 reason =
"'" + name +
"' runs as '" + v.
method +
"' on this model." +
923 (reason.empty() ? std::string() :
" " + reason);
924 if (!ok && !show_all)
continue;
927 row.method = family +
"." + name;
931 is_qbd_shape, has_cache);
932 row.metrics = metric_list;
943 const std::string& metric = std::string(),
944 bool show_all =
false) {
951 const std::string& metric = std::string(),
952 bool show_all =
false) {
962 if (rows.empty())
return "No solver method can analyze this model.\n";
963 std::vector<std::array<std::string, 6>> cells;
964 cells.push_back({
"Solver",
"Method",
"Runnable",
"Class",
"Metrics",
"Reason"});
966 cells.push_back({r.solver, r.method, r.runnable ?
"true" :
"false", r.method_class,
967 r.metrics, r.reason});
968 std::array<std::size_t, 6> width{};
969 for (
const auto& row : cells)
970 for (std::size_t c = 0; c < 5; ++c) width[c] = std::max(width[c], row[c].size());
972 for (
const auto& row : cells) {
974 for (std::size_t c = 0; c < 5; ++c)
line += row[c] + std::string(width[c] - row[c].size() + 2,
' ');
976 while (!
line.empty() &&
line.back() ==
' ')
line.pop_back();
1006 std::vector<std::string> out{
"accurate",
"auto",
"bound",
"default",
1007 "exact",
"fast",
"heur",
"sim"};
1009 out.push_back(row.method);
1010 out.push_back(row.solver);
1012 std::sort(out.begin(), out.end());
1013 out.erase(std::unique(out.begin(), out.end()), out.end());
UnsupportedError(const std::string &what)
A subset of the registry: MATLAB's SolverFeatureSet, whose list is a flag per field.
A network plus its refreshed NetworkStruct.
The exception types the port throws.
The language-feature gate: what a MODEL uses against what a SOLVER declares.
The fluid solver's outermost entry point: @@SolverFLD/runAnalyzer.m's method resolution over solver_f...
The option and result records of SolverLDES, the discrete-event simulator.
The flat-Network path of @@SolverLQNS: its qns methods, served by qnsolver of the RADS/LQNS distribut...
std::vector< std::string > list_valid_methods()
Every method SolverAG serves, as the other families expose theirs.
std::string sn_patience_refusal(const qn::NetworkStruct< T > &sn, std::size_t ist, std::size_t r)
Port of sn_patience_refusal.m: the by-name refusal of a reneging patience that is not a Markovian law...
bool auto_supports(AutoSolver s, const qn::NetworkStruct< T > &sn, const std::string &token)
Solver.supports(model) for a candidate slot, tightened by the two method-level rules a flat feature s...
AutoSolver
The Network candidate slots, in the reference's slot order (SolverAUTO.m:41-50), which is also the or...
std::string auto_method_class(const std::string &family, const std::string &method, bool is_stochastic, bool is_product_form, bool is_qbd_shape, bool has_cache=false)
What KIND of answer a method returns: "exact", "approx", "bound" or "simulation".
std::vector< std::string > auto_network_family_names()
The method families that solve a flat Network, in SolverAUTO.familyNames' own order – which is also t...
std::string auto_metric_group_of(const std::string &name)
The measure group an accessor belongs to, "" when the name belongs to none.
bool auto_solver_is_available(AutoSolver s)
True when this port has an engine behind the slot at all.
std::string auto_family_refusal(const std::string &family, const qn::NetworkStruct< T > &sn, const std::string &method)
Solver.supportsModelMethod for a family method name: may THIS model run THIS method of THIS family?
std::string auto_find_solver_table(const std::vector< SolverCandidate > &rows)
The rows as an aligned text table, the form the CLI and a console caller want.
bool auto_is_stochastic_method(const std::string &family, const std::string &method)
Solver.isStochasticMethod for a family method name: does this method return seed-dependent estimates?
std::vector< std::string > auto_family_metrics(const std::string &family)
The measure groups a method family can answer.
std::vector< SolverCandidate > auto_find_method(const qn::NetworkStruct< T > &sn, const std::string &metric=std::string(), bool show_all=false)
Alias of auto_find_solver: the same table, asked for by method.
std::string auto_family_resolve_method(const std::string &family, const qn::NetworkStruct< T > &sn, const std::string &method)
resolveMethod for a family method name: the concrete method METHOD runs as on THIS model,...
std::vector< std::string > auto_metric_groups()
The measure groups auto_find_solver reports on, in report order.
bool auto_family_supports(const std::string &family, const qn::NetworkStruct< T > &sn, const std::string &method)
const char * auto_solver_name(AutoSolver s)
AutoToken auto_resolve_token(const std::string &raw, const qn::NetworkStruct< T > &sn)
resolveMethodToken with its third arm: an intent, a family[.submethod], or else a BARE method name,...
std::vector< SolverCandidate > auto_find_solver(const qn::NetworkStruct< T > &sn, const std::string &metric=std::string(), bool show_all=false)
SolverAUTO.findSolver: which solvers and solver methods can analyze this model, and for the ones that...
std::vector< SolverCandidate > auto_help(const qn::NetworkStruct< T > &sn, const std::string &metric=std::string(), bool show_all=false)
Alias of auto_find_solver: what can this model be solved with?
std::vector< std::string > auto_list_valid_methods(const qn::NetworkStruct< T > &sn)
SolverAUTO.listValidMethods: every method name this model can be asked for.
std::vector< std::string > auto_family_methods(const std::string &family, const qn::NetworkStruct< T > &sn)
The methods a family declares ON THIS MODEL, empty when it declares none.
ResolvedVerdict auto_family_supports_resolved(const std::string &family, const qn::NetworkStruct< T > &sn, const std::string &method)
NetworkSolver.supportsResolvedMethod for a family method name: resolve first, then gate the RESOLVED ...
std::string auto_family_declaring_method(const qn::NetworkStruct< T > &sn, const std::string &name)
familyDeclaringMethod: the first family, in familyNames order, whose method list on this model names ...
std::vector< std::string > auto_method_alias_prefixes(const std::string &family)
The prefixes under which a family advertises a SECOND SPELLING of a method it already declares plainl...
bool auto_is_method_alias(const std::string &family, const std::string &name, const std::vector< std::string > &declared)
Is name a second spelling of another method this family declares?
std::string resolve_model_method(const qn::NetworkStruct< T > &L, const std::string &method)
Port of ba_resolve_model_method.m (SolverBA.resolveMethod): the method METHOD runs as on THIS model.
std::string method_refusal(const qn::NetworkStruct< T > &L, const std::string &method)
The STRUCTURAL premises of the SolverBA bound families, in one place: the reason METHOD cannot bound ...
std::vector< std::string > list_valid_methods()
Port of SolverBA.listValidMethods.
std::vector< std::string > list_valid_methods()
Port of SolverCTMC.listValidMethods.
std::string solver_ctmc_mdd_supports(const NetworkStruct< T > &sn)
Can the mdd decision-diagram method be asked for this model?
std::string fluid_qsys_horizon_supports(const std::string &method, const FluidOptions &opt)
The horizon rule the time-varying limits impose, as a public predicate a REPORT can ask: empty when m...
std::vector< std::string > fluid_list_valid_methods()
Port of SolverFLD.listValidMethods.
std::vector< std::string > jmt_list_valid_methods()
Port of SolverJMT.listValidMethods.
std::string jmt_method_refusal(const qn::NetworkStruct< T > &sn, const std::string &method, const JmtOptions &opt)
bool ldes_is_available()
True when this machine can run the engine at all, by either image.
std::vector< std::string > list_valid_methods()
Port of SolverLDES.listValidMethods.
std::vector< std::string > qns_methods()
Port of SolverLQNS.listValidMethods on a flat Network.
std::string qns_method_refusal(const qn::NetworkStruct< T > &L, const std::string &method)
SolverLQNS.supportsModelMethod's structural rules on a Network, as the REASON they refuse,...
bool qnsolver_is_available()
Port of SolverLQNS.hasQnsolver: a native qnsolver binary on the PATH.
std::vector< std::string > list_valid_methods()
Port of SolverMAM.listValidMethods.
std::string mam_model_method_refusal(const qn::NetworkStruct< T > &L, const std::string &method)
check_model_method asked WITHOUT raising: the same verdict as a sentence.
std::string resolve_method(const qn::NetworkStruct< T > &L, const std::string &method)
Port of SolverMVA.resolveMethod: the feature-driven default -> rqna upgrade for a bursty single-class...
std::vector< std::string > list_valid_methods(const qn::NetworkStruct< T > &L)
Port of SolverMVA.listValidMethods.
std::string mva_erlanga_patience_reason(const qn::NetworkStruct< T > &L)
Why method 'erlanga' cannot answer this model's patience, or "".
MemSupport solver_nc_mem_supports(const qn::NetworkStruct< T > &sn)
Port of solver_nc_mem_supports.m.
std::string resolve_method(const qn::NetworkStruct< T > &, const std::string &method)
Port of SolverNC.resolveMethod: default is NOT resolved ahead of the run.
std::vector< std::string > list_valid_methods()
Port of SolverNC.listValidMethods.
bool is_stochastic_method(const std::string &method)
Port of SolverNC.isStochasticMethod.
std::string nc_method_refusal(const qn::NetworkStruct< T > &sn, const std::string &method, bool slotted=false, bool for_report=true)
May method run on this model?
std::string solver_nc_cftp_supports(const qn::NetworkStruct< T > &sn)
The cftp model-class gate as a public predicate.
FeatureSet ldes_feature_set(const std::string &)
SolverLDES.getFeatureSet, transcribed WHOLE.
FeatureSet fluid_feature_set(const std::string &method)
FeatureSet ssa_feature_set(const std::string &method)
FeatureSet jmt_feature_set(const std::string &method)
Port of SolverJMT.getFeatureSet (@@SolverJMT/SolverJMT.m:180-290).
FeatureSet used_lang_features(const NetworkStruct< T > &sn)
FeatureSet lqns_network_feature_set(const std::string &)
SolverLQNS.getFeatureSet on a flat Network (its qns methods), transcribed WHOLE.
FeatureSet nc_feature_set(const std::string &method)
SolverNC.getFeatureSet, 48 names, transcribed unchanged.
FeatureSet ba_feature_set(const std::string &method)
SolverBA.getFeatureSet, transcribed name for name.
std::string sn_fj_supports(const NetworkStruct< T > &sn)
Can the exact fork-join construction be asked for this model?
bool has_binding_capacity(const NetworkStruct< T > &sn)
getUsedLangFeatures: the features the MODEL uses.
FeatureSet ctmc_feature_set(const std::string &method)
SolverCTMC.getFeatureSet, the reference's 104 MATLAB names in full.
SupportResult feature_set_supports(const std::string &solver, const FeatureSet &declared, const FeatureSet &used)
SolverFeatureSet.supports: is every feature the model uses declared?
FeatureSet mam_feature_set(const std::string &method)
SolverMAM.getFeatureSet, the union of its four setTrue calls: 55 MATLAB names, WIDENED for 'default'/...
FeatureSet mva_feature_set(const std::string &raw_method)
SolverMVA.getFeatureSet, plus getMethodFeatureSet's per-method deltas.
FeatureSet ag_feature_set(const std::string &)
SolverAG.getFeatureSet: what the RCAT decomposition can represent.
std::vector< std::string > list_valid_methods()
Port of SolverSSA.listValidMethods.
Conservation laws of a layered queueing network, enumerated from its structure.
A queueing network and its refreshed NetworkStruct.
The gates and the dispatch of the agent-based (RCAT) solver.
The SolverAUTO chooser: which solver a model is handed to.
The SolverBA class surface: @@SolverBA/runAnalyzer.m, listValidMethods, getBounds and getBoundsTable.
Port of solver_ctmc_analyzer.m and the parts of @@SolverCTMC/runAnalyzer.m that surround one solve: t...
The mdd method of SolverCTMC: stationary analysis of a closed single-class network whose state space ...
The DECLARED side of the gate: one feature set per solver.
Port of SolverJMT, the Java Modelling Tools client.
The SolverMAM class surface: @@SolverMAM/runAnalyzer.m and the gates around it.
The SolverMVA class surface: @@SolverMVA/runAnalyzer.m and the gates around it.
The SolverNC class surface: @@SolverNC/runAnalyzer.m and the gates around it.
The SolverSSA entry surface: a port of @@SolverSSA/runAnalyzer.m's method whitelist,...
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
The verdict of sn_fluid_refusal: ok when no rule is broken, else the reason.
resolveMethodToken, minus the unqualified-algorithm-name arm.
std::string submethod
the method handed to the family, "default" when bare
std::string family
empty when is_intent
NetworkSolver.supportsResolvedMethod's answer: the gate on the resolved name.
bool ok
the model passes the gate of the method that runs
std::string method
the method METHOD runs as on this model
std::string reason
why it does not, "" when it does
One row of auto_find_solver: a (family, method) pair this model can be asked for, whether it runs,...
std::string method
the method name to pass, "mva.exact"
bool runnable
the model passes this method's own support gate
std::string metrics
the measure groups the family answers, comma-joined
std::string reason
why a refused pair was refused, prefixed by "'x' runs as 'y' on this model.
std::string solver
the method family: "mva", "ctmc", "ldes", ...
std::string method_class
"exact", "approx", "bound" or "simulation"
Controls, defaulting to SolverOptions('Fluid') in the reference.
The options of one JMT solve, SolverOptions('JMT') restricted to what is read.
One station of the network.
The outcome of the gate: the verdict, the offending features, the message.
std::string reason
empty when ok