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
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,13 @@ epsilon / remembered-previous / max-iteration boilerplate every numeric loop in
Python or JS hand-rolls — see
[docs/COMPARISON.md → Convergence loops](docs/COMPARISON.md#convergence-loops-boilerplate-you-stop-writing).

> **What `improving` and the rest actually mean.** EigenScript's observer
> rests on a specific idea — a value locating itself *from the inside*,
> with no external goal — so the trajectory words don't always match a
> naive "smaller is better" reading. The full model, including the
> resolution knob (`set_observer_thresholds`), is in
> **What `improving` and the rest actually mean.** For numbers the
> trajectory words read the value's own motion (#861): `converged` is the
> standard stopping criterion — steps settled under a tolerance — and
> `improving` means the steps are contracting toward a limit. For
> non-numeric values the observer's entropy reading applies — a value
> locating itself *from the inside*, with no external goal. The full
> model, including the resolution knob (`set_observer_thresholds`), is in
> [docs/OBSERVER.md](docs/OBSERVER.md); the precise predicate semantics
> (what `converged` requires, how it differs from `equilibrium`, the
> N-step window) are in [docs/PREDICATES.md](docs/PREDICATES.md).
Expand Down
12 changes: 9 additions & 3 deletions docs/COMPARISON.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,15 @@ print of ("sqrt(2) = " + (str of (newton_sqrt of 2)))
sqrt(2) = 1.414213562373095
```

`converged` reads the loop's last-assigned value and is true once its trend has
flattened. (Use it inside a function so the loop gets a fresh binding to watch —
see `examples/observer_vs_boilerplate.eigs`.) The next section is *why* this
`converged` reads the loop's last-assigned value and fires once a full
window of its relative steps sits under the settle deadband — the standard
mixed-tolerance stopping criterion, built in (#861). This run exits
through the predicate itself in 13 iterations; the deadband is the
tolerance (`set_observer_thresholds`), and an input that genuinely
diverges ends via the observer's stall backstop with
`__loop_exit__ == "stalled"` instead of hanging or lying. (Use the loop
inside a function so it gets a fresh binding to watch — see
`examples/observer_vs_boilerplate.eigs`.) The next section is *why* this
works; you can reach for it long before you need the theory.

## What has no equivalent elsewhere: the observer
Expand Down
30 changes: 20 additions & 10 deletions docs/OBSERVER.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,18 @@ you put the thresholds — see [Resolution](#resolution).

### Two signals: entropy vs. value (`report` vs. `report_value`)

`report`/the bare predicates classify the trajectory of **`entropy(value)`** —
the information content, not the number. That is the right signal for "how
**Since #861 the predicate words and `report` ROUTE: numeric bindings
answer from the value channel described below; non-numeric bindings (and
the explicit `classify of [t, "entropy"]`) answer from the entropy
channel.** The routing exists because of everything this section
documents — the entropy signal's lossiness for "has the value settled"
was measured at 19/27 against an analytic convergence corpus, vs 25/27
for the value channel (`tests/test_convergence_oracle.eigs`). The
paragraphs below describe the two signals themselves; where they say
`report` reads entropy, that is now true only for non-numeric bindings.

`report`/the bare predicates historically classified the trajectory of
**`entropy(value)`** — the information content, not the number. That is the right signal for "how
*determined* is this value," but it is a *lossy proxy* for "has this value
*settled*": because `where` is non-monotonic (the watershed below), the
entropy signal goes flat in mid-magnitude regions, so a real value oscillation
Expand Down Expand Up @@ -321,14 +331,14 @@ point, not an accident:
not a snapshot raises `type_mismatch` — a bare value silently classifying as
"no trajectory" is exactly the hole the snapshot exists to close.

- **Convergence is detected on the value channel, not entropy.** A
monotonically *exploding* value has falling-then-flat entropy, so `report`
labels a runaway solver `converged` (measured: `grow` = `x*1.5` for 40 steps
→ `report` = `converged`). Only `report_value` keeps a converging solver and a
diverging one apart — same run reads `moving`. This is the [`report` vs
`report_value`](#two-signals-entropy-vs-value-report-vs-report_value)
distinction made load-bearing: a contract the entropy signal would silently
pass.
- **Convergence is detected on the value channel — now by every surface
(#861).** A monotonically *exploding* value has falling-then-flat
entropy, so the old entropy-routed `report` labeled a runaway solver
`converged` (measured: `grow` = `x*1.5` for 40 steps). Since #861
`report` and the predicate words route numerics to the value channel,
so the same run reads `diverging` on every surface — the distinction
this bullet used to warn about is now enforced by the runtime rather
than left to the caller's channel choice.

- **Contract-convergence means "settled to the step deadband" (`dh_zero`,
default `1e-3`), not arbitrary precision.** Newton reaches machine-epsilon
Expand Down
Loading
Loading