2021-05-10 19:32:53 +02:00
|
|
|
from sys import argv
|
|
|
|
from pathlib import Path
|
2021-05-17 00:33:41 +02:00
|
|
|
|
2021-05-17 18:39:28 +02:00
|
|
|
from common import printerr, replaceContent
|
2021-05-17 00:33:41 +02:00
|
|
|
|
2021-05-10 22:12:15 +02:00
|
|
|
try:
|
|
|
|
from tabulate import tabulate
|
|
|
|
except:
|
2021-05-17 00:33:41 +02:00
|
|
|
printerr('Couldn\'t find tabulate. Do you have it installed?')
|
2021-05-10 22:12:15 +02:00
|
|
|
|
2021-05-10 19:32:53 +02:00
|
|
|
|
|
|
|
def parseExpressionList(inputData):
|
|
|
|
return [e.strip() for e in inputData.split(',')]
|
|
|
|
|
|
|
|
|
|
|
|
class OverloadedBool:
|
|
|
|
"""Overloads the bool in order to make Implies and Iff functions"""
|
|
|
|
|
|
|
|
def __init__(self, val):
|
|
|
|
self.val = val
|
|
|
|
|
|
|
|
def __bool__(self):
|
2021-05-17 18:39:28 +02:00
|
|
|
val = self.val
|
|
|
|
while(type(val) is OverloadedBool):
|
|
|
|
val = val.val
|
|
|
|
return val
|
2021-05-10 19:32:53 +02:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return str(self.val)
|
|
|
|
|
|
|
|
def __add__(self, bool2):
|
|
|
|
""" Implies """
|
2021-05-17 18:39:28 +02:00
|
|
|
return OverloadedBool(not self.val or bool2)
|
2021-05-10 19:32:53 +02:00
|
|
|
|
|
|
|
def __sub__(self, bool2):
|
|
|
|
""" Iff """
|
2021-05-17 18:39:28 +02:00
|
|
|
return OverloadedBool((not self.val or bool2) and (not bool2 or self.val))
|
2021-05-10 19:32:53 +02:00
|
|
|
|
|
|
|
def flattenImpliesIff(exps):
|
|
|
|
return [exp.replace('implies', '+').replace('iff', '-').replace('E', '') for exp in exps]
|
|
|
|
|
|
|
|
def generateTruthTable(exps):
|
|
|
|
|
|
|
|
exps = flattenImpliesIff(exps)
|
|
|
|
|
|
|
|
boolvars = [e for e in exps if len(e) == 1]
|
|
|
|
|
|
|
|
truthtable = []
|
|
|
|
|
|
|
|
for x in reversed(range(2 ** len(boolvars))):
|
|
|
|
for i,digit in enumerate('{0:b}'.format(x).zfill(len(boolvars))):
|
|
|
|
exec(f'{boolvars[i]} = OverloadedBool({digit == "1"})', globals())
|
|
|
|
|
|
|
|
def calculateGridLine():
|
|
|
|
line = []
|
|
|
|
for exp in exps:
|
2021-05-17 18:39:28 +02:00
|
|
|
exec(f'line.append(({exp}))')
|
2021-05-10 19:32:53 +02:00
|
|
|
return line
|
|
|
|
|
|
|
|
truthtable.append(calculateGridLine())
|
|
|
|
|
|
|
|
return truthtable
|
|
|
|
|
|
|
|
|
|
|
|
def latexify(exps, truthtable):
|
|
|
|
|
|
|
|
latex_expressions = \
|
|
|
|
[ (
|
|
|
|
'E' in exp,
|
|
|
|
exp
|
|
|
|
.replace('not', '\\neg')
|
|
|
|
.replace('and', '\\wedge')
|
|
|
|
.replace('or', '\\vee')
|
|
|
|
.replace('implies', '\\Rightarrow')
|
|
|
|
.replace('iff', '\\Leftrightarrow')
|
|
|
|
.replace('E', ''
|
|
|
|
.strip())
|
|
|
|
)
|
|
|
|
for exp in exps]
|
|
|
|
|
|
|
|
return \
|
|
|
|
"""
|
|
|
|
\\begin{{truthtable}}
|
|
|
|
{{{}}}
|
|
|
|
{{{}}}
|
|
|
|
{}
|
|
|
|
\\end{{truthtable}}
|
|
|
|
""".format(
|
|
|
|
'|'.join('e' if e else 'c' for e,_ in latex_expressions),
|
|
|
|
' & '.join(f'${exp}$' for _,exp in latex_expressions),
|
2021-05-10 22:12:15 +02:00
|
|
|
'\n'.join(' ' + ' & '.join('\\T' if b else '\\F' for b in line) + ' \\\\' for line in truthtable)
|
2021-05-10 19:32:53 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def printTruthtable(exps, truthtable):
|
|
|
|
stringTable = [ ['\033[32mT\033[0m ' if b else '\033[31mF\033[0m' for b in line] for line in truthtable]
|
2021-05-10 22:12:15 +02:00
|
|
|
try:
|
|
|
|
print(tabulate(stringTable, headers=exps))
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2021-05-17 18:39:28 +02:00
|
|
|
def processFileContent(raw):
|
2021-05-10 22:12:15 +02:00
|
|
|
exps = parseExpressionList(raw)
|
|
|
|
truthtable = generateTruthTable(exps)
|
|
|
|
|
|
|
|
printTruthtable(exps, generateTruthTable(exps))
|
|
|
|
|
|
|
|
content = latexify(exps, truthtable)
|
2021-05-17 18:39:28 +02:00
|
|
|
return replaceContent(content, 'Truthtable')
|
2021-05-10 19:32:53 +02:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2021-05-17 18:39:28 +02:00
|
|
|
pass
|