1function isValid = isValid(sn, n, s, options)
2% ISVALID Validate network state against capacity and scheduling constraints
4% @brief Checks
if a given state
is valid according to network constraints
5% @param sn Network structure or Network
object
6% @param n Number of jobs per
class at
the station
7% @param s Number of jobs per
class that are currently running/being served
8% @param options Optional validation configuration parameters
9% @
return isValid Boolean indicating
if the state satisfies all constraints
11% This function validates whether a proposed network state
is feasible
12% given
the network
's capacity limitations, scheduling constraints, and
13% other structural requirements. It is essential for state space generation
14% and state-based analysis methods.
16% Copyright (c) 2012-2026, Imperial College London
25if isempty(n) & ~isempty(s)
30if iscell(n) %then n is a cell array of states
33 for isf=1:length(ncell)
34 ist = sn.statefulToStation(isf);
35 ind = sn.statefulToNode(isf);
36 [~, n(ist,:), s(ist,:), ~] = State.toMarginal(sn, ind, ncell{isf});
44 K(r) = sn.phases(ist,r);
45 if sn.nodetype(sn.stationToNode(ist)) ~= NodeType.Place
46 if ~isempty(sn.proc) && ~isempty(sn.proc{ist}{r}) && any(any(isnan(sn.proc{ist}{r}{1}))) && n(ist,r)>0 % if disabled
48 % line_error(mfilename,sprintf('Chain %d
is initialized with an incorrect number of jobs: %f instead of %d.
', nc, statejobs_chain, njobs_chain));
53 if any(n(ist,:)>sn.classcap(ist,:))
54 line_warning(mfilename,'Station %d
is in a state with more jobs than its allowed capacity.\n
');
60if nargin > 2 && ~isempty(s)
61 for ist=1:sn.nstations
62 % A queueing place (QPN embedded queue) carries a token-marking state that
63 % does not split in-service from waiting tokens; its embedded-server occupancy
64 % is managed by the simulation algorithm, not the native state, so the
65 % running-jobs-versus-servers constraint below does not apply to Place nodes.
66 isPlaceStation = sn.nodetype(sn.stationToNode(ist)) == NodeType.Place;
67 if sn.nservers(ist)>0 && ~isPlaceStation
68 % if more running jobs than servers
69 if sum(s(ist,:)) > sn.nservers(ist)
70 switch sn.sched(ist) % don't flag invalid
if ps
71 case {SchedStrategy.FCFS,SchedStrategy.SIRO,SchedStrategy.LCFS,SchedStrategy.HOL,SchedStrategy.POLLING}
76 %
if more running jobs than jobs at
the node
81 % non-idling condition
82 if sum(s(ist,:)) ~= min(sum(n(ist,:)), sn.nservers(ist))
83 % commented because in ps queues s are in service as well
92 njobs_chain = sum(sn.njobs(find(sn.chains(nc,:))));
93 if ~isinf(njobs_chain)
94 statejobs_chain = sum(sum(n(:,find(sn.chains(nc,:))),2),1);
95 %
if ~options.force && abs(1-njobs_chain/statejobs_chain) > options.iter_tol
96 if abs(1-njobs_chain/statejobs_chain) > GlobalConstants.CoarseTol
98 line_error(mfilename,sprintf(
'Chain %d is initialized with an incorrect number of jobs: %f instead of %d.', nc, statejobs_chain, njobs_chain));