Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ is the [test](docs/about/what-counts-as-language.md) for what belongs here.
Three properties follow:

- **Nothing is guessed.** A misspelled name, a `where` string on an undeclared
parameter, a constraint whose dimensions do not match its `foreach`: each fails
parameter, a constraint whose dimensions do not match its `dims`: each fails
when the file loads, with a message that names the fix. A repository of models
checks in CI with no data ([errors](docs/reference/language/errors.md)).
- **The operators are a fixed set.** `sum`, `sum_back`, `at` and `shift`. A file
Expand Down Expand Up @@ -86,13 +86,13 @@ parameters:
variables:
p:
description: output of a generator in a snapshot
foreach: [snapshot, generator]
dims: [snapshot, generator]
where: "p_max > 0"
bounds: { lower: 0, upper: p_max }

constraints:
power_balance:
foreach: [snapshot]
dims: [snapshot]
expression: sum(p, over=generator) == load

objective:
Expand Down Expand Up @@ -208,7 +208,7 @@ git reference until then; see [RELEASING.md](RELEASING.md).
Every file under `src/` was written in [lpspec](https://github.com/fluxopt/lpspec)
and extracted here, so that the language and the syntax tree a tool reads it
through are a dependency rather than one engine's internals. The keys themselves,
which are YAML math, a block per component, `foreach:` and a `where:` string,
which are YAML math, a block per component, `dims:` and a `where:` string,
come from [Calliope](https://github.com/calliope-project/calliope).
[linopy](https://github.com/PyPSA/linopy) supplies the vocabulary that
`sum(over=)` and the dimension rules are named against. Issue numbers in these
Expand Down
4 changes: 2 additions & 2 deletions docs/about/limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ the same model written out by hand.
| **this project puts the work elsewhere** | data preparation such as resampling; helpers for one domain; Python that decides which declarations exist | it could; this project does not want it to |

Three things never appear inside one model: an `if`, a loop, and a set of
declarations that depends on the data. `foreach: [snapshot]` does not know how
declarations that depends on the data. `dims: [snapshot]` does not know how
many snapshots there are, and it does not need to. A dimension computed before
the model loads is fine: a cycle basis for Kirchhoff's voltage law is a graph
algorithm run in data preparation, and its result arrives as a parameter. What no
Expand Down Expand Up @@ -155,7 +155,7 @@ That another tool has a feature is not by itself a reason to add it.
| A vocabulary for tracked metrics: `impacts:`, `effects:`, a `costs` axis | a named expression already does this | an `impact` dimension and one named expression. Cap it with a constraint, whose dual is the shadow price; weight it in the objective; read it back after the solve ([#124](https://github.com/fluxopt/lpspec/issues/124)) |
| `**` with a variable in the base or the exponent | the exponent would decide the degree, and `to_spec` reads no data. `p ** n` is linear at `n = 1`, quadratic at `n = 2`, and refused at `n = 3` | `x * x` for a square. `**` over parameters and numbers is allowed ([#1175](https://github.com/fluxopt/lpspec/issues/1175)) |
| Normalisation, `x / sum(x)` | dividing by a variable is not a polynomial, and no solver takes it | write the ratio as a constraint, or fix the denominator |
| An `if`, a loop, or declarations that depend on the data | `to_spec` could no longer read the file without the data | `where:` masks and `foreach:` dimensions. A tool may loop over models |
| An `if`, a loop, or declarations that depend on the data | `to_spec` could no longer read the file without the data | `where:` masks and `dims:` dimensions. A tool may loop over models |
| A Python API for building models | the model is the file you review and diff | YAML, or a `dict` with the same keys ([below](#composition-component-libraries)) |

## Composition (component libraries)
Expand Down
14 changes: 7 additions & 7 deletions docs/examples/commitment.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ parameters:
variables:
p:
description: output of a generator in a snapshot
foreach: [snapshot, generator]
dims: [snapshot, generator]
bounds: { lower: 0, upper: p_max }
status:
description: whether the unit is running in a snapshot
foreach: [snapshot, generator]
dims: [snapshot, generator]
domain: binary

expressions:
previous_status:
description: the commitment state a unit carries into a snapshot
foreach: [snapshot, generator]
dims: [snapshot, generator]
cases:
always_on:
when: "not committable"
Expand All @@ -64,21 +64,21 @@ expressions:

constraints:
power_balance:
foreach: [snapshot]
dims: [snapshot]
expression: sum(p, over=generator) == load
upper:
description: a unit that is not running produces nothing
foreach: [snapshot, generator]
dims: [snapshot, generator]
expression: p <= status * p_max
lower:
description: and one that is running produces at least its floor
foreach: [snapshot, generator]
dims: [snapshot, generator]
expression: p >= status * p_min
ramp_up:
description: >-
one inequality for both regimes — a unit already running is held to
`ramp_limit`, a unit starting up to `start_up_limit`.
foreach: [snapshot, generator]
dims: [snapshot, generator]
expression: >-
p - shift(p, over=snapshot, offset=1, edge=0)
<= ramp_limit * previous_status + start_up_limit * (1 - previous_status)
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/dispatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ varies when it needs a base to change one thing in.
The `where:` on `p` deletes the rows where a generator has no capacity, so
[absence](../reference/language/absence.md) is declared in the file rather than
checked at run time. `sum(p, over=generator)` names the dimension it reduces, so
the constraint's `foreach` is what remains.
the constraint's `dims` is what remains.

<!-- gallery:begin -->
```yaml
Expand All @@ -31,13 +31,13 @@ parameters:
variables:
p:
description: output of a generator in a snapshot
foreach: [snapshot, generator]
dims: [snapshot, generator]
where: "p_max > 0"
bounds: { lower: 0, upper: p_max }

constraints:
power_balance:
foreach: [snapshot]
dims: [snapshot]
expression: sum(p, over=generator) == load

objective:
Expand Down
68 changes: 34 additions & 34 deletions docs/examples/operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ parameters:

variables:
p:
foreach: [snapshot, generator]
dims: [snapshot, generator]
bounds: { lower: 0 }

constraints:
fleet_budget:
foreach: []
dims: []
expression: sum(p) <= budget

objective: { sense: minimize, expression: sum(p) }
Expand All @@ -60,12 +60,12 @@ parameters:

variables:
p:
foreach: [snapshot, generator]
dims: [snapshot, generator]
bounds: { lower: 0 }

constraints:
fleet_total:
foreach: [snapshot]
dims: [snapshot]
expression: sum(p, over=generator) <= limit

objective: { sense: minimize, expression: sum(p) }
Expand Down Expand Up @@ -96,12 +96,12 @@ parameters:

variables:
p:
foreach: [snapshot, generator]
dims: [snapshot, generator]
bounds: { lower: 0 }

constraints:
bus_total:
foreach: [snapshot, bus]
dims: [snapshot, bus]
expression: sum(p, by=gen_bus) <= limit

objective: { sense: minimize, expression: sum(p) }
Expand Down Expand Up @@ -134,12 +134,12 @@ parameters:

variables:
p:
foreach: [snapshot, generator]
dims: [snapshot, generator]
bounds: { lower: 0 }

constraints:
bus_technology_total:
foreach: [snapshot, bus, technology]
dims: [snapshot, bus, technology]
expression: sum(p, by=[gen_bus, gen_tech]) <= limit

objective: { sense: minimize, expression: sum(p) }
Expand Down Expand Up @@ -168,12 +168,12 @@ parameters:

variables:
p:
foreach: [snapshot]
dims: [snapshot]
bounds: { lower: 0 }

constraints:
within_cap:
foreach: [snapshot]
dims: [snapshot]
expression: p <= at(cap, by=period_of)

objective: { sense: minimize, expression: sum(p) }
Expand All @@ -195,12 +195,12 @@ dimensions:

variables:
p:
foreach: [snapshot]
dims: [snapshot]
bounds: { lower: 0 }

constraints:
no_faster_than_before:
foreach: [snapshot]
dims: [snapshot]
expression: p <= shift(p, over=snapshot, offset=1)

objective: { sense: minimize, expression: sum(p) }
Expand All @@ -222,12 +222,12 @@ dimensions:

variables:
p:
foreach: [snapshot]
dims: [snapshot]
bounds: { lower: 0 }

constraints:
no_faster_than_before:
foreach: [snapshot]
dims: [snapshot]
expression: p <= shift(p, over=snapshot, offset=1, edge='wrap')

objective: { sense: minimize, expression: sum(p) }
Expand All @@ -249,12 +249,12 @@ dimensions:

variables:
p:
foreach: [snapshot]
dims: [snapshot]
bounds: { lower: 0 }

constraints:
no_faster_than_before:
foreach: [snapshot]
dims: [snapshot]
expression: p <= shift(p, over=snapshot, offset=1, edge=0)

objective: { sense: minimize, expression: sum(p) }
Expand Down Expand Up @@ -282,12 +282,12 @@ parameters:

variables:
order:
foreach: [technology, month]
dims: [technology, month]
bounds: { lower: 0 }

constraints:
arrives_after_its_lead:
foreach: [technology, month]
dims: [technology, month]
expression: shift(order, over=month, offset=lead, edge=0) >= demand

objective: { sense: minimize, expression: sum(order) }
Expand All @@ -313,12 +313,12 @@ lookups:

variables:
p:
foreach: [snapshot]
dims: [snapshot]
bounds: { lower: 0 }

constraints:
no_faster_than_before_in_season:
foreach: [snapshot]
dims: [snapshot]
expression: p <= shift(p, over=snapshot, offset=1, edge='wrap', by=season_of)

objective: { sense: minimize, expression: sum(p) }
Expand All @@ -344,15 +344,15 @@ parameters:

variables:
started:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary
on:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary

constraints:
stays_up_its_own_time:
foreach: [unit, hour]
dims: [unit, hour]
expression: sum_back(started, over=hour, within=3) <= on

objective: { sense: minimize, expression: sum(on) }
Expand All @@ -378,15 +378,15 @@ parameters:

variables:
started:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary
on:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary

constraints:
stays_up_its_own_time:
foreach: [unit, hour]
dims: [unit, hour]
expression: sum_back(started, over=hour, within=min_up) <= on

objective: { sense: minimize, expression: sum(on) }
Expand All @@ -412,15 +412,15 @@ parameters:

variables:
started:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary
on:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary

constraints:
stays_up_its_own_time:
foreach: [unit, hour]
dims: [unit, hour]
expression: sum_back(started, over=hour, within=min_up, edge='wrap') <= on

objective: { sense: minimize, expression: sum(on) }
Expand Down Expand Up @@ -448,15 +448,15 @@ lookups:

variables:
started:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary
on:
foreach: [unit, hour]
dims: [unit, hour]
domain: binary

constraints:
stays_up_inside_its_day:
foreach: [unit, hour]
dims: [unit, hour]
expression: sum_back(started, over=hour, within=3, by=day_of) <= on

objective: { sense: minimize, expression: sum(on) }
Expand All @@ -479,12 +479,12 @@ parameters:

variables:
p:
foreach: [snapshot]
dims: [snapshot]
bounds: { lower: 0 }

constraints:
balance:
foreach: [snapshot]
dims: [snapshot]
expression: p >= load

expressions:
Expand Down
Loading
Loading