PHP 如何计算递归 json 对象包含真值和假值

PHP How to evaluate a recursive json object contains true and false values

我正在开发一个 php 脚本,用于将对象评估为真或假。对象本身可以嵌套,包含很多对象,例如:

{
    "nodeType": "and",
    "0": {
        "nodeType": "or",
        "0": {
            "nodeType": "or",
            "1": false,
            "2": true
        },
        "3": false
    },
    "4": true
}

前一个对象的计算结果应为真。也可以嵌套,例如:

{
    "nodeType": "and",
    "0": {
        "nodeType": "or",
        "0": {
            "nodeType": "and",
            "0": {
                "nodeType": "or",
                "1": false,
                "2": true
            },
            "2": true
        },
        "3": false
    },
    "4": true
}

我已经有一个工作脚本,在 trincot 的帮助下运行良好脚本是:

    public function findAnswer($expr) {
        if (is_bool($expr)) return $expr; // Base case
        // If OR, we can stop when we find true (and return true). 
        // If AND, we can stop when we find false (and return false).
        // if($expr["nodeType"] == "not"){
        //     return ! $expr;
        // }
        if($expr["nodeType"] == "or"){
            $search = true;
        }
        else{
            $search = false;
        }
        foreach ($expr as $key => $value) {
            if ($key !== "nodeType" && $this->findAnswer($value) === $search) {
                
                return $search;
            }
            
        }
        // If that never happened, return the opposite (false for OR, true for AND)
        return !$search;
    }

问题是当节点类型为 not 时,脚本无法运行。示例:

{
    "nodeType": "and",
    "0": {
        "nodeType": "or",
        "0": {
            "nodeType": "not",
            "1": false,
        },
        "3": false
    },
    "4": false
}

前一个对象的计算结果应为 false。

有什么建议可以改进脚本以与 not nodeTypes 一起使用吗?

编辑:答案适用于某些情况,但不适用于以下情况:

{
    "nodeType": "and",
    "0": {
        "nodeType": "or",
        "0": {
            "nodeType": "and",
            "0": {
                "nodeType": "not",
                "1": true
            },
            "2": true
        },
        "3": false
    },
    "4": true
}

这被评估为真,而它应该被评估为假。

当运算符为“非”时,我们可以将其他参数视为 NAND 逻辑运算符的参数。因此,如果所有参数都是假的,那么它将被评估为真,否则为假。如果您永远不会将多个参数传递给 NOT 运算符,那么这并没有什么区别,但是当需要支持更多参数时,让它也可以与某些逻辑一起工作是很好的。

这是建议的代码:

public function findAnswer($expr) {
    if (is_bool($expr)) return $expr; // Base case
    // If OR, we can stop when we find true, and return true. 
    // If AND or NOT, we can stop when we find false,
    //                and return false or true respectively.
    // If NOT, and multiple arguments, this performs like a NAND operator
    $negate = $expr["nodeType"] == "not";
    $search = $expr["nodeType"] == "or";
    foreach ($expr as $key => $value) {
        if ($key !== "nodeType" && $this->findAnswer($value) === $search) {
            return $search !== $negate;
        }
    }
    // If that never happened, return the opposite (false for OR, true for AND)
    return $search === $negate;
}