relations: Phase 3 path explanation + distance + mixed-kind reachability (explain.sx, reach_any) + 24 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ links. Reuses `lib/datalog/` — does not reimplement the engine.
|
||||
|
||||
## Status (rolling)
|
||||
|
||||
`bash lib/relations/conformance.sh` → **46/46** (Phases 1–2 complete)
|
||||
`bash lib/relations/conformance.sh` → **70/70** (Phases 1–3 complete)
|
||||
|
||||
## Ground rules
|
||||
|
||||
@@ -81,11 +81,11 @@ lib/relations/federation.sx
|
||||
|
||||
## Phase 3 — Typed relations + path explanation
|
||||
|
||||
- [ ] multiple kinds coexisting; mixed-kind vs single-kind reachability
|
||||
- [ ] `lib/relations/explain.sx` — `(path db a b kind)` returns the connecting
|
||||
- [x] multiple kinds coexisting; mixed-kind vs single-kind reachability
|
||||
- [x] `lib/relations/explain.sx` — `(path db a b kind)` returns the connecting
|
||||
chain (the relationship equivalent of acl's proof tree), nil if unreachable
|
||||
- [ ] `(distance db a b kind)` (hops) + shortest-path selection
|
||||
- [ ] `lib/relations/tests/path.sx` — path correctness, shortest among many, no-path
|
||||
- [x] `(distance db a b kind)` (hops) + shortest-path selection
|
||||
- [x] `lib/relations/tests/path.sx` — path correctness, shortest among many, no-path
|
||||
|
||||
## Phase 4 — Federation
|
||||
|
||||
@@ -100,6 +100,24 @@ lib/relations/federation.sx
|
||||
|
||||
## Progress log
|
||||
|
||||
- **Phase 3 — typed relations + path explanation** (70/70). New `explain.sx`:
|
||||
`relations-path(db,a,b,kind)` is relations' answer to acl's proof tree — the
|
||||
`reach(K,a,b)` derivation read off as the node chain. lib/datalog/ keeps no
|
||||
provenance, so the chain is re-derived breadth-first over the saturated edge set
|
||||
(`relations-children-of` per frontier node) so the returned path is a SHORTEST
|
||||
derivation; every consecutive pair is a real `rel` fact (no invented edges) and
|
||||
a visited set makes cyclic data terminate. `relations-distance` = hops (0 for
|
||||
a=b, nil if unreachable). Mixed-kind reachability added to engine.sx as a
|
||||
kind-agnostic `reach_any` closure (`relations-descendants-any`,
|
||||
`relations-reachable-any?`) — distinct from single-kind `reach`, so tests show a
|
||||
parent+member graph where a→m is reachable cross-kind but not under `parent`
|
||||
alone. api/explain grew `relations/path`, `/distance`, `/descendants-any`,
|
||||
`/reachable-any?` current-db wrappers. path.sx covers shortest-among-many
|
||||
(a→c→d beats a→b→c→d), direct edge, self path, no-path/disconnected, kind
|
||||
isolation in paths, mixed vs single kind, and path-out-of-a-cycle. Note: the
|
||||
dict-mode conformance driver has no per-suite timeout and the shared machine is
|
||||
contended by sibling loops — a full run can take a few minutes; the path suite
|
||||
alone runs in <1s.
|
||||
- **Phase 2 — reachability + cycles** (46/46). New `engine.sx` is one Datalog
|
||||
ruleset. Reachability is kind-parameterised — `reach(K,X,Y)` carries the kind as
|
||||
its first arg so a transitive walk over `parent` never leaks through `reply`
|
||||
|
||||
Reference in New Issue
Block a user