Get variables associated to the eval details

21 views
Skip to first unread message

Demontiê Junior

unread,
Jul 25, 2024, 9:21:04 AM (2 days ago) Jul 25
to CEL Go Discussion Forum
Hi,

TL;DR: Is there a way to map the variables used in a rule condition to an ID on the EvalState (returned as part of the EvalDetails)?

Context:

I'm evaluating the use of cel-go as the rules engine for a new service. In my use case, I need  to know the reason that triggered a specific rule.

Let's say the rule is written as follows:

  features.value1 > 100 &&
  features.value2 < 500

And my input data has "value1 = 90". I want to know that the rule evaluated to false because of value1.

One way I found to do that was to write the rule as

  features.value1 < 100 ? "value1" :
  features.value2 > 500 ? "value2" :
  ""

and then consider it evaluated to true if the returned value is empty. However, I think that harms readability as I need to chain multiple ternary operations.

So I saw that I can use the eval option OptPartialEval and an EvalDetails object will be returned. When I print the values I can see it holds the evaluations in a map with the keys as integers and the value for each operator. However, I don't know how to map variables to those IDs so I can check if the value for the condition was true or false.

Is it possible to do? I appreciate any suggestions (even for other ways of writing the condition).

Tristan Swadell

unread,
Jul 25, 2024, 11:58:23 AM (2 days ago) Jul 25
to Demontiê Junior, CEL Go Discussion Forum
Hi Demontiê,

If you track the eval state, then the expression id attached to each node is available in the eval state. You could collect the `IdentExpr` expressions using a navigable expr and then map the eval state ids to the variables. If that makes sense. The other option is to decorate the identifier expressions using a program decorator. There's an example of a custom decorator in the cel_test.go file which captures some additional state about evaluation in a more custom manner.

Cheers,

-Tristan

--
You received this message because you are subscribed to the Google Groups "CEL Go Discussion Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cel-go-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cel-go-discuss/cd2f62d1-7abd-4370-a139-44a494ddc58en%40googlegroups.com.

Tristan Swadell

unread,
Jul 25, 2024, 11:14:21 PM (2 days ago) Jul 25
to Demontiê Junior, CEL Go Discussion Forum
Hi Demontiê,

The variables should definitely come back as identifiers, unless there's something unusual about the expression. However, I was thinking you could try the following:
https://github.com/google/cel-go/blob/master/cel/cel_test.go#L1407

If you create a CustomDecorator for the interpreter, you can intercept all intermediate program plan steps. Identifiers are surfaced as `interpreter.InterpretableAttribute` values which let you inspect the field path selection and plain identifiers. You can also intercept interpreter.InterpretableCall values to check whether an argument is an InterpretableAttribute and then replace the program step with one of your own that records the values you observe. It's a little hacky, but hopefully this gets you started.

-Tristan

On Thu, Jul 25, 2024 at 1:59 PM Demontiê Junior <demonti...@gmail.com> wrote:
Hi Tristan,

thanks a lot for your quick response! I'm trying to explore your suggestion. What I did so far:

I used [Pre/Post]OrderVisit passing a NewExprVisitor just to check the info I'd get access to. In fact, I could get variable names and IDs so I can map them. One caveat is that for some reason the expression kind for the variables is set as Literal and not Ident, so it might make it difficult to differentiate variables from values. However, one thing I'm struggling with is that I need to map the whole branch (condition) to the used variables. I.e., from my previous example, I need to map features.value1 > 100 to "value1" and also to the node ID that represents the condition (probably the node pointing to the > operator, which I wasn't able to identify through the traversal, as it apparently has UnspecifiedExprKind.

I'm I going on the right direction? Did you think of something else that would give me more contextual information?

Also, I didn't find the cel_test.go field (the closest one was tools/celrpc/celrpc_test.go, in which I didn't see any decorators). Can you point me to the right path?

Thanks,
Demontiê
--
Demontiê Junior - demontiejr.com
Reply all
Reply to author
Forward
0 new messages