简体   繁体   中英

How do I deal with a logical expression in Python?

let's say I got a logical expression in the format of ie. AvBv~C->D . It consists of boolean elements and operators like (v,~,->) (disjunction,negation,implication). I need to store those expressions and each element they consist of. Also each element should have a description so I guess I will have to make a class that will represent them (with fields representation and description ie. element1.representation="A" and element1.description="This is element A" but I am not sure whether this is the pythonic way, maybe a 2D array with names and descriptions as columns would be a better idea since the names are all unique.

  1. Which data structure should I use to store such an expression? Note the fact I need to store elements and operators which are of different type and then be able to restore them as logical expressions and do operations on them.
  2. Should I create methods for recognition of each element and operator to deal with the logical operations or is there a better approach? Maybe use a parser like Lex-Yacc or some other library that deals with those?

Forgive me if I am not too clear but I'm coming from Java where I can't store different types of elements in the same data structure.

  1. Create a tree data structure that represents each element in the expression.
  2. You can indeed use a parser generator to produce the above data structures from a given string.

For example, a conjunction can be represented as follows and a similar approach can be used for variables:

class Node:
    operator = "AND"
    left_node = None
    right_node = None
    description = "text"
    value = None

class Node:
    operator = "VAR"
    left_node = None
    right_node = None
    description = "text"
    value = "B"

You can then compose a tree out of these nodes.

For example: A^B can be represented as a Node with AND where the left_node is a VAR node ( value=A ) and the right_node is a VAR node as well ( value=B ).

By declaring the __and__ , __or__ , and __invert__ methods, you can use the & , | and ~ operators to define your expressions.

class Element(object):
    def __init__(self, elt_id, elt_description=None):
        self.id = elt_id
        self.description = elt_description
        if self.description is None:
            self.description = self.id

    def __or__(self, elt):
        return CombinedElement(self, elt, op="OR")

    def __and__(self, elt):
        return CombinedElement(self, elt, op="AND")

    def __invert__(self):
        return CombinedElement(self, op="NOT")

    def __str__(self):
        return self.id

class CombinedElement(Element):
    def __init__(self, elt1, elt2=None, op="NOT"):
        # ID1
        id1 = elt1.id
        if isinstance(elt1, CombinedElement):
            id1 = '('+id1+')'
        # ID2
        if elt2 is not None:
            id2 = elt2.id
            if isinstance(elt2, CombinedElement):
                id2 = '('+id2+')'
        # ELT_ID
        if op == "NOT" and elt2 is None:
            elt_id = "~"+id1
        elif op == "OR": 
            elt_id = id1+" v "+id2
        elif op == "AND":
            elt_id = id1+" ^ "+id2
        # SUPER
        super(CombinedElement, self).__init__(elt_id)

a = Element("A")
b = Element("B")
c = Element("C")
d = Element("D")
e = Element("E")

print(a&b|~(c&d)|~e)

Output :

((A ^ B) v (~(C ^ D))) v (~E)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM