Certification Authorities Software Team (CAST)

Position Paper

CAST-6

####### Rationale for Accepting Masking MC/DC in Certification Projects

Completed August, 2001

####### Rationale for Accepting Masking MC/DC in Certification Projects

# **Background**

Structural coverage analysis in DO-178B (ref. 1) asks the question: Do
the requirements-based test cases adequately exercise the structure of
the source code? Two factors in exercising any structural element of the
source code are: (a) the ability to test that element by setting the
values of the element's inputs (this is the concept of controllability),
and (b) the ability to propagate the output of that element to some
observable point (this is the concept of observability). Controllability
and observability are fundamental concepts used in testing logic
circuits, and also apply well to testing software.

Different coverage measures found in Table A-7 of DO-178B address
different structural elements of the code.

-   For statement coverage, the structural elements to be exercised are
    the statements, and the adequacy requirement is that each statement
    must be executed at least once.

-   For decision coverage, the structural elements to be exercised are
    the decisions, and the adequacy requirement is that each decision
    must take on each possible value at least once.

-   For modified condition/decision coverage (MC/DC), the structural
    elements to be exercised are the logical conditions within a
    decision, and the adequacy requirement is that each logical
    condition must be shown to independently affect the decision's
    outcome.

Showing that each logical condition within a decision independently
affects the decision's outcome requires a minimum test set for each
logical operator as given in the original paper on MC/DC by Chilenski
and Miller (ref. 2) and repeated here as follows:

-   For a 2-input ***and*** operator, there is one test set: (TT, TF,
    FT).[^1]

-   For a 2-input ***or*** operator, there is one test set: (FF, TF,
    FT).

-   For a 2-input ***xor*** operator, there are 4 possible test sets:
    (TT, TF, FT); (TF, FT, FF); (FT, FF, TT), and (FF, TT, TF).

These minimum test sets establish the inputs needed at a logical
operator to show independent effect of each input to that operator. Note
that the minimum test sets are not exhaustive test sets and, hence, will
not detect all possible errors. For example, a test set that contains
the minimum tests for an ***or*** operator will not detect an error if
an ***xor*** is incorrectly coded in place of an ***or***, and vice
versa. However, the minimum test cases are sufficient to show
independent effect required to meet the MC/DC criteria.

Two different approaches to confirming that the minimum tests are
achieved are the unique-cause approach and the masking approach.

> For unique-cause MC/DC, a condition is shown to independently affect a
> decision's outcome by varying just that condition while holding fixed
> all other possible conditions.
>
> For masking MC/DC, a condition is shown to independently affect a
> decision's outcome by applying principles of Boolean logic to assure
> that no other condition influences the outcome (even though more than
> one condition in the decision may change value).

# 

# **Purpose**

The purpose of this white paper is to establish that masking MC/DC:

-   meets the definition of independent effect by guaranteeing the same
    minimum test cases at each logical operator as unique cause, and

-   is acceptable for meeting the MC/DC objective of DO-178B (objective
    5 in Table A-7).

> **Note: This paper assumes that the test cases are developed from the
> software requirements, DO-178B per Section 6.4.4.3.**

**Showing Independent Effect**

A condition independently affects a decision\'s outcome if that
condition *alone* can determine the value of the decision\'s outcome.
Two test cases that show the independent effect of a condition within a
decision are referred to as an independence pair.

*Unique-Cause MC/DC*

Unique cause is the original approach to showing the independent effect
of a condition mentioned in the description of MC/DC in the DO-178B
Glossary. In the unique-cause approach, only the values of the condition
of interest and the decision\'s outcome can change between the two test
cases in an independence pair--everything else must remain the same.
Holding the value of every other condition fixed ensures that the one
condition that changed value is the only condition that influences the
value of the decision\'s outcome. The logic of the decision does not
need to be examined to determine that the condition of interest is
solely responsible for the change in the value of the decision\'s
outcome.

A truth table is often used to illustrate the unique-cause approach. The
left-hand columns of the truth table list all possible input
combinations for the decision, while the shaded columns on the right
indicate the possible independence pairs for each condition. The truth
table for the decision **Z** = (**A** ***or*** **B**) ***and*** (**C**
***or*** **D**), where **A**, **B**, **C**, **D**, and **Z** are Boolean
conditions, is shown in Table 1.

Table 1. Unique-Cause Approach to Independence Pairs for **Z** = (**A**
***or*** **B**) ***and*** (**C** ***or*** **D**)

  -------------- ------- ------- ------- ------- -- ------- -- ------- ------- ------- -------
  **Test Case    **A**   **B**   **C**   **D**      **Z**      **A**   **B**   **C**   **D**
  \#**                                                                                 

  1              *F*     *F*     *F*     *F*        *F*                                

  2              *F*     *F*     *F*     *T*        *F*        10      6               

  3              *F*     *F*     *T*     *F*        *F*        11      7               

  4              *F*     *F*     *T*     *T*        *F*        12      8               

  5              *F*     *T*     *F*     *F*        *F*                        7       6

  6              *F*     *T*     *F*     *T*        *T*                2               5

  7              *F*     *T*     *T*     *F*        *T*                3       5       

  8              *F*     *T*     *T*     *T*        *T*                4               

  9              *T*     *F*     *F*     *F*        *F*                        11      10

  10             *T*     *F*     *F*     *T*        *T*        2                       9

  11             *T*     *F*     *T*     *F*        *T*        3               9       

  12             *T*     *F*     *T*     *T*        *T*        4                       

  13             *T*     *T*     *F*     *F*        *F*                        15      14

  14             *T*     *T*     *F*     *T*        *T*                                13

  15             *T*     *T*     *T*     *F*        *T*                        13      

  16             *T*     *T*     *T*     *T*        *T*                                
  -------------- ------- ------- ------- ------- -- ------- -- ------- ------- ------- -------

With unique cause, each test case can pair with at most one other test
case to show independent effect of a condition. In Table 1, for example,
test case 2 can only be paired with test case 10 to show the independent
effect of **A**. The following are the possible independence pairs for
each condition as shown in Table 1: test pairs (2, 10), (3, 11), and (4,
12) show the independent effect of **A**; (2, 6), (3, 7), (4, 8) show
the independent effect of **B**; (5, 7), (9, 11), and (13, 15) show the
independent effect of **C**; and (5, 6), (9, 10), and (13, 14) show the
independent effect of **D**.

Any combination of the independence pairs (with a minimum of one pair
for each condition) will yield the minimum tests described by Chilenski
and Miller for each logical operator. To see this, consider test cases
2, 5, 6, 7, and 10 from Table 1 for **Z** = (**A *or* B**) ***and***
(**C *or* D**). This set of test cases contains an independence pair for
each condition. These test cases are mapped to a schematic
representation of the code in Figure 1.

![](media/image1.wmf)

Figure 1. Schematic View of **Z** = (**A *or* B**) ***and*** (**C *or*
D**) with test cases 2, 5, 6, 7, and 10

For a test case to count for credit towards MC/DC at a particular
logical operator, the output of the test case at that operator must be
observable. In Figure 1, the output of (**A *or* B**) is unobservable at
**Z** for test case 5 because of the *false* output of (**C *or* D**)
for that test. Similarly, the output of (**C** ***or*** **D**) is
unobservable at **Z** for test case 2 because of the *false* output of
(**A** **or** **B**). Discounting those test cases, there are FF, FT,
and TF tests for each ***or*** operator, and TT, TF, and FT tests for
the ***and*** operator.

The unique cause approach guarantees the minimum tests for each logical
operator for decisions *without* strongly coupled conditions (such as
repeated conditions). The difficulty with coupled conditions stems from
the DO-178B Glossary definition of *decision* that states that "If a
condition appears more than once in a decision, each occurrence is a
distinct condition". Hence, for the decision (**A** ***and*** **B**)
***or*** (**A** ***and*** **C**), showing independent effect by unique
cause requires, among other things, showing what happens when the value
of the first **A** is held constant, while the value of the second **A**
is toggled between *false* and *true*. This typically cannot be
accomplished in any meaningful way. Note that some developers may
establish coding standards that do not allow decisions with coupled
conditions to avoid the coupling problem with unique cause MC/DC.

*Masking*

Masking refers to the concept that specific inputs to a logic construct
can hide the effect of other inputs to the construct. For example, a
*false* input to an ***and*** operator masks all other inputs, and a
*true* input to an ***or*** operator masks all other inputs. The masking
approach to MC/DC allows more than one input to change in an
independence pair, as long as the condition of interest is shown to be
the ***only*** condition that affects the value of the decision outcome.
However, analysis of the internal logic of the decision is needed to
show that the condition of interest is the only condition causing the
value of the decision\'s outcome to change.

To illustrate masking MC/DC, consider again the decision **Z** = (**A**
***or*** **B**) ***and*** (**C** ***or*** **D**). To show the
independent effect of **A**, the subterm (**C *or* D**) must be *true*
because the value of the decision\'s outcome will always be *false* if
(**C *or* D**) is *false*. For unique-cause, the values of **C** and
**D** must be fixed in any independence pair for **A**. However, masking
allows **C** and **D** to change values in the independence pair for
**A** *as long as* the outcome of (**C** **or** **D**) is *true*. In
this way, the masking approach allows for more independence pairs for
each condition than unique cause. For example, test case 2 could be
paired with either test case 10, 11, or 12 to show the independent
effect of **A** using masking. Table 2 shows the possible independence
pairs for the example decision using the masking approach.

Table 2. Masking Approach to Independence Pairs for (**A** ***or***
**B**) ***and*** (**C** ***or*** **D**)

<table>
<colgroup>
<col style="width: 11%" />
<col style="width: 5%" />
<col style="width: 0%" />
<col style="width: 5%" />
<col style="width: 0%" />
<col style="width: 5%" />
<col style="width: 0%" />
<col style="width: 5%" />
<col style="width: 0%" />
<col style="width: 5%" />
<col style="width: 0%" />
<col style="width: 4%" />
<col style="width: 0%" />
<col style="width: 4%" />
<col style="width: 0%" />
<col style="width: 2%" />
<col style="width: 0%" />
<col style="width: 12%" />
<col style="width: 0%" />
<col style="width: 13%" />
<col style="width: 0%" />
<col style="width: 13%" />
<col style="width: 0%" />
<col style="width: 13%" />
</colgroup>
<tbody>
<tr class="odd">
<td><strong>Test Case #</strong></td>
<td><strong>A</strong></td>
<td colspan="2"><strong>B</strong></td>
<td colspan="2"><h4 id="x">X*</h4></td>
<td colspan="2"><strong>C</strong></td>
<td colspan="2"><strong>D</strong></td>
<td colspan="2"><h4 id="y">Y*</h4></td>
<td colspan="2"><strong>Z</strong></td>
<td colspan="2"></td>
<td colspan="2"><strong>A</strong></td>
<td colspan="2"><strong>B</strong></td>
<td colspan="2"><strong>C</strong></td>
<td colspan="2"><strong>D</strong></td>
</tr>
<tr class="even">
<td>1</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td></td>
</tr>
<tr class="odd">
<td>2</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2">10, 11, 12</td>
<td colspan="2">6, 7, 8</td>
<td colspan="2"></td>
<td></td>
</tr>
<tr class="even">
<td>3</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2">10, 11, 12</td>
<td colspan="2">6, 7, 8</td>
<td colspan="2"></td>
<td></td>
</tr>
<tr class="odd">
<td>4</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2">10, 11, 12</td>
<td colspan="2">6, 7, 8</td>
<td colspan="2"></td>
<td></td>
</tr>
<tr class="even">
<td>5</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">7, 11, 15</td>
<td>6, 10, 14</td>
</tr>
<tr class="odd">
<td>6</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">2, 3, 4</td>
<td colspan="2"></td>
<td>5, 9, 13</td>
</tr>
<tr class="even">
<td>7</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">2, 3, 4</td>
<td colspan="2">5, 9, 13</td>
<td></td>
</tr>
<tr class="odd">
<td>8</td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">2, 3, 4</td>
<td colspan="2"></td>
<td></td>
</tr>
<tr class="even">
<td>9</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">7, 11, 15</td>
<td>6, 10, 14</td>
</tr>
<tr class="odd">
<td>10</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2">2, 3, 4</td>
<td colspan="2"></td>
<td colspan="2"></td>
<td>5, 9, 13</td>
</tr>
<tr class="even">
<td>11</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2">2, 3, 4</td>
<td colspan="2"></td>
<td colspan="2">5, 9, 13</td>
<td></td>
</tr>
<tr class="odd">
<td>12</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2">2, 3, 4</td>
<td colspan="2"></td>
<td colspan="2"></td>
<td></td>
</tr>
<tr class="even">
<td>13</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">7, 11, 15</td>
<td>6, 10, 14</td>
</tr>
<tr class="odd">
<td>14</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td>5, 9, 13</td>
</tr>
<tr class="even">
<td>15</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>F</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2">5, 9, 13</td>
<td></td>
</tr>
<tr class="odd">
<td>16</td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"><em>T</em></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td colspan="2"></td>
<td></td>
</tr>
</tbody>
</table>

\* Note that ***[X]{.underline}*** and ***[Y]{.underline}*** represent
intermediate subterm (**A *or* B**) and subterm (**C *or* D**),
respectively

Another way of examining the issue is to substitute proxy variables for
all but the subterm of interest. For example, when looking for the
independence of **A** or **B** in the above example, substitute the
value of ***[Y]{.underline}*** for the subterm (**C** ***or*** **D)**
and then the same rules as unique-cause apply.

To verify that the minimum test cases exist for each logical operator
with masking, consider the test cases 2, 5, 6, 7, and 12 shown with the
schematic representation in Figure 2. This test set is the same as the
test set in Figure 1, except test case 12 has replaced test case 10. In
terms of independence pairs, test cases 2 and 12 together form an
independence pair for **A** under the definition of masking.

Note that the input values in Figure 2 are the same as in Figure 1
except for the inputs in test case 12 to (**C** ***or*** **D**). That
is, the difference that masking makes for the independence pair for
**A** is localized to a single logical operator. Note also, that the
minimum tests at each operator are still observed in this example.
Minimum tests for each logical operator are guaranteed in all cases with
the masking approach, for decisions with non-coupled as well as coupled
conditions.

![](media/image2.wmf)

Figure 2. Schematic View of (**A *or* B**) ***and*** (**C *or* D**) with
test cases 2, 5, 6, 7, and 12

*Comparing Unique Cause and Masking*

Both unique-cause MC/DC and masking MC/DC guarantee the minimum tests
discussed by Chilenski and Miller at each logical operator of a
decision---thus, showing the independent effect of each condition in the
decision. Unique-Cause MC/DC and Masking MC/DC are identical for
decisions with a common logical operator; that is, for decisions such as
(**A** ***and*** **B** ***and*** **C**) or (**A** ***or*** **B**
***or*** **C**). When comparing unique cause and masking for decisions
with mixed logical operators (e.g., (**A** ***or*** **B**) ***and***
**C**), the following points should be considered:

-   In most cases, masking MC/DC allows more independence pairs per
    condition than unique-cause MC/DC. Any test set that satisfies
    unique cause will also satisfy masking; that is, masking
    independence pairs are a superset of unique-cause independence
    pairs. The advantage of having more independence pairs is the
    potential to reduce time for both humans and tools to determine
    whether the requirements-based test cases provide MC/DC.

-   In general, the same number of test cases are needed to satisfy
    unique cause as masking.

-   Masking MC/DC requires analysis of the decision logic to confirm
    either the minimum tests for each logical operator, or the
    independence pair for each condition in the decision. This analysis
    is not needed for unique-cause MC/DC.

-   Masking MC/DC can be applied to decisions with coupled conditions.
    Hence, masking can be applied to decisions where unique-cause cannot
    be applied.

**Note on Error Sensitivity**

It is tempting to compare the unique-cause approach to masking with
respect to the ability to detect errors. In a research project funded by
the FAA, John Chilenski (of the Boeing Company) carried out a comparison
of unique-cause MC/DC and masking MC/DC. The full report (ref. 3) will
be available on the FAA web-site in the very near future
(<http://av-info.faa.gov/software>). In a recent white paper, Chilenski
concluded that his analysis of error sensitivity between unique-cause
and masking "has not shown that there is any significant difference"
(ref. 4). However, reliance on such a comparison is unwise because: (a)
the purpose of MC/DC is to determine the adequacy of the
requirements-based tests to exercise the structure of the code---not to
detect errors, (b) analysis of the ability of different test sets to
detect different types of errors is extremely complex and subjective,
and (c) Chilenski's work has not been reviewed by the engineering or
academic community.

**Summary**

According to SC-190/WG-52 Frequently Asked Question #43 (ref. 5),
structural coverage analysis complements requirements-based tests by:

1.  Providing *"evidence that the code structure was verified to the
    degree required for the applicable software level";*

2.  Providing "*a means to support demonstration of absence of
    unintended functions*"; and

3.  Establishing "*the thoroughness of requirements-based testing*".

Masking MC/DC, as well as unique-cause MC/DC, satisfies all three of
these "intents".

Both the unique-cause and masking approaches to MC/DC provide the same
minimum tests of a logical operator in a decision. These minimum tests
confirm that each condition independently affects the decision's
outcome. The significant difference between the two approaches is that
masking requires analysis of the logic of each decision, whereas
unique-cause does not. Note that the masking MC/DC artifacts should be
subject to the same planning, configuration management, and quality
assurance requirements as any other artifact of the verification
process.

When DO-178B was written, the research on masking MC/DC was still being
carried out; therefore, unique-cause MC/DC was the technique documented.
Since that time, research has shown that masking MC/DC also meets the
intent of the MC/DC objective. Therefore, it is proposed that masking
MC/DC be considered an acceptable method for meeting MC/DC by applicants
striving to meet the objectives of DO-178B, Level A.

**References**

1\. *RTCA/DO-178B, Software Considerations in Airborne Systems and
Equipment Certification*. RTCA, Inc., Washington, D. C., December 1992.

2\. Chilenski, John Joseph; and Miller, Steven. P.: "Applicability of
modified condition/decision coverage to software testing", Software
Engineering Journal, Vol. 7, No. 5, September 1994, pp. 193-200.

3\. Chilenski, John Joseph: An Investigation of Three Forms of the
Modified Condition Decision Coverage (MCDC) Criterion. Deliverable to
NASA Langley Research Center under contract NAS1-20341, January 2000.

4\. Chilenski, John Joseph: MCDC Forms (Unique-Cause, Masking) versus
Error Sensitivity, a white paper submitted to NASA Langley Research
Center under contract NAS1-20341, January 2001.

5\. *RTCA/DO-248A, Second Annual Report for Clarification of DO-178B
\"Software Considerations in Airborne Systems and Equipment
Certification\"*. RTCA, Inc., Washington, D. C., September 13, 2000.

#### 

[^1]: ^^ For convenience, the inputs to a test case are written as T
    for *true* and F for *false*. The notation TT, for example,
    represents a 2-input test case where both inputs are *true*.