- Forward


Inferential Transformations
A Programming Pattern


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Review
Back SMYC Forward
  • Some Constructs that use boolean Values:
    • Conditions (e.g., if)
    • Loops/Iterations (e.g., while, for)
  • Some Operations that Evaluate to boolean Values:
    • Relational operations (e.g., >, ==) evaluate to a boolean value
    • Boolean operations (e.g., ||, &&) can be performed on boolean values and evaluate to a boolean value
Motivation
Back SMYC Forward
  • A Common Situation:
    • Messy/complicated conditions and/or loops
  • A Good Practice:
    • Transform the boolean expressions to reduce the mess
  • Examples:
    • Eliminating empty if or else blocks
    • Simplifying nested if statements
    • Simplifying sequential if statements
Eliminating Empty Blocks
Back SMYC Forward
  • An Example of Inelegant Code:
    • if (x <= limit) { } else { message = x + " exceeds the limit."; }
  • The Solution:
    • Negate the boolean expression
Negating Boolean Expressions
Back SMYC Forward
  • The Direct Approach:
    • Use the ! operator
    • if (!(x <= limit)) { message = x + " exceeds the limit."; }
  • Using Rules of Inference:
    • Evaluate the negated expression by hand
Negating Boolean Expressions (cont.)
Back SMYC Forward
  • Simple Rules of Inference:
    • !(a > b) becomes (a <= b)
    • !(a >= b) becomes (a < b)
    • !(a < b) becomes (a >= b)
    • !(a <= b) becomes (a > b)
    • !(a == b) becomes (a != b) or ((a < b) || (a > b))
  • de Morgan's Laws:
    • !(a && b) becomes (!a) || (!b)
    • !(a || b) becomes (!a) && (!b)
Simplifying Nested if Statements
Back SMYC Forward
railroad_nested-if railroad_nested-if-inference
Simplifying Nested if Statements (cont.)
Back SMYC Forward
  • An Example of a Common Situation:
    • if (speed > limit) { if (type == SPORTSCAR) { // Additional Statements } }
  • Using Rules of Inference:
    • if ((speed > limit) && (type == SPORTSCAR)) { // Additional Statements }
Simplifying Sequential if Statements
Back SMYC Forward
  • An Example of a Common Situation:
    • Sequential if statements with identical ramifications. For example:
    • if (weight > safeWeight) { atRisk = true; } if (bloodSugar > safeBloodSugar) { atRisk = true; }
  • Using Rules of Inference:
    • if ((weight > safeWeight) || (bloodSugar > safeBloodSugar)) { atRisk = true; }
Expanding Boolean Expressions Involving ||
Back SMYC Forward
  • The Initial Correct Code:
    • if ((weight > safeWeight) || (bloodSugar > safeBloodSugar)) { ++risk; }
  • An Example of a Common Mistake:
    • if (weight > safeWeight) { ++risk; } if (bloodSugar > safeBloodSugar) { ++risk; }
  • The Correct Expansion:
    • if (weight > safeWeight) { ++risk; } else { if (bloodSugar > safeBloodSugar) { ++risk; } }
Expanding Boolean Expressions Involving ||
Back SMYC Forward
railroad_or-if-if railroad_or-if-else-if
Expanding Boolean Expressions Involving ||(cont.)
Back SMYC Forward
  • Should You Expand?
    • Almost never -- the use of || is simpler and clearer!
    • railroad_or
  • Why Not?
    • The possibility of making a mistake
    • Even the correct expansion involves duplicate code
Short Circuits
Back SMYC Forward
  • Nested if Statements with a Twist:
    • if (Array.getLength(sales) > 1) { if (sales[1] == 0) { // Additional statements } }
  • A More Elegant Implementation:
    • if ((Array.getLength(sales) > 1) && (sales[1] == 0)) { // Additional statements }
  • A Potential Problem:
    • sales[1] doesn't exist if sales has a length of 1
Short Circuits (cont.)
Back SMYC Forward
  • Resolving the Problem:
    • Stop evaluating the boolean expression when the outcome can be determined
  • Rules of Inference:
    • false && x evaluates to false (sometimes called the simplification rule)
    • true || x evaluates to true (sometimes called the addition rule)
  • Taking Advantage:
    • Think carefully about the order of complicated boolean expressions
There's Always More to Learn
Back -