Skip to content

Instantly share code, notes, and snippets.

@samwho
Created August 2, 2024 20:45
Show Gist options
  • Select an option

  • Save samwho/736b295b2de42c16b17222a4257bd9a6 to your computer and use it in GitHub Desktop.

Select an option

Save samwho/736b295b2de42c16b17222a4257bd9a6 to your computer and use it in GitHub Desktop.
import itertools
from sys import stdout
from typing import Self
def emoji_bool(b: bool):
return b and "✅" or "❌"
class Node:
def __and__(self, other):
return And(self, other)
def __or__(self, other):
return Or(self, other)
def __neg__(self):
return Not(self)
def eval(self) -> bool:
raise NotImplementedError()
def children(self) -> list[Self]:
return []
def variables(self) -> list["Variable"]:
variables = []
for child in self.children():
if isinstance(child, Variable):
variables.append(child)
else:
variables.extend(child.variables())
return variables
def truth_table(self):
variables = self.variables()
for variable in variables:
stdout.write(f"{variable.name} |")
print(self)
print("----------")
for values in itertools.product([False, True], repeat=len(variables)):
for i, value in enumerate(values):
variables[i].value = value
stdout.write(f"{emoji_bool(value)}|")
print(emoji_bool(self.eval()))
class BinaryNode(Node):
left: Node
right: Node
def __init__(self, left: Node, right: Node):
self.left = left
self.right = right
def children(self):
return [self.left, self.right]
class UnaryNode(Node):
node: Node
def __init__(self, node: Node):
self.node = node
def children(self):
return [self.node]
class Variable(Node):
name: str
value: bool = None
def __init__(self, name: str):
self.name = name
def __repr__(self):
return self.name
def __str__(self) -> str:
return self.__repr__()
def eval(self):
if self.value is None:
raise Exception(f"variable {self} has no value")
return self.value
def children(self):
return [self.left, self.right]
class And(BinaryNode):
def __repr__(self):
return f"({self.left} ∧ {self.right})"
def eval(self):
return self.left.eval() and self.right.eval()
class Or(BinaryNode):
def __repr__(self):
return f"({self.left} ∨ {self.right})"
def eval(self):
return self.left.eval() or self.right.eval()
class Not(UnaryNode):
def __repr__(self):
return f"(¬{self.node})"
def eval(self):
return not self.node.eval()
A = Variable("A")
B = Variable("B")
C = Variable("C")
expr = -(A & (B | C))
expr.truth_table()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment