Skip to content

This feature is currently in Preview.

relationalai.experimental.solvers.count()

Signature
count(*args: dsl.Instance|SolverExpression, per: list = []) -> SolverExpression

Returns a solver expression that counts how many rows are produced by the input arguments. Rows are generated by taking the Cartesian product (cross join) of the values produced by each argument. Rows with any False or missing values are excluded from the count. If one or more per keys are provided, aggregation is performed per group. Must be called in a Model.rule() or solvers.operators() context.

NameTypeDescription
*argsdsl.Instance, SolverExpressionOne or more solver expressions to evaluate as boolean conditions.
perlistOptional grouping key(s) to perform aggregation per value of one or more variables. Defaults to [].

A SolverExpression object representing the count of inputs that evaluate to True.

Use count() with the SolverModel.constraint() method to limit how many expressions can evaluate to True:

import relationalai as rai
from relationalai.experimental import solvers
# Create a model.
model = rai.Model("DietaryConstraints")
# Declare entity types.
Food = model.Type("Food")
Day = model.Type("Day")
Portion = model.Type("Portion")
23 collapsed lines
# Declare properties.
Food.calories.declare()
Food.fat.declare()
Food.salt.declare()
Food.carbs.declare()
Portion.food.declare()
Portion.day.declare()
# Define foods.
with model.rule():
Food.add(name="Oatmeal").set(calories=150, fat=3, salt=0.1, carbs=27)
Food.add(name="Egg").set(calories=70, fat=5, salt=0.2, carbs=1)
Food.add(name="Banana").set(calories=100, fat=0.5, salt=0.0, carbs=26)
Food.add(name="Toast").set(calories=80, fat=1, salt=0.3, carbs=15)
# Define days.
with model.rule():
for name in ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]:
Day.add(name=name)
# Define all possible food portions for each day.
with model.rule():
Portion.add(food=Food(), day=Day())
# Create a solver model.
solver_model = solvers.SolverModel(model)
# Define solver variables for portions.
with model.rule():
portion = Portion()
solver_model.variable(
portion,
name_args=["portion", portion.food.name, portion.day.name],
lower=0,
upper=5,
)
# Constrain no more than two foods to exceed 20g of carbs.
with solvers.operators():
portion = Portion()
num_portions = solvers.count(portion.food.carbs * portion > 20, per=[portion.day])
day = portion.day
solver_model.constraint(num_portions <= 2)