Markdown for LLMs
LDC-E2115 — An undeclared name in an interval bound
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# LDC-E2115 — An undeclared name in an interval bound
## What it means
An interval bound is a value position: it must be a literal, a bound
rule variable, a declared constant, an enum member, or a parameter —
never a bare unknown name. A name with no binding in any of those
places is a free variable, and the compiler rejects it at the bound.
Binding the name with a rule variable plus a premise that yields it,
or replacing it with a literal floor date for a deliberately open
window, resolves it. Either way the bound ends up a genuine value.
## Example
```law
language "law.core" version "0.2";
package demo.diagnostics version "0.1.0";
namespace "urn:law:demo:diagnostics";
entity Person;
relation active(p: Person) kind empirical;
relation held(p: Person) kind institutional;
rule R strict {
for p: Person;
when active(p);
then duty D {
bearer p;
goal maintenance {
condition held(p);
window [moment, infinity);
}
};
}
```
## Fix
```law
language "law.core" version "0.2";
package demo.diagnostics version "0.1.0";
namespace "urn:law:demo:diagnostics";
entity Person;
relation active(p: Person) kind empirical;
relation started(p: Person, since: Date) kind empirical;
relation held(p: Person) kind institutional;
rule R strict {
for p: Person;
for moment: Date;
when active(p) and started(p, moment);
then duty D {
bearer p;
goal maintenance {
condition held(p);
window [moment, infinity);
}
};
}
```
## Engine message
The engine reports this in its own wording:
```text
example.law:15:15: error LDC-E2115: name "moment" in a §20 interval bound is not declared: it is bound by neither a rule `for`, nor `let`, and is declared by neither `const` §54, nor a §38 enum member, nor an A3 §A3.2 parameter — it is a free variable (§188 unresolved name). An interval bound is a VALUE of an ordered scale (a position §135 window has `Date` or `Instant`), not a §52 identity, so a domain constant does not read the name here. Two legal resolutions. If the intended date is FROM THE CASE — bind the name with a rule body: `for moment: Date;` plus a premise yielding it. If the window is deliberately without an inscribed date — the corpus floor `[@0001-01-01, infinity)`, the technical floor «раньше всякой даты, которую пакет может назвать». The `[-infinity, infinity)` form does NOT work here: `check` accepts it, but lowering rejects it with LDC-E1305 — `lower_term` has an `infinity` branch and no `-infinity` branch
```
## Related
- [Time](/constructs/time/) — what interval bounds may hold.
- [Deadline calendar](/constructs/deadline-calendar/) — how position windows are dated.