Logical Expressions with Unknown

Posted by Simon L. Prinsloo on 18-Nov-2011 04:32

Hi

We picked up some strange behaviour which does not seem to conform with documentation.

According to the ABL handbook, in the section "Assigning a value to a variable", using an unknown value in any expression will yield the unknown value. I do however expect slightly different results in logical expressions, mainly due to short circuit evaluation. I do however get one condition which does not make sense to me.

I exprect (TRUE OR ?) to be true, since the part to the right of the operation will not be evaluated for the OR once it is true.

I would also expect (FALSE AND ?) to be FALSE, since the part to the right of the operation will not be evaluated for the AND once any condition is not true.

OR must also continue to evaluate the second expression ifthe first is not true, so I expect (? OR TRUE) to be true as well.

In the code below, I would thus expect Five unknowns, two trues and a false, but that is not what I get.

Even though (? AND FALSE) should not evaluate x, (since AND must stop if the left hand is not true) and consequently always yield a ? value, but it does not. When X = FALSE, the expression returns FALSE instead, which means that AND did not short circuit.

Should this be considered a bug?

Example code:

DEFINE VARIABLE UAT AS LOGICAL     NO-UNDO.
DEFINE VARIABLE UAF AS LOGICAL     NO-UNDO.
DEFINE VARIABLE TAU AS LOGICAL     NO-UNDO.
DEFINE VARIABLE FAU AS LOGICAL     NO-UNDO.

DEFINE VARIABLE UOT AS LOGICAL     NO-UNDO.
DEFINE VARIABLE UOF AS LOGICAL     NO-UNDO.
DEFINE VARIABLE TOU AS LOGICAL     NO-UNDO.
DEFINE VARIABLE FOU AS LOGICAL     NO-UNDO.

DEFINE VARIABLE UNK AS LOGICAL     NO-UNDO.


ASSIGN UNK = ?
       UAT = UNK AND TRUE
       UAF = UNK AND FALSE
       TAU = TRUE AND UNK
       FAU = FALSE AND UNK

       UOT = UNK OR TRUE
       UOF = UNK OR FALSE
       TOU = TRUE OR UNK
       FOU = FALSE OR UNK
       .


DISP UAT UAF TAU FAU
     UOT UOF TOU FOU.

All Replies

Posted by Admin on 18-Nov-2011 05:58

It's coming down to a combination of handling of unknown values and how logical expressions are evalated.

The ABL is lazy, so when the whole logical expression can be evaluated without checking each parts, only the first parts are touched:

TRUE OR ? : This is TRUE as soon as the first part is TRUE. There is no need to check the ?, it's always going to be TRUE

FALSE OR ?: This needs to evalate the second part, hence it falls accross the ? and the whole expression becomes ?.

This lazyness is *very* helpful in other cases:

IF VALID-HANDLE (hBuffer) AND hBuffer:AVAILABLE THEN ....

Here the ABL will only evaluate the hBuffer:AVAILALBE, when the first part is TRUE. Otherwize you'd run into runtime errors on the second part (accessing a property of an invalid handle) which is similar to encountering an ?

Posted by Simon L. Prinsloo on 20-Nov-2011 14:15

That is correct and indeed what I said as well. What you call "Lazy" is what I called short circuit.

But still, by that logic, taking into account the (handy, usefull Lazy ways of the compiler) I would expect the follwibg, which I don't get:

? AND FALSE = ?.

Why? Because as soon as the left of the AND is not true, the laziness should stop the evaluation and return whatever is to the left. In this case, ?.

But that is not what happens. It seems that the compiler does evaluate what is to the right and then returns FALSE. This specific condition just seems wrong to me.

As a more practical example, I do not expect the following code to pop up the message box, since I expect Lazy to figgure that, sincethe expression can never be true, it must be unknown. Yet you will get the message box.

Sample Code:

FUNCTION xx RETURNS LOGICAL():

    MESSAGE "True, False or Unknown?"

        VIEW-AS ALERT-BOX QUESTION BUTTONS YES-NO-CANCEL SET res AS LOGICAL.

    RETURN res.

END FUNCTION.


DEFINE VARIABLE unk AS LOGICAL INIT ?    NO-UNDO.



DISP unk AND xx()

This thread is closed