● just ci green, end-to-end smoke shows the App-held query streaming through ; correctly and reaching false. after #39
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set.
Reference
navicore/patch-prolog-v1!39
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "repl-phase-2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
exhaustion.
What landed in this turn:
self.rename_clause(clause) sites now clone the clause first (the borrow on *self.db through Arc deref ties to
&self, conflicting with the &mut self on rename_clause; cloning is bounded since rename already walks the
structure).
mechanically: 21 Solver::new(&db, …) → Solver::new(Arc::new(db), …) sites with use std::sync::Arc; added where
needed.
Arc::make_mut to mutate the interner during parse (strong count is 1 in practice — App drops prior Query before
submitting a new goal), then Arc::clone to hand a fresh handle to the new Solver.
load-bearing proof: pre-Arc this wouldn't compile.
path. No more local Query.
Tests: 49 → 50 (added the App-held query test). Workspace just ci clean.
Review
What it does: The
Arc<CompiledDatabase>refactor —Solver<'a>→ ownedSolver, soQueryloses its lifetime and can live onApp.active. CLI call sites updated mechanically;main.rsnow drives the query through App-held state on the real path. The newactive_query_can_be_held_on_app_statetest is indeed the load-bearing proof.Verified locally (scratch copies of the branch): all suites pass (148 core + 248 integration + 6 runner + 12 repl), and the smoke run streams
member/3through;tofalse.viaApp.active. The design is the right call — it dissolves the self-referential problem instead of papering over it, andArc::make_mutinSession::queryhas correct semantics even in the worst case (if a query were still alive, the oldQuerykeeps its db snapshot — exactly what you'd want).🟡 One real finding: the clause clone is a measurable hot-path regression — and avoidable
The three
let clause = self.db.clauses[clause_idx].clone()sites run on every clause-match attempt. The PR comment argues "rename already walks the structure, so the extra clone is bounded" — true that it's bounded, but it's a full extra deep copy (allocations included) per resolution step, roughly doubling term allocation during clause selection. Benchmarked with naive-reverse (nrev of a 60-list × 300 iterations), interleaved runs to control for machine noise:The fix is the standard owned-handle trick — clone the
Arc(an atomic refcount bump), not the clause. The local handle's borrow is independent of&mut self:Same three sites, two lines each. Applied to a scratch copy: compiles clean, all 148 core unit tests + 248 integration tests pass, and it recovers the full regression. Note this also affects
prlg run, not just the REPL — core's hot path is shared.🟢 Minor
Solver<'a>→Solveris a breaking change to core's public API — fine under the workspace's0.xversioning (cargo treats0.6 → 0.7as incompatible), just noting it's not patch-level.db,in theSolver::newinitializer.Arc::make_mutcomment's "strong count is 1 in practice" assumption depends on the TUI loop continuing to dropApp.activebefore submitting a new goal. If that invariant ever breaks, behavior stays correct but each submit silently deep-clones the database. Adebug_assert_eq!(Arc::strong_count(&self.db), 1)would make the assumption checkable rather than narrative.stream_solutionsre-matchesapp.active.as_mut()every loop iteration though it can't becomeNonemid-loop — harmless, reads slightly oddly.with_history_pathseam, the README, theProgramDirectivesdestructure).Verdict
Right refactor, right shape, honestly tested — but take the Arc-handle version of the three solver sites before merging. It's strictly better: same borrow-checker escape, zero deep copies, verified green against the full suite, and it keeps core's interpreter at parity with main instead of ~9% behind.
Review by Claude Code