Skip to main content
GridOS has its own formula engine built into the kernel. Formulas let cells compute values dynamically from other cells, update automatically when dependencies change, and serve as the building blocks for agent-generated financial models. This page covers everything you need to write, read, and debug GridOS formulas.

Formula syntax basics

A cell becomes a formula cell when its value starts with =. Everything after the = is evaluated by the GridOS expression parser.
=SUM(A1, B1)
=DIVIDE(C3, D3)
=IF(GT(A2, 0), "Profit", "Loss")
GridOS formulas are typically written as named function calls with comma-separated arguments in parentheses.

Infix arithmetic

The engine parser does accept the four basic infix operators (+, -, *, /) plus exponentiation (^ or **), so a hand-typed formula like:
=(A1 + B1) * 0.4
works when you type it into a cell directly.
But agents never emit infix. The built-in finance and general agents are instructed to use named primitives (MULTIPLY, MINUS, etc.) for three reasons: auditability (every computation is a named registry call), macro composability (primitives can be wrapped into user macros easily), and cross-provider determinism (LLMs disagree about operator precedence but agree about function names).So you’ll see =MULTIPLY(C3, 0.4) in agent output, not =C3*0.4 — even though both work. Stick with named primitives in anything the agent will read or modify.

Cell references

Reference another cell by its A1 address inside any function argument:
=MULTIPLY(C3, 0.4)      ← C3 is a cell reference; 0.4 is a literal
=SUM(B2, B3, B4)        ← three individual cell references
=DIVIDE(C10, C1)        ← C10 / C1
When the referenced cell changes value, every formula that depends on it recalculates automatically.

Excel-ism tolerance

LLMs trained on Excel examples sometimes emit formulas with Excel-specific syntax. The parser normalizes three of the most common patterns before tokenizing, so these work transparently:
Excel-ismNormalized toExample
Absolute refs ($ prefix)Plain A1 ref$C$5, $C5, C$5C5
Percent literals(N*0.01)15%(15*0.01)
Unicode math operatorsASCII equivalentsA1 × B1A1 * B1
GridOS has no fill-down semantics, so the $ in absolute refs is semantically meaningless here — it’s just noise the parser strips. Similarly, the percent normalization means =MULTIPLY(C5, 15%) and =MULTIPLY(C5, 0.15) compute identically.

Range syntax

Pass a rectangular block of cells to a function using start:end notation:
=SUM(A1:A10)        ← sums all values in column A, rows 1 through 10
=AVERAGE(B2:D2)     ← averages B2, C2, and D2
=MAX(C1:C20)        ← largest value in column C, rows 1–20
A range expands to every cell in the bounding rectangle, row by row, left to right. Empty cells in a range contribute 0 to numeric functions.
Range arguments (A1:B6) are only valid as direct function arguments, not as sub-expressions. =SUM(AVERAGE(A1:A5), B1) is forbidden in cells for the same reason nested calls are — use a macro if you need that composition.

Nested calls

No nested function calls in cells. =SUM(MAX(A1, B1), C1) is not valid in a grid cell. To compose functions, create a user macro — macro bodies are the one place where nesting is allowed.
The reason: the preview/apply flow inspects each cell’s top-level formula to compute dependencies and run the pre-apply safety guard. Nesting would make that analysis recursive and much harder to audit. Macros opt in to that complexity explicitly.

Built-in primitives

These 21 functions are always available. Agents receive the authoritative list at runtime, so they will never invent names outside this table. Plugins can add more.

Math functions

FunctionArgumentsReturnsExample
SUM*args (one or more numbers or a range)Sum of all arguments=SUM(A1:A10)
MINUSa, ba − b=MINUS(C3, D3)
SUBTRACTa, ba − b (alias for MINUS)=SUBTRACT(Revenue, COGS)
MULTIPLYa, ba × b=MULTIPLY(Units, Price)
DIVIDEa, ba ÷ b (returns #DIV/0! if b is 0)=DIVIDE(Profit, Revenue)
AVERAGE*args or rangeArithmetic mean=AVERAGE(B2:B13)
POWERbase, exponentbase ^ exponent=POWER(1.1, 4)

Comparison functions

All comparisons return true or false and are most useful as the first argument to IF.
FunctionArgumentsReturnsExample
GTa, ba > b=GT(B2, 0)
LTa, ba < b=LT(C4, 100)
EQa, ba == b=EQ(Status, "Done")
GTEa, ba >= b=GTE(Score, 90)
LTEa, ba <= b=LTE(Spend, Budget)

Logical functions

FunctionArgumentsReturnsExample
IFcondition, when_true, when_falsewhen_true if condition is truthy, else when_false=IF(GT(A2, 0), "Profit", "Loss")
AND*argstrue if all arguments are truthy=AND(GT(A1, 0), LT(A1, 100))
OR*argstrue if any argument is truthy=OR(EQ(A1, "Y"), EQ(A1, "yes"))
NOTvalueLogical negation=NOT(EQ(A3, ""))
Empty strings and null are treated as falsy by IF, AND, OR, and NOT. Every other value — including 0 and false — follows standard Python truthiness rules.

Formula examples by category

=MULTIPLY(C3, 0.4)              ← COGS at 40% of revenue in C3
=MULTIPLY(C3, 40%)              ← same result (percent literal normalized)
=MINUS(C3, C4)                  ← gross profit (revenue − COGS)
=DIVIDE(C5, C3)                 ← gross margin
=SUM(D3:D14)                    ← annual total from monthly column
=POWER(1.1, 4)                  ← 10% growth compounded for 4 periods

Error codes

CodeCauseFix
#DIV/0!DIVIDE was called with a zero denominator, or a referenced cell is empty and used as a divisor.Ensure the denominator cell is populated before applying the formula. The pre-apply guard blocks the empty-cell form automatically.
#NAME?The formula called a function that isn’t in the registry — typo (=MULTIPLE vs =MULTIPLY) or an Excel-only name (=VLOOKUP).Check the primitives table above, or define a macro / plugin for the missing behavior.
#VALUE!Wrong number of arguments, or a non-numeric value where a number was required.Inspect the cell references to confirm they contain numeric data.
#PARSE_ERROR!The formula string couldn’t be tokenized — usually unsupported syntax like comparison infix (A1 > 0) or cross-sheet refs (Sheet2!A1).Rewrite using named functions (GT(A1, 0)) or move data to the active sheet. See Troubleshooting for the full list.