Logic Expressions
In Ada, logical expressions are expressions that can evaluate to one of two values:
True - Represented by the Ada keyword TRUE
False - Represented by the Ada keyword FALSE
For example:
A := True; -- Assign TRUE
B := False; -- Assign FALSE
if A and B then -- Evaluates to FALSE
...
end if
if A or B then -- Evaluates to TRUE
...
end if
if not A then -- Evaluates to FALSE
...
end if
Any non-zero numeric value will also evaluate to TRUE in a boolean context, while 0 evaluates to FALSE.
C := 1;
if C then -- Evaluates to TRUE
...
end if
D := 0;
if D then -- Evaluates to FALSE
...
end if
Boolean Operators
Ada supports the following Boolean operators:
and - Logical and. Returns true if both operands are true.
or - Logical or. Returns true if either operand is true.
not - Logical not. Reverses the logical state of its operand.
Examples:
A and B -- True if both A and B are true
A or B -- True if either A or B is true
not A -- True if A is false, false if A is true
Ada also has short-circuit evaluation for logical expressions, meaning that the second operand is not evaluated if the first operand determines the result.
You can use logical expressions in if statements, case statements, and loops in Ada. For example:
if A and B then
-- Code
end if
Order of evaluation
The order of evaluation for Boolean operators in Ada is:
NOT - The NOT operator is evaluated first.
AND - The AND operator is evaluated next.
OR - The OR operator is evaluated last.
This is known as the NOT-AND-OR order of evaluation.
For example:
not A and B or C
Will be evaluated as:
NOT A
AND (result of 1 with B)
OR (result of 2 with C)
This ensures that:
NOT operators are applied first
AND operators are applied next
OR operators are applied last
This is important because AND has higher precedence than OR, so it needs to be evaluated first.
We can also use parentheses to explicitly specify the order of evaluation:
(not A) and (B or C)
Here, B or C will be evaluated first, then ANDed with not A.
Relation Operators
Ada has four logic relation operators:
"=" (Equal): Checks if two operands are equal
"/=" (Not equal): Checks if two operands are not equal
"<" (Less than): Checks if the left operand is strictly less than the right operand
">" (Greater than): Checks if the left operand is strictly greater than the right operand
These operators can be used to compare two expressions or variables of compatible types. For example:
A := 1;
B := 2;
if A = B then
... -- This will not execute
end if
if A /= B then
... -- This will execute
end if
if A < B then
... -- This will execute
end if
if A > B then
... -- This will not execute
end if
You can also compare values of different numeric types:
X : Integer := 1;
Y : Float := 1.0;
if X = Y then
... -- This will execute
end if
Notes: Ada do not use "!=" and "==" that are normal ussages in other languages. Also operator "/=" may be interpreted by someone as a division modifier in other languages but in ada this represents "divergence" or "not equal".
Order of evaluation
Here is a table showing the order of evaluation for relation operators (<, >, =, /=) relative to logic operators (AND, OR, NOT) in Ada:
Operator | Order of Evaluation |
NOT | Highest (1) |
<, >, =, /= | Medium (2) |
AND | Medium (2) |
OR | Lowest (3) |
So the order of evaluation from highest to lowest is:
NOT
Relation operators and AND (have equal precedence)
OR
For example, in the expression:
NOT (A = B) AND (C > D OR E /= F)
It will be evaluated as follows:
A = B is evaluated
NOT is applied
C > D and E /= F are evaluated
OR is applied
AND is applied
So in summary, NOT has the highest precedence, relation operators and AND have equal medium precedence, and OR has the lowest precedence. This means expressions with NOT will be evaluated first, followed by relation comparisons, and finally OR operations.
Note: The order of evaluation can be changed in complex expressions using round parenthesis. This can also improve the readability of logic expressions.
Selection Statement
Ada has two selection statements based on logical expressions:
IF statement
CASE statement
The IF statement has the basic form:
if condition then
-- Executes if condition is TRUE
else
-- Optionally, executes if condition is FALSE
end if;
The condition can be any logical expression using variables, operators, and function calls. For example:
A := 1;
B := 2;
if A < B then
Put_Line("A is less than B");
end if;
You can also have an else if clause:
if A < B then
...
elsif A > B then
...
else
...
end if;
The CASE statement has the form:
case expression is
when choice1 =>
-- Executes if expression equals choice1
when choice2 =>
-- Executes if expression equals choice2
...
when others =>
-- (Optional) catch-all for any other values
end case;
For example:
case Day is
when Mon => Put_Line("Monday");
when Tue => Put_Line("Tuesday");
when others => Put_Line("Invalid day");
end case;
So in summary, Ada has two selection statements based on logical expressions:
IF statement - Checks a single condition
CASE statement - Checks multiple conditions against a single expression
Both statements allow you to execute different code blocks based on the evaluation of logical expressions.
Performance Tricks
There are a few shortcut and performance considerations for logic expressions in Ada:
Short-circuit evaluation - Ada uses short-circuit evaluation for logical AND (and then) and logical OR (or else) expressions. This means that if the result can be determined after evaluating the first operand, the second operand is not evaluated. This can improve performance.
Morgan's laws - Ada supports Morgan's laws which allow rearranging logical expressions to improve performance:
NOT (A AND B) <=> (NOT A) OR (NOT B)
NOT (A OR B) <=> (NOT A) AND (NOT B)
These equivalencies allow replacing an expression with multiple NOTs with an equivalent expression that has fewer NOTs. Since NOT is faster than AND and OR, this can improve performance.
For example:
if not (A and B) then ...
-- Can be rewritten as:
if (not A) or (not B) then ...
The second version will likely be faster since it avoids evaluating A and B, and then applying NOT.
- Avoid multiple evaluations - Avoid evaluating the same subexpression multiple times. For example:
if A < B and A > C then ...
Here, A is evaluated twice. Instead store the result in a temporary variable:
Temp := A;
if Temp < B and Temp > C then ...
Now Temp is evaluated only once.
In summary, you can improve the performance of logic expressions in Ada by:
Leveraging short-circuit evaluation
Applying Morgan's laws to reduce the number of NOT operations
Avoiding multiple evaluations by storing subexpressions in temporary variables
Disclaim: This article was created with Rix (AI). I ask the questions so you don't have to. Learn and prosper. ๐