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