Skip to content

fix-mps-encoding-non-factorizing: §1-§8 implementation - #48

Merged
jascal merged 1 commit into
mainfrom
fix-mps-encoding-non-factorizing-impl
May 2, 2026
Merged

fix-mps-encoding-non-factorizing: §1-§8 implementation#48
jascal merged 1 commit into
mainfrom
fix-mps-encoding-non-factorizing-impl

Conversation

@jascal

@jascal jascal commented May 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Implement the cross-coupled-by-sum bond-2 MPS encoding (Alternative A from the change's design.md) — Ry(q0, a); CNOT; Ry(q1, a+b); CNOT; Ry(q2, b+c) — so the canonical hierarchical-polysemantic example has a Gram that genuinely differs from the rung-0 product-state factorization. Fixes the silent factorization documented in the post-mortem of add-mps-concept-encoding.
  • Generalize compute_concept_gram_mps to accept linear-combination angle expressions via Python ast walking; extend evaluate_angle to recurse on top-level +/- so the new effect strings parse end-to-end. Re-pin example, demo, README, research note, tests, and add tech-debt §5.7 with a back-link from §5.6.
  • OpenSpec validates strict; all 29 change tasks ticked. Test suite: 774 passed, 6 skipped. Demo passes with max empirical-vs-analytic error 0.0077 < 0.0469 (3·MC-std) threshold.

Test plan

  • openspec validate fix-mps-encoding-non-factorizing --strict returns valid
  • openspec list shows the change as ✓ Complete
  • pytest tests/ passes (774 / 6 skipped)
  • tests/test_examples.py::TestExamples::test_larql_polysemantic_hierarchical_pipeline re-pinned tier bands + non-factorization assertion both pass
  • tests/test_compiler.py::TestComputeConceptGramMps 19 cases pass (incl. new cross-coupled, single-bound-param-degenerate, swapped-position, and unrecognized_angle_expression sad paths)
  • python demos/larql_polysemantic_hierarchical/demo.py runs end-to-end and prints PASS
  • Reviewer confirms post-mortem entry in archived add-mps-concept-encoding/design.md is the only edit to archived content
  • Reviewer confirms README hierarchical-polysemy section, research-note caveat box, and rung-1 entry read accurately

🤖 Generated with Claude Code

Implement the cross-coupled-by-sum bond-2 MPS encoding (Alternative A
from the change's design.md) so the canonical hierarchical-polysemantic
example has a Gram that genuinely differs from the rung-0 product-state
factorization, fixing the silent factorization documented in the
post-mortem of `add-mps-concept-encoding`.

- compiler helper: generalize the Ry-segment matcher in
  compute_concept_gram_mps to accept linear-combination angle
  expressions via ast walking; new `unrecognized_angle_expression`
  error kind for non-linear forms
- angle evaluator: extend evaluate_angle to recurse on top-level + / -
  so `Ry(qs[1], a + b)` parses cleanly through markdown_parser and the
  effect_parser
- example: re-pin to `Ry(q0,a); CNOT; Ry(q1, a+b); CNOT; Ry(q2, b+c)`;
  refresh tier table (sub-mate 0.882 / super-sib {0.335, 0.593, 0.753}
  / cross [0.000, 0.178]), heatmap, polysemy column, β values, and
  add the `non_factorized_gram` verification rule
- demo: update prepare/query circuits to the cross-coupled angles,
  re-pin the tier ranges, and reword §6 narrative to ground the
  hierarchy in the cross-coupling rather than the staircase entanglement
- docs: README hierarchical-polysemy section, post-mortem appended to
  archived `add-mps-concept-encoding/design.md` (only edit to archived
  content), and a "Schmidt rank > 1 ≠ non-factorized overlap" caveat
  box plus updated rung-1 entry in the research note
- tests: re-pin tier-band assertions, add the non-factorization
  assertion, replace the obsolete mixed-signs / param-position-mismatch
  tests with new tests for cross-coupled, single-bound-param-degenerate,
  swapped-position, and unrecognized_angle_expression sad paths
- tech-debt: add §5.7 (verifier blind spot — Gram factorization vs.
  encoding entanglement) with a back-link from §5.6

OpenSpec: validates strict; all 29 change tasks ticked.
Test suite: 774 passed, 6 skipped. Demo passes with max error 0.0077
< 0.0469 threshold.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jascal
jascal merged commit 7b7fce3 into main May 2, 2026
6 checks passed
@jascal
jascal deleted the fix-mps-encoding-non-factorizing-impl branch May 2, 2026 00:23
jascal added a commit that referenced this pull request May 2, 2026
#49)

Bumps version 0.6.0 → 0.7.0 and lands the post-merge documentation
sync after PR #46 (`add-mps-concept-encoding`) and PR #48
(`fix-mps-encoding-non-factorizing`).

- README: move MPS concept encoding (rung 1) from "Near-term —
  implementation pending" into "Recently shipped" with PR refs and
  the cross-coupled-by-sum encoding formula.
- CHANGELOG: convert "Unreleased" → "0.7.0 (2026-05-01)"; correct
  the stale tier values (`super-group-sibling [0.47, 0.54]` →
  `{0.335, 0.593, 0.753}`, `cross-group [0.12, 0.25]` → `[0.000,
  0.178]`) and the encoding (single-bound-param → cross-coupled-by-
  sum) in the hierarchical-polysemy entry; add Changed entry for the
  generalized angle parser; add Fixed entry for
  `fix-mps-encoding-non-factorizing` referencing PR #48 and tech-
  debt §5.7.
- Research doc: link the rung-1 entry in
  `docs/research/polysemantic-encoding-beyond-product-states.md` to
  the merged PRs (#46 + #48) and the post-mortem in
  `add-mps-concept-encoding/design.md`.
- OpenSpec: archive `add-mps-concept-encoding` (25/26 — task 4.2
  superseded by `fix-mps-encoding-non-factorizing`) and
  `fix-mps-encoding-non-factorizing` (✓ Complete) under
  `openspec/changes/archive/2026-05-02-…`. Both updates flow
  through to `openspec/specs/{compiler,language}/spec.md`.
- Tech debt: append §5.8–§5.15 from a post-merge self-review of
  PR #48 (HIGH: scientific-notation regression in
  `_split_linear_combination`; MEDIUM: error-message drift, etc.).

Note: the demo-smoke step in `verify-examples.yml` is split out of
this commit (PAT lacks workflow scope) — to be added via the GitHub
UI as a follow-up.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
jascal added a commit that referenced this pull request May 6, 2026
… polish (#58)

Cluster of small concept_gram_mps fixes from the 2026-05-01 PR #48
self-review and Sonnet 4.6's PR #45 review:

- §3.11: fold the angle-matrix build into the per-call-site loop and
  wrap `float(b.value)` in a try/except that re-raises as
  `MpsGramConfigurationError` naming the call site, action, argument
  index, and offending value. Defensive guard for programmatically-
  built `QMachineDef`s; the parser only ships int/float literals into
  `BoundArg.value` today, so this is purely a contract hardening.
- §5.12 + §5.13: refactor the Mult branch of `_parse_linear_combination`
  through a new `_as_numeric_const` helper that recognizes both bare
  `Constant` and `UnaryOp(USub|UAdd, Constant)` shapes. As a side
  effect this also accepts the canonical `-2*a` form (previously
  silently rejected — the AST is `BinOp(Mult, UnaryOp(USub, Constant),
  Name)`, not `BinOp(Mult, Constant(-2), Name)`). The two-constants
  case (`2*3`) now raises with a clearer "no parameter reference"
  message instead of the misleading "two non-constant terms" wording.
- §5.10: cover the spec-listed but untested `unrecognized_angle_
  expression` triggers — bare numeric literal (`Ry(qs[1], 2.5)`) and
  power expression (`a**2`).
- §5.11: focused unit test for the inverse-form linear-combination
  path, asserting `|gram_inverse| == |gram_prep|` on shared angle
  triples — pins the helper's `is_inverse=True` cross-coupled branch
  directly rather than via the example pipeline.
- §5.15: update the live spec example at
  `openspec/specs/language/spec.md` to reflect the qiskit compiler's
  actual fully-evaluated-float emission (`qc.ry(-0.85, 2)`) instead
  of the misleading symbolic `qc.ry(a_value + b_value, 1)` form.
  (The `MpsGramConfigurationError` docstring half of §5.15 was
  already addressed by an interim PR.)
- §5.2: bump `docs/compute-needs.md` from "All 15 example machines"
  to "All 19" — the README references had already drifted forward
  via interim PRs; only this doc remained stale.

852 tests pass, no new ruff violations on touched files.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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