You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(typecheck): implement [T-Twist-Strand] — (~a) on a named strand (#96) (#101)
`conformance/valid/v09_twist.tangle` parsed but failed to typecheck:
```tangle
def twisted =
weave strands a:Q into
(~a)
yield strands a:Q
```
```
Strand name 'a' cannot be used as a standalone expression
```
## The spec licenses it explicitly
`FORMAL-SEMANTICS.md` §3.10:
```
Σ(a) = (i, T)
─────────────────────────────────── [T-Twist-Strand]
Γ; Σ ⊢ (~a) : Tangle[[T], [T]]
```
and `spec/grammar.ebnf`: *"In weave context: `(~a)` twists named strand
a."*
The `Twist` case inferred its operand as an ordinary expression, and the
`Var` rule rejects strand names outright — so the strand-name guard
fired before the twist rule could apply. `[T-Twist-Strand]` is now tried
**first**, leaving `[T-Twist-Word]`/`[T-Twist-Tangle]` to the standalone
forms.
## One of a matched pair was missing
The spec presents this rule immediately alongside `[T-Self-Cross]`:
```
Σ(a) = (i, T) Σ(a) = (i, T)
───────────────────────────────── ─────────────────────────────────
Γ; Σ ⊢ (~a) : Tangle[[T], [T]] Γ; Σ ⊢ (a > a) : Tangle[[T], [T]]
```
`[T-Self-Cross]` was already implemented; its twin was not. **A test now
pins that the two agree**, so they can't drift apart again.
## Evaluation
Mirrors `Crossing`: structural, yielding the empty word. Weave bodies
only became evaluable in #93, so this construct had **never run**.
That's also defensible mathematically — a single-strand twist is
invisible to the braid *word*: it's a framing change (Reidemeister I)
that the braid group doesn't see.
Detecting it as "a `Var` the environment doesn't bind" is safe because
typechecking runs first and admits `Twist (Var a)` only when `a` is a
strand.
## Result
conformance **16/19 → 17/19 evaluating** (18/19 parse). The corpus
ratchet demanded the manifest update — exactly what it's for.
**`v11_add_block` (#94, the Harvard sub-language) is now the only
remaining gap.**
Tests: the rule itself; agreement with `[T-Self-Cross]`; a regression
guard that standalone twist on a `Word` is unchanged; and that a
nonsense twist still fails.
All suites green; corpus and RSR gates pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
0 commit comments