MODULE 4 · CONDITIONS · 4/8

Compound and abbreviated conditions

14 min30 XPExercise

Real business rules combine several tests. COBOL joins conditions with AND, OR and NOT, and lets you leave out repeated words so the code reads like the spec.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. COMPOUND.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-AGE      PIC 99   VALUE 20.
       01  WS-INCOME   PIC 9(6) VALUE 18000.
       01  WS-CODE     PIC X    VALUE "A".
       PROCEDURE DIVISION.
           IF WS-AGE >= 18 AND WS-AGE <= 65
               DISPLAY "1 WORKING AGE"
           END-IF
           IF WS-AGE >= 18 AND <= 65
               DISPLAY "2 SAME TEST, ABBREVIATED"
           END-IF
           IF WS-CODE = "A" OR "B" OR "C"
               DISPLAY "3 CODE IS A, B OR C"
           END-IF
           IF WS-AGE < 25 OR WS-AGE > 60 AND WS-INCOME > 50000
               DISPLAY "4 PRINTED: AND WENT FIRST"
           END-IF
           IF (WS-AGE < 25 OR WS-AGE > 60) AND WS-INCOME > 50000
               DISPLAY "5 NOT PRINTED"
           END-IF
           IF WS-CODE NOT = "A" OR "B"
               DISPLAY "6 ALWAYS TRUE - A BUG"
           END-IF
           IF WS-CODE NOT = "A" AND "B"
               DISPLAY "7 NEITHER A NOR B"
           ELSE
               DISPLAY "7 CODE IS A OR B"
           END-IF
           STOP RUN.

Output:

1 WORKING AGE
2 SAME TEST, ABBREVIATED
3 CODE IS A, B OR C
4 PRINTED: AND WENT FIRST
6 ALWAYS TRUE - A BUG
7 CODE IS A OR B

Precedence: NOT, then AND, then OR

Line 4 surprises people. The writer meant "young or old, and high income", but AND is evaluated before OR, so COBOL read it as WS-AGE < 25 OR (WS-AGE > 60 AND WS-INCOME > 50000). The customer is 20, so the whole thing is true. Line 5 adds parentheses and gets it right.

Rule of thumb: whenever a condition mixes AND and OR, add parentheses. Even if you know the precedence, the next reader may not.

Abbreviated conditions

When consecutive tests share the same subject, you can omit it (line 2). When they also share the operator, you can omit that too (line 3):

Written Means
A >= 18 AND <= 65 A >= 18 AND A <= 65
A = "X" OR "Y" A = "X" OR A = "Y"
A NOT = "X" AND "Y" A NOT = "X" AND A NOT = "Y"

The NOT trap

Line 6 is a genuine production bug pattern. "Code is not A or B" in English means neither. But WS-CODE NOT = "A" OR "B" expands to WS-CODE NOT = "A" OR WS-CODE NOT = "B", which is true for every value. To say "neither", use AND (line 7) — or better, avoid negated abbreviations altogether and use an 88:

       01  WS-CODE         PIC X.
           88  CODE-A-OR-B          VALUE "A" "B".
      *    ...
           IF NOT CODE-A-OR-B

On the job

Business analysts write rules like "customers aged 18–70 who are employed or have a score over 750". Translate them with explicit parentheses, then test the boundaries: 17, 18, 70, 71. Boundary mistakes (> versus >=) are among the most common defects found in code review.

Your task

A loan pre-screening program reads four lines:

  1. applicant age (WS-AGE)
  2. annual income in whole euros (WS-INCOME)
  3. credit score (WS-SCORE)
  4. employment code (WS-EMPLOYMENT): F full-time, P part-time, S self-employed, U unemployed

The applicant is eligible only if all of these hold:

  • age is 18 to 70 inclusive
  • employment code is F, P or S
  • credit score is at least 600
  • income is at least 30,000 or the credit score is at least 750

Display ELIGIBLE or NOT ELIGIBLE. Write it as one IF with a compound condition, and use abbreviated conditions for the age range and the employment codes.

Check your understanding

1. How does COBOL evaluate A OR B AND C?
2. WS-CODE holds "A". Is WS-CODE NOT = "A" OR "B" true?
fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.