%% Analyzing MCDC for Cascaded Logic Blocks
% This example illustrates how Simulink(R) Coverage(TM) records 
% the MCDC metric for a cascade of Logical Operator blocks.

%   Copyright 2016-2019 The MathWorks, Inc.

%% Example Model
% In Simulink, there are various ways to implement Boolean logic, such as through 
% the use of an |if| statement in a MATLAB Function block, a conditional transition 
% in a Stateflow Chart, or a combination of multiple Logical Operator blocks connected 
% together in a cascade.
% 
% The example model |slvnvdemo_cv_logic_cascade| implements the same Boolean 
% expression through the use of MATLAB code in a MATLAB Function block as well
% as with a cascade of Logical Operator blocks.  
% 
% Use the following command to open the model |slvnvdemo_cv_logic_cascade|:
open_system('slvnvdemo_cv_logic_cascade');

%%
% Open the MATLAB Function block to see the associated function.

open_system('slvnvdemo_cv_logic_cascade/MATLAB Function')

%%
% <<../cvLogicCascadeMcdc_MatlabFunc.png>> 
% 
% In the MATLAB Function block, if _(a && (b | | c))_ is true, then the signal 
% *Data1* will be output; otherwise, the signal *Data2* is output.

%%
% Open the subsystem 'Logic Cascade' using the following command and note 
% that this subsystem implements the exact same logic using Logical Operator blocks 
% and a Switch.

open_system('slvnvdemo_cv_logic_cascade/Logic Cascade');

%% 
% Finally, open the Signal Builder and note that there are three combinations 
% given for the Boolean inputs *a*, *b*, and *c*. These combinations are _FFF_, 
% _TFT_, and _TTT_.

open_system('slvnvdemo_cv_logic_cascade/Signal Builder');

%% 
% Close the Signal Builder.
close_system('slvnvdemo_cv_logic_cascade/Signal Builder', 0);

%% Comparing MCDC Results in the Coverage Report
% Simulate the model and generate a Coverage Report.

testObj = cvtest('slvnvdemo_cv_logic_cascade');
testObj.settings.decision = 1;
testObj.settings.condition = 1;
testObj.settings.mcdc = 1;
covdata = cvsim(testObj); % Simulate for coverage
cvhtml('exampleReport.html',covdata); % Generate Coverage Report

%% 
% *MCDC Results for MATLAB Function block*
%
% In the generated report, navigate to the details for the MATLAB Function 
% block.
% 
% <<../cvLogicCascadeMcdc_report_MatlabFunc.png>> 
% 
% <<../cvLogicCascadeMcdc_report_MatlabFunc2.png>> 
% 
% The MCDC results for the |if| statement in the MATLAB Function block are 
% as would be expected, given the specified inputs.

%% 
% *MCDC Results for Logic Cascade*
%
% Next examine the results for the logic cascade. Recall that this combination 
% of blocks implements the same logic as the MATLAB code in the MATLAB Function block; 
% therefore, we would expect that the MCDC results would be the same, as well.
% 
% Let's first take a look at the upstream |Or_Block|.  
% 
% <<../cvLogicCascadeMcdc_report_or.png>> 
% 
% Notice that the MCDC summary for this block has a link with the text |"see 
% And_Block"|, referring to the Logical Operator at the root of the cascade. Click 
% on this link to be taken to the section of the report showing results for this 
% block.
% 
% 
% <<../cvLogicCascadeMcdc_report_and.png>> 
% 
% The Logical Operator block at the root of the cascade (in this case |And_Block|) 
% reports the MCDC results for the entire cascade.
% 
% The details for the MCDC analysis of the cascade first show a link illustrating 
% how many blocks are included in the cascade. Clicking on the link |"Includes 
% 2 blocks"| will bring up the model and highlight the two blocks included in 
% the cascade (|Or_Block| and |And_Block|).
% 
% This section of the report then shows the Boolean expression represented 
% by the cascade, in this case _C1 && (C2 | | C3)_, where |C1|, |C2|, and |C3| 
% are the conditions which correspond to the three inputs to the cascade. For 
% each condition, the table illustrates the associated block and its input (shown 
% in parenthesis) as well as the MCDC result. These results indicate that the 
% input combinations |TTx|, |Fxx|, and |TFT| have all been exercised, but |TFF| 
% has not. This matches the expectation given the inputs generated by the Signal 
% Builder (|TTT|, |FFF|, and |TFT|).
% 
% Furthermore, as expected, both the Boolean expression and MCDC results 
% shown for this cascade match what was shown for the |if| statement implementing 
% the equivalent logic in the MATLAB Function block.

%% Coverage Informer and Model Coloring
% Display coverage results on the model using the following command:
cvmodelview(covdata);
%%
%
% <<../cvLogicCascadeMcdc_highlight.png>> 
% 
% As was shown in the Coverage Report, MCDC objectives are not recorded for 
% the individual Logical Operator blocks in a cascade; rather, MCDC objectives 
% are recorded for the Boolean expression represented by the combination of blocks 
% in the cascade, and results are reported on the final block in the cascade. 
% The highlighting of the model reflects this, as well. Given the input combinations 
% |FFF|, |TFT|, and |TTT| for the three inputs *a*, *b*, and *c*, |Or_Block| receives 
% full coverage, because all of the block's Condition coverage objectives have 
% been satisfied. However, because there are MCDC objectives associated with this 
% cascade which have not been satisfied, |And_block| (the final block in the cascade) 
% is highlighted in red.
% 
% Hover over |And_block| for more information.
% 
% <<../cvLogicCascadeMcdc_informer.png>> 
% 
% The tooltip correctly reports that this block does not receive full coverage, 
% because some MCDC objectives for the cascade are not satisfied.

%% Command Line
% You can also retrieve the MCDC results for the logic block cascade  from the 
% MATLAB command line using |mcdcinfo|. Again, MCDC objectives for the cascade 
% will be found on the final block in the cascade.

[coverage_casc, description_casc] = mcdcinfo(covdata, 'slvnvdemo_cv_logic_cascade/Logic Cascade/And_Block')
description_casc.condition(1)
description_casc.condition(2)
description_casc.condition(3)
%% 
% 
% 
% Other blocks that are members of the cascade will not exhibit MCDC objectives.

[coverage_or, description_or] = mcdcinfo(covdata, 'slvnvdemo_cv_logic_cascade/Logic Cascade/Or_Block')

%% Short-Circuiting of Boolean Expressions for MCDC
% In example model |slvnvdemo_cv_logic_cascade|, coverage settings are set 
% such that Logical Operator blocks are treated as short-circuiting.  
%
% Due to this setting, when analyzing a cascade of Logical Operator blocks, the operators in the 
% corresponding Boolean expression are treated as short-circuiting for the purposes 
% of MCDC. As illustrated by the results shown above, this means that MCDC recognizes 
% short-circuiting that occurs both within and across Logical Operator blocks.  
% As such, the MCDC results for the cascade of Logical Operator blocks 
% matches those of the |if| statement in the MATLAB Function block, as the
% latter is always treated as short-circuiting.
% 
% *Short-circuiting within a block*
% 
% Notice that in the example above, the True Out MCDC objective outcome for 
% |C2| is |TTx|, indicating that when |C1| and |C2| are both true, |C3| is inconsequential 
% due to short-circuiting within the |Or_Block|.
% 
% *Short-circuiting across multiple blocks*
% 
% Furthermore, consider the False Out MCDC objective outcome for |C1|, |Fxx|.  
% This outcome illustrates how MCDC analysis recognizes short-circuiting across 
% blocks.  Because the first input to |And_Block| is false, the second input is 
% short-circuited. Subsequently, for the purposes of MCDC, this short-circuits 
% |Or_Block| (and both of its inputs) entirely. The short-circuiting behavior 
% of MCDC for logic block cascades occurs based on the precedence of operations 
% in the corresponding Boolean expression (regardless of the execution order of 
% the Logical Operator blocks during simulation).
%
% *Non-short-circuiting Boolean expressions*
%
% You can also treat the Boolean expression represented by a cascade of
% Logical Operator blocks as non-short-circuiting during MCDC analysis,
% provided that the masking definition of MCDC is being used.  To do so,
% set the parameter *CovLogicBlockShortCircuit* to |"off"| and ensure that
% *CovMcdcMode* is set to |"Masking"|.
% These are, in fact, the default settings for these parameters when 
% creating a new model.
%
% Note, if *CovLogicBlockShortCircuit* is |"off"| and
% *CovMcdcMode* is set to |"UniqueCause"| then the Logical Operator blocks
% in a cascade will be analyzed individually for the purposes of MCDC, and
% MCDC for the Boolean expression represented by the cascade as a whole
% will not be calculated.
%
% Notice that when the cascade in this example is not treated as
% short-circuiting, some MCDC objectives are no longer satisfied by the
% given inputs.

set_param('slvnvdemo_cv_logic_cascade', 'CovLogicBlockShortCircuit', 'off');
set_param('slvnvdemo_cv_logic_cascade', 'CovMcdcMode', 'Masking'); 
covdata_non_sc = cvsim('slvnvdemo_cv_logic_cascade'); % Simulate for coverage with logic block short-circuiting off
cvhtml('exampleReport_non_sc.html',covdata_non_sc); % Generate Coverage Report
%%
%
% <<../cvLogicCascadeMcdc_report_and_non_sc.png>> 
%
