Skip to content

ogar-elk: borrowed lens over the baked edge table - #258

Closed
AdaWorldAPI wants to merge 1 commit into
mainfrom
claude/elk-observes-the-bake
Closed

ogar-elk: borrowed lens over the baked edge table#258
AdaWorldAPI wants to merge 1 commit into
mainfrom
claude/elk-observes-the-bake

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Reshapes ogar-elk from an owning graph into a borrowed lens over the baked
edge table, and states the crate's position in the pipeline explicitly.

Position

ogar-elk runs after the bake. Joining — resolving a CURIE, reconciling
which source asserts what, deciding two labels name one concept — completes
upstream, and the bake freezes the result into positions. This crate observes
what the resulting spine entails. The module documentation now says so; the
previous text placed the crate before the bake, which does not match what it
consumes.

The shape that follows from it

An observation over a bake borrows what the bake already holds:

before after
Closure owning HashMap<ClassAddr, Vec<ClassAddr>> Spine<'a> — a lens over a sorted &'a [Subsumption]
from_asserted(impl IntoIterator<Item = …>) Spine::over(&[…])
supers_of walks an owned map parents_of — equal-range binary search returning a subslice of the caller's data
extended clones the whole map with_overlay — a second borrowed slice

Bake::triples already lays the adjacency out in sorted order, so the map was a
second copy of it. Removing the copy removes a second thing that can disagree
with the first, and makes "what would this merge do" cost a lens rather than a
clone of the spine.

parents_are_a_borrowed_window_not_a_copy asserts pointer identity against the
source slice, so the borrowing is verified rather than documented.

Sortedness

The binary search requires edges sorted by subclass. An unsorted slice makes it
miss parents, which surfaces as entails() == false — a wrong answer that looks
like a legitimate one. over documents the precondition and debug-asserts it
(the bake emits sorted output); try_over validates in release builds and
returns None, rather than sorting a copy, since sorting would reintroduce
ownership.

Scope notes

  • The HashSet in supers_of is the traversal frontier — it holds the answer
    being accumulated, bounded by the answer's size, not a copy of the edge table.
    The documentation distinguishes the two.
  • MergeVerdict (R3) is not redundant with ogar_obo::BakeStats::is_a_cycles:
    that field reports cycles within a single baked core, whereas R3 reports what
    an additional axiom set would introduce into a spine already baked.

Verification

  • cargo test -p ogar-elk — 10 passed, 0 failed (up from 8; adds the
    borrowed-window and sortedness cases)
  • cargo clippy -p ogar-elk --all-targets — clean

Touches crates/ogar-elk/src/lib.rs only. Follow-up to #256.

@cursor

cursor Bot commented Aug 7, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_df3393b2-5085-4d07-bed4-33d5e0a901f0)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c6f4b54a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +406 to +408
let merged = Spine {
base: self.base,
overlay: &overlay,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the existing overlay during merge checks

When merge is called on a Spine produced by with_overlay, this reconstruction drops self.overlay and checks cycles using only the base plus the new axioms. For example, base 1→2, existing overlay 2→3, and candidate 3→1 form a cycle, but this code reports is_sound() == true; include the existing overlay in the graph used for the merged cycle check.

Useful? React with 👍 / 👎.

@AdaWorldAPI AdaWorldAPI changed the title ogar-elk: observe the bake as a borrowed lens (corrects #256's stage) ogar-elk: borrowed lens over the baked edge table Aug 7, 2026
`ogar-elk` runs after the bake. Joining -- resolving a CURIE, reconciling
which source asserts what -- completes upstream, and the bake freezes the
result into positions; this crate observes what the resulting spine
entails. The module documentation now states that position. The previous
text placed the crate before the bake, which does not match what it
consumes.

The shape follows from the position: an observation over a bake borrows
what the bake already holds.

- `Closure`, which owned a `HashMap<ClassAddr, Vec<ClassAddr>>`, becomes
  `Spine<'a>`, a lens over a sorted `&'a [Subsumption]` -- the caller's
  projection of `Bake::triples` to its is_a edges. The bake already lays
  that adjacency out in sorted order, so the map was a second copy of it,
  and a second copy is a second thing that can disagree with the first.
- `from_asserted(impl IntoIterator)` becomes `Spine::over(&[..])`.
- `parents_of` is an equal-range binary search returning a subslice of
  the caller's data. `parents_are_a_borrowed_window_not_a_copy` asserts
  pointer identity against the source slice, so the borrowing is verified
  rather than documented.
- `extended`, which cloned the whole map, becomes `with_overlay`, a
  second borrowed slice. Evaluating a candidate merge now costs a lens.

Sortedness is a precondition of the search: an unsorted slice makes it
miss parents, surfacing as `entails() == false` -- a wrong answer that
looks like a legitimate one. `over` debug-asserts it (the bake emits
sorted output); `try_over` validates in release builds and returns None
rather than sorting a copy, since sorting would reintroduce ownership.

Two scope notes are now in the documentation. The `HashSet` in
`supers_of` is the traversal frontier, holding the answer being
accumulated, not a copy of the edge table. And R3 is not redundant with
`ogar_obo::BakeStats::is_a_cycles`: that field reports cycles within a
single baked core, whereas R3 reports what an additional axiom set would
introduce into a spine already baked.

10 tests pass (up from 8; adds the borrowed-window and sortedness cases),
clippy clean.
@AdaWorldAPI
AdaWorldAPI force-pushed the claude/elk-observes-the-bake branch from 3c6f4b5 to 0a93a83 Compare August 7, 2026 13:31
@AdaWorldAPI AdaWorldAPI closed this Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant