python - 用列表表示布尔表达式

Posted

技术标签:

【中文标题】python - 用列表表示布尔表达式【英文标题】:python - representing boolean expressions with lists 【发布时间】:2012-07-13 17:54:51 【问题描述】:

我试图用 Python 中的产品总和形式 (SOP) 表示布尔表达式,仅使用列表。

例如,我有布尔表达式

ABC+DE(FG+IH)

我需要找到一个与上述表达式等效的列表,因此通过读取列表或嵌套列表并遵循某些规则来读取列表,读取列表的程序/程序员将能够将其转换回布尔表达式.

我想到的一种方法是构建嵌套列表。遵循两条规则:

    同一个列表中的元素是 AND 在一起的 列表彼此平行,因此 ORed 在一起。

因此对于上面的示例,它将转换为:

[[A,B,C],[D,E,[[F,G],[I,H]]]]

但是这组规则在某些情况下会发生冲突。例如,给定 [[E,F],[D,C]],它可以表示 EF+DC 或 EFDC,因为 [E,F] 和 [D,C] 在同一个列表中,因此它们应该是与,但列表是并行的,因此它们也应该是 ORed。

我觉得我需要在上述两条规则之间设置一些优先级,或者添加另一个规则以使其更清晰。

欢迎任何想法或建议。这也不是功课,只是为了好玩。 提前致谢!!

【问题讨论】:

您可能希望接受您提出的更多问题的答案,或者至少表明您是否有可接受的答案。 【参考方案1】:

为什么是列表而不是树?

OR = 0
AND = 1

class OpNode:
   def __init__(self, op, left, right):
       self.op = op
       self.left = left
       self.right = right

class LeafNode:
    def __init__(self, name, value):
       self.name = name
       self.value = value

A = LeafNode("A", True)
B = LeafNode("B", True)

exp = OpNode(OR, A, OpNode(AND, B, 
                                OpNode(OR, 
                                          LeafNode("C", False), 
                                          LeafNode("D", True))))

exp 相当于A+B(C+D)

【讨论】:

我相信这只是一个有趣的问题! 这实际上是个好主意。用二叉树表示一个布尔表达式,所有的叶子节点都是变量,它们的父节点就是操作【参考方案2】:

我认为您可以添加一个附加规则,即当逗号旁边的基本元素是列表时,它们是ORed 一起。因此,您不会得到这种矛盾的解释。

因此[A,B] 的两个元素都是单例,所以它们和ANDed,但[[A,B],[C,D]] 在单例之间有ANDs,在列表之间有ORs,导致AB+CD。

在某种程度上,这意味着您的 rule #2 优先于 rule #1

【讨论】:

这可能会解决部分问题,但是当同一列表中同时存在列表和基本变量时它会失败。那么 [[A,B],C] 是什么? [[A,B], C] 为 AND,[[A,B], [C]] 为 OR。 但是你会怎么写 (A AND B) AND (C AND D) ?也许 [[A,B], [C,D], True] ? @Luke 你怎么把两个列表放在一起呢?比如快递(A+B)(C+D)? @Luke 正要问这个问题。那个实际上是让我卡住的原因【参考方案3】:

对 AND 使用列表,对 OR 使用元组。

【讨论】:

【参考方案4】:

您可以走 LISPy 路线,并让每个列表中的第一项成为运算符。比如你给的表达式

ABC+DE(FG+IH)

会变成

['or', ['and', A, B, C], ['and', D, E, ['or', ['and', F, G], ['and', I, H]]]]

考虑到这一点,这很容易阅读。干杯!

【讨论】:

元组而不是列表会更接近 lisp【参考方案5】:

您可以让最外面的列表表示“OR 所有直接条目”,然后在 OR 和 AND 直接条目之间交换嵌套列表的含义。如果从最外层的嵌套层数为 1,则奇数嵌套层中的项应为 OR'd,偶数嵌套层中的项应为 AND'd 一起。

所以ABC+DE(FG+IH)

变成[[A,B,C],[D,E,[[F,G],[I,H]]]]

这是一些 Python 代码:

它从列表形式返回一个表达式:

def to_bool(lst, depth=0, or_them=True):
    if type(lst) == str:
        return lst
    else:
        partial = ( '+' if or_them else ''
                  ).join( to_bool(x, depth+1, not or_them) for x in lst)
        if or_them and depth > 0:
            # Mixture of variables and sublists so parenthesize
            return '(' + partial + ')'
        else:
            return partial

def main():
    A,B,C,D,E,F,G,H,I = 'ABCDEFGHI'
    e = [[A,B,C],[D,E,[[F,G],[I,H]]]]
    print('The list form of the boolean expression:', e)
    print('The boolean expression:', to_bool(e))


if __name__ == '__main__':
    main()

它的输出:

The list form of the boolean expression: [['A', 'B', 'C'], ['D', 'E', [['F', 'G'], ['I', 'H']]]]
The boolean expression: ABC+DE(FG+IH)

【讨论】:

以上是关于python - 用列表表示布尔表达式的主要内容,如果未能解决你的问题,请参考以下文章

python-布尔表达式

布尔表达式

两个布尔列表上的 Python AND 运算符 - 如何?

如果列表在其他列表中的布尔表达式

使用带有布尔表达式的数组从列表中提取值

Java断言绝对不是鸡肋