Skip to main content

Arithmetic Operations

HelixQL provides six fundamental arithmetic functions for performing basic mathematical calculations in your queries.

Available Functions

ADD - Addition

ADD(a, b)  // Returns a + b

SUB - Subtraction

SUB(a, b)  // Returns a - b

MUL - Multiplication

MUL(a, b)  // Returns a * b

DIV - Division

DIV(a, b)  // Returns a / b

POW - Power

POW(base, exponent)  // Returns base^exponent

MOD - Modulo

MOD(a, b)  // Returns a % b (remainder)
When using the SDKs or curling the endpoint, the query name must match what is defined in the queries.hx file exactly.

Example 1: Basic arithmetic in property calculations

Calculate discounted prices and tax for products:
QUERY CalculateProductPricing(discount_percent: F64, tax_rate: F64) =>
    products <- N::Product
        ::{
            name,
            original_price: price,
            discount: MUL(_::{price}, DIV(discount_percent, 100.0)),
            final_price: SUB(_::{price}, MUL(_::{price}, DIV(discount_percent, 100.0))),
            with_tax: MUL(SUB(_::{price}, MUL(_::{price}, DIV(discount_percent, 100.0))), ADD(1.0, tax_rate))
        }
    RETURN products

QUERY InsertProduct(name: String, price: F64) =>
    product <- AddN<Product>({ name: name, price: price })
    RETURN product
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Insert sample products
products = [
    {"name": "Laptop", "price": 999.99},
    {"name": "Mouse", "price": 29.99},
    {"name": "Keyboard", "price": 79.99},
]

for product in products:
    client.query("InsertProduct", product)

# Calculate pricing with 15% discount and 8.5% tax
result = client.query("CalculateProductPricing", {
    "discount_percent": 15.0,
    "tax_rate": 0.085
})

print("Product pricing:", result)

Example 2: Using POW for exponential calculations

Calculate compound interest over time:
QUERY CalculateInvestmentGrowth(years: I32, rate: F64) =>
    accounts <- N::Account
        ::{
            account_id,
            initial_amount,
            final_amount: MUL(_::{initial_amount}, POW(ADD(1.0, rate), years))
        }
    RETURN accounts

QUERY CreateAccount(account_id: String, initial_amount: F64) =>
    account <- AddN<Account>({ account_id: account_id, initial_amount: initial_amount })
    RETURN account
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create accounts
accounts = [
    {"account_id": "ACC001", "initial_amount": 10000.0},
    {"account_id": "ACC002", "initial_amount": 25000.0},
    {"account_id": "ACC003", "initial_amount": 50000.0},
]

for account in accounts:
    client.query("CreateAccount", account)

# Calculate growth over 10 years at 7% annual rate
result = client.query("CalculateInvestmentGrowth", {
    "years": 10,
    "rate": 0.07
})

print("Investment growth:", result)

Example 3: Using MOD for cyclic patterns

Use modulo to determine recurring patterns or groupings:
QUERY CategorizeByRotation(group_size: I64) =>
    items <- N::Item
        ::{
            item_id,
            position,
            group: MOD(_::{position}, group_size),
            is_first_in_group: MOD(_::{position}, group_size)::EQ(0)
        }
    RETURN items

QUERY CreateItem(item_id: String, position: I64) =>
    item <- AddN<Item>({ item_id: item_id, position: position })
    RETURN item
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create items with positions
for i in range(15):
    client.query("CreateItem", {
        "item_id": f"ITEM{i:03d}",
        "position": i
    })

# Categorize into groups of 5
result = client.query("CategorizeByRotation", {
    "group_size": 5
})

print("Categorized items:", result)

Function Composition

Arithmetic functions can be nested to create complex calculations:
// Multi-factor scoring
ADD(
    MUL(_::{base_score}, 0.6),
    MUL(_::{bonus_score}, 0.4)
)

// Percentage calculation
MUL(DIV(_::{partial}, _::{total}), 100.0)

// Exponential decay
MUL(_::{initial_value}, POW(0.9, _::{time_elapsed}))

Use in Shortest Path Weights

Arithmetic functions are commonly used in custom weight calculations:
// Distance-based weight with decay
::ShortestPathDijkstras<Route>(
    MUL(_::{distance}, POW(0.95, DIV(_::{days_old}, 30)))
)

// Multi-factor routing cost
::ShortestPathDijkstras<Road>(
    ADD(
        MUL(_::{distance}, 0.7),
        MUL(_::{toll_cost}, 0.3)
    )
)