Katkat

Represent and Evaluate Boolean Predicate Expressions

CoreweaveSoftware Engineer · Onsite

Last updated

Design an object-oriented or tree-based representation for boolean predicate expressions and implement an evaluation engine that supports logical operators, comparison operations, and short-circuit evaluation against attribute dictionaries.

Problem Statement

Cloud infrastructure platforms frequently need to filter compute resources (nodes, clusters, or workloads) based on dynamic attribute criteria, such as available GPU memory, region, or machine tags.

Design an extensible representation for boolean predicate expressions and implement an evaluation mechanism that assesses whether a given resource context (a dictionary mapping string keys to scalar values) satisfies the predicate.

Your solution should support:

  1. Comparison Predicates:
    • Equals(field: str, value: Any): returns True if context.get(field) == value.
    • GreaterThan(field: str, value: Union[int, float]): returns True if context.get(field) > value. If field is missing or the value is not comparable, evaluate to False.
    • InSet(field: str, values: Set[Any]): returns True if context.get(field) exists in values.
  2. Logical Predicates:
    • And(*predicates: Predicate): returns True if all child predicates evaluate to True. Supports short-circuiting (stops evaluating upon encountering the first False). An empty And() evaluates to True.
    • Or(*predicates: Predicate): returns True if any child predicate evaluates to True. Supports short-circuiting (stops evaluating upon encountering the first True). An empty Or() evaluates to False.
    • Not(predicate: Predicate): returns the logical negation of the child predicate.

Interface

from abc import ABC, abstractmethod
from typing import Any, Set, Union

class Predicate(ABC):
    @abstractmethod
    def evaluate(self, context: dict[str, Any]) -> bool:
        """Evaluate the predicate against the given context dictionary."""
        pass

class Equals(Predicate):
    def __init__(self, field: str, value: Any):
        ...

class GreaterThan(Predicate):
    def __init__(self, field: str, value: Union[int, float]):
        ...

class InSet(Predicate):
    def __init__(self, field: str, values: Set[Any]):
        ...

class And(Predicate):
    def __init__(self, *predicates: Predicate):
        ...

class Or(Predicate):
    def __init__(self, *predicates: Predicate):
        ...

class Not(Predicate):
    def __init__(self, predicate: Predicate):
        ...

Examples

Example 1

# Expression: gpu == "H100" AND (vram_gb > 40 OR region IN {"us-east-1", "us-west-1"})
expr = And(
    Equals("gpu", "H100"),
    Or(
        GreaterThan("vram_gb", 40),
        InSet("region", {"us-east-1", "us-west-1"})
    )
)

node_a = {"gpu": "H100", "vram_gb": 80, "region": "eu-central-1"}
node_b = {"gpu": "A100", "vram_gb": 80, "region": "us-east-1"}

assert expr.evaluate(node_a) is True   # H100 matches, 80 > 40 matches
assert expr.evaluate(node_b) is False  # gpu is A100, short-circuits

Constraints

  • Attribute values in context dictionaries can be str, int, float, bool, or None.
  • Comparison with missing keys in comparison operators should safely return False rather than raising KeyError.
  • The depth of the expression tree will not exceed 100 nodes.

Hints

Hint 1

Use the Composite design pattern: both leaf predicates and composite operators share the common abstract interface with an evaluate method.

Hint 2

Implement short-circuiting in And and Or by iterating through child predicates with a generator or early return upon finding an absorbing element.

Hint 3

Ensure comparison methods handle missing keys and incompatible type comparisons gracefully with a try-except block or explicit type checks.

Follow-up questions

  • How would you serialize and deserialize this predicate expression tree to and from JSON (e.g., for storing filter rules in a database or passing via REST API)?
  • How would you optimize evaluating the same predicate against millions of resource contexts in parallel or via vectorization?
  • How would you implement static validation to verify that an expression tree contains no contradictory clauses (e.g., `x > 10 AND x < 5`) before running evaluation?