简体   繁体   English

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

[英]Evaluate boolean logic using DFS in python dict

I have a dict structure that appears like the following: 我有一个字典结构,如下所示:

{
"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
    }
]

} }

For each rule, I derive a decision and attach it to the policy rule. 对于每个规则,我都会得出一个决策并将其附加到策略规则中。 I do that via a simple recursive walk of the dict. 我通过简单的递归操作字典来做到这一点。 In the above sample policy, the boolean logic equates to the following: 在上面的示例策略中,布尔逻辑等同于以下内容:

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

I'd like to have a function that takes this policy in and is able to derive the boolean logic in order to return the final evaluation. 我希望有一个函数接受此策略,并且能够派生布尔逻辑以返回最终评估。 I know a depth-search first approach is liable to be the direction here, but am struggling with how to maintain the boolean state and know which level I am at within the structure. 我知道深度搜索优先方法很可能是这里的方向,但是我在努力保持布尔状态并知道我在结构中处于哪个级别上很挣扎。

Create a dictionary to hold functions that correspond to 'conditions' 创建一个字典来保存对应于'conditions'函数

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

Write a recursive function that will recurse when 'conditions' is a key in a rule, otherwise iterate over the rules and accumulate 'decisions' in a list. 编写一个递归函数,当'conditions'是规则的关键时将递归,否则将迭代规则并在列表中累积'decisions' Use functools.reduce to apply the condition to the 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 was meant to be the base case but I'm not so sure it's needed - if that happens the dict is messed up and it probably should raise a ValueError I think this has an implicit base case (if there is such a thing) - it relies on the for rule in d['rules']: loop to run out of items. if func is None: return应该是基本情况,但我不确定是否需要-如果发生这种情况,字典就搞砸了,它可能会引发ValueError我认为这有一个隐含的基本情况(如果有这样的事情)-它依靠for rule in d['rules']:循环中的for rule in d['rules']:来耗尽项目。


If the conditions limited to 'AND' and 'OR' you can use all and any . 如果条件限制为“ AND”和“ OR”,则可以使用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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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