Search code examples
open-policy-agent

Limit OPA Rego to a single rule solution


If I have a rule like this: (playground)

package play

rule[message] {
    max_index := count(input)-1

    some i

    index_a = i
    index_b = (max_index-i)
    point_a := input[index_a]
    point_b := input[index_b]

    point_a != point_b

    message := sprintf("%d (%s) and %d (%s)", [index_a, point_a, index_b, point_b])
}

and have this input:

["a", "b", "c"]

I get multiple solutions to my rule, e.g.

"0 (a) and 2 (c)",
"2 (c) and 0 (a)"

Is there a way I can stop OPA searching once any solution as been found?


Solution

  • Today there's no way to ask OPA to stop after a single answer. The algorithms support it, but it's just not something people seem to need.

    You can certainly ask for the first answer OPA finds by turning your set into an array and grabbing the first element. Playground

    array_rule = [message | rule[message]]
    first = array_rule[0]
    

    Alternatively, if order is important, you could write your logic as an array comprehension to start and then grab the first element again. Playground

    array_rule = [message |
        max_index := count(input)-1
    
        some i
    
        index_a = i
        index_b = (max_index-i)
        point_a := input[index_a]
        point_b := input[index_b]
    
        point_a != point_b
    
        message := sprintf("%d (%s) and %d (%s)", [index_a, point_a, index_b, point_b])
    ]
    
    first = array_rule[0]