Skip to content

Commit 883a560

Browse files
author
Alex Bikeyev
committed
docs: update rule_order references, clarify dimension binding defaults, fix anchored rule syntax examples, and add use command documentation
1 parent 6556cee commit 883a560

3 files changed

Lines changed: 34 additions & 21 deletions

File tree

‎docs/reference/rule-engine-semantics.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ Rule semantics must preserve:
2424

2525
## Rule execution order
2626

27-
Rules execute in the order specified by `workspace.formula_rule_order`. This list of rule IDs is the semantic contract. Do not rely on dictionary insertion order as a semantic execution contract — always use `formula_rule_order`.
27+
Rules execute in the order specified by `workspace.rule_order`. This list of rule IDs is the semantic contract. Do not rely on dictionary insertion order as a semantic execution contract — always use `rule_order`.
2828

2929
## Value precedence
3030

3131
When a cell is evaluated, the engine resolves value precedence from highest to lowest:
3232

33-
1. Hardcoded user override (`user_override_addrs`)
33+
1. Hardcoded user override (`cube.user_override_addrs`)
3434
2. Cell rule (single-cell rule)
3535
3. Slice rule (rule targeted at a pattern)
3636
4. Empty cell (`None`)
3737

38-
A more specific rule always wins over a less specific rule. When two rules have the same specificity and match the same cell, the later rule in `workspace.formula_rule_order` wins.
38+
A more specific rule always wins over a less specific rule. When two rules have the same specificity and match the same cell, the later rule in `workspace.rule_order` wins.
3939

4040
## Rule invalidation
4141

@@ -49,15 +49,15 @@ The system must not expose a durable state where deleted graph or item reference
4949

5050
## Rule deletion
5151

52-
Deleting a rule must remove its rule ID from `workspace.formula_rule_order` in the same semantic mutation. The system must not persist dangling rule-order entries.
52+
Deleting a rule must remove its rule ID from `workspace.rule_order` in the same semantic mutation. The system must not persist dangling rule-order entries.
5353

5454
## Anti-patterns
5555

5656
| Anti-pattern | Why we avoid | Correct approach |
5757
| --- | --- | --- |
5858
| Skipping dependency cleanup during recompute | Leaves stale state | Ensure recompute cleanup and indegree updates always run |
5959
| Rule references stored by label | Renames break rules | Resolve to stable IDs |
60-
| Relying on dict order for rule execution | Serialization drift | Use `workspace.formula_rule_order` |
60+
| Relying on dict order for rule execution | Serialization drift | Use `workspace.rule_order` |
6161
| Bidirectional recurrence | Ambiguous dependency direction | Use only `PREV` or only `NEXT` |
6262
| Writing to `PREV` / `NEXT` on LHS | Ambiguous mutation target | LHS may target only current cell or explicit slice |
6363
| Persisting error values | Reload corrupts state | Recalculate errors on load |

‎docs/reference/rule-syntax.md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ This is **not** the same as `Year[2026]`. Bracket shorthand applies to a full cu
9696

9797
### Cube-relative shorthand on the RHS
9898

99-
RHS references may use cube-relative shorthand. If a referenced cube shares a dimension with the current target cell, OM Core binds that dimension from the current evaluation context, provided the binding is unambiguous. Dimensions that do not exist in the referenced cube are ignored. A fully explicit address is always safer and required when the shorthand would be ambiguous.
99+
RHS references may use cube-relative shorthand. If a referenced cube shares a dimension with the current target cell, OM Core binds that dimension from the current evaluation context, provided the binding is unambiguous. Dimensions that do not exist in the referenced cube are not carried over; they default to the first item of that dimension in the target cube. A fully explicit address is always safer and required when the shorthand would be ambiguous.
100100

101101
For example, if the target cell is `AnnualDep::Asset.Vehicle:Year.2026`, then this shorthand:
102102

103103
```text
104104
Inputs::[Metric.Cost]
105105
```
106106

107-
carries over the shared `Asset.Vehicle` context to resolve `Inputs::Asset.Vehicle:Metric.Cost`. The `Year` dimension is not carried over because `Inputs` does not have a `Year` dimension.
107+
carries over the shared `Asset.Vehicle` context to resolve `Inputs::Asset.Vehicle:Metric.Cost`. The `Year` dimension is not carried over because `Inputs` does not have a `Year` dimension; it would default to the first `Year` item of `Inputs` if that dimension existed there.
108108

109109
Use the full semantic address whenever you need to read from a different context than the current target cell.
110110

@@ -198,11 +198,11 @@ This behavior lets you define a general rule first and then add targeted overrid
198198
An **anchored rule** targets exactly one cell. The user opts in by prefixing the rule target with `$`.
199199

200200
```text
201-
rule $[Year.2024, Region.North] = 1100 # anchored: one cell
202-
rule [Year.2024, Region.North] = 1100 # standard: slice (wildcarded)
201+
rule $Sales::@.value:Year.2024:Region.North = 1100 # anchored: one cell
202+
rule Sales::@.value:Year.2024:Region.North = 1100 # standard: slice (wildcarded)
203203
```
204204

205-
The `$[...]` form is a **contextual shorthand** used when the active cube, channel, and view context are already known, such as in the grid or rule panel. In standalone scripts, prefer the full form:
205+
The `$` prefix is the only anchored shorthand available in standalone scripts. The bracket form `$[...]` is **not** accepted as a rule target; it is only valid in contextual input such as the grid or rule panel, where the active cube, channel, and view are already known. In scripts, prefer the full form:
206206

207207
```text
208208
rule Cube::@.value:Dim.Item:Dim.Item = expression
@@ -222,10 +222,10 @@ Example with a 3D cube `(Year, Region, Scenario)`:
222222

223223
| Target | Anchored? | Scenario selector | Coverage |
224224
| --- | --- | --- | --- |
225-
| `$[Year.2024, Region.North, Scenario.Actual]` | Yes | `Actual` | One cell: `(2024, North, Actual)` |
226-
| `[Year.2024, Region.North]` | No | wildcard | Slice: `(2024, North, *)` |
225+
| `$Sales::@.value:Year.2024:Region.North:Scenario.Actual` | Yes | `Actual` | One cell: `(2024, North, Actual)` |
226+
| `Sales::@.value:Year.2024:Region.North` | No | wildcard | Slice: `(2024, North, *)` |
227227

228-
Use `$` when entering a rule via the grid or rule panel to bind it to one specific cell. In scripts, use the full `Cube::@.channel:...` form and omit `$` when defining rules that should apply across dimensions.
228+
In scripts, use `$` only as a prefix on a full canonical address. In the grid or rule panel, the contextual `$[...]` form may be used to bind a rule to one specific cell.
229229

230230
## Error behavior
231231

@@ -261,7 +261,7 @@ rule BS::@.value:BS.Cash:* = IF(POS(Year)=1, Drivers::@.value:Driver.OpeningCash
261261
### Anchored rule
262262

263263
```text
264-
rule $[Year.2024, Region.North] = 1100
264+
rule $Sales::@.value:Year.2024:Region.North = 1100
265265
```
266266

267267
Prefer the full script form in standalone `.openm` files:
@@ -279,7 +279,7 @@ When generating rule syntax:
279279
- Use `[THIS]` for the current item, `[PREV]` / `[NEXT]` for recurrence on the RHS only.
280280
- Use `*` for slice wildcards on the LHS.
281281
- Use cube-relative shorthand (`Cube::[Dim.Item]`) only when the context binding is unambiguous.
282-
- Use `$` only for contextual input such as the grid or rule panel; in scripts, use the full `Cube::@.channel:...` form.
282+
- Use `$` only as a prefix on a full canonical address in scripts. Avoid the `$[...]` bracket form in standalone `.openm` files.
283283
- Avoid `PREV` / `NEXT` / `FIRST` / `LAST` on the LHS.
284284
- Avoid mixing `PREV` and `NEXT` in the same rule.
285285
- Reference cells by stable semantic address, not grid coordinates.

‎docs/reference/scripting.md‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ rule {{selected}} = 100000
126126
Use `exec {{cmd}}` to execute a command and capture its output.
127127

128128
```openm
129-
# Legacy $(selection) is deprecated. Use exec selection instead.
130-
cells=exec selection
129+
# Legacy $(timestamp) is deprecated. Use exec timestamp instead.
130+
ts=exec timestamp %Y%m%d_%H%M%S
131131
```
132132

133133
### Legacy syntax
@@ -170,6 +170,15 @@ view PnL
170170

171171
The first form defines a view. The second form activates it.
172172

173+
#### `use` — set the active cube context
174+
175+
```openm
176+
use Sales
177+
rule Revenue = Cost * 1.15
178+
```
179+
180+
`use` sets the default cube for subsequent `rule` commands that omit a `Cube::` prefix. It is optional; explicit `Cube::@.value:...` addresses are preferred in scripts.
181+
173182
### Rule definition
174183

175184
#### `rule` — define a calculation rule
@@ -211,7 +220,7 @@ References can also use bracket shorthand:
211220
rule AnnualDep::@.value:*.* = (Inputs::[Metric.Cost] - Inputs::[Metric.Salvage]) / Inputs::[Metric.Life]
212221
```
213222

214-
When a referenced cube shares a dimension with the current target cell, the shorthand binds that dimension from the context. Dimensions that do not exist in the referenced cube are ignored. For example, `AnnualDep` has dimensions `Asset` and `Year`, while `Inputs` has `Asset` and `Metric`. The shorthand `Inputs::[Metric.Cost]` binds the current `Asset` from the target cell but ignores the `Year` dimension because `Inputs` does not have one.
223+
When a referenced cube shares a dimension with the current target cell, the shorthand binds that dimension from the context. Dimensions that do not exist in the referenced cube are not carried over; they default to the first item of that dimension in the target cube. For example, `AnnualDep` has dimensions `Asset` and `Year`, while `Inputs` has `Asset` and `Metric`. The shorthand `Inputs::[Metric.Cost]` binds the current `Asset` from the target cell. The `Year` dimension is not carried over because `Inputs` does not have a `Year` dimension.
215224

216225
### Calculation
217226

@@ -287,16 +296,18 @@ assert Inputs::@.value:Asset.Equipment:Metric.Life == 4 "Equipment life"
287296

288297
### Selection and navigation
289298

290-
#### `selection` — return the current selection
299+
#### `selection` — show the current selection
291300

292301
```openm
293-
selected=exec selection
302+
selection
294303
```
295304

305+
Prints the current cursor position as `(row, col)`. It does not return a list of semantic addresses.
306+
296307
#### `select`, `up`, `down`, `left`, `right` — navigate the grid
297308

298309
```openm
299-
select C::@.value:PL.Revenue:Year.2026
310+
select 5 2
300311
up 3
301312
right 2
302313
```
@@ -372,6 +383,8 @@ When generating `.openm` scripts:
372383
- Place rules after dimensions and cubes.
373384
- Run `calc` after defining rules.
374385
- Use `assert` to verify expected values.
386+
- Use `use <cube>` to set an active cube context only when omitting the cube prefix in rules.
387+
- Use `$` as a prefix on a full canonical address for anchored rules; do not use the `$[...]` bracket form in scripts.
375388

376389
## See also
377390

0 commit comments

Comments
 (0)