The worksheetDownload the PDF
Answers

A8.3 Boolean identities and laws

Boolean algebra and logic circuits · A level · OCR H446 1.4.3, AQA 7517 4.6.5.1, Eduqas A500QS 1.2 · about 20 min

BugBotLab

What this lesson is about

The identities, commutation, association, distribution, double negation and absorption, proved by truth table.

Questions 6 marks in all

  1. [1 mark]Which law is used in the step A ∧ (B ∨ C) = (A ∧ B) ∨ (A ∧ C)?

    1. ADistribution
    2. BAssociation
    3. CCommutation
    4. DAbsorption
    Answer: A. Distribution multiplies out the bracket, like a × (b + c) = ab + ac.
  2. [1 mark]What is A ∨ 1?

    1. A1
    2. BA
    3. C0
    4. D¬A
    Answer: A. Anything OR true is true.
  3. [1 mark]What does A ∨ (A ∧ B) simplify to?

    1. AA
    2. BA ∧ B
    3. CA ∨ B
    4. DB
    Answer: A. Absorption: if A is 1 the result is 1, and if A is 0 then A ∧ B is 0, so the result is A.
  4. [1 mark]What does A ∨ (¬A ∧ B) simplify to?

    1. AA ∨ B
    2. BA
    3. CB
    4. DA ∧ B
    Answer: A. Distribute: (A ∨ ¬A) ∧ (A ∨ B) = 1 ∧ (A ∨ B) = A ∨ B.
  5. [1 mark]Which of these are true for every value of A, B and C?

    Tick every answer that is true.

    1. AA ∧ ¬A = 0
    2. BA ∨ B = B ∨ A
    3. CA ∨ A = 2A
    4. DA ∧ (A ∨ B) = A
    5. EA ∨ (B ∧ C) = (A ∨ B) ∧ C
    Answer: A, B, D. Complement, commutation and absorption hold; A ∨ A is A, and the last one fails at A = 1, C = 0.
  6. [1 mark]What does this program print?

    count = 0
    for a in [0, 1]:
        for b in [0, 1]:
            for c in [0, 1]:
                if (a | (b & c)) != ((a | b) & c):
                    count = count + 1
    print(count)
    Answer:
    2

    A ∨ (B ∧ C) and (A ∨ B) ∧ C differ whenever A = 1 and C = 0, which is 2 of the 8 rows.

The task: prove it by brute force

Write equivalent(f, g). Its inputs f and g are functions of three bits, f(a, b, c), each returning 0 or 1. It tries all eight rows in binary order (a, then b, then c, each 0 then 1) and returns the first row where f and g give different results, as a tuple (a, b, c), or None if they agree on every row. Then, for each (name, f, g) in the list laws, in order, print one line: <name>: equivalent if they agree, or <name>: not equivalent at A=<a> B=<b> C=<c> using the row equivalent returned. That makes six lines.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

laws = [
    ("distribution", lambda a, b, c: a & (b | c), lambda a, b, c: (a & b) | (a & c)),
    ("absorption", lambda a, b, c: a | (a & b), lambda a, b, c: a),
    ("association", lambda a, b, c: (a | b) | c, lambda a, b, c: a | (b | c)),
    ("OR over AND", lambda a, b, c: a | (b & c), lambda a, b, c: (a | b) & (a | c)),
    ("false friend", lambda a, b, c: a | (b & c), lambda a, b, c: (a | b) & c),
    ("half absorbed", lambda a, b, c: a & (a | b), lambda a, b, c: a | b),
]

def equivalent(f, g):
    return None

The hint students can ask for: Two expressions are equal only if they agree on every row, so loop through all eight combinations in binary order and stop at the first row where they differ. Return that row, or None if there is none, and let the printing code decide which message to show.

A solution

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

laws = [
    ("distribution", lambda a, b, c: a & (b | c), lambda a, b, c: (a & b) | (a & c)),
    ("absorption", lambda a, b, c: a | (a & b), lambda a, b, c: a),
    ("association", lambda a, b, c: (a | b) | c, lambda a, b, c: a | (b | c)),
    ("OR over AND", lambda a, b, c: a | (b & c), lambda a, b, c: (a | b) & (a | c)),
    ("false friend", lambda a, b, c: a | (b & c), lambda a, b, c: (a | b) & c),
    ("half absorbed", lambda a, b, c: a & (a | b), lambda a, b, c: a | b),
]

def equivalent(f, g):
    for a in [0, 1]:
        for b in [0, 1]:
            for c in [0, 1]:
                if f(a, b, c) != g(a, b, c):
                    return (a, b, c)
    return None

for name, f, g in laws:
    row = equivalent(f, g)
    if row is None:
        print(f"{name}: equivalent")
    else:
        print(f"{name}: not equivalent at A={row[0]} B={row[1]} C={row[2]}")

Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.