Where Did The Logic Go?
Written by Ian Elliot   
Article Index
Where Did The Logic Go?
Solution

Logic never goes wrong but in this case a simple refactoring of an if block seem to give a different result, even though it does exactly the same thing. Or does it? This Programmer Puzzle explores a gotcha in PHP

Banner

Background

The program was going well but there was a minor problem with an if statement block.

The condition was very long and difficult to read and hence modify.

It was suggested that computing it in parts as a logical expression would allow reuse in other conditionals and make the logic easy to follow.

For the sake of a simple example the code below is much shorter and hence doesn't really need to be evaluated in portions but imagine if the condition was much more complicated.

The original if statement was similar to this simple test for one numeric range to be completely within another:

if($max<20 and $min>15){
echo 'in range';
else{
 echo 'out range';
}

The meaning of this if is clear. If the numeric range specified by $min and $max is completely within the range 15 to 20 then the echo is "in range". You should have no trouble working out for example that if $max=15 and $min=10 then $max<20 is true and $min>15 is false. Thus the final logical expression is:

true and false 

which is by the laws of logic evaluates to false and so we see the string 'out range'.

logic2

Puzzle

So far so good.

The refactoring needed is to evaluate the conditionals and the logical expression separately. This is also trivial, but remember in the real code the conditions and the logic were much more complicated but the principle is exactly the same.

First we evaluate the conditionals:

$a=$max<20;
$b=$min>15;

then the logical expression:

$inrange = $a and $b;

With these in place the if statement can be written:

if($inrange){
echo 'in range';
else{
echo 'out range';
}

So the task is complete.

The only problem is that now with the same values of $max=15 and $min=10 the if statement results in the string 'in range' being echoed to the web page - the exact opposite of the original result, even though the conditionals and logic are the same.

So two if statments that should do the same thing actually do two different things.

What is going on?

Turn to the next page when you are ready to find out.

 

Banner