Python dict 使用真值表的逻辑输入

Python dict using logic input for truth tables

好的男孩女孩们,我们开始吧。首先我有几个问题。由于我的程序很大,我会简单地分阶段提问,这个问题是第一个。我正在创建一个为后缀逻辑表达式生成真值 table 的程序。以下是允许的运算符及其逻辑等价物:

Operators:
=                Logical Equivalence (≡ or ↔) 
`->` or `<=`     Logical Implication (→)
+                Disjunction (∨), AKA “or”
*                Conjunction (∧), AKA “and” 
`~` or `!`       Negation (¬), AKA “not”

这里有一些输入和输出的例子:

input
p True =

output
p      p True =
False  False
True   True

input
p !

output
p      p !
False  True
True   False

input
p q =

output
p      q      p q =
False  False  True
False  True   False
True   False  False
True   True   True

好吧,我真的不知道 从哪里开始,但我并不是要任何人为我编写这个程序。我知道我需要使用 Python dict 来编写代码,它与相应命题的键相匹配。但是我怎么知道哪些可以作为键,哪些可以作为值呢?另外,如果是:

`->` or `<=`     Logical Implication (→)

`~` or `!`       Negation (¬), AKA “not”

如何分配 2 个不同的输入以便能够在 python 字典中使用?我希望这不会太混乱,我在 python 非常菜鸟,感谢任何帮助。谢谢!

更新 好的,这是我现在的代码:

propositions = {
    '=' : (2, {(True, True): True,
              (True, False): False,
              (False, True) : False,
              (False, False): True,
              }),
    '->' : (2, {(True, True): True,
                (True, False): False,
                (False, True): True,
                (False, False): True,
                }),
    '+' : (2, {(True, True): True,
               (True, False): True,
               (False, True): True,
               (False, False): False,
               }),
    '*' : (2, {(True, True): True,
               (True, False): False,
               (False, True): False,
               (False, False): False,
               }),
    '!' : (1, {True: False,
               False: True})}

prop = sys.stdin.readline()
prop = prop.split()
prop = prop[::-1]
for x in prop:

我相信我成功地反转了字符串并删除了所有空格,但我仍然对遍历它感到有点困惑。

第二次更新这是我的代码:

propositions = {
    '=' : (2, {(True, True): True,
              (True, False): False,
              (False, True) : False,
              (False, False): True,
              }),
    '->' : (2, {(True, True): True,
                (True, False): False,
                (False, True): True,
                (False, False): True,
                }),
    '+' : (2, {(True, True): True,
               (True, False): True,
               (False, True): True,
               (False, False): False,
               }),
    '*' : (2, {(True, True): True,
               (True, False): False,
               (False, True): False,
               (False, False): False,
               }),
    '!' : (1, {True: False,
               False: True})}

prop = sys.stdin.readline()
prop = prop.strip().split()
prop = reversed(prop)
def evaluate():
    token = next(prop)
    try:
        nargs, table = propositions[token]
    except KeyError:
        if token.lower() in ('true', '1'):
            return True
        elif token.lower() in ('false', '0'):
            return False
        else:
            return token
    return table[tuple(evaluate() for i in range(nargs))]

你必须按照从外到内的解析顺序构建你的字典:

master_dict = {
   '=': (2, {(True, True): True,
             (True, False): False,
             ...
             }),
   ...
   '!': (1, {True: False,
             False: True})}

数字表示运算符需要多少个操作数。

要解析输入,请从右到左阅读。

使用递归函数,从右边消耗一个标记。

(1) 如果令牌是一个运算符(即你字典中的一个键)从你的主字典中检索相应的值。

首先存储的数字是运算符采用的参数数量。因此,您的函数现在必须调用自身的次数与参数的次数一样多。请务必跟踪哪些令牌已被读取。一种简洁的方法是使用列表迭代器,它会恰好吐出每个元素一次,因此您不会弄错索引。一旦你有了所有的论据,你就应用了你刚刚检索到的真相table,读出结果并return它。

(2) 如果令牌不是运算符,您的函数必须 return 它。

prop = sys.stdin.readline()

def solve_no_var(prop):
    rev_iter = reversed(prop)
    def evaluate():
        token = next(rev_iter)
        try:
            nargs, table = propositions[token]
        except KeyError:
            if token.lower() in ('true', '1'):
                return True
            elif token.lower() in ('false', '0'):
                return False
            else:
                return token
        return table[tuple(evaluate() for i in range(nargs))]
    return evaluate()

def solve(prop):
    prop = prop.strip().split()
    variables = list(set(prop) - set(propositions)
        - {'True', 'TRUE', 'true', '1', 'False', 'FALSE', 'false', '0'})
    lookup = {v: [j for j, p in enumerate(prop) if p == v] for v in variables}
    N = len(variables)
    print((N*" {:6} ").format(*variables), 'result')
    for p in itertools.product(("True", "False"), repeat=N):
        prop_nv = prop.copy()
        for v, b in zip (variables, p):
            for j in lookup[v]:
                prop_nv[j] = b
        res = solve_no_var(prop_nv)
        print(((N+1)*" {:6} ").format(*(p + (res,))))

solve(prop)