Skip to content

fix(language): a file whose terms read each other's sums is refused at load - #780

Merged
FBumann merged 2 commits into
mainfrom
claude/eager-ptolemy-nzg4oj
Sep 29, 2026
Merged

FBumann merged 2 commits into
mainfrom
claude/eager-ptolemy-nzg4oj

Conversation

@FBumann

@FBumann FBumann commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Prompt: Then do 5 now.

Note

The following content was generated by AI.

A file whose terms read each other's sums loaded alone and failed only at merge. It is now refused at load, and the message names the sums the loop runs through.

What this changes

lower resolves every term of a file first. Then _loop follows each term's reads through the file's other terms. A term that reads its own sum, directly or through another term, is refused with Given expression 's1': its term 'a' reads 's1', the sum the term adds to, through 's2', so the sum would define itself. The direct self-read keeps its message, without the through clause.

Why

Finding 5 of the review of #763. One file with s1: {term: a}, s2: {term: b}, a: p + s2 and b: p + s1 passed to_spec. merge then failed with a circular expression reference cascade that named neither the file nor the rewrite. The file alone decides this, so the load decides it.

Method, gate output, alternatives

Reproduced on origin/main (9ace314) before the change: to_spec(f) loads, and merge([owner, f]) fails with Named expression 's1': named expression 'a' does not load….

Test first. two-terms-reading-each-other-s-sum in test_what_a_term_may_not_be_is_refused_at_load failed on the unfixed tree (DID NOT RAISE) and passes with the fix. test_a_term_may_read_another_sum_its_file_adds_to holds that a read of another sum without a loop back still loads.

Gates. pixi cannot be installed in this environment, so I ran the tools from a venv directly:

  • ruff format and ruff check src tests tools (0.16.1): clean.
  • pytest -q -n auto: 2545 passed, 52 skipped.
  • pyrefly check (1.2.0): the same 14 errors as on main. All are missing pydantic/yaml stubs in the venv, and none are in lowering.py.
  • I did not run lefthook, docs-build or compile-tex.

Not done. #763 moves this check into lowering._term under adds_to:. This PR fixes it on main first. #763 takes it when it merges main in. No docs page states the self-read rule, so no page changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AzXL2w5xdUm8FsYMNWf1KW


Generated by Claude Code

…t load

A term that reads its own sum through another term of the same file
loaded alone and failed only at merge, as a circular-reference cascade.
The per-file check now follows the file's terms, and names the sums the
loop runs through.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AzXL2w5xdUm8FsYMNWf1KW
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AzXL2w5xdUm8FsYMNWf1KW
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 mathspec | 🛠️ Build #34822227 | 📁 Comparing 530e522 against latest (9ace314)

  🔍 Preview build  

1 file changed
± changelog/index.html

@FBumann
FBumann merged commit fcb654d into main Sep 29, 2026
5 checks passed
FBumann pushed a commit that referenced this pull request Sep 29, 2026
#780 refuses a file whose terms read each other's sums. Under `adds_to:`
one file may add several terms to one sum, so `_terms` groups the terms
by the sum they add to, and `_loop` follows each term's reads through
those groups. The direct self-read is the loop of length one, and keeps
its message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AzXL2w5xdUm8FsYMNWf1KW
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.

2 participants