在python dict中使用DFS评估布尔逻辑

时间:2018-06-01 03:06:30

标签: python recursion depth-first-search boolean-logic

我有一个dict结构,如下所示:

{
"condition": "AND",
"rules": [
    {
        "id": "monitor_category",
        "field": "monitor_category",
        "type": "string",
        "input": "select",
        "operator": "equal",
        "value": "Competition",
        "decision": True
    },
    {
        "id": "monitor_tag",
        "field": "monitor_tag",
        "type": "string",
        "input": "text",
        "operator": "equal",
        "value": "PassiveTotal",
        "decision": True
    },
    {
        "condition": "OR",
        "rules": [
            {
                "id": "article_tag",
                "field": "article_tag",
                "type": "string",
                "input": "text",
                "operator": "contains",
                "value": "Attack",
                "decision": False
            },
            {
                "id": "article_tag",
                "field": "article_tag",
                "type": "string",
                "input": "text",
                "operator": "contains",
                "value": "Hunt",
                "decision": True
            },
            {
                "id": "article_tag",
                "field": "article_tag",
                "type": "string",
                "input": "text",
                "operator": "contains",
                "value": "Threat",
                "decision": False
            }
        ]
    },
    {
        "id": "monitor_tag",
        "field": "monitor_tag",
        "type": "string",
        "input": "text",
        "operator": "equal",
        "value": "Analysis",
        "decision": False
    }
]

}

对于每条规则,我都会得出一个决定并将其附加到策略规则中。我通过dict的简单递归遍历来做到这一点。在上面的示例策略中,布尔逻辑等同于:

(True and True and (False or True or False) and False)

我想拥有一个接受此策略的函数,并且能够派生布尔逻辑以返回最终评估。我知道深度搜索第一种方法可能是这里的方向,但我正在努力维护布尔状态并知道我在结构中的哪个级别。

1 个答案:

答案 0 :(得分:1)

创建一个字典以容纳functions that correspond to 'conditions'

import operator, functools
operations = {'AND':operator.and_, 'OR':operator.or_, 'XOR':operator.xor}

编写递归函数,当'conditions'是规则中的键时将递归,否则迭代规则并在列表中累积'decisions'。使用functools.reducecondition应用于决策。

def f(d):
    func = operations.get(d['condition'], None)
    if func is None:
        return
    decisions = []
    for rule in d['rules']:
        if 'condition' in rule:
            decision = f(rule)
        else:
            decision = rule['decision']
        decisions.append(decision)
    return functools.reduce(func, decisions)

if func is None: return本来是基本情况,但我不太确定它是否需要 - 如果发生这种情况,dict会搞砸,它可能会引发ValueError我认为这是隐含的基本情况(如果有这样的事情) - 它依赖for rule in d['rules']:循环来用完项目。

如果条件仅限于“与”和“或”,您可以使用allany

ops = {'AND':all, 'OR':any}
def g(d):
    func = ops.get(d['condition'], None)
    if func is None:
        return
    decisions = []
    for rule in d['rules']:
        if 'condition' in rule:
            decision = f(rule)
        else:
            decision = rule['decision']
        decisions.append(decision)
    return func(decisions)