Truth tables for logical expressions

与P302类似,只是表达式中可包含任意多个变量,比如A and (B or C) equ A and B or A and C。 我们可以重用大部份P302中的实现,仅需修改直值表构造和变量值解柝两步,使其支持任意个数变量。

照例,先写单元测试:

from python99.logic_codes.p303 import table def test_table(): assert table({'A': [True, False], 'B': [True, False], 'C': [True, False]}, 'A and B or C') == [ (True, True, True, True), (True, True, False, True), (True, False, True, True), (True, False, False, False), (False, True, True, True), (False, True, False, False), (False, False, True, True), (False, False, False, False) ]

首先,构造如下形式的输入表:

A B C ...
True True True ...
True True False ...
True False True ...
... ... ... ...

这个可以使用递归构造。分别构造每一个变量的取值选项,再列出所有排列。代码实现:

def constructInputs(variables): if len(variables)==1: e = variables[0] return [[(e[0],v)] for v in e[1]] e = variables[0] kv = [(e[0],v) for v in e[1]] print(kv) return [[first] + remain for first in kv for remain in constructInputs(variables[1:])]

然后,逐一使用输入表中的变量值,计算表达式值。在将变量值替换进青达式时,可以将变量值先转换成字典,方便查找。代码实现:

def resolveVariable(expr, input): resolved = [] kv = {} for e in input: kv[e[0]]=e[1] for e in expr: if e in kv: resolved.append(kv[e]) else: resolved.append(e) return resolved

最后,转换一下结果直值表结构,将每一行从列表转换为元组。

def table(variables, expr): postExpr = postOrderTraversal(buildTreeFrom(tokenize(expr))) inputTable = constructInputs([(k,v) for k,v in variables.items()]) result = [extractValue(input) +[evaluate(resolveVariable(postExpr,input))] for input in inputTable] return [tuple(e) for e in result]

results matching ""

    No results matching ""