def evaluateRule(node, sphinxContext):
    isFormulaRule = isinstance(node, astFormulaRule)
    isReportRule = isinstance(node, astReportRule)
    name = (node.name or ("sphinx.report" if isReportRule else "sphinx.raise"))
    nodeId = node.nodeTypeName + ' ' + name
    if node.precondition:
        result = evaluate(node.precondition, sphinxContext, value=True)
        if sphinxContext.formulaOptions.traceVariableSetExpressionResult:
            sphinxContext.modelXbrl.info("sphinx:trace",
                 _("%(node)s precondition evaluation: %(value)s"), 
                 sourceFileLine=node.sourceFileLine, node=nodeId, value=result)
        if not result:
            return None 
    # nest hyperspace binding
    sphinxContext.ruleNode = node
    hsBindings = None
    ruleIteration = 0
    try:
        hsBindings = HyperspaceBindings(sphinxContext)
        while True:
            ruleIteration += 1
            sphinxContext.dynamicSeverity = None
            sphinxContext.tags.clear()
            sphinxContext.localVariables.clear()
            if sphinxContext.formulaOptions.traceVariableSetExpressionResult:
                sphinxContext.modelXbrl.info("sphinx:trace",
                     _("%(node)s starting iteration %(iteration)s"), 
                     sourceFileLine=node.sourceFileLine, node=nodeId, iteration=ruleIteration)
            for varAssignNode in node.variableAssignments:
                evaluateVariableAssignment(varAssignNode, sphinxContext)
            result = evaluate(node.expr, sphinxContext, value=True)
            if result is UNBOUND:
                result = None # nothing to do for this pass
            elif isFormulaRule:
                left, right = result
                if left is UNBOUND:
                    difference = UNBOUND
                elif right is UNBOUND:
                    difference = UNBOUND
                else:
                    difference = abs(left - right)
                result = difference != 0
                resultTags = {"left": left, "right": right, "difference": difference}
                sphinxContext.dynamicSeverity = None
                if node.severity in sphinxContext.functions:
                    evaluateFunctionDeclaration(sphinxContext.functions[node.severity],
                                                sphinxContext,
                                                {"difference": difference, "left": left, "right": right})
                    if sphinxContext.dynamicSeverity is None or sphinxContext.dynamicSeverity == "pass": # don't process pass
                        sphinxContext.dynamicSeverity = None
                        result = False
            else:
                if isReportRule:
                    resultTags = {"value": result}
                else:
                    resultTags = {}
            if sphinxContext.formulaOptions.traceVariableSetExpressionResult:
                sphinxContext.modelXbrl.info("sphinx:trace",
                     _("%(node)s result %(result)s %(severity)s iteration %(iteration)s"), 
                     sourceFileLine=node.sourceFileLine, node=nodeId, iteration=ruleIteration,
                     result=result,
                     severity=(sphinxContext.dynamicSeverity or node.severity or 
                               ("info" if isReportRule else "error")))
            if ((result or isReportRule) or 
                (sphinxContext.dynamicSeverity and sphinxContext.dynamicSeverity != "pass")):
                severity = (sphinxContext.dynamicSeverity or node.severity or 
                            ("info" if isReportRule else "error"))
                if isinstance(severity, astFunctionReference):
                    severity = severity.name
                logSeverity = {"error" : "ERROR", "warning": "WARNING", "info": "INFO"}[severity]
                if node.message:
                    sphinxContext.modelXbrl.log(logSeverity, name, 
                                                evaluateMessage(node.message, sphinxContext, resultTags, hsBindings),
                                                sourceFileLine=[node.sourceFileLine] + 
                                                [(fact.modelDocument.uri, fact.sourceline) for fact in hsBindings.boundFacts],
                                                severity=severity)
                elif isFormulaRule:
                    sphinxContext.modelXbrl.log(logSeverity,
                                                name,
                                                _("Formula %(severity)s difference %(value)s for %(aspects)s"),
                                                sourceFileLine=[node.sourceFileLine] + 
                                                [(fact.modelDocument.uri, fact.sourceline) for fact in hsBindings.boundFacts],
                                                severity=severity,
                                                value=difference,
                                                aspects=contextView(sphinxContext))
                elif isReportRule:
                    sphinxContext.modelXbrl.log(logSeverity,
                                                name,
                                                _("Report %(severity)s %(value)s for %(aspects)s"),
                                                sourceFileLine=[node.sourceFileLine] + 
                                                [(fact.modelDocument.uri, fact.sourceline) for fact in hsBindings.boundFacts],
                                                severity=severity,
                                                value=result,
                                                aspects=contextView(sphinxContext))
                else:
                    sphinxContext.modelXbrl.log(logSeverity,
                                                name,
                                                _("Validation rule %(severity)s for %(aspects)s"),
                                                sourceFileLine=[node.sourceFileLine] + 
                                                [(fact.modelDocument.uri, fact.sourceline) for fact in hsBindings.boundFacts],
                                                severity=severity,
                                                aspects=contextView(sphinxContext))
            hsBindings.next() # raises StopIteration when done
    except __HOLE__:
        if sphinxContext.formulaOptions.traceVariableSetExpressionResult:
            sphinxContext.modelXbrl.info("sphinx:trace",
                 _("%(node)s StopIteration"), 
                 sourceFileLine=node.sourceFileLine, node=nodeId)
    except SphinxException as ex:
        sphinxContext.modelXbrl.log("ERROR",
                                    ex.code,
                                    _("Exception in %(node)s: %(exception)s"),
                                    node=nodeId,
                                    ruleName=name,
                                    exception=ex.message % ex.kwargs,
                                    sourceFileLine=[node.sourceFileLine] + ([ex.node.sourceFileLine] if ex.node is not node else []),
                                    **ex.kwargs)
    if hsBindings is not None:
        hsBindings.close()
    return None
dataset/ETHPy150Open Arelle/Arelle/arelle/plugin/sphinx/SphinxEvaluator.py/evaluateRule