%% Extracting Detailed Information from Coverage Data 
% This example shows how coverage utility commands can be used to extract
% information for an individual subsystem, block, or Stateflow(R) object
% from cvdata objects.

%   Copyright 1990-2020 The MathWorks, Inc.

%%
% Move the current MATLAB&reg; directory to the location that contains the
% example files.

openExample('slcoverage/ExtractingDetailedCoverageDataExample');

%% Example Model
% This example illustrates command line access of coverage data for a small
% model that contains aspects of various supported coverage metrics.
%  

%% 
% Use the following commands to open the model 'slvnvdemo_cv_small_controller' and its
% subsystem 'Gain.'  

open_system('slvnvdemo_cv_small_controller');
open_system('slvnvdemo_cv_small_controller/Gain');

%% Generate Coverage Data and an HTML Report
% Simulate the model using <docid:simulink_ref#bvfe92n |sim|>. Use a
% <docid:simulink_ref#bvn9b0e |Simulink.SimulationInput|> object to capture
% coverage settings and use it as an input to |sim|. After the simulation,
% coverage data will be stored in a |cvdata| object.
%

simIn = Simulink.SimulationInput('slvnvdemo_cv_small_controller');
simIn = simIn.setModelParameter('CovEnable','on');
simIn = simIn.setModelParameter('CovMetricStructuralLevel','MCDC');
simIn = simIn.setModelParameter('CovSaveSingleToWorkspaceVar','on');
simIn = simIn.setModelParameter('CovSaveName','covData');
simIn = simIn.setModelParameter('CovScope','EntireSystem');
simIn = simIn.setModelParameter('CovMetricLookupTable','on');
simIn = simIn.setModelParameter('CovMetricSignalRange','on');
simOut = sim(simIn);

%%
% Process the coverage data returned from a |cvsim| command with the report
% generation command |cvhtml|. The resulting report is a convenient
% representation of model coverage for the entire model.
%  

cvhtml('tempfile.html',covData);

%%
% The coverage data is also available in the simulation output object.
%

simOut

%% Extract Decision Coverage Information 
% Use the |decisioninfo| command to extract decision coverage information for
% individual Simulink blocks or Stateflow objects. 
%  
% The following command extracts a coverage array for the entire model. The 
% first element is the number of coverage objective outcomes satisfied for the model; the
% second element is the total number of coverage objective outcomes for the model.  
%  

cov = decisioninfo(covData,'slvnvdemo_cv_small_controller')
percent = 100*cov(1)/cov(2)

%%
% Retrieve coverage information for the 'Saturation' block using the full path
% to that block.  Provide a second return argument for textual descriptions of
% the coverage objective outcomes within that block. 
% 
%  

[blkCov, description] = decisioninfo(covData,'slvnvdemo_cv_small_controller/Saturation')

decision1 = description.decision(1).text
out_1a = description.decision(1).outcome(1).text
count_1a = description.decision(1).outcome(1).executionCount
out_1b = description.decision(1).outcome(2).text
count_1b = description.decision(1).outcome(2).executionCount

%%
% Quantitative coverage information is available for every outcome in the 
% hierarchy that contains or has coverage objective outcomes. Textual descriptions 
% are generated only for objects that have coverage objective outcomes themselves. For 
% example, invoke |decisioninfo| for the virtual subsystem Gain, and the
% description return value is empty. 
%  

[blkCov, description] = decisioninfo(covData,'slvnvdemo_cv_small_controller/Gain')

%%
% In some cases an object has internal coverage objectives but also contains 
% descendants with additional coverage objectives.  Coverage information normally
% includes all the descendants unless a third argument for ignoring descendants
% is set to 1.
%  

subsysOnlycov = decisioninfo(covData,'slvnvdemo_cv_small_controller/Gain',1)

%%
% The |decisioninfo| command also works with block handles, Stateflow IDs, and 
% Stateflow API objects. 
%

blkHandle = get_param('slvnvdemo_cv_small_controller/Saturation','Handle')
blkCov = decisioninfo(covData,blkHandle)

%%
% If an object has no decision coverage, the command returns empty outputs.
%  

missingBlkCov = decisioninfo(covData,'slvnvdemo_cv_small_controller/Sine1')

%% Extract Condition Coverage Information 
% Condition coverage indicates if the logical inputs to Boolean expressions
% have been evaluated to both true and false.  In Simulink, conditions are the
% inputs to logical operations.
%  
% The |conditioninfo| command for extracting condition coverage information is very
% similar to the |decisioninfo| command.  It normally returns information about
% an object and all its descendants, but can take a third argument that indicates
% if descendants should be ignored.  It can also return a second output
% containing descriptions of each condition.
%  

cov = conditioninfo(covData,'slvnvdemo_cv_small_controller/Gain/Logic')
[cov, desc] = conditioninfo(covData,'slvnvdemo_cv_small_controller/Gain/Logic');
desc.condition(1)
desc.condition(2)

%% Extract Modified Condition/Decision Coverage Information 
% Modified Condition/Decision Coverage (MCDC) is satisfied for a condition 
% within a Boolean expression if there are two evaluations of the 
% expression, representing an _independence pair_, which illustrate that 
% the value of the condition independently affects the outcome of the 
% entire expression.  That is to say, for these evaluations, toggling the
% value of the condition would cause the expression outcome to toggle as well.
%   
% In this example, the logical AND block is analyzed for MCDC and this
% information can be extracted using the |mcdcinfo| command.
% This command uses the same syntax as |conditioninfo| and |decisioninfo| commands.
%  

[cov, desc] = mcdcinfo(covData,'slvnvdemo_cv_small_controller/Gain/Logic')
desc.condition(1)
desc.condition(2)

%% Extract Lookup Table Coverage Information
% Lookup table coverage records the frequency that lookup occurs for each
% interpolation interval.  Valid intervals for coverage purposes also include
% values less than the smallest breakpoint and values greater than the largest
% breakpoint.  For consistency with the other commands, this information is 
% returned as a pair of counts with the number of intervals that executed and 
% the total number of intervals.
%  
% A second output argument causes |tableinfo| to return the execution counts 
% for all interpolation intervals.  If the table has M-by-N output values,
% execution counts are returned in an M+1-by-N+1 matrix.
%  
% A third output argument causes |tableinfo| to return the counts where the input
% was exactly equal to the breakpoint.  This is returned in a cell array of 
% vectors, one for each dimension in the table.
%  

[cov,execCnts,brkEq] = tableinfo(covData, 'slvnvdemo_cv_small_controller/Gain/Gain Table')

%% Extract Signal Range Information 
% The signal range metric records the smallest and largest value of Simulink 
% block outputs and Stateflow data objects.  The |sigrangeinfo| command returns 
% two return arguments for the minimum and maximum values, respectively.
%  
% The |sigrangeinfo| command works only for leaf blocks that perform a
% computation; otherwise the command returns empty arguments.
%  

[sigMin, sigMax] = sigrangeinfo(covData,'slvnvdemo_cv_small_controller/Gain/Gain Table')  % Leaf
[sigMin, sigMax] = sigrangeinfo(covData,'slvnvdemo_cv_small_controller/Gain')             % Nonleaf
