www.gusucode.com > sldv工具箱matlab源码程序 > sldv/slicer/+Transform/computeUnreachableSystems.m
function ancestorSystems = computeUnreachableSystems(mdl) % Copyright 2013-2014 The MathWorks, Inc. sysBlks = find_system(mdl,'LookUnderMasks', 'on',... 'BlockType', 'SubSystem'); hdls = cellfun(@(s)get_param(s, 'Handle'), sysBlks); isEmptySys = arrayfun(@(x) isDisconnectedSubsystem(x) &&... ~hasNonvirtualBlocks(x) && ~isLocked(x), hdls); if all(~isEmptySys) ancestorSystems = []; return; end nNodes = length(hdls); ids = int32(1:nNodes)'; bhToTree = containers.Map(hdls, ids); roots = true(length(hdls),1); parentMap = containers.Map('KeyType', 'double', 'ValueType', 'int32'); for i=1:length(hdls) sysO = get(hdls(i), 'Object'); parentO = sysO.getParent; if isa(parentO, 'Simulink.SubSystem') h = parentO.Handle; if bhToTree.isKey(h) roots(i) = false; parentMap(sysO.Handle) = bhToTree(h); end end end % Propagate empty flag % If any children is not empty, the parents are not empty for i=1:numel(hdls) if ~isEmptySys(i) if ~roots(i) sysIdx = parentMap(hdls(i)); isEmptySys(sysIdx) = false; while parentMap.isKey(hdls(sysIdx)) sysIdx = parentMap(hdls(sysIdx)); isEmptySys(sysIdx) = false; end end end end ancestorSystems = []; for i=1:numel(hdls) if isEmptySys(i) && isRootOrIsParentNonempty(i) ancestorSystems = [ancestorSystems; hdls(i)]; %#ok<AGROW> end end function yesno = isRootOrIsParentNonempty(idx) if roots(idx) yesno = true; else assert(parentMap.isKey(hdls(idx))); pIdx = parentMap(hdls(idx)); if isEmptySys(pIdx) yesno = false; else yesno = true; end end end end function yesno = isDisconnectedSubsystem(bh) % A subsystem is disconnected if all its input and all its output are % disconnected. obj = get(bh, 'Object'); ph = obj.PortHandles; isConditional = ~isempty(ph.Enable) || ~isempty(ph.Trigger) || ... ~isempty(ph.Ifaction) || ~isempty(ph.Reset); children = obj.getChildren; inports = children(arrayfun(@(x)isa(x, 'Simulink.Inport'), children)); outports = children(arrayfun(@(x)isa(x, 'Simulink.Outport'), children)); if ~isempty(inports) i1 = arrayfun(@isInportDisconnected, inports); i2 = arrayfun(@isPortDisconnected, obj.PortHandles.Inport'); i = all(i1 | i2); else i = true; end if ~isempty(outports) portBlockDisc = arrayfun(@isOutportDisconnected, outports); portHasZeroIC = arrayfun(@hasZeroIc, outports); sysPortDisc = arrayfun(@isPortDisconnected, obj.PortHandles.Outport'); if isConditional outDisc = all((portBlockDisc & portHasZeroIC) | sysPortDisc); else outDisc = all(portBlockDisc | sysPortDisc); end else outDisc = true; end hasGlobal = false; dsr = children(arrayfun(@(x)isa(x, 'Simulink.DataStoreRead'), children)); if ~isempty(dsr) hasGlobal = true; end dsw = children(arrayfun(@(x)isa(x, 'Simulink.DataStoreWrite'), children)); if ~isempty(dsw) hasGlobal = true; end yesno = i && outDisc && ~hasGlobal; end function out = getChildBlocks(bh) out = find_system(bh, ... 'LookUnderMasks', 'all', ... 'SearchDepth', 1, ... 'Type', 'block'); out(out==bh) = []; end function out = isVirtualBlk(blkH) obj = get_param(blkH,'Object'); out = strcmp(obj.Virtual, 'on') || strcmp(get(blkH,'MaskType'),'ModelSlicer_replaced'); end function yesno = hasNonvirtualBlocks(bh) blocks = getChildBlocks(bh); isVirtual = arrayfun(@isVirtualBlk, blocks); yesno = ~all(isVirtual); end function yesno = isLocked(bh) % Test whether the subsystem is locked and should not be analyzed or % removed. if strcmp(get(bh, 'Mask'), 'on') && ~isempty(get(bh, 'MaskType')) if any(strcmp(get(bh, 'MaskType'), {'Sigbuilder block', 'Enumerated Constant'})) yesno = true; else yesno = false; end else yesno = false; end end function yesno = isInportDisconnected(inportB) yesno = get(inportB.PortHandles.Outport, 'Line') < 0; end function yesno = isOutportDisconnected(outportB) yesno = get(outportB.PortHandles.Inport, 'Line') < 0; end function yesno = hasZeroIc(outportB) ic = outportB.InitialOutput; yesno = strcmp(ic, '[]') || strcmp(ic, '0'); end function yesno = isPortDisconnected(pH) yesno = get(pH, 'Line') <0; end