Python libraries will help us a bit:
import re import itertools
Record the required function:
def analyse(expression): # Find all used symbols symbols = set(re.findall(r"\b[AZ]\b", expression)) # Find all combinations of symbols and values mappings = (dict(zip(symbols, values)) for values in itertools.product([False, True], repeat=len(symbols))) # Select combinations that make the whole expression true solutions = [sorted(name for name in mapping if mapping[name]) for mapping in mappings if eval(expression, None, mapping)] # Filter out redundant solutions return sorted(s1 for s1 in solutions if not any(set(s1) > set(s2) for s2 in solutions))
And let him test it:
assert analyse("( A and ( B or C ) )") == [["A", "B"], ["A", "C"]] assert analyse("( A and B and ( C or D and F ) or F and G )") == [["A", "B", "C"], ["A", "B", "D", "F"], ["F", "G"]]
There are comments in the source code. In any case, the main steps:
- Variable expressions are found as single-character uppercase names.
- Each variable can be either True or False. We find all the combinations.
- We select only those combinations that make the whole expression True.
- We keep only minimal solutions, i.e. those that are not supernets of other solutions.
I would like to thank you for a good question. Python itertools never ceases to amaze me .; -)
dlask source share