Conversation
Replace the remaining stdlib-backed PREVIOUS behavior with a single intrinsic two-argument path. Unary PREVIOUS now desugars to PREVIOUS(x, 0), module-backed and expression arguments rewrite through scalar helper auxes, and LTM first-step guards use INITIAL_TIME semantics instead of an implicit previous model. This removes stdlib/previous.stmx and its generated registration, updates dependency classification so PREVIOUS fallback expressions behave like init-only dependencies, and keeps interpreter/VM behavior aligned across direct, arrayed, SELF, module-backed, and nonzero-start cases.
Code ReviewReviewed the full diff (425 additions, 623 deletions across 32 files). This PR makes PREVIOUS fully intrinsic by:
No bugs found. Key observations:
Overall correctness: CORRECT — The patch is well-structured, tests are updated comprehensively, and the behavioral changes (INITIAL_TIME guards, intrinsic fallback) are improvements over the old module-based approach. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d4fb6dc9b5
ℹ️ 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".
| Opcode::LoadPrev { off } => { | ||
| let fallback = stack.pop(); | ||
| let abs_off = module_off + *off as usize; |
There was a problem hiding this comment.
Fix LoadPrev stack effect after adding fallback pop
Opcode::LoadPrev now consumes a fallback value (stack.pop()) before pushing the selected result, but the stack-effect metadata still treats it as (0, 1) in Opcode::stack_effect. That mismatch makes ByteCode::max_stack_depth overestimate stack usage for equations with many PREVIOUS(...) calls and can trigger false "compiled bytecode requires stack depth..." failures even when runtime execution is safe, so models can fail compilation purely due incorrect static stack accounting.
Useful? React with 👍 / 👎.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #389 +/- ##
==========================================
- Coverage 76.86% 76.40% -0.46%
==========================================
Files 143 143
Lines 36171 36233 +62
==========================================
- Hits 27802 27684 -118
- Misses 8369 8549 +180 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add explanatory comments for the interpreter non-Var PREVIOUS fallback invariant and the dual desugaring of unary PREVIOUS in expr1.rs. Clean up the dead `let _ = args` binding in equation_is_stdlib_call and remove the unused model_name parameter from classify_module_for_ltm.
Code Review[P2]
|
Fix two bugs found by codex review: 1. LoadPrev pops a fallback value from the stack before pushing its result, so its stack effect is (1,1) not (0,1). The incorrect metadata made ByteCode::max_stack_depth() overestimate capacity. 2. In unit inference, Previous(a, b) was returning the units of the fallback (b) instead of the lagged argument (a). For unary PREVIOUS(x) desugared to PREVIOUS(x, 0), this returned Constant instead of propagating x's units, breaking inference for variables that depend solely on PREVIOUS for their unit information.
Code ReviewI reviewed the full diff across all 32 changed files. This PR converts PREVIOUS from a stdlib module-backed implementation to a fully intrinsic two-argument builtin ( AnalysisVM/Interpreter consistency: Both the VM ( Dependency classification ( Module routing: Unit checking/inference: LTM augmentation: First-timestep guards now use VerdictNo bugs found. The patch is correct. All semantic changes are internally consistent across the VM, interpreter, codegen, dependency classification, unit analysis, and LTM subsystems. The desugaring is applied at multiple pipeline stages (builtins_visitor Expr0, expr1.rs Expr1) to handle both pre-expanded and raw inputs. Tests have been appropriately updated to reflect the new architecture. |
Add an explicit equality constraint between the lagged argument and fallback in PREVIOUS during unit inference, analogous to Max/Min handling. Without this, equations like PREVIOUS(x, seed) could leave the fallback unconstrained or with inconsistent units even though units_check requires compatibility, leading to spurious diagnostics. Also reflows an awkward comment in db_ltm.rs.
Code ReviewReviewed the full diff (569 additions, 634 deletions across 32 files). This PR replaces the stdlib-module-based Summary of changes
FindingsNo blocking bugs found. The changes are mechanically consistent across the full pipeline:
The Overall correctness: correct — the patch is internally consistent, tests have been appropriately updated, and existing behavior is preserved through the desugaring equivalence. |
Review cycle summaryThree review iterations with both codex and Claude reviewers. The initial commit was clean and well-structured; reviews caught two real bugs and prompted several improvements: Bugs fixed: LoadPrev stack effect metadata was (0,1) instead of (1,1) since the opcode now pops a fallback. Unit inference for PREVIOUS was returning units from the fallback argument instead of the lagged argument, causing variables using unary PREVIOUS(x) to lose their inferred units. Both fixed with regression tests. Improvements: Added equality constraint between PREVIOUS's lagged argument and fallback in unit inference (matching Max/Min handling), so incompatible fallback units are caught during inference rather than only at check time. Removed the dead |
Summary
Test plan