CB-WP-0041 T01: perfect recall fails on the projection, holds on the history
Some checks failed
ci / check (push) Failing after 4s
Some checks failed
ci / check (push) Failing after 4s
The answer is "it depends what you call an information set", and the distinction is the result. 44,938 decision points, random play, 2/3/4/6 seats. Reading A — information set = the seat's current projection, which is what project(Viewer::Player(seat)) returns and what the page renders: 22 violations. Reading B — information set = the seat's observation history, every view seen and action taken in order: 0. The Reading A witness is concrete. Two histories reach a byte-identical view — round 3, Select step, same hand, same claimed Problem — where the seat had played SOLVE then GROUND-OU(protect) in one and SUPPORT then SOLVE in the other. The view does not tell the seat what it did, because our state is a snapshot rather than a history: selections clear each round and effects coincide, so a player cannot reconstruct their own past from the present. In a real game the player's memory supplies it; in the state, nothing does. That is precisely OpenSpiel's ObservationString vs InformationStateString split, arrived at here by measurement rather than read off. project() is an observation, not an information state. So Track B is not closed, it is constrained, and usefully: an extensive-form game built from this engine must key information sets on observation histories, never on project(). Both directions are asserted — Reading B empty AND Reading A non-empty — because if the sample stops finding Reading A violations the conclusion is unsupported and must be re-derived rather than quietly kept. And the check samples, so it can falsify perfect recall and cannot establish it: Reading B's zero means no counterexample was drawn, which is printed as such. Wired into make panels, so it is re-derived by the gate rather than by hand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
d4d25b903e
commit
4b40a537a6
4 changed files with 283 additions and 2 deletions
|
|
@ -46,7 +46,7 @@ concept if it turns out badly.
|
|||
|
||||
```task
|
||||
id: CB-WP-0041-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
|
|
@ -69,6 +69,43 @@ information sets* along `h` and `h'` must be identical.
|
|||
reported as plainly as the other outcome. It would be a real finding
|
||||
and would make Track B's adoption unsound as it stands.
|
||||
|
||||
**Done 2026-08-08. The answer is "it depends what you call an information
|
||||
set", and the distinction is the result.** 44,938 decision points, random
|
||||
play, 2/3/4/6 seats.
|
||||
|
||||
| reading | information set is… | violations |
|
||||
|---|---|---|
|
||||
| **A** | the seat's **current projection** — what `project(Viewer::Player(seat))` returns and the page renders | **22** |
|
||||
| **B** | the seat's **observation history** — every view seen and action taken, in order | **0** |
|
||||
|
||||
**Reading A fails, and the witness is concrete**: two histories reach a
|
||||
byte-identical view — round 3, Select, same hand, same claimed Problem —
|
||||
where the seat had played `SOLVE, GROUND—OU(protect)` in one and
|
||||
`SUPPORT, SOLVE` in the other. **The view does not tell the seat what it
|
||||
did.**
|
||||
|
||||
**The mechanism is that our state is a snapshot, not a history.**
|
||||
Selections clear each round and effects coincide, so a player cannot
|
||||
reconstruct their own past from the present. In a real game the player's
|
||||
memory supplies it; in the state, nothing does.
|
||||
|
||||
**This is precisely OpenSpiel's `ObservationString` vs
|
||||
`InformationStateString` split**, arrived at here by measurement rather
|
||||
than by reading it off. `project()` is an *observation*.
|
||||
|
||||
**So Track B is not closed — it is constrained**, and usefully:
|
||||
|
||||
> **An extensive-form game built from this engine must key information
|
||||
> sets on observation histories, never on `project()`.**
|
||||
|
||||
**Both directions are asserted.** Reading B empty, *and* Reading A
|
||||
non-empty — because if the sample stops finding Reading A violations the
|
||||
conclusion is unsupported and must be re-derived, not quietly kept.
|
||||
|
||||
**What this cannot say.** It samples; it can falsify perfect recall and
|
||||
cannot establish it. Reading B's zero means *no counterexample was
|
||||
drawn*, which is weaker than "the property holds" and is printed as such.
|
||||
|
||||
## Task: say precisely what our chance is
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue