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

时间:2012-07-13 20:33:40

标签: python algorithm list boolean

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

例如,我有布尔表达式

ABC+DE(FG+IH)

我需要找到上面表达式的等价列表,所以通过读取列表或嵌套列表并遵循某些规则来读取列表,读取列表的程序/程序员将能够将其转换回布尔表达式。

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

  1. 同一列表中的元素是AND在一起的
  2. 列表彼此平行,因此ORed在一起。
  3. 因此,对于上面的示例,它将转换为:

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

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

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

    欢迎任何想法或建议。此外,它不是功课,只是为了好玩。 在此先感谢!!

5 个答案:

答案 0 :(得分:4)

为什么列出而不是树?

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)

答案 1 :(得分:4)

你可以去LISPy路线并让每个列表中的第一项成为运营商。例如,你给出的表达式

ABC+DE(FG+IH)

会变成

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

考虑到这一点,这是非常可读的。干杯!

答案 2 :(得分:2)

您可以让最外面的列表表示“或所有直接条目”,然后在OR和AND直接条目之间交换嵌套列表的含义。如果您计算最外层的嵌套级别为1,那么嵌套的奇数级别中的术语应为“或”,并且嵌套的均匀级别中的术语应该是“和”。

所以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)

答案 3 :(得分:1)

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

因此[A,B]将这两个元素都视为单例,因此它们和ANDed,但[[A,B],[C,D]]在单例之间有ANDs,列表之间有ORs,从而产生AB + CD。

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

答案 4 :(得分:0)

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