codexlogical-implication-truth-table.py
logical-implication-truth-table.py
"""Generate logical-implication-truth-table.png in cwd.
Tested with Python 3.14.4, numpy 2.3.5, matplotlib 3.10.7.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def main():
numbers = [4, 2, 3, 1]
rows = []
implications = []
converses = []
for n in numbers:
a, b = n % 2 == 0, n > 2
implication = not a or b
contrapositive = b or not a
converse = not b or a
assert implication == contrapositive
implications.append(implication)
converses.append(converse)
rows.append([str(n)] + ["T" if x else "F" for x in
(a, b, implication, contrapositive, converse)])
assert implications == [True, False, True, True]
assert converses == [True, True, False, True]
fig, ax = plt.subplots(figsize=(9.3, 4.0), dpi=120, facecolor="white")
ax.axis("off")
fig.suptitle("Classical implication: one forbidden case", fontsize=17, y=.96)
ax.set_title(r"$A$: $n$ is even $B$: $n>2$ T = true, F = false",
fontsize=12, pad=15)
table = ax.table(cellText=rows,
colLabels=[r"$n$", r"$A$", r"$B$", r"$A\to B$",
r"$\neg B\to\neg A$", r"$B\to A$"],
colWidths=[.09, .11, .11, .21, .25, .23],
cellLoc="center", bbox=[0, .16, 1, .76])
table.auto_set_font_size(False)
table.set_fontsize(14)
for (row, col), cell in table.get_celld().items():
cell.set_edgecolor("#9fa9b2")
if row == 0:
cell.set_facecolor("#edf1f4")
elif col >= 3:
true = rows[row - 1][col] == "T"
cell.set_facecolor("#e2f0e9" if true else "#f9dedb")
cell.set_text_props(color="#166044" if true else "#a12f28")
fig.text(.5, .10, "Implication and contrapositive agree in every row.",
ha="center", fontsize=12)
fig.text(.5, .045, "The converse differs at n = 2 and n = 3.",
ha="center", fontsize=12)
fig.subplots_adjust(left=.04, right=.96, top=.75, bottom=.15)
fig.savefig(Path.cwd() / "logical-implication-truth-table.png",
facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()