Add the monoid-algebra spine (#768) - #778
Merged
Merged
Conversation
The representation four features share, per *One structure under several features*
in AGENTS.md: a finitely-supported map from a basis into a coefficient semiring,
where the basis is a monoid.
Three types, no more:
- Semiring -- Zero, One, Add, Multiply, IsIdempotent. That last is the whole
reason this is a type rather than a pair of delegates: `a or a = a` holds in the
boolean semiring and fails in the complex one, and that single difference is
what separates covering from superposition. Anything reading the flag is asking
whether it may cover the same basis element twice.
- IBasisOps<TBasis> -- Identity, Combine, Meet, TryDivide. Meet is what makes
factoring one operation across features: dividing out the meet of the support is
simultaneously "take the common monomial out of a polynomial" and "detect that a
quantum state is separable".
- SparseTerms<TBasis> -- immutable, with the invariant that no term carries a zero
coefficient. Add, Scale, Multiply and FactorOutCommon. Collecting like terms in
an idempotent semiring *is* absorption, so it needs no special case.
Deliberately absent: cover selection, factorisation into irreducibles and series
truncation. Each is specific to one feature, and a shared engine that swallowed
them would be wrong in a way that still type-checks.
Not System.Collections.Immutable -- that would be the library's first package
reference of its kind, which is a packaging decision rather than a design one, so
the dictionary is copied on construction and never handed out.
TBasis must compare by value, and that is documented on the type parameter rather
than left to be discovered: the terms are keyed on it, so a basis with reference
equality leaves every element distinct and quietly stops collecting like terms --
not an error anywhere, just a wrong answer. Writing the tests is what surfaced it.
netstandard2.0 has no Deconstruct on KeyValuePair, and the net7.0 build said
nothing about it.
**Unverified, and the reason is not neglect.** Every type here is internal, and
InternalsVisibleTo("UnitTests") cannot simply be uncommented: this assembly is
strong-name signed, so a friend reference needs the test assembly signed with the
same key and its public key named in the attribute. That is a change to the build
and to an assembly's identity, and it is the maintainer's to make. The tests are
written -- two IBasisOps over one value-typed basis, exercising the claim that a
single Meet covers both an exponent vector and a ket -- and land the moment the
access question is settled. Nothing references the spine, so the suite is
unchanged at 5359.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The representation four features share, per One structure under several features in
AGENTS.md(#773). No behaviour change: nothing references it yet.Three types
SemiringZero,One,Add,Multiply,IsIdempotent— instancesFieldandBooleanIBasisOps<TBasis>Identity,Combine,Meet,TryDivideSparseTerms<TBasis>Add,Scale,Multiply,FactorOutCommonIsIdempotentis whySemiringis a type rather than a pair of delegates.a or a = aholds in the boolean semiring and fails in the complex one, and that single difference is what separates covering from superposition. Anything reading the flag is asking whether it may cover the same basis element twice.Meetis why this is one abstraction rather than two. Dividing out the meet of the support is simultaneously "take the common monomial out of a polynomial" and "detect that a quantum state is separable":What is deliberately absent
Cover selection, factorisation into irreducibles, series truncation. Each belongs to exactly one feature, and a shared engine that swallowed them would be wrong in a way that still type-checks. That list is in
AGENTS.mdtoo, so it survives someone finding this class inviting later.Two things found by building it
TBasismust compare by value, now documented on the type parameter. Terms are keyed on it, so a basis with reference equality leaves every element distinct and quietly stops collecting like terms — no error anywhere, just a wrong answer. Writing the tests is what surfaced it.DeconstructonKeyValuePair. The net7.0 build said nothing. Third such catch today, afterToHashSetandBitOperations.Unverified, and why that is not neglect
Every type here is
internal, andInternalsVisibleTo("UnitTests")cannot simply be uncommented — I tried:SignAssemblyis on withkey.snk, so a friend reference needs the test assembly signed with the same key and its public key named in the attribute. That is a change to the build and to an assembly's identity — the maintainer's call, not mine, so I reverted it.The tests are written and waiting: two
IBasisOpsimplementations over one value-typed basis — exponent vectors (meet = componentwise minimum) and kets (meet = agree-or-free) — put through the sameFactorOutCommon, which is the one claim this whole design rests on. They land the moment the access question is settled.Nothing references the spine, so the suite is unchanged at 5359 passing. That says the build is sound and says nothing about whether these types are correct.
Reviewer's note: if you would rather not sign the test assembly, the alternative is to let the quantum module be the spine's first test, through its public surface. Merging this as-is is reasonable because it is inert — but it should not be read as verified.