get elements in "AND" in logic string with Python -
i want parse logic strings , combinations of elements in "and" logic. instance, string '( , ( b or c ) )' should [[a,b],[a,c]] , string '( , b , ( c or d , f ) or f , g )' should [[a,b,c],[a,b,d,f],[f,g]].
i'm trying use pyparsing. following post here parsing complex logical expression in pyparsing in binary tree fashion manage nested list letters grouped according preferences ("and" has preference on "or", , parenthesis overrides this):
import pyparsing pp complex_expr = pp.forward() vars = pp.word(pp.alphas, pp.alphanums + "_") | pp.regex(r"[+-]?\d+(:?\.\d*)?(:?[ee][+-]?\d+)?").setname('proteins') clause = pp.group(vars ^ (pp.suppress("(") + complex_expr + pp.suppress(")") )) expr = pp.operatorprecedence(clause,[ ("and", 2, pp.opassoc.left, ), ("or", 2, pp.opassoc.left, ),]) #print expr complex_expr << expr parseresult=complex_expr.parsestring('( , b , ( c or d , f ) or f , g )') print parseresult
which gives:
[[[[['a'], 'and', ['b'], 'and', [[['c'], 'or', [['d'], 'and', ['f']]]]], 'or', [['f'], 'and', ['g']]]]]
now how can process result achieve desired output? greateful help. tried pyparsing i'm open other modules may better.
thanks in advance.
python libraries going little bit:
import re import itertools
let's write required function:
def analyse(expression): # find used symbols symbols = set(re.findall(r"\b[a-z]\b", expression)) # find combinations of symbols , values mappings = (dict(zip(symbols, values)) values in itertools.product([false, true], repeat=len(symbols))) # select combinations make whole expression true solutions = [sorted(name name in mapping if mapping[name]) mapping in mappings if eval(expression, none, mapping)] # filter out redundant solutions return sorted(s1 s1 in solutions if not any(set(s1) > set(s2) s2 in solutions))
and let's test it:
assert analyse("( , ( b or c ) )") == [["a", "b"], ["a", "c"]] assert analyse("( , b , ( c or d , f ) or f , g )") == [["a", "b", "c"], ["a", "b", "d", "f"], ["f", "g"]]
there comments in source code. anyway, main steps are:
- the expression variables found single-character uppercase names.
- each variable can either true or false. find combinations.
- we select such combinations make whole expression true.
- we keep minimal solutions, i.e. not supersets of other solutions.
i thank nice question. python's itertools
never stop surprising me. ;-)
Comments
Post a Comment