Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

and/or relational checks in cobol 3

Status
Not open for further replies.

leewest

Programmer
Mar 19, 2007
6
US
I have the following COBOL statement.
004250 IF SW-PRINT = 1
AND HLD-REC-TYPE = '5' OR '4' OR '6'
R11725 MOVE PRT-LINE TO HD-LINE
R11725* MOVE STAA-PRT-LINE TO HD-LINE
004270 PERFORM P1000-HEADING
011725 MOVE HD-LINE TO PRT-LINE
R11725* MOVE HD-LINE TO STAA-PRT-LINE
004280 GO TO W0005-CONTINUE.

My understanding is;
If SW-PRINT = 1 the AND statements are checked.
if HOLD-REC-TYPE does not happen to be '5' the checks for '4' and '6' will not be executed because of
not having been enclosed with (). Is this the correct understanding or am I incorrect?
Thanks
 
Yes Tom.
I quite don't understand why, without parentheses, some people think that the AND operator should be glued to all the following ORs [ponder]
 
In the early days of the IBM mainframe compilers, there were implied paretheses around abreviated onditions. This was clarified with the implementation of the '85 rules, where it is explicitly stated that all such statements are to be evaluated as though they were writen out in full, with the left-to-right and precedence of "and" over "or" always folloed. This caused some of the code I inherited to fail.

Following current rules, HLD-REC-TYPE will always be evaluated, regardless of the value of SW-PRINT.
 
leewest,
This may be what you are remembering from the past. With this code

IF A = B AND C = D AND E = F

As soon as an untrue condition is encountered, control passes to the ELSE or the next statement if there is no ELSE. When all conditions are connected with AND, as soon as one is false, the condition is false.

Likewise, if all conditions are connected with OR, it will check conditions until it finds one that is true. When one is true, there is no need to check any further.

In essence, your IF statement is 3 OR conditions. The first of these is a compound connected with AND and because AND has priority, there are implied parentheses. So, as the others have said you have

IF (SW-PRINT = 1 AND HLD-REC-TYPE = '5') OR
( HLD-REC-TYPE = '4') OR
( HLD-REC-TYPE = '6')

As soon as one of these conditions is true, the compound condition is true. IF SW-PRINT does not equal 1, the first of these is false but since they are connected with OR, it will go to the next condition to see if it is true.
 
Lee contacted me directly, and I clarified my response as it pertains to my FAQ regarding the order of evaluation of complex conditions. Here is a copy of my reply...

I will start from the expression I posted as the equivalent with all the abbreviation removed, and with parentheses added to show the operator precedence.

Evaluate:
[tt]IF (SW-PRINT = 1 AND HLD-REC-TYPE = '5') OR
( HLD-REC-TYPE = '4') OR
( HLD-REC-TYPE = '6')[/tt]
Where:
SW-PRINT is 1, and
HLD-REC-TYPE is '6'

Since this is the expression that the compiler will be evaluating (after supplying the omitted portions of the expression in the source code -- the compiler still has to do the 'real thing'), expressed in disjunctive normal form, the boolean expressions between the ORs will be evaluated left-to-right. A disjunctive expression becomes true if any one of its terms is true, so by standard, the expression evaluation will terminate when a true term is found. (Finding a false term tells us nothing until we come to the end of the expression, since this is disjunction.)

So, step by step...[ol][li]Evaluate SW-PRINT = 1 AND HLD-REC-TYPE = '5'; it is false, so evaluation continues.[/li][li]Evaluate HLD-REC-TYPE = '4'; it is false, so evaluation continues.[/li][li]Evaluate HLD-REC-TYPE = '6'; it is true, so evaluation terminates, and the condition is true.[/li][/ol]

Now consider changing HLD-REC-TYPE to '7':[ol][li]Evaluate SW-PRINT = 1 AND HLD-REC-TYPE = '5'; it is false, so evaluation continues.[/li][li]Evaluate HLD-REC-TYPE = '4'; it is false, so evaluation continues.[/li][li]Evaluate HLD-REC-TYPE = '6'; it is false, so evaluation continues.[/li][li]End-of-expression; condition is therefore false.[/li][/ol]

Now consider changing HLD-REC-TYPE to '4':[ol][li]Evaluate SW-PRINT = 1 AND HLD-REC-TYPE = '5'; it is false, so evaluation continues.[/li][li]Evaluate HLD-REC-TYPE = '4'; it is true, so evaluation terminates, and the condition is true.[/li][/ol]

Notice that an expression in conjunctive normal form (a AND b AND c) has to continue evaluating when a term is true, and can terminate when finding a false term.


Tom Morrison
 
ANSI 85 standards:

IF SW-PRINT = 1
AND HLD-REC-TYPE = "5" OR "4" OR "6"
DO SOMETHING
END-IF.

Is equivalent to the statement:

IF SW-PRINT = 1 AND HLD-REC-TYPE = "5"
DO SOMETHING
END-IF.

If either SW-PRINT and HLD-REC-TYPE does not evaluate true for 1 and 5 respectively there is no further evaluation.

Here is the statment that I would use and my reason for using it;

IF SW-PRINT = 1
AND (HLD-REC-TYPE = "5" OR "4" OR "6")
DO SOMETHING
END-IF.

The code generated is an array with 3 variables for the second condition; 5,4 and 6. First, the test performed is a comparison of SW-PRINT to a static value of 1. If this fails the array is not checked for any of the three values. If the test passes, values in the array are tested against HLD-REC-TYPE. If the comparison returns a condition code of anything other than zero, the test fails causing the evaluation to test false.
 
jibdsnet said:
Is equivalent to the statement:

Well, welcome to Tek-Tips.

Unfortunately, the quoted portion of your post fails the accuracy test.

jibdsnet said:
The code generated is an array with 3 variables for the second condition; 5,4 and 6.

This is just plain silly. Do you have an existence proof for a COBOL compiler that behaves this way?

Tom Morrison
 
Thanks for the welcome, Tom.

Actually, I do not have proof. However, I could create a test and disassemble and send the instructions. Although I don't understand how on the one hand a person can delcare something to be silly then on the other imply they do not know whether such could be.

I registered for this board to learn and, perhaps, help others to learn, that's it.
 
Well, jibdsnet, I think it's silly. I have never used a compiler that works that way, and never hope to use one. It certainly would not conform to '85 (or '68) standards. If you find one that does, then get rid of it, call in a priest to exorcise it.
 
Did you read the post immediately above yours? And the one from PHV datestamped 19 Mar 07 16:39?

so let's go to the standard, which has not changed in this matter since 1985.
Code:
[b]8.8.4.2.4 Abbreviated combined relation conditions[/b]
When simple or negated simple relation conditions are combined with logical connectives in a consecutive sequence such that a succeeding relation condition contains a subject or subject and relational operator that is common with the preceding relation condition, and no parentheses are used within such a consecutive sequence, any relation condition except the first may be abbreviated by:
1) The omission of the subject of the relation condition, or
2) The omission of the subject and relational operator of the relation condition.
Within a sequence of relation conditions, both forms of omission may be used.

[b]8.8.4.2.4.1 [Demonstrates syntax of abbreviated combined conditions]

8.8.4.2.4.2 Syntax Rules[/b]
1) Relation-condition-1 shall not be a boolean relation condition.
2) The result of implied insertion shall comply with the rules of table 6, Combinations of conditions, logical operators, and parentheses.
3) The word NOT shall not be followed immediately by the word NOT or the words IS NOT.

[b]8.8.4.2.4.3 General rules[/b]
1) The effect of using abbreviations is as if the last preceding stated subject were inserted in place of the omitted subject, and the last stated relational operator were inserted in place of the omitted relational operator. The insertion of an omitted subject and/or relational operator terminates once a complete simple condition is
encountered within a complex condition.
2) The interpretation applied to the use of the word NOT in an abbreviated combined relation condition is as follows:
a) If an extended relational operator immediately follows the word NOT, then the NOT is interpreted as a logical operator; otherwise,
b) If the relational operator following the word NOT is a simple relational operator, then the NOT participates as part of the simple relational operator; otherwise,
c) The NOT is interpreted as a logical operator and, therefore, the implied insertion of subject or relational
operator results in a negated relation condition.
NOTE The use of NOT often leads to results that are not intuitive and therefore it should be avoided. Some examples of such usage with the expanded equivalent expression follow:[small][b]
Abbreviated combined relation condition     Expanded equivalent
a > b AND NOT < c OR d                      ((a > b) AND (a NOT < c)) OR (a NOT < d)
a NOT EQUAL b OR c                          (a NOT EQUAL b) OR (a NOT EQUAL c)
NOT a = b OR c                              (NOT (a = b)) OR (a = c)
NOT (a GREATER b OR < c)                    NOT ((a GREATER b) OR (a < c))
NOT (a NOT > b AND c AND NOT d)             NOT (((a NOT > b) AND (a NOT > c)) AND (NOT (a NOT > d)))[/b][/small]
You cite the 1985 standard, but your interpretation is not standard complaint. If your goal is to learn, no problem, but when you appear to make statements of fact that are incorrect, then, as a computer professional, be prepared for posts that seek to correct you. If you are asking a question, use question marks.

And, I call your attention to my post datestamped 19 Mar 07 17:11, where I exposed my stupidity for the world to see. Even the COBOL standard itself issues a warning (rare to see in ISO standards) of the intuitive pitfalls.

Abbreviated combined conditions -- just say NO!
nope.gif


Tom Morrison
 
As I stated earlier, an old compiler assumed parentheses around abreviated conditions. '85 rules prohibit such assumption. I inherited many programs which were written with this assumption. The original stated code looks like that is what happened.
 
webrabbit,

That must be a truly old, or non-FIPS compliant, compiler, since the 1974 ANSI standard contains virtually identical wording to that quoted above, including the examples (but without the warning). I don't have the 1968 standard at hand.

Abbreviated combined conditions: challenging programmers for over three decades.

Tom Morrison
 
TTEST001 CSECT
A000000 B 112(,R15)
DC X'23'
A000005 EQU *
DC C'TTEST001'
DC C' C2 1.4.'
DC C'0 03/29/'
DC C'07 11.30'
DC C'.59'
DC A(A000054)
DC X'E0882C4C'
DC F'0'
DC F'00264'
DC F'0'
DC X'08000000'
DC F'0'
DC F'00004'
DC F'00003'
DC F'0'
DC C' '
A000054 EQU *
DC A(A000000)
DC A(A000080)
DC A(A000230)
DC A(A000005)
DC A(A000000)
DC A(A000178)
DC V(IGZEBST)
STM R14,R12,12(R13) SAVE REGS
L R1,40(,R15)
LM R14,R15,104(R15) RESTORE REGS
BR R15
DC H'0'
A000080 EQU *
DC C' '
DC C' '
DC A(A000094)
A000090 EQU *
DC A(A00012C)
A000094 EQU *
DC A(A000178)
DC F'00001'
DC F'0'
DC C'WORKING '
DC C'STORAGE '
DC C'STARTS H'
DC C'EREPRINT'
DC C' LINETTE'
DC C'ST001SYS'
DC C'OUT 6 4'
DC C' 5 '
A0000DB EQU *
DC X'00'
DC F'0'
DC F'74752'
DC F'00256'
DC F'75776'
DC F'00256'
DC F'0'
DC F'00128'
DC X'000000'
DC C' '
DC X'80000000'
DC X'0025C000'
DC X'01'
DC C' '
DC H'0008'
DC X'0800000C'
DC X'00318000'
DC X'000000'
DC C' '
DC X'C00001'
DC C' '
DC X'00080800'
DC X'000C0031'
DC X'02'
DC C' '
DC H'0008'
DC X'0800000C'
DC H'0049'
DC C' '
A00012C EQU *
DC C'K'
DC X'1A'
STM R0,R0,12(R10) SAVE REGS
MVI 32(R9),C'0'
MVC 33(2,R9),0(R12)
MVC 35(10,R9),39(R10)
MVC 45(10,R9),0(R12)
L R2,288(,R13)
MVC 0(4,R2),8(R10)
MVC 8(4,R2),8(R10)
MVC 16(4,R2),8(R10)
MVC 24(8,R2),57(R10)
MVC 32(4,R2),8(R10)
MVI 40(R2),X'0E'
MVI 48(R2),X'0F'
L R3,300(,R13)
BR R3
A000178 L R10,12(,R12)
L R9,292(,R13)
MVC 236(4,R13),4(R10)
TM 308(R13),X'80'
L R11,16(,R12)
BC 8,116(,R11)
L R2,92(,R13)
L R15,460(,R2)
LA R1,122(,R10)
BALR R14,R15 STD LINKAGE
OI 308(R13),X'80'
TM 308(R13),X'40'
BO 152(,R11)
MVC 304(4,R13),300(R13)
LA R2,146(,R11)
ST R2,300(,R13)
B 0(,R11)
MVC 300(4,R13),304(R13)
OI 308(R13),X'40'
MVC 328(1,R13),32(R9)
OI 328(R13),X'F0'
CLI 328(R13),C'1'
L R11,16(,R12)
BC 7,214(,R11)
CLC 33(2,R9),69(R10)
BE 208(,R11)
CLC 33(2,R9),67(R10)
BE 208(,R11)
CLC 33(2,R9),65(R10)
BNE 214(,R11)
MVC 45(10,R9),35(R9)
B 240(,R11)
TM 84(R13),X'20'
BNO 240(,R11)
L R2,92(,R13)
L R15,460(,R2)
LA R1,104(,R10)
BALR R14,R15 STD LINKAGE
NI 308(R13),X'7F'
L R2,92(,R13)
L R15,548(,R2)
LA R1,103(,R10)
BALR R14,R15 STD LINKAGE
DC C' '
A000230 EQU *
DC X'00108001'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC C'C2TGT'
DC X'4E'
DC C'48'
DC X'03000000'
DC F'00032'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'00055'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'00001'
DC F'0'
DC C'SYSOUT '
DC C'IGZSRTCD'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC A(A000364)
DC F'0'
DC A(A0000DB)
DC F'0'
DC A(A000000)
DC A(A000094)
DC A(A00035C)
DC A(A000090)
DC F'0'
DC A(A000380)
DC F'0'
DC C' '
DC A(A0003B8)
DC A(A000380)
DC F'0'
A00035C EQU *
DC A(A000178)
DC F'0'
A000364 EQU *
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
A000380 EQU *
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
A0003B8 EQU *
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC F'0'
DC X'00'
REQU
END
 
I'm sure you'll see where register 10 is used (array) to store the three static symbols; 5,4 and 6.
 
pointlaugh.gif

This may come as a great shock, but I have no competence in IBM Assembly Language. Others will have to judge this, since my most recent brush with IBM was a line of 360 model 30 machines (a very long line) running 1401 emulation mode, and I was being employed to convert Autocoder to COBOL.

Run the following as a test.
Code:
       identification division.
       program-id. test-abbr-combined.
       data division.
       working-storage section.
       01  pr-head pic x(40) value
           "SW-PRINT    HLD-REC-TYPE    Result".
       01  pr-result value spaces.
           02                      pic x(3).
           02  SW-PRINT            pic 9.
           02                      pic x(13).
           02  HLD-REC-TYPE        pic x.
           02  HLD-REC-TYPE-NUM    redefines HLD-REC-TYPE
                                   pic 9.
           02                      pic x(10).
           02                      pic x(5).
               88  the-result value "True" false "False".

       procedure division.
       a.  
           display pr-head.

           perform varying SW-PRINT from 0 by 1
                     until SW-PRINT > 1

               perform varying HLD-REC-TYPE-NUM from 4 by 1
                         until HLD-REC-TYPE-NUM > 6

                   set the-result to false
                   IF SW-PRINT = 1                             
                     AND HLD-REC-TYPE = '5' OR '4' OR '6' 
                       set the-result to true
                   end-if
                   display pr-result

               end-perform
           end-perform.
           stop run.

Here is the expected output.
Code:
SW-PRINT    HLD-REC-TYPE    Result
   0             4          True
   0             5          False
   0             6          True
   1             4          True
   1             5          True
   1             6          True
[small]Generated by a FIPS compliant (1985) compiler.[/small]

jibdsnet said:
Is equivalent to the statement:
Code:
IF SW-PRINT = 1 AND HLD-REC-TYPE = "5"
   DO SOMETHING
END-IF.

If we substitute this IF statement in the test program, we get this
Code:
SW-PRINT    HLD-REC-TYPE    Result
   0             4          False
   0             5          False
   0             6          False
   1             4          False
   1             5          True
   1             6          False
Clearly not equivalent.

jibdsnet said:
Here is the statment that I would use and my reason for using it;
Code:
IF SW-PRINT = 1
AND (HLD-REC-TYPE = "5" OR "4" OR "6")
   DO SOMETHING
END-IF.
If we substitute this IF statement in the test program, we get this
Code:
SW-PRINT    HLD-REC-TYPE    Result
   0             4          False
   0             5          False
   0             6          False
   1             4          True
   1             5          True
   1             6          True
Clearly not equivalent.

So, if you are using a FIPS-compliant compiler, you should get these results. (It has been a while, but I fairly certain that the FIPS tests exercise the abbreviated combined condition rules.)

Please show us your results. Please document the make and model of the COBOL compiler you are using.


Tom Morrison
 
Expected result with Micro Focus COBOL for Unix V3.1 revision 03.
 
jibdsnet, This does look like assembler generated from COBOL, but where is the COBOL source? I can see the generated logic, but not the source code. It looks like there are parentheses around the abreviated conditions, but since I can't see the source I don't know. BTW, your "array" is just the constants in the literal pool, and R10 is just the pointer to the literal pool.

kt5m, you are right, it was a pre-'74 compiler. I inherited the code in '68.
 
Expected (Identical) result with Fuzitsu COBOL97 V6L10 for Windows.

Steve
 
As I recall, we had two COBOL compilers, the COBOL E compiler and the COBOL F compiler. The COBOL F compiler was too large to run on the smaller machine, which had only 128K of memory. The E compiler interpreted abreviated conditions as though they had parentheses around them, the F compiler did not. There were a number of other differences, which caused many problems.
 
webrabbit,

That sure goes back aways. From IBM System Reference Library, IBM system/360 Disk and Tape Operating Systems COBOL language Specifications (Fourth Edition, November 1966) File Number S360-24, Form C24-3433-3 Page 73;

1. AND and its surrounding conditions are evaluated first, starting at the left of the expression and proceeding to the right.

2. OR and its surrounding conditions are then evaluated, also working from left to right.

Thus, the expression:
A IS GREATER THAN B OR A IS EQUAL TO C AND D IS POSITIVE
would be evaluated as if it were parenthesized as follows:
(A IS GREATER THAN B)
OR
((A IS EQUAL TO C) AND (D IS POSITIVE)).

This was my first encounter with COBOL, running on a 360 model 30 with 64k of main.



Steve
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top