solvers.wrappers.LQNS

solver_qns_analyzer(sn, options)

[QN,UN,RN,TN,CN,XN,RUNTIME,ACTUALMETHOD] = SOLVER_QNS_ANALYZER(QN, OPTIONS)

solver_qns(sn, options)

[Q,U,R,T,C,X] = SOLVER_QNS(QN, OPTIONS)

qns_multiserver_refusal(sn, method)

[OK, REASON] = QNS_MULTISERVER_REFUSAL(SN, METHOD) Whether qnsolver’s own -m switch offers this multiserver approximation.

ASKED ON THE MULTISERVER APPROXIMATION, i.e. the name after ‘qns.’ that SolverLQNS.qnsMultiserver extracts, or options.config.multiserver at run time. runAnalyzerNetwork sets the config value from the method name before SOLVER_QNS runs, so SolverLQNS(model,’qns.suri’) reaches qnsolver asking for ‘suri’, which qnsolver has no flag for. SOLVER_QNS used to fall off its inner switch there, leaving CMD unassigned, so the failure surfaced as an undefined-variable error about a temporary rather than as a diagnosis.

‘qnsolver -m’ accepts conway, reiser, rolia and zhou. ‘suri’ and ‘schmidt’ are LQNS approximations, reachable only on the non-product-form closed branch of SolverLQNS, where QN2LQN hands the model to lqns, and qnsolver has no flag for either.

THE RULE IS INSIDE THE MULTISERVER BRANCH, and that is not a detail. Without a multiserver station the reference emits no -m at all and answers under the caller’s method name, so refusing ‘suri’ there would refuse a model this solver does solve. With one, SOLVER_QNS used to fall off its inner switch and leave CMD unassigned, so the failure surfaced as an undefined-variable error about a temporary rather than as a diagnosis naming the method. The C++ port has diagnosed this since it was written (solver_qns.h, is_qnsolver_multiserver); this is the same rule, stated where MATLAB, the JAR and python can all reach it.

qns_immfeed_refusal(sn)

REASON = QNS_IMMFEED_REFUSAL(SN) Why SolverLQNS cannot serve a model with immediate feedback, or ‘’ when the model has none.

Immediate feedback (sn.immfeed) keeps a self-looping job on its server instead of re-queueing it, and neither path of SolverLQNS can state that: the JMVA document qnsolver reads carries a mean demand and a visit count per chain, and the LQN QN2LQN writes turns the routing into OR-fork precedences of pseudo-activities on the reference task, where a repeated visit is a new call. Either would answer for re-queueing under this solver’s name.

ONE PREDICATE, TWO CALLERS: SolverLQNS.supportsModelMethod (the gate, hence model.help and SolverAUTO) and SolverLQNS.runAnalyzerNetwork (the run, for a caller with enableChecks off). SolverJMT keeps its own wording in jmtMethodRefusal.

Copyright (c) 2012-2026, Imperial College London All rights reserved.

lqns_method_refusal(model, method)

[OK, REASON] = LQNS_METHOD_REFUSAL(MODEL, METHOD) Whether lqns or lqsim can serve this LayeredNetwork under METHOD, as a predicate. METHOD ‘’ asks the method-neutral half only.

ONE PREDICATE, TWO CALLERS. SolverLQNS.supportsModelMethod asks it, so model.help and SolverAUTO never offer a pair that dies at run time, and runAnalyzer asks it again before the .lqnx is written, so a caller naming the method by hand gets LINE’s own sentence rather than the binary’s parse error.

WHY NOT A FEATURE SET. SolverLQNS.supports used to compare the per-layer Networks that SolverLN builds against a flat set naming Queue, Exp and FCFS. Every LN layer carries a Delay(‘Clients’) under INF with PROB routing, which that set did not declare, so the comparison refused every layered model there is, and it never saw an LQN-level construct at all. lqns reads the .lqnx and not the layers, so the rules are stated on the LayeredNetwork itself.

THE RULES. (1) The constructs neither binary models, named one by one by SolverLQNS.unsupportedLNConstructs. (2) The scheduling vocabulary: writeXML writes SchedStrategy.toText verbatim (FCFSPRPRIO as ‘pri’), and the LQN schema names fcfs, ps, inf, hol, pri and ref only, so any other discipline reaches lqns as a syntax error for what is a modelling limit. (3) Under ‘sim’/’lqsim’, a replicated processor or task, which lqsim refuses to simulate.

Copyright (c) 2012-2026, Imperial College London All rights reserved.

findlqnelem(lqn, name, elemType)

IDX = FINDLQNELEM(LQN, NAME, ELEMTYPE) Index of the layered element called NAME whose lqn.type is ELEMTYPE, or -1 when the struct carries no such element. ELEMTYPE is a LayeredNetworkElement constant (HOST, TASK, ENTRY, ACTIVITY, CALL).

THE KIND IS PART OF THE KEY, and has to be. A LINE-generated layered model routinely gives a processor, its task and that task’s entry the SAME name, and lqn.names holds all three, so findstring(lqn.names,name) returns EVERY match and an assignment indexed by it writes one element’s result into all of them: the processor row ends up carrying the task’s numbers and then the entry’s, so one .lqxo yields three different wrong answers. The result file states which kind each row describes – it is the tag being read – so the ambiguity does not have to exist. On a model whose names are unique this agrees with findstring element for element.

Copyright (c) 2012-2026, Imperial College London All rights reserved.