Created
August 2, 2024 20:45
-
-
Save samwho/736b295b2de42c16b17222a4257bd9a6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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