Diet Optimization
Select foods to satisfy daily nutritional requirements at minimum cost.
Select foods to satisfy daily nutritional requirements at minimum cost.
Select foods to satisfy nutritional requirements at minimum cost.
What this template is for
Meal planning services, hospitals, and institutional food services need to design menus that meet nutritional requirements without overspending. This template models selecting from a small set of foods to satisfy daily bounds on calories, protein, fat, and sodium at minimum cost.
This is the classic “diet problem”, one of the earliest practical applications of linear programming originally formulated by economist George Stigler in 1945. This template uses RelationalAI’s prescriptive reasoning (optimization) capabilities to find the optimal food combination that meets all nutritional constraints at the lowest cost.
Prescriptive reasoning helps you:
- Reduce cost while still meeting nutrition guidelines.
- Guarantee compliance with min/max nutrient bounds.
- Scale decision-making from a handful of foods to large catalogs.
Who this is for
- You want a small, end-to-end example of prescriptive reasoning (optimization) with RelationalAI.
- You’re comfortable with basic Python and linear optimization concepts.
What you’ll build
- A semantic model of foods and nutrients using concepts and properties.
- A linear program that chooses non-negative servings per food.
- Nutrient bound constraints and a cost-minimization objective.
- A solver that uses the HiGHS backend to print a readable diet plan.
What’s included
- Model + solve script:
diet.py - Sample data:
data/foods.csv,data/nutrients.csv
Prerequisites
Access
- A Snowflake account that has the RAI Native App installed.
- A Snowflake user with permissions to access the RAI Native App.
Tools
- Python >= 3.10
Quickstart
Follow these steps to run the template with the included sample data.
-
Download the ZIP file for this template and extract it:
Terminal window curl -O https://private.relational.ai/templates/zips/v0.13/diet.zipunzip diet.zipcd diet -
Create and activate a virtual environment
Terminal window python -m venv .venvsource .venv/bin/activatepython -m pip install --upgrade pip -
Install dependencies
Terminal window python -m pip install . -
Configure Snowflake connection and RAI profile
Terminal window rai init -
Run the template
Terminal window python diet.py -
Expected output
Status: OPTIMALMinimum cost: $11.83Optimal diet:name amounthamburger 0.604514icecream 2.591319milk 6.970139
Template structure
.├─ README.md├─ pyproject.toml├─ diet.py # main runner / entrypoint└─ data/ # sample input data ├─ foods.csv └─ nutrients.csvStart here: diet.py
Sample data
Data files are in data/.
nutrients.csv
Defines nutrient bounds (min/max) for a single day.
| Column | Meaning |
|---|---|
name | Nutrient name (e.g., calories, protein) |
min | Minimum daily requirement |
max | Maximum daily allowance |
foods.csv
Lists foods, their cost, and nutrient quantities per serving.
Each nutrient in nutrients.csv.name is also a column in this file.
| Column | Meaning |
|---|---|
name | Food name |
cost | Cost per serving |
<nutrient columns> | Quantity per serving (e.g., calories, protein, fat, sodium) |
Model overview
The semantic model for this template is built around two concepts and one relationship.
Nutrient
A nutrient with minimum and maximum daily bounds.
| Property | Type | Identifying? | Notes |
|---|---|---|---|
name | string | Yes | Loaded as the key from data/nutrients.csv |
min | float | No | Minimum daily requirement |
max | float | No | Maximum daily allowance |
Food
A food item with a cost, plus a decision variable (amount) chosen by the solver.
| Property | Type | Identifying? | Notes |
|---|---|---|---|
name | string | Yes | Loaded from data/foods.csv.name and used for output labeling |
cost | float | No | Cost per serving |
amount | float | No | Continuous decision variable (servings, |
Relationships
This template uses a relationship (not just properties) to represent per-food nutrient quantities.
| Relationship | Schema (reading string fields) | Notes |
|---|---|---|
Food.nutrients | {Food} contains {qty:float} of {Nutrient} | Quantity per serving loaded from the nutrient columns in data/foods.csv |
How it works
This section walks through the highlights in diet.py.
Import libraries and configure inputs
This template uses Concept objects from relationalai.semantics to model foods and nutrients, and uses Solver and SolverModel from relationalai.semantics.reasoners.optimization to define and solve the linear program:
from pathlib import Path
import pandasfrom pandas import read_csv
from relationalai.semantics import Model, data, define, require, select, sumfrom relationalai.semantics.reasoners.optimization import Solver, SolverModel
# --------------------------------------------------# Configure inputs and create the model# --------------------------------------------------
DATA_DIR = Path(__file__).parent / "data"
# Disable pandas inference of string types. This ensures that string columns# in the CSVs are loaded as object dtype. This is only required when using# relationalai versions prior to v1.0.pandas.options.future.infer_string = False
# --------------------------------------------------# Define semantic model & load data# --------------------------------------------------
# Create a Semantics model container.model = Model("diet", config=globals().get("config", None), use_lqp=False)Define concepts and load CSV data
First, it declares Nutrient and Food concepts, loads nutrients.csv into Nutrient, and then uses define(...).where(...) to populate Food.nutrients from the nutrient columns in foods.csv:
# Nutrient concept: represents a nutrient with minimum and maximum daily requirements.Nutrient = model.Concept("Nutrient")Nutrient.name = model.Property("{Nutrient} is named {name:string}")Nutrient.min = model.Property("{Nutrient} has minimum daily requirement {min:float}")Nutrient.max = model.Property("{Nutrient} has maximum daily requirement {max:float}")
nutrient_csv = read_csv(DATA_DIR / "nutrients.csv")data(nutrient_csv).into(Nutrient, keys=["name"])
# Food concept: foods have a cost and contain nutrients in some quantity.Food = model.Concept("Food")Food.nutrients = model.Relationship("{Food} contains {qty:float} of {Nutrient}")Food.cost = model.Property("{Food} costs {cost:float}")
food_csv = read_csv(DATA_DIR / "foods.csv")food_data = data(food_csv)
# Create one Food entity per row in the food data and define its cost.food = Food.new(name=food_data.name)define(food, food.cost(food_data.cost))
# Define nutrient quantities for each food by iterating the nutrient columns.for nutrient_name in nutrient_csv.name: define(Food.nutrients(food, food_data[nutrient_name], Nutrient)).where( Nutrient.name == nutrient_name )Define decision variables, constraints, and objective
Next, it creates one continuous, non-negative decision variable per food (Food.x_amount), enforces nutrient bounds with require(...), and minimizes total cost:
# Create a continuous optimization model.s = SolverModel(model, "cont")
# Decision Variable: amount of each food (continuous, non-negative)Food.x_amount = model.Property("{Food} has {amount:float}")s.solve_for(Food.x_amount, name=Food.name, lower=0)
# Calculate total quantity of each nutrient across all foods: sum(qty * amount) per nutrient.nutrient_total = sum( Food.nutrients["qty"] * Food.x_amount).where( Food.nutrients == Nutrient).per(Nutrient)
# Constraint: nutrient totals must be within specified bounds.nutrient_bounds = require( nutrient_total >= Nutrient.min, nutrient_total <= Nutrient.max)s.satisfy(nutrient_bounds)
# Objective: minimize total costtotal_cost = sum(Food.cost * Food.x_amount)s.minimize(total_cost)Solve and print results
Finally, it solves with the HiGHS backend and prints only foods with a non-trivial amount (Food.x_amount > 0.001):
# Solve the model with a time limit of 60 seconds using the HiGHS solver.solver = Solver("highs")s.solve(solver, time_limit_sec=60)
print(f"Status: {s.termination_status}")print(f"Minimum cost: ${s.objective_value:.2f}")
# Select the foods with non-trivial amounts in the optimal solution.diet_plan = select(Food.name, Food.x_amount).where(Food.x_amount > 0.001).to_df()
print("\nOptimal diet:")print(diet_plan.to_string(index=False))Customize this template
Here are some ideas for how to customize and extend this template to fit your specific use case.
Use your own data
- Replace the CSVs in
data/with your own, keeping the same column names (or update the loading logic indiet.py). - Ensure
foods.csvincludes a column for every nutrient listed innutrients.csv.name.
Tune parameters
- Tighten or relax nutritional bounds by editing
data/nutrients.csv. - Add new nutrients by adding rows to
data/nutrients.csvand adding matching columns todata/foods.csv.
Extend the model
- Add constraints like maximum servings per food or food category requirements.
- Add an “integer servings” variant by making
Food.x_amountan integer variable (and adjusting the model type if needed).
Scale up and productionize
- Replace CSV ingestion with Snowflake sources.
- Write the resulting diet plan back to Snowflake after solving.
Troubleshooting
Why does authentication/configuration fail?
- Run
rai initto create/updateraiconfig.toml. - If you have multiple profiles, set
RAI_PROFILEor switch profiles in your config.
Why does the script fail to connect to the RAI Native App?
- Verify the Snowflake account/role/warehouse and
rai_app_nameare correct inraiconfig.toml. - Ensure the RAI Native App is installed and you have access.
Why do I get Status: INFEASIBLE?
- Check for impossible bounds (e.g.,
min > maxfor a nutrient). - Confirm that the foods collectively can meet each nutrient’s minimum without violating other maximums.
Why is the output diet empty?
- The script filters foods with
Food.x_amount > 0.001. If all values are tiny, inspect nutrient bounds and costs. - Confirm the CSVs were read correctly and contain rows.
What this template is for
Meal planning services, hospitals, and institutional food services need to design menus that meet nutritional requirements without overspending. This template models selecting from a small set of foods to satisfy daily bounds on calories, protein, fat, and sodium at minimum cost.
This is the classic “diet problem”, one of the earliest practical applications of linear programming originally formulated by economist George Stigler in 1945. This template uses RelationalAI’s Prescriptive reasoning capabilities to find the optimal food combination that meets all nutritional constraints at the lowest cost.
Prescriptive reasoning helps you:
- Reduce cost while still meeting nutrition guidelines.
- Guarantee compliance with min/max nutrient bounds.
- Scale decision-making from a handful of foods to large catalogs.
Who this is for
- You want a small, end-to-end example of prescriptive reasoning (optimization) with RelationalAI.
- You’re comfortable with basic Python and linear optimization concepts.
What you’ll build
- A semantic model of foods and nutrients using concepts and properties.
- A linear program that chooses non-negative servings per food.
- Nutrient bound constraints and a cost-minimization objective.
- A solver that uses the HiGHS backend to print a readable diet plan.
What’s included
- Model + solve script:
diet.py - Sample data:
data/foods.csv,data/nutrients.csv
Prerequisites
Access
- A Snowflake account that has the RAI Native App installed.
- A Snowflake user with permissions to access the RAI Native App.
Tools
- Python >= 3.10
Quickstart
Follow these steps to run the template with the included sample data.
-
Download the ZIP file for this template and extract it:
Terminal window curl -O https://private.relational.ai/templates/zips/v0.14/diet.zipunzip diet.zipcd diet -
Create and activate a virtual environment
Terminal window python -m venv .venvsource .venv/bin/activatepython -m pip install --upgrade pip -
Install dependencies
Terminal window python -m pip install . -
Configure Snowflake connection and RAI profile
Terminal window rai init -
Run the template
Terminal window python diet.py -
Expected output
Status: OPTIMALMinimum cost: $11.83Optimal diet:name amounthamburger 0.604514icecream 2.591319milk 6.970139
Template structure
.├─ README.md├─ pyproject.toml├─ diet.py # main runner / entrypoint└─ data/ # sample input data ├─ foods.csv └─ nutrients.csvStart here: diet.py
Sample data
Data files are in data/.
nutrients.csv
Defines nutrient bounds (min/max) for a single day.
| Column | Meaning |
|---|---|
name | Nutrient name (e.g., calories, protein) |
min | Minimum daily requirement |
max | Maximum daily allowance |
foods.csv
Lists foods, their cost, and nutrient quantities per serving.
Each nutrient in nutrients.csv.name is also a column in this file.
| Column | Meaning |
|---|---|
name | Food name |
cost | Cost per serving |
<nutrient columns> | Quantity per serving (e.g., calories, protein, fat, sodium) |
Model overview
The semantic model for this template is built around two concepts and one relationship.
Nutrient
A nutrient with minimum and maximum daily bounds.
| Property | Type | Identifying? | Notes |
|---|---|---|---|
name | string | Yes | Loaded as the key from data/nutrients.csv |
min | float | No | Minimum daily requirement |
max | float | No | Maximum daily allowance |
Food
A food item with a cost, plus a decision variable (amount) chosen by the solver.
| Property | Type | Identifying? | Notes |
|---|---|---|---|
name | string | Yes | Loaded from data/foods.csv.name and used for output labeling |
cost | float | No | Cost per serving |
amount | float | No | Continuous decision variable (servings, |
Relationships
This template uses a relationship (not just properties) to represent per-food nutrient quantities.
| Relationship | Schema (reading string fields) | Notes |
|---|---|---|
Food.nutrients | {Food} contains {qty:float} of {Nutrient} | Quantity per serving loaded from the nutrient columns in data/foods.csv |
How it works
This section walks through the highlights in diet.py.
Import libraries and configure inputs
This template uses Concept objects from relationalai.semantics to model foods and nutrients, and uses Solver and SolverModel from relationalai.semantics.reasoners.optimization to define and solve the linear program:
from pathlib import Path
import pandasfrom pandas import read_csv
from relationalai.semantics import Model, data, define, require, select, sumfrom relationalai.semantics.reasoners.optimization import Solver, SolverModel
# --------------------------------------------------# Configure inputs and create the model# --------------------------------------------------
DATA_DIR = Path(__file__).parent / "data"
# Disable pandas inference of string types. This ensures that string columns# in the CSVs are loaded as object dtype. This is only required when using# relationalai versions prior to v1.0.pandas.options.future.infer_string = False
# --------------------------------------------------# Define semantic model & load data# --------------------------------------------------
# Create a Semantics model container.model = Model("diet", config=globals().get("config", None))Define concepts and load CSV data
First, it declares Nutrient and Food concepts, loads nutrients.csv into Nutrient, and then uses define(...).where(...) to populate Food.nutrients from the nutrient columns in foods.csv:
# Nutrient concept: represents a nutrient with minimum and maximum daily requirements.Nutrient = model.Concept("Nutrient")Nutrient.name = model.Property("{Nutrient} is named {name:string}")Nutrient.min = model.Property("{Nutrient} has minimum daily requirement {min:float}")Nutrient.max = model.Property("{Nutrient} has maximum daily requirement {max:float}")
nutrient_csv = read_csv(DATA_DIR / "nutrients.csv")data(nutrient_csv).into(Nutrient, keys=["name"])
# Food concept: foods have a cost and contain nutrients in some quantity.Food = model.Concept("Food")Food.nutrients = model.Relationship("{Food} contains {qty:float} of {Nutrient}")Food.cost = model.Property("{Food} costs {cost:float}")
food_csv = read_csv(DATA_DIR / "foods.csv")food_data = data(food_csv)
# Create one Food entity per row in the food data and define its cost.food = Food.new(name=food_data.name)define(food, food.cost(food_data.cost))
# Define nutrient quantities for each food by iterating the nutrient columns.for nutrient_name in nutrient_csv.name: define(Food.nutrients(food, food_data[nutrient_name], Nutrient)).where( Nutrient.name == nutrient_name )Define decision variables, constraints, and objective
Next, it creates one continuous, non-negative decision variable per food (Food.x_amount), enforces nutrient bounds with require(...), and minimizes total cost:
# Create a continuous optimization model.s = SolverModel(model, "cont")
# Decision Variable: amount of each food (continuous, non-negative)Food.x_amount = model.Property("{Food} has {amount:float}")s.solve_for(Food.x_amount, name=Food.name, lower=0)
# Calculate total quantity of each nutrient across all foods: sum(qty * amount) per nutrient.nutrient_total = sum( Food.nutrients["qty"] * Food.x_amount).where( Food.nutrients == Nutrient).per(Nutrient)
# Constraint: nutrient totals must be within specified bounds.nutrient_bounds = require( nutrient_total >= Nutrient.min, nutrient_total <= Nutrient.max)s.satisfy(nutrient_bounds)
# Objective: minimize total costtotal_cost = sum(Food.cost * Food.x_amount)s.minimize(total_cost)Solve and print results
Finally, it solves with the HiGHS backend and prints only foods with a non-trivial amount (Food.x_amount > 0.001):
# Solve the model with a time limit of 60 seconds using the HiGHS solver.solver = Solver("highs")s.solve(solver, time_limit_sec=60)
print(f"Status: {s.termination_status}")print(f"Minimum cost: ${s.objective_value:.2f}")
# Select the foods with non-trivial amounts in the optimal solution.diet_plan = select(Food.name, Food.x_amount).where(Food.x_amount > 0.001).to_df()
print("\nOptimal diet:")print(diet_plan.to_string(index=False))Customize this template
Here are some ideas for how to customize and extend this template to fit your specific use case.
Use your own data
- Replace the CSVs in
data/with your own, keeping the same column names (or update the loading logic indiet.py). - Ensure
foods.csvincludes a column for every nutrient listed innutrients.csv.name.
Tune parameters
- Tighten or relax nutritional bounds by editing
data/nutrients.csv. - Add new nutrients by adding rows to
data/nutrients.csvand adding matching columns todata/foods.csv.
Extend the model
- Add constraints like maximum servings per food or food category requirements.
- Add an “integer servings” variant by making
Food.x_amountan integer variable (and adjusting the model type if needed).
Scale up and productionize
- Replace CSV ingestion with Snowflake sources.
- Write the resulting diet plan back to Snowflake after solving.
Troubleshooting
Why does authentication/configuration fail?
- Run
rai initto create/updateraiconfig.toml. - If you have multiple profiles, set
RAI_PROFILEor switch profiles in your config.
Why does the script fail to connect to the RAI Native App?
- Verify the Snowflake account/role/warehouse and
rai_app_nameare correct inraiconfig.toml. - Ensure the RAI Native App is installed and you have access.
Why do I get Status: INFEASIBLE?
- Check for impossible bounds (e.g.,
min > maxfor a nutrient). - Confirm that the foods collectively can meet each nutrient’s minimum without violating other maximums.
Why is the output diet empty?
- The script filters foods with
Food.x_amount > 0.001. If all values are tiny, inspect nutrient bounds and costs. - Confirm the CSVs were read correctly and contain rows.
What this template is for
Choosing a balanced diet that meets nutritional requirements while staying within a budget is a classic optimization problem. Given a set of foods with known costs and nutrient contents, and a set of nutrients with minimum and maximum daily intake bounds, the goal is to find the cheapest combination of foods that satisfies all nutritional constraints. It also shows how the same model answers a “what if” question — how cost moves as requirements tighten or loosen — without re-modeling anything.
The template uses prescriptive reasoning to formulate the diet problem as a linear program and solve several requirement scenarios in a single solve.
Who this is for
- Data scientists and analysts learning prescriptive optimization with RelationalAI
- Operations researchers looking for a clean LP formulation example
- Anyone interested in nutritional planning or cost minimization problems
- Beginners who want to understand scenario analysis in optimization
What you’ll build
- A least-cost diet plan — the amount of each food that meets every nutrient bound at minimum total cost — produced by prescriptive reasoning (a linear program).
- Nutritional constraints holding total intake within minimum and maximum daily bounds for calories, protein, fat, and sodium.
- A scenario comparison showing how least-cost changes as requirements scale, built with a first-class
Scenarioconcept so all cases solve at once.
Built using prescriptive reasoning (linear programming with continuous decision variables and a Scenario concept for multi-case solves).
What’s included
- Model: two concepts (
Food,Nutrient), aScenarioconcept, per-food decision variables, nutrient-bound constraints, and a cost-minimizing objective — all indiet.py. - Runner:
diet.py, a single Python script that runs end-to-end against a Snowflake-connected RAI account. - Runbook:
runbook.md— a paste-testable walkthrough that reproduces the template step by step with the RAI skills; as important a reference as the script itself. - Sample data:
data/foods.csv(foods with cost and per-nutrient content) anddata/nutrients.csv(nutrient min/max bounds). - Outputs: per-scenario termination status, objective cost, and a table of the foods (and amounts) in each least-cost basket, printed to stdout.
Prerequisites
Access
- A Snowflake account that has the RAI Native App installed.
- A Snowflake user with permissions to access the RAI Native App.
Tools
- Python >= 3.10
Quickstart
-
Download ZIP:
Terminal window curl -O https://docs.relational.ai/templates/zips/v1/diet.zipunzip diet.zipcd diet -
Create venv:
Terminal window python -m venv .venvsource .venv/bin/activatepython -m pip install --upgrade pip -
Install:
Terminal window python -m pip install . -
Configure:
Terminal window rai init -
Run:
Terminal window python diet.py -
Expected output — a few lines confirm a successful run:
Solve result:• status: OPTIMAL• objective: 35.49Diet plan per scenario (0.8 / 1.0 / 1.2 demand): the same baselinebasket — hamburger + icecream + milk — scaled per scenario, for aper-scenario cost of $9.46 / $11.83 / $14.19.The full per-scenario diet plan prints above; see
runbook.mdfor the complete log.
Template structure
.├── README.md # this file├── runbook.md # step-by-step analyst walkthrough├── pyproject.toml # dependencies├── diet.py # main script (model, constraints, scenarios, solve)└── data/ ├── foods.csv # foods with cost and per-nutrient content └── nutrients.csv # nutrient min/max boundsStart here: run python diet.py for the full model and scenario solve end to end, or follow runbook.md to rebuild it step by step.
Sample data
The bundled data is small and illustrative — a handful of foods and four nutrients, sized to teach the linear-program formulation, not to represent a clinically complete diet.
data/foods.csv— one row per food, with acostper serving and one column per nutrient (calories,protein,fat,sodium) giving that food’s content per serving. Each food’s nutrient columns must match the nutrientnames innutrients.csv.data/nutrients.csv— one row per nutrient, withminandmaxdaily-intake bounds. The scenario scaling factor multiplies these bounds up and down.
Model overview
The model is small and self-contained: two source concepts plus a Scenario concept that parameterizes the solve.
- Key entities:
Food— a food with a per-serving cost and a per-nutrient content, carrying a continuous decision variable for the amount to include;Nutrient— a nutrient with minimum and maximum daily-intake bounds (the constraint bounds, scaled per scenario); andScenario— a requirement-scaling case that scales every nutrient bound by its factor, with all scenarios solving together in one solve. - Primary identifiers:
Food.nameandNutrient.name(both strings);Scenario.scenario_name(string). - Important invariants: nutrient
minandmaxbounds are non-negative andmin <= max; each food’s decision amount is non-negative (lower=0); each food’s per-nutrient content is keyed by a nutrient that exists innutrients.csv.
For the full concept and property definitions, see diet.py; runbook.md builds them step by step with the RAI skills.
How it works
The model reads two source tables, adds a scenario axis, and hands a single parameterized linear program to the prescriptive solver:
foods.csv + nutrients.csv → concepts → decision variables → constraints + objective → multi-scenario solve → per-scenario baskets-
Define concepts and map data.
Nutrientcarries min/max daily-intake bounds;Foodcarries a per-serving cost and a per-nutrient content (a ternarycontainsproperty linking each food to a nutrient quantity). -
Decision variables. Each food gets a continuous, non-negative decision variable — the amount to include in the diet — created per scenario so all cases share one formulation.
-
Constraints and objective. For each nutrient, total intake across foods (quantity times amount, summed) must fall between the scenario-scaled min and max bounds. The objective minimizes total cost (cost times amount, summed over foods).
-
Scenario analysis. A first-class
Scenarioconcept scales every nutrient bound by a factor (0.8 / 1.0 / 1.2 here), so tighter and looser requirements solve together in a single solve and their costs are directly comparable.
The prescriptive decision variable appears in the model schema alongside the source-data properties — a unified view of everything the model knows, including variables added by solve_for(). See diet.py for the implementation and runbook.md for the skill-driven reproduction.
Customize this template
Focus on the first changes most users will make.
Use your own data
- Replace
data/foods.csvanddata/nutrients.csvwith your own; keep the column names described in Sample data above. Each food’s nutrient columns must match the nutrientnames innutrients.csv— the model reads one food column per nutrient row. - For Snowflake-backed runs, swap the
read_csv(...)calls formodel.data(snowflake_table)calls.
Tune parameters
- Edit the scenario rows in
diet.py(the("scaling_80pct", 0.8),("baseline", 1.0),("scaling_120pct", 1.2)tuples) to test different scaling factors, or add rows for finer resolution. - Adjust the solver time limit (
time_limit_sec) if you scale up to many foods and nutrients.
Extend the model
- Add dietary preferences: introduce upper bounds on specific foods (for example, limiting red meat), or add binary variables to model food inclusion/exclusion.
- Weight the objective: add a secondary term to penalize undesirable foods alongside cost minimization.
- Add a second scenario axis (for example, budget caps) as another
Scenario-style concept.
Scale up / productionize
- Pin
relationalaiand schedule the run as a pipeline step for reproducible, deterministic re-runs. - Size the prescriptive engine up if the food and nutrient counts grow the linear program substantially.
Troubleshooting
Problem is infeasible
The nutritional bounds may be too tight for the available foods. Check that at least one combination of foods can satisfy all min/max constraints simultaneously. Try relaxing the scaling factor to a lower value (e.g., 0.5).
rai init fails or connection errors
Ensure your Snowflake credentials are configured correctly and that the RAI Native App is installed on your account. Run rai init again and verify the connection settings.
ModuleNotFoundError for relationalai
Make sure you activated the virtual environment and ran python -m pip install . from the template directory. The pyproject.toml declares the required dependencies.
Unexpected zero values in solution
Foods with zero in the solution are not cost-effective given the constraints. This is expected behavior. If you want to force inclusion of specific foods, add a minimum bound on their decision variables.
Learn more
Core concepts
- PyRel v1 query language —
model.where(...)/model.select(...)/.per(...)and result extraction. - Concepts and properties — modeling entities like
FoodandNutrientwith typed properties.
Reasoner reference
- Prescriptive reasoner —
ProblemAPI, decision variables, constraints, and objectives. - Scenario modeling — parameterizing one solve across cases with a
Scenarioconcept.
CLI / SDK guides
- RelationalAI setup —
rai init, profiles, andraiconfig.yaml.
Support
- File issues at the RelationalAI templates repository.