Performing MCDC for a condition (A && B && C) || D - unit-testing

I have a situation where I need to write few test cases to get complete coverage of the code.
At a perticular branch I got following situation
if((A && B && C) || D)
if((A && B && C) || D)
{
//perform task 1'
}
else
{
//perform task 2;
}
But with this I am unable to get test case combination for MCDC..
What could be the way out here...

Your way out could be to use the tool MCDC to identify possible test cases.
Doing this manually could be really a lot of work, because of the many possible test pair combinations.
I am sorry that I cannot share all the details of my research. I would recomend to start with reading "An Investigation of Three Forms of the Modified Condition Decision Coverage (MCDC) Criterion", published by the FAA (DOT/FAA/AR-01/18).
Including Masking there are 52 possible test pairs. If you do a proper WhiteBox Analysis, including boolean short cut evaluation, then you will find even 63 MCDC test pairs. Apllying the set cover algorithm will result in 3 possible minimum test sets.
Doing some heuristics will lead to the maybe surprising test vector:
Test Pair for Condition 'a': 0 14 (Unique Cause)
Test Pair for Condition 'b': 8 14 (Unique Cause)
Test Pair for Condition 'c': 12 14 (Unique Cause)
Test Pair for Condition 'd': 0 1 (Unique Cause)
Testvector: Recommended Result: 0 1 8 12 14
0: a=0 b=0 c=0 d=0 (0)
1: a=0 b=0 c=0 d=1 (1)
8: a=1 b=0 c=0 d=0 (0)
12: a=1 b=1 c=0 d=0 (0)
14: a=1 b=1 c=1 d=0 (1)

With MC/DC you have to find, for each condition (input) i, a pair of combinations where only i toggles, and the output changes. For A to have a toggling effect on the result of (A && B && C) || D, B and C need to be true and D needs to be false. Similarly, for B to have a toggling effect, A and C need to be true, and D needs to be false. With D it is a bit different: The output toggles on D given that at least one of A, B, C is false. This gives the following combinations (x represents the toggling input):
A B C D
x 1 1 0 - for A
1 x 1 0 - for B
1 1 x 0 - for C
q r s x - for D, where q + r + s < 3
By multiplying out the lines for A, B, and C we get (added lines numbers and column R for the result):
# A B C D R
1 0 1 1 0 0 - for A
2 1 1 1 0 1 - for A
3 1 0 1 0 0 - for B
4 1 1 1 0 1 - for B (duplicate)
5 1 1 0 0 0 - for C
6 1 1 1 0 1 - for C (duplicate)
7 q r s x - for D, where q + r + s < 3
Lines 4 and 6 are duplicates of line 2. To represent line 7, we can use one of the lines 1,3,5 and add the same line with D set to 1, which gives the following result (picked line 1):
# A B C D R
1 0 1 1 0 0 - for A and D
2 1 1 1 0 1 - for A,B,C
3 1 0 1 0 0 - for B
4 1 1 0 0 0 - for C
5 0 1 1 1 1 - for D
That's one possible solution.

I think one way could be for all the false combination of (A && B && C) keep D = 1 and for true combination of (A && B && C) keep D = 0 and at the last Keep all inputs 0. So test case combination can be:
a b c d
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0
0 0 0 0

Related

Efficient way of finding all feasible solutions to set of Boolean constrains

I'm solving the following problem with cp_model from ortools.sat.python in Python, but I'm looking for a more efficient solver.
Problem:
Let's have n boolean variables A, B, C, ...
The goal is to find all possible/feasible combinations on boolean values that satisfy a set of rules. There are 3 types of rules:
One and only one of (A, B) might be true. I'm applying this as:
model.AddBoolXOr([A,B])
model.Add(A == False).OnlyEnforceIf(B)
model.Add(B == False).OnlyEnforceIf(A)
At most one of (C, D, E) might be true. I'm applying this as:
model.Add(C == False).OnlyEnforceIf(D)
model.Add(C == False).OnlyEnforceIf(E)
model.Add(D == False).OnlyEnforceIf(C)
model.Add(D == False).OnlyEnforceIf(E)
model.Add(E == False).OnlyEnforceIf(C)
model.Add(E == False).OnlyEnforceIf(D)
F is only possible when (A and ~C) or (B and (C or E)). First I'm converting this to CNF: (A or B) and (B or ~C) and (A or C or E). Then I insert that to the model:
model.Add(F == False).OnlyEnforceIf([A.Not(), B.Not()])
model.Add(F == False).OnlyEnforceIf([B.Not(), C])
model.Add(F == False).OnlyEnforceIf([A.Not(), C.Not(), E.Not()])
The result for above looks like:
1 0 0 0 0 0
1 0 1 0 0 0
1 0 0 1 0 0
1 0 0 0 1 0
1 0 0 0 1 1
1 0 0 0 0 1
1 0 0 1 0 1
0 1 0 0 1 1
0 1 0 0 1 0
0 1 0 0 0 0
0 1 0 1 0 0
0 1 1 0 0 0
0 1 1 0 0 1
Since my problem is big, I'm looking for a more efficient solution. I found minisat but I'm not sure if it is possible to express the above constraints in the DIMACS form and make minisat calculate all feasible solutions (by default it finds first and stops).
Is there any there solver capable of solving such a problem?
what a convoluted way of writing the model.
1)
model.Add(a + b == 1)
or
model.AddBoolOr([a, b])
model.AddImplication(a, b.Not())
model.AddImplication(b, a.Not())
model.Add(c + d + e <= 1)
or
model.AddImplication(c, d.Not())
model.AddImplication(c, e.Not())
model.AddImplication(d, c.Not())
model.AddImplication(d, e.Not())
model.AddImplication(e, c.Not())
model.AddImplication(e, d.Not())
Create 1 bool var for each and
(A and ~C) <=> G
model.AddImplication(G, A)
model.AddImplication(G, C.Not())
model.AddBoolOr([A.Not(), C, G.Not())
then F is only possible if x1 or x2 or x3
model.AddBoolOr([F.Not(), x1, x2, x3])

How to code: "If (A is True) and (B is True when C is True)"

How do I code this if statement (let's say in c++):
if (condition1 == true and condition2 == true (when condition3 == true))
{
// condition2 need to be true only when condition3 is true
}
When figuring out how to express any boolean-predicate it helps to build a truth-table that lists the possible values of each boolean value in separate columns and the expected output in its own column. The values in each column increment by +1 as though each column is a binary-digit in a base-2 number.
Like so:
A B C Output
---------------------
0 0 0 ?
0 0 1 ?
0 1 0 ?
0 1 1 ?
1 0 0 ?
1 0 1 ?
1 1 0 ?
1 1 1 ?
Based on your question's title (and not the example pseudocode that you posted), I assume you want this output:
A B C Output
---------------------
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 0
1 0 0 0
1 0 1 0
1 1 0 0
1 1 1 1
...which is just a trivial AND between all 3 values:
bool a = ...
bool b = ...
bool c = ...
if( a && b && c )
{
do_the_thing();
}

How to fix a bug in my homework solution in C++?

I need to write a program which reads the statistics of n League A football teams and prints the teams name which fall in League B.
A team falls in League B, if it has less than k points after having played m weeks where m is between 1 and 150. Each team gets three points for a win, one point for draw and zero points when lost.
Input Specification: In the first line, you will be given the number of teams 0 < n ≤ 500 and the points 0 < k ≤ 300 needed to stay in league A. Then in the following n lines, there will be the team name and its results. Semicolon indicates the end of input series.
Number 2 represents win, number one represents draw and number zero represents loss.
Output specification:
Sample Input I
4 19
Team_A 1 1 1 1 1 1 1 1 1 0 1 1 1 0 2 1 0 ;
Team_B 0 1 0 2 2 1 1 0 1 1 0 2 0 1 0 0 2 ;
Team_C 0 0 1 0 2 2 2 1 1 1 1 1 0 0 2 1 2 ;
Team_D 0 1 0 1 2 1 2 1 0 0 0 2 2 2 0 0 0 ;
Sample Output I
Team_A 16
Team_B 18
This is the code I came up with, but the output is wrong and I don't know why,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n,points,sum=0,i,value;
char name[15];
char p;
scanf("%d %d",&n,&points);
for(i=1;i<=n;i++)
{
scanf("%s",&name);
do
{
scanf("%c ",&p);
if(p!=';')
{
value=p-48;
sum=sum+value;
}
}while(p!=';');
if(sum<=points)
printf("%s %d",name,sum);
}
return 0;
}
You might look for problems by stuffing the program with output statements.
If you add after scanf("%c ",&p); an output statement to show the value of p, you will find that the first value for p is a space character, which spoils your calculation.
In the same way, if you trace the value of value, you will find that you forgot to initialize this variable to zero for each team.

Formula that uses previous value

In Stata I want to have a variable calculated by a formula, which includes multiplying by the previous value, within blocks defined by a variable ID. I tried using a lag but that did not work for me.
In the formula below the Y-1 is intended to signify the value above (the lag).
gen Y = 0
replace Y = 1 if count == 1
sort ID
by ID: replace Y = (1+X)*Y-1 if count != 1
X Y count ID
. 1 1 1
2 3 2 1
1 6 3 1
3 24 4 1
2 72 5 1
. 1 1 2
1 2 2 2
7 16 3 2
Your code can be made a little more concise. Here's how:
input X count ID
. 1 1
2 2 1
1 3 1
3 4 1
2 5 1
. 1 2
1 2 2
7 3 2
end
gen Y = count == 1
bysort ID (count) : replace Y = (1 + X) * Y[_n-1] if count > 1
The creation of a dummy (indicator) variable can exploit the fact that true or false expressions are evaluated as 1 or 0.
Sorting before by and the subsequent by command can be condensed into one. Note that I spelled out that within blocks of ID, count should remain sorted.
This is really a comment, not another answer, but it would be less clear if presented as such.
Y-1, the lag in the formula would be translated as seen in the below.
gen Y = 0
replace Y = 1 if count == 1
sort ID
by ID: replace Y = (1+X)*Y[_n-1] if count != 1

Bitwise operation to get 1 if both are 0

I'd need to perform a bitwise operation (or a serie) so that:
0 1 = 0
1 1 = 1
1 0 = 0
so far AND (&) works fine but I also need that
0 0 = 1
and here AND (&) is not the correct one.
I'm using it in a jquery grep function that reads:
jQuery.grep(json, function (e, index) {
return (e.value & (onoff << 3)) != 0;
});
where onoff could be either 1 or 0 and e.value is a representation of a 4 bits string (i.e. could be "1001"). In this above example I'm testing first bit on the left (<< 3).
Can this be done with a serie of AND, OR, XOR?
This is just XNOR(a, b), which is equal to NOT(XOR(a, b)), i.e. exclusive OR with the output inverted. In C and C-like languages this would be:
!(a ^ b)
or in your specific case:
return !((e.value >> 3) ^ onoff);
Having said that, you could just test for equality:
return (e.value >> 3) == onoff;
This looks roughly like XOR which has the following results table:
0 0 = 0
0 1 = 1
1 0 = 1
1 1 = 0
Now you want to have the opposite, meaning that you want 1 if both inputs are the same value. And this leads us to NOT XOR
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1