Search in sources :

Example 1 with InterpretableConst

use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.

the class CELTest method CustomInterpreterDecorator.

@Test
void CustomInterpreterDecorator() {
    AtomicReference<Interpretable> lastInstruction = new AtomicReference<>();
    InterpretableDecorator optimizeArith = i -> {
        lastInstruction.set(i);
        // Only optimize the instruction if it is a call.
        if (!(i instanceof InterpretableCall)) {
            return i;
        }
        InterpretableCall call = (InterpretableCall) i;
        // Only optimize the math functions when they have constant arguments.
        switch(call.function()) {
            case "_+_":
            case "_-_":
            case "_*_":
            case "_/_":
                // These are all binary operators so they should have to arguments
                Interpretable[] args = call.args();
                // an empty activation and the value returns as a constant.
                if (!(args[0] instanceof InterpretableConst) || !(args[1] instanceof InterpretableConst)) {
                    return i;
                }
                Val val = call.eval(emptyActivation());
                if (isError(val)) {
                    throw new RuntimeException(val.toString());
                }
                return newConstValue(call.id(), val);
            default:
                return i;
        }
    };
    Env env = newEnv(declarations(Decls.newVar("foo", Decls.Int)));
    AstIssuesTuple astIss = env.compile("foo == -1 + 2 * 3 / 3");
    env.program(astIss.getAst(), evalOptions(OptPartialEval), customDecorator(optimizeArith));
    assertThat(lastInstruction.get()).isInstanceOf(InterpretableCall.class);
    InterpretableCall call = (InterpretableCall) lastInstruction.get();
    Interpretable[] args = call.args();
    Interpretable lhs = args[0];
    assertThat(lhs).isInstanceOf(InterpretableAttribute.class);
    InterpretableAttribute lastAttr = (InterpretableAttribute) lhs;
    NamespacedAttribute absAttr = (NamespacedAttribute) lastAttr.attr();
    String[] varNames = absAttr.candidateVariableNames();
    assertThat(varNames).containsExactly("foo");
    Interpretable rhs = args[1];
    assertThat(rhs).isInstanceOf(InterpretableConst.class);
    InterpretableConst lastConst = (InterpretableConst) rhs;
    // This is the last number produced by the optimization.
    assertThat(lastConst.value()).isSameAs(IntOne);
}
Also used : BoolT(org.projectnessie.cel.common.types.BoolT) Interpretable(org.projectnessie.cel.interpreter.Interpretable) Macro(org.projectnessie.cel.parser.Macro) Call(com.google.api.expr.v1alpha1.Expr.Call) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) PartialActivation(org.projectnessie.cel.interpreter.Activation.PartialActivation) EnvOption.container(org.projectnessie.cel.EnvOption.container) Macro.newReceiverMacro(org.projectnessie.cel.parser.Macro.newReceiverMacro) Activation.emptyActivation(org.projectnessie.cel.interpreter.Activation.emptyActivation) Disabled(org.junit.jupiter.api.Disabled) InterpretableDecorator(org.projectnessie.cel.interpreter.InterpretableDecorator) Collections.singletonList(java.util.Collections.singletonList) True(org.projectnessie.cel.common.types.BoolT.True) Err.isError(org.projectnessie.cel.common.types.Err.isError) Container(org.projectnessie.cel.common.types.traits.Container) Arrays.asList(java.util.Arrays.asList) CEL.estimateCost(org.projectnessie.cel.CEL.estimateCost) OptPartialEval(org.projectnessie.cel.EvalOption.OptPartialEval) ProtoTypeRegistry.newEmptyRegistry(org.projectnessie.cel.common.types.pb.ProtoTypeRegistry.newEmptyRegistry) ParsedExpr(com.google.api.expr.v1alpha1.ParsedExpr) EnvOption.customTypeProvider(org.projectnessie.cel.EnvOption.customTypeProvider) Val(org.projectnessie.cel.common.types.ref.Val) TypeRegistry(org.projectnessie.cel.common.types.ref.TypeRegistry) InterpretableAttribute(org.projectnessie.cel.interpreter.Interpretable.InterpretableAttribute) Collections.emptyList(java.util.Collections.emptyList) Expr(com.google.api.expr.v1alpha1.Expr) Ident(com.google.api.expr.v1alpha1.Expr.Ident) InterpretableCall(org.projectnessie.cel.interpreter.Interpretable.InterpretableCall) OptExhaustiveEval(org.projectnessie.cel.EvalOption.OptExhaustiveEval) OptTrackState(org.projectnessie.cel.EvalOption.OptTrackState) StringT.stringOf(org.projectnessie.cel.common.types.StringT.stringOf) Decls(org.projectnessie.cel.checker.Decls) CEL.attributePattern(org.projectnessie.cel.CEL.attributePattern) Executors(java.util.concurrent.Executors) Test(org.junit.jupiter.api.Test) ProgramOption.functions(org.projectnessie.cel.ProgramOption.functions) DefaultTypeAdapter(org.projectnessie.cel.common.types.pb.DefaultTypeAdapter) Overload(org.projectnessie.cel.interpreter.functions.Overload) EvalResult(org.projectnessie.cel.Program.EvalResult) Err.newErr(org.projectnessie.cel.common.types.Err.newErr) IntOne(org.projectnessie.cel.common.types.IntT.IntOne) IntStream(java.util.stream.IntStream) Overloads(org.projectnessie.cel.common.types.Overloads) Env.newEnv(org.projectnessie.cel.Env.newEnv) StdLib(org.projectnessie.cel.Library.StdLib) IntT(org.projectnessie.cel.common.types.IntT) Trait(org.projectnessie.cel.common.types.traits.Trait) EnvOption.declarations(org.projectnessie.cel.EnvOption.declarations) CompletableFuture(java.util.concurrent.CompletableFuture) Err.valOrErr(org.projectnessie.cel.common.types.Err.valOrErr) CEL.partialVars(org.projectnessie.cel.CEL.partialVars) AtomicReference(java.util.concurrent.atomic.AtomicReference) EnvOption.customTypeAdapter(org.projectnessie.cel.EnvOption.customTypeAdapter) AstIssuesTuple(org.projectnessie.cel.Env.AstIssuesTuple) Mapper(org.projectnessie.cel.common.types.traits.Mapper) ProgramOption.evalOptions(org.projectnessie.cel.ProgramOption.evalOptions) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) Type(com.google.api.expr.v1alpha1.Type) CEL.astToCheckedExpr(org.projectnessie.cel.CEL.astToCheckedExpr) CEL.noVars(org.projectnessie.cel.CEL.noVars) ExecutorService(java.util.concurrent.ExecutorService) Collections.emptyMap(java.util.Collections.emptyMap) CEL.astToString(org.projectnessie.cel.CEL.astToString) ProgramOption.globals(org.projectnessie.cel.ProgramOption.globals) Operator(org.projectnessie.cel.common.operators.Operator) NamespacedAttribute(org.projectnessie.cel.interpreter.AttributeFactory.NamespacedAttribute) UnknownT(org.projectnessie.cel.common.types.UnknownT) Cost(org.projectnessie.cel.interpreter.Coster.Cost) EnvOption.types(org.projectnessie.cel.EnvOption.types) ProgramOption.customDecorator(org.projectnessie.cel.ProgramOption.customDecorator) EnvOption.macros(org.projectnessie.cel.EnvOption.macros) Interpretable.newConstValue(org.projectnessie.cel.interpreter.Interpretable.newConstValue) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) CEL.parsedExprToAst(org.projectnessie.cel.CEL.parsedExprToAst) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) InterpretableConst(org.projectnessie.cel.interpreter.Interpretable.InterpretableConst) CEL.astToParsedExpr(org.projectnessie.cel.CEL.astToParsedExpr) CEL.checkedExprToAst(org.projectnessie.cel.CEL.checkedExprToAst) EvalState(org.projectnessie.cel.interpreter.EvalState) Util.mapOf(org.projectnessie.cel.Util.mapOf) StringT(org.projectnessie.cel.common.types.StringT) EnvOption.homogeneousAggregateLiterals(org.projectnessie.cel.EnvOption.homogeneousAggregateLiterals) Env.newCustomEnv(org.projectnessie.cel.Env.newCustomEnv) EnvOption.abbrevs(org.projectnessie.cel.EnvOption.abbrevs) Val(org.projectnessie.cel.common.types.ref.Val) InterpretableConst(org.projectnessie.cel.interpreter.Interpretable.InterpretableConst) InterpretableDecorator(org.projectnessie.cel.interpreter.InterpretableDecorator) AtomicReference(java.util.concurrent.atomic.AtomicReference) CEL.astToString(org.projectnessie.cel.CEL.astToString) Env.newEnv(org.projectnessie.cel.Env.newEnv) Env.newCustomEnv(org.projectnessie.cel.Env.newCustomEnv) NamespacedAttribute(org.projectnessie.cel.interpreter.AttributeFactory.NamespacedAttribute) InterpretableCall(org.projectnessie.cel.interpreter.Interpretable.InterpretableCall) AstIssuesTuple(org.projectnessie.cel.Env.AstIssuesTuple) Interpretable(org.projectnessie.cel.interpreter.Interpretable) InterpretableAttribute(org.projectnessie.cel.interpreter.Interpretable.InterpretableAttribute) Test(org.junit.jupiter.api.Test)

Example 2 with InterpretableConst

use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.

the class AttributesTest method attributesRelativeAttr.

@Test
void attributesRelativeAttr() {
    TypeRegistry reg = newRegistry();
    AttributeFactory attrs = newAttributeFactory(Container.defaultContainer, reg, reg);
    Map<Object, Object> data = mapOf("a", mapOf(-1, new int[] { 2, 42 }), "b", 1);
    Activation vars = newActivation(data);
    // The relative attribute under test is applied to a map literal:
    // {
    // a: {-1: [2, 42], b: 1}
    // b: 1
    // }
    // 
    // The expression being evaluated is: <map-literal>.a[-1][b] -> 42
    InterpretableConst op = newConstValue(1, reg.nativeToValue(data));
    Attribute attr = attrs.relativeAttribute(1, op);
    Qualifier qualA = attrs.newQualifier(null, 2, "a");
    Qualifier qualNeg1 = attrs.newQualifier(null, 3, intOf(-1));
    attr.addQualifier(qualA);
    attr.addQualifier(qualNeg1);
    attr.addQualifier(attrs.absoluteAttribute(4, "b"));
    Object out = attr.resolve(vars);
    assertThat(out).isEqualTo(intOf(42));
    assertThat(estimateCost(attr)).extracting("min", "max").containsExactly(1L, 1L);
}
Also used : NamespacedAttribute(org.projectnessie.cel.interpreter.AttributeFactory.NamespacedAttribute) Attribute(org.projectnessie.cel.interpreter.AttributeFactory.Attribute) InterpretableConst(org.projectnessie.cel.interpreter.Interpretable.InterpretableConst) AttributePattern.newPartialAttributeFactory(org.projectnessie.cel.interpreter.AttributePattern.newPartialAttributeFactory) AttributeFactory.newAttributeFactory(org.projectnessie.cel.interpreter.AttributeFactory.newAttributeFactory) Activation.emptyActivation(org.projectnessie.cel.interpreter.Activation.emptyActivation) Activation.newPartialActivation(org.projectnessie.cel.interpreter.Activation.newPartialActivation) Activation.newActivation(org.projectnessie.cel.interpreter.Activation.newActivation) Qualifier(org.projectnessie.cel.interpreter.AttributeFactory.Qualifier) TypeRegistry(org.projectnessie.cel.common.types.ref.TypeRegistry) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 3 with InterpretableConst

use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.

the class AttributesTest method attributesRelativeAttr_OneOf.

@Test
void attributesRelativeAttr_OneOf() {
    TypeRegistry reg = newRegistry();
    Container cont = newContainer(Container.name("acme.ns"));
    AttributeFactory attrs = newAttributeFactory(cont, reg, reg);
    Map<Object, Object> data = mapOf("a", mapOf(-1, new int[] { 2, 42 }), "acme.b", 1);
    Activation vars = newActivation(data);
    // The relative attribute under test is applied to a map literal:
    // {
    // a: {-1: [2, 42], b: 1}
    // b: 1
    // }
    // 
    // The expression being evaluated is: <map-literal>.a[-1][b] -> 42
    // 
    // However, since the test is validating what happens with maybe attributes
    // the attribute resolution must also consider the following variations:
    // - <map-literal>.a[-1][acme.ns.b]
    // - <map-literal>.a[-1][acme.b]
    // 
    // The correct behavior should yield the value of the last alternative.
    InterpretableConst op = newConstValue(1, reg.nativeToValue(data));
    Attribute attr = attrs.relativeAttribute(1, op);
    Qualifier qualA = attrs.newQualifier(null, 2, "a");
    Qualifier qualNeg1 = attrs.newQualifier(null, 3, intOf(-1));
    attr.addQualifier(qualA);
    attr.addQualifier(qualNeg1);
    attr.addQualifier(attrs.maybeAttribute(4, "b"));
    Object out = attr.resolve(vars);
    assertThat(out).isEqualTo(intOf(42));
    assertThat(estimateCost(attr)).extracting("min", "max").containsExactly(1L, 1L);
}
Also used : Container.newContainer(org.projectnessie.cel.common.containers.Container.newContainer) Container(org.projectnessie.cel.common.containers.Container) NamespacedAttribute(org.projectnessie.cel.interpreter.AttributeFactory.NamespacedAttribute) Attribute(org.projectnessie.cel.interpreter.AttributeFactory.Attribute) InterpretableConst(org.projectnessie.cel.interpreter.Interpretable.InterpretableConst) AttributePattern.newPartialAttributeFactory(org.projectnessie.cel.interpreter.AttributePattern.newPartialAttributeFactory) AttributeFactory.newAttributeFactory(org.projectnessie.cel.interpreter.AttributeFactory.newAttributeFactory) Activation.emptyActivation(org.projectnessie.cel.interpreter.Activation.emptyActivation) Activation.newPartialActivation(org.projectnessie.cel.interpreter.Activation.newPartialActivation) Activation.newActivation(org.projectnessie.cel.interpreter.Activation.newActivation) Qualifier(org.projectnessie.cel.interpreter.AttributeFactory.Qualifier) TypeRegistry(org.projectnessie.cel.common.types.ref.TypeRegistry) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with InterpretableConst

use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.

the class InterpretableDecorator method maybeOptimizeConstUnary.

static Interpretable maybeOptimizeConstUnary(Interpretable i, InterpretableCall call) {
    Interpretable[] args = call.args();
    if (args.length != 1) {
        return i;
    }
    if (!(args[0] instanceof InterpretableConst)) {
        return i;
    }
    Val val = call.eval(emptyActivation());
    throwErrorAsIllegalStateException(val);
    return newConstValue(call.id(), val);
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) InterpretableConst(org.projectnessie.cel.interpreter.Interpretable.InterpretableConst)

Example 5 with InterpretableConst

use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.

the class InterpretableDecorator method maybeOptimizeSetMembership.

/**
 * maybeOptimizeSetMembership may convert an 'in' operation against a list to map key membership
 * test if the following conditions are true:
 *
 * <ul>
 *   <li>the list is a constant with homogeneous element types.
 *   <li>the elements are all of primitive type.
 * </ul>
 */
static Interpretable maybeOptimizeSetMembership(Interpretable i, InterpretableCall inlist) {
    Interpretable[] args = inlist.args();
    Interpretable lhs = args[0];
    Interpretable rhs = args[1];
    if (!(rhs instanceof InterpretableConst)) {
        return i;
    }
    InterpretableConst l = (InterpretableConst) rhs;
    // When the incoming binary call is flagged with as the InList overload, the value will
    // always be convertible to a `traits.Lister` type.
    Lister list = (Lister) l.value();
    if (list.size() == IntZero) {
        return newConstValue(inlist.id(), False);
    }
    IteratorT it = list.iterator();
    Type typ = null;
    Set<Val> valueSet = new HashSet<>();
    while (it.hasNext() == True) {
        Val elem = it.next();
        if (!Util.isPrimitiveType(elem)) {
            // Note, non-primitive type are not yet supported.
            return i;
        }
        if (typ == null) {
            typ = elem.type();
        } else if (!typ.typeName().equals(elem.type().typeName())) {
            return i;
        }
        valueSet.add(elem);
    }
    return new EvalSetMembership(inlist, lhs, typ.typeName(), valueSet);
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) IteratorT(org.projectnessie.cel.common.types.IteratorT) Type(org.projectnessie.cel.common.types.ref.Type) Lister(org.projectnessie.cel.common.types.traits.Lister) EvalSetMembership(org.projectnessie.cel.interpreter.Interpretable.EvalSetMembership) InterpretableConst(org.projectnessie.cel.interpreter.Interpretable.InterpretableConst) HashSet(java.util.HashSet)

Aggregations

InterpretableConst (org.projectnessie.cel.interpreter.Interpretable.InterpretableConst)8 Test (org.junit.jupiter.api.Test)6 TypeRegistry (org.projectnessie.cel.common.types.ref.TypeRegistry)6 Activation.emptyActivation (org.projectnessie.cel.interpreter.Activation.emptyActivation)6 NamespacedAttribute (org.projectnessie.cel.interpreter.AttributeFactory.NamespacedAttribute)6 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)5 Activation.newActivation (org.projectnessie.cel.interpreter.Activation.newActivation)5 Activation.newPartialActivation (org.projectnessie.cel.interpreter.Activation.newPartialActivation)5 Qualifier (org.projectnessie.cel.interpreter.AttributeFactory.Qualifier)5 AttributeFactory.newAttributeFactory (org.projectnessie.cel.interpreter.AttributeFactory.newAttributeFactory)5 AttributePattern.newPartialAttributeFactory (org.projectnessie.cel.interpreter.AttributePattern.newPartialAttributeFactory)5 Attribute (org.projectnessie.cel.interpreter.AttributeFactory.Attribute)4 Val (org.projectnessie.cel.common.types.ref.Val)3 Expr (com.google.api.expr.v1alpha1.Expr)2 ParsedExpr (com.google.api.expr.v1alpha1.ParsedExpr)2 Collections.singletonList (java.util.Collections.singletonList)2 Container (org.projectnessie.cel.common.containers.Container)2 Container.newContainer (org.projectnessie.cel.common.containers.Container.newContainer)2 TestAllTypes (com.google.api.expr.test.v1.proto2.TestAllTypesProto.TestAllTypes)1 CheckedExpr (com.google.api.expr.v1alpha1.CheckedExpr)1