1function sn_fj_validate(sn)
4% Validate that a fork-join model
is within
the supported feature set of
5%
the native CTMC/SSA fork-join implementation (v1): closed classes only,
6% non-nested fork-join pairs, standard join strategy (wait for all
7% siblings), one task per output link. Unsupported models raise a
8% line_error with a specific message; further structural checks (
class
9% switching on a branch, nesting, sibling traps) are performed during
the
10% branch discovery in ModelAdapter.fjtag.
12% Copyright (c) 2012-2026, Imperial College London
16forkIndexes = find(sn.nodetype == NodeType.Fork)
';
17joinIndexes = find(sn.nodetype == NodeType.Join)';
18Vnodes = cellsum(sn.nodevisits);
23 line_error(mfilename,
'Fork nodes without a matched Join are not supported by the native CTMC/SSA fork-join implementation.');
26 line_error(mfilename,
'Multiple Join nodes per Fork are not supported by the native CTMC/SSA fork-join implementation.');
28 if isfield(sn.nodeparam{f},
'fanOut') && any(sn.nodeparam{f}.fanOut ~= round(sn.nodeparam{f}.fanOut))
29 line_error(mfilename,'Non-integer tasksPerLink
is not supported by
the native CTMC/SSA fork-join implementation.');
31 for r=find(Vnodes(f,:)>0)
32 c = find(sn.chains(:,r), 1);
33 if isinf(sn.njobs(r)) || (~isempty(c) && any(isinf(sn.njobs(sn.chains(c,:)))))
34 line_error(mfilename,'Open classes routed through a Fork are not supported by
the native CTMC/SSA fork-join implementation.');
41 line_error(mfilename,'Join
nodes without a matched Fork are not supported by
the native CTMC/SSA fork-join implementation.');
43 if isfield(sn.
nodeparam{j},
'joinStrategy')
45 if length(sn.
nodeparam{j}.joinStrategy) >= r && ~isempty(sn.
nodeparam{j}.joinStrategy{r}) && sn.
nodeparam{j}.joinStrategy{r} ~= JoinStrategy.STD
46 line_error(mfilename,
'Only JoinStrategy.STD is supported by the native CTMC/SSA fork-join implementation.');