# LOGICAL Operators and Expressions

Fortran has five LOGICAL operators that can only be used with expressions whose results are logical values (i.e., .TRUE. or .FALSE.). All LOGICAL operators have priorities lower than arithmetic and relational operators. Therefore, if an expression involving arithmetic, relational and logical operators, the arithmetic operators are evaluated first, followed by the relational operators, followed by the logical operators.

These five logical operators are

• .NOT. : logical not
• .AND. : logical and
• .OR. : logical or
• .EQV. : logical equivalence
• .NEQV. : logical not equivalence
The following is a table of these operators, including there priority and associativity.

 Type Operator Associativity Arithmetic ** right to left * / left to right + - left to right Relational < <= > >= == /= none Logical .NOT. right to left .AND. left to right .OR. left to right .EQV. .NEQV. left to right

### Truth Tables

The evaluation of logical expressions is determined by truth tables. Let us start with the .NOT. operator.

 .NOT. Operand Result .TRUE. .FALSE. .FALSE. .TRUE.

Note that .NOT. is a unary operator. Therefore, .NOT. a yields .TRUE. (resp., .FALSE.) if the value of LOGICAL variable a is .FALSE. (resp., .TRUE.).

The following is the truth table of .AND.:

 .AND. .TRUE. .FALSE .TRUE. .TRUE. .FALSE. .FALSE. .FALSE. .FALSE.

Therefore, the result of logical expression a .AND. b is .TRUE. if and only if both operands a and b are .TRUE.. In all other cases, the result is always .FALSE.

The following is the truth table of .OR.:

 .OR. .TRUE. .FALSE .TRUE. .TRUE. .TRUE. .FALSE. .TRUE. .FALSE.

Therefore, the result of logical expression a .OR. b is .FALSE. if and only if both operands a and b are .FALSE.. In all other cases, the result is always .TRUE. In other words, if one of the two operands of the .OR. operator is .TRUE., the result is .TRUE.

The following is the truth table of .EQV.:

 .EQV. .TRUE. .FALSE .TRUE. .TRUE. .FALSE. .FALSE. .FALSE. .TRUE.

Therefore, the result of logical expression a .EQV. b is .TRUE. if and only if both operands a and b have the same value (i.e., both are .TRUE. or both are .FALSE.). As mentioned in relational expressions, relational operators can only compare arithmetic values and cannot be used to compare logical values. To compare if two logical values are equal, use .EQV.

The following is the truth table of .NEQV.:

 .NEQV. .TRUE. .FALSE .TRUE. .FALSE. .TRUE. .FALSE. .TRUE. .FALSE.

Therefore, the result of logical expression a .NEQV. b is .TRUE. if and only if both operands a and b do not have the same value. As mentioned in relational expressions, relational operators can only compare arithmetic values and cannot be used to compare logical values. To compare if two logical values are not equal, use .NEQV. Note that .NEQV is the opposite of .EQV.. Hence, to test if logical variables x and y have different values, one can use .NOT. (x .EQV. y). Here, if x and y have the same value, x .EQV. y is .TRUE. and .NOT. (x .EQV. y) is .FALSE. On the other hand, if x and y have different values, x .EQV. y is .FALSE. and .NOT. (x .EQV. y) is .TRUE.

### Priority

The priority of .NOT. is the highest, followed by .AND., followed by .OR., followed by .EQV. and .NEQV. Note that .NOT. is right associative, while the other four are left associative.

Here are some examples:

• Let LOGICAL variables Something and Another have values .TRUE. and .FALSE., respectively.
```.NOT.  Something .AND. Another
--> .NOT.  .TRUE.  .AND.  .FALSE.
--> [.NOT.  .TRUE.]  .AND.  .FALSE.
--> .FALSE.  .AND.  .FALSE.
--> .FALSE.
```
In the above, since .NOT. has the highest priority, it is evaluated first. Now, look at the following example:
```.NOT.  (Something .AND. Another)
--> .NOT.  (.TRUE.  .AND.  .FALSE.)
--> .NOT.  ([.TRUE.  .AND.  .FALSE.])
--> .NOT.  .FALSE.
--> .TRUE.
```
• Let LOGICAL variables a, b and c have values .TRUE., .TRUE. and .FALSE., respectively.
```.NOT.  a .OR. .NOT. b .AND. c
--> .NOT.  .TRUE.  .OR.  .NOT.  .TRUE.  .AND.   .FALSE.
--> [.NOT.  .TRUE.]  .OR.  .NOT.  .TRUE.  .AND.   .FALSE.
--> .FALSE.  .OR.  .NOT.  .TRUE.  .AND.   .FALSE.
--> .FALSE.  .OR.  [.NOT.  .TRUE.]  .AND.   .FALSE.
--> .FALSE.  .OR.  .FALSE.  .AND.   .FALSE.
--> .FALSE.  .OR.  [.FALSE.  .AND.   .FALSE.]
--> .FALSE.  .OR.  .FALSE.
--> .FALSE.
```
• Let INTEGER variable n have a value of 4:
```n**2 + 1 > 10 .AND. .NOT. n < 3
--> 4**2 + 1 > 10 .AND. .NOT. 4 < 3
--> [4**2] + 1 > 10 .AND. .NOT. 4 < 3
--> 16 + 1 > 10 .AND. .NOT. 4 < 3
--> [16 + 1] > 10 .AND. .NOT. 4 < 3
--> 17 > 10 .AND. .NOT. 4 < 3
--> [17 > 10] .AND. .NOT. 4 < 3
--> .TRUE. .AND. .NOT. 4 < 3
--> .TRUE. .AND. .NOT. [4 < 3]
--> .TRUE. .AND. .NOT. .FALSE
--> .TRUE. .AND. [.NOT. .FALSE]
--> .TRUE. .AND. .TRUE.
--> .TRUE.
```
Note that the above expression, if you like, can be rewritten with parentheses as follows:
```(n**2 + 1 > 10) .AND. .NOT. (n < 3)
```
• Let INTEGER variables m, n, x and y have values 3, 5, 4 and 2, respectively:
```.NOT. (m > n .AND. x < y) .NEQV.  (m <= n .AND. x >= y)
--> .NOT. (3 > 5 .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .NOT. ([3 > 5] .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .NOT. (.FALSE. .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .NOT. (.FALSE. .AND. [4 < 2]) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .NOT. (.FALSE. .AND. .FALSE.) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .NOT. ([.FALSE. .AND. .FALSE.]) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .NOT. (.FALSE.) .NEQV. (3 <= 5 .AND. 4 >= 2)
--> [.NOT. .FALSE.] .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .TRUE. .NEQV. (3 <= 5 .AND. 4 >= 2)
--> .TRUE. .NEQV. ([3 <= 5] .AND. 4 >= 2)
--> .TRUE. .NEQV. (.TRUE. .AND. 4 >= 2)
--> .TRUE. .NEQV. (.TRUE. .AND. [4 >= 2])
--> .TRUE. .NEQV. (.TRUE. .AND. .TRUE.)
--> .TRUE. .NEQV. ([.TRUE. .AND. .TRUE.])
--> .TRUE. .NEQV. (.TRUE.)
--> .TRUE. .NEQV. .TRUE.
--> .FALSE.
```

### Assignments

The result of a logical expression can be assigned into a LOGICAL variable. Note that only logical values can be put into LOGICAL variables. The follow assignments save the results of the examples into LOGICAL variables:
```LOGICAL :: Result1, Result2, Result3, Result4

Result1 =  .NOT.  Something .AND. Another
Result2 =  .NOT.  a .OR. .NOT. b .AND. c
Result3 =  (n**2 + 1 > 10) .AND. .NOT. (n < 3)
Result4 =  .NOT. (m > n .AND. x < y) .NEQV.  (m <= n .AND. x >= y)
```
Thus, Result1, Result2, Result3 and Results receive .FALSE., .FALSE., .TRUE. and .FALSE., respectively.