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.
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:
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-ism | Normalized to | Example |
|---|
Absolute refs ($ prefix) | Plain A1 ref | $C$5, $C5, C$5 → C5 |
| Percent literals | (N*0.01) | 15% → (15*0.01) |
| Unicode math operators | ASCII equivalents | A1 × B1 → A1 * 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
Arithmetic
Rounding & absolute
| Function | Arguments | Returns | Example |
|---|
SUM | *args (one or more numbers or a range) | Sum of all arguments | =SUM(A1:A10) |
MINUS | a, b | a − b | =MINUS(C3, D3) |
SUBTRACT | a, b | a − b (alias for MINUS) | =SUBTRACT(Revenue, COGS) |
MULTIPLY | a, b | a × b | =MULTIPLY(Units, Price) |
DIVIDE | a, b | a ÷ b (returns #DIV/0! if b is 0) | =DIVIDE(Profit, Revenue) |
AVERAGE | *args or range | Arithmetic mean | =AVERAGE(B2:B13) |
POWER | base, exponent | base ^ exponent | =POWER(1.1, 4) |
| Function | Arguments | Returns | Example |
|---|
ROUND | value, digits (digits defaults to 0) | Rounded value | =ROUND(A1, 2) |
CEIL | value | Ceiling integer | =CEIL(A2) |
ABS | value | Absolute value | =ABS(MINUS(A1, B1)) |
SQRT | value | Square root | =SQRT(C5) |
MAX | *args or range | Largest value | =MAX(A1:A12) |
MIN | *args or range | Smallest value | =MIN(A1:A12) |
Comparison functions
All comparisons return true or false and are most useful as the first argument to IF.
| Function | Arguments | Returns | Example |
|---|
GT | a, b | a > b | =GT(B2, 0) |
LT | a, b | a < b | =LT(C4, 100) |
EQ | a, b | a == b | =EQ(Status, "Done") |
GTE | a, b | a >= b | =GTE(Score, 90) |
LTE | a, b | a <= b | =LTE(Spend, Budget) |
Logical functions
| Function | Arguments | Returns | Example |
|---|
IF | condition, when_true, when_false | when_true if condition is truthy, else when_false | =IF(GT(A2, 0), "Profit", "Loss") |
AND | *args | true if all arguments are truthy | =AND(GT(A1, 0), LT(A1, 100)) |
OR | *args | true if any argument is truthy | =OR(EQ(A1, "Y"), EQ(A1, "yes")) |
NOT | value | Logical 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.
Finance
Comparison & logic
Aggregation
=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
=IF(GT(A2, 0), "Positive", "Non-positive")
=AND(GT(Revenue, 0), GT(EBITDA, 0))
=OR(EQ(Status, "Done"), EQ(Status, "Closed"))
=NOT(EQ(A3, ""))
Tiered logic (=IF(…, …, IF(…, …, …))) requires nesting, which isn’t valid in cells. Wrap it in a macro — see Macros. =SUM(A1:A10) ← column total
=AVERAGE(B2:B13) ← monthly average over a year
=MAX(C1:C20) ← peak value
=MIN(D1:D20) ← floor value
Error codes
| Code | Cause | Fix |
|---|
#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. |