diff --git a/research/p104-literal-slot-defect/PROOF.md b/research/p104-literal-slot-defect/PROOF.md new file mode 100644 index 0000000000..8cd3f035d8 --- /dev/null +++ b/research/p104-literal-slot-defect/PROOF.md @@ -0,0 +1,91 @@ +# Literal-slot defect of the old correction + +Let the two banks have the same finite dimension. Write \(I\) for the identity, +\(H\) for a linear projection (\(H^2=H\)), and \(J_0=I-H\). Then +\(HJ_0=J_0H=0\) and \(J_0+H=I\). Let \(T\) be invertible, \(K=T^{-1}\), and let +\(D\) be any matrix of the same size. No hypothesis makes \(D\) commute with +\(T\). + +The old correction and the ordered terminal encoding are +\[ +P=\begin{pmatrix}I&0\\K&I\end{pmatrix}, +\qquad +L_T=\begin{pmatrix}D&HT\\0&I\end{pmatrix}. +\] +The literal slot swap on the image of \(H\), fixing the complementary ports, is +\[ +\Pi=\begin{pmatrix}J_0&H\\H&J_0\end{pmatrix}. +\] +The literal encoding is \(A_T=\Pi L_T\). + +## Ordered commutator, without \(HT=TH\) + +Block multiplication gives +\[ +PL_T=\begin{pmatrix}D&HT\\KD&KHT+I\end{pmatrix}, +\qquad +L_TP=\begin{pmatrix}D+HTK&HT\\K&I\end{pmatrix}. +\] +Subtracting and using \(KD-K=K(D-I)\) yields the identity +\[ +PL_T-L_TP += +\begin{pmatrix}-HTK&0\\K(D-I)&KHT\end{pmatrix}. +\] +If in addition \(HT=TH\), then \(KT=TK=I\) implies \(HTK=H\) and \(KHT=H\), so +\[ +PL_T-L_TP += +\begin{pmatrix}-H&0\\K(D-I)&H\end{pmatrix}. +\] +The bottom-right block is \(H\) only under that commutation. A triangular \(T\) +that moves mass between \(J_0\) and \(H\) keeps the unsimplified identity and +rejects the simplified one. + +## Literal slots + +Assume now that \(H\) is a projection and \(HT=TH\), hence \(HK=KH\) and +\(J_0K=KJ_0\). Then \(\Pi^2=I\), and +\[ +A_T=\Pi L_T += +\begin{pmatrix}J_0D&H\\HD&HT+J_0\end{pmatrix}. +\] +The same expansion, reduced by \(J_0H=0\), \(H^2=H\) and \(HTK=H\), gives +\[ +PA_T-A_TP += +\begin{pmatrix}-HK&0\\KJ_0(D-I)-H&KH\end{pmatrix}. +\] +On an input \((a,0)\) the first-bank image of this commutator is \(-HKa\). +If \(a\) is supported on the image of \(H\), that image is \(-Ka\). If \(a\) is +supported on the image of \(J_0\), the first bank is \(0\). + +Thus the ordered defect \(-Ha\) and the literal defect \(-HKa\) are different +whenever some value of \(T\) on the image of \(H\) is not \(1\). + +## What a uniform scalar cannot cancel + +Suppose the diagonal entries of \(T\) on the image of \(H\) are not all equal. +Then \(-Ka=\lambda a\) cannot hold for every \(H\)-supported \(a\), for any +single scalar \(\lambda\). A uniform bank multiplier is not an intertwiner of +\(P\) through \(A_T\). + +If those diagonal entries are equal to one value \(t\), then \(\lambda=-1/t\) +does cancel the first bank for every \(H\)-supported amplitude. It still does +not cancel a vector with a nonzero \(J_0\) component, because \(-HKa\) has no +\(J_0\) component and \(\lambda a\) does. + +## Conjugation + +Whenever \(D\) is invertible, \(L_T\) is invertible and +\(P_{\mathrm{enc}}=L_TPL_T^{-1}\) satisfies \(P_{\mathrm{enc}}L_T=L_TP\). +The literal-slot operator that satisfies the same relation for \(A_T\) is +\(\Pi P_{\mathrm{enc}}\Pi\), not \(P\) and not \(P_{\mathrm{enc}}\). This +identity prices neither \(\Pi\) nor the rank of \(HD^{-1}\) as a native tariff. + +## What this does not prove + +It does not exhibit an adjacent completed-call pair, a helper-role match, or a +complete bill. It does not rerun the 10,816-line census of PR #3954. Linear +rank is not a native-call lower bound. No \(\kappa\) changes. diff --git a/research/p104-literal-slot-defect/README.md b/research/p104-literal-slot-defect/README.md new file mode 100644 index 0000000000..3ab47a2d93 --- /dev/null +++ b/research/p104-literal-slot-defect/README.md @@ -0,0 +1,108 @@ +# Literal-slot defect of the old P104 correction + +**Negative interface certificate. No new κ.** Selected κ stays +`0.001672660197076918`. + +Discussion #1166 comment 19034066 asks for one adjacent completed-call pair +whose encoded exit matches the next entrance on every role. This package does +not supply that pair. It certifies the obstruction that pair would have to +cancel if it reused the old correction, and it shows a uniform scalar bank +multiplier cannot cancel it when the N-port scales differ. + +## Result + +Let \(H\) be a projection, \(J_0=I-H\), \(T\) invertible, \(K=T^{-1}\), and +\(D\) any matrix of the same size. With +\[ +P=\begin{pmatrix}I&0\\K&I\end{pmatrix}, +\qquad +L_T=\begin{pmatrix}D&HT\\0&I\end{pmatrix}, +\qquad +\Pi=\begin{pmatrix}J_0&H\\H&J_0\end{pmatrix}, +\qquad +A_T=\Pi L_T, +\] +the ordered commutator is +\[ +PL_T-L_TP=\begin{pmatrix}-HTK&0\\K(D-I)&KHT\end{pmatrix} +\] +with no assumption that \(H\) commutes with \(T\). When \(HT=TH\) and \(H\) is a +projection, \(\Pi^2=I\) and the literal-slot commutator is +\[ +PA_T-A_TP=\begin{pmatrix}-HK&0\\KJ_0(D-I)-H&KH\end{pmatrix}. +\] +On an N-port amplitude the first bank of that defect is \(-Ka\). If two N-port +diagonal entries of \(T\) differ, no scalar \(\lambda\) satisfies \(-Ka=\lambda a\) +for every such amplitude. If they agree at \(t\), then \(\lambda=-1/t\) works +on the image of \(H\) and still fails as soon as a complementary port is +present. The ordered conjugated correction \(L_TPL_T^{-1}\) does intertwine +\(L_T\); the literal slots require the extra conjugation by \(\Pi\). + +The block multiplication is in [PROOF.md](PROOF.md). `verify.py` recomputes it +over the rationals on one \(4\times 4\) witness with unequal N-port scales and +a noncommuting \(D\), on the constant-scale sharpness case, and on the two +dropped hypotheses (commutation, idempotence). + +## Scope + +Task `p104-side-correction`, scope **changed**. The card asks for a +chronological correction program with a complete bill. Comment 19034066 is +item 4 of this session's eligible handoff list, and the list has fewer than +21 entries, so the session refines that item instead of constructing the pair. +The refinement is the commutator, not a caller. + +Base `bb4bccbf42844d2801487450727c2f63e10d1d0f`, priority revision 6. +PR #3954 already records these block formulas for the P104 shapes +\(H=\mathrm{diag}(0_8,I_{96})\) and checks them inside its full root census. +This package separates the dimension-free identity and the scalar obstruction +from that census. It does not import PR #3954. + +## Reproduce + +Python 3.12, standard library, from the repository root: + +```sh +python3.12 -B scripts/research_package.py --package research/p104-literal-slot-defect +``` + +Direct check: + +```sh +python3 -B research/p104-literal-slot-defect/verify.py +``` + +Expected marker: + +```text +PASS_P104_LITERAL_SLOT_DEFECT ordered=general literal=projection_and_commutation distinct_scales=no_scalar constant_scale=-1/2 pi_required=1 no_new_kappa +``` + +The same command passes under `-O`. Not run: Lean, Docker, a selected cold +replay, the 10,816-line census, and hosted CI. + +## Open next questions + +1. Does one adjacent pair that uses \(\Pi P_{\mathrm{enc}}\Pi\), rather than + \(P\), match every helper role as well as both data banks, and is the + resulting bill favorable? The scalar obstruction does not answer that. + First step: pin one helper entrance and exit from the PR #3954 endpoint + and price \(\Pi\) as a real slot exchange. Blocker: this identity has no + helper schedule and does not convert linear rank into a native tariff. +2. Which portwise diagonal corrections, other than \(K\) on the image of + \(H\), can cancel the first bank for every N-port amplitude? The identity + says the first bank is exactly \(-HKa\), so any such correction is fixed + on that image. First step: state the allowed diagonal alphabet and test + it on two distinct N-port scales. Blocker: a new alphabet is a different + contract from the old correction \(P\). + +## Credit + +The block shapes, the literal swap \(\Pi\), and the P104 reading of \(H\) and +\(T\) are Chris R / Clear1nsight's PR #3954, from the handoff in discussion +#1166 comment 19034066. That package retains the PR #3882 / #3940 residual +boundary and the native P104 lineage (Rohan Arun, Chafik Boukhalfa, Adam Gall, +and the contributors named there). The dimension-free expansion, the scalar +obstruction, and these checks are new. + +Prepared by unpaidmoon with substantial AI assistance (Cursor Grok 4.7). +Apache-2.0. No independent human or formal-kernel review is claimed. diff --git a/research/p104-literal-slot-defect/SOURCES.json b/research/p104-literal-slot-defect/SOURCES.json new file mode 100644 index 0000000000..a604c6a640 --- /dev/null +++ b/research/p104-literal-slot-defect/SOURCES.json @@ -0,0 +1,18 @@ +{ + "schema_version": 1, + "base_commit": "bb4bccbf42844d2801487450727c2f63e10d1d0f", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "b1fea0c94436b236cc2b7d41a7be032811b94c81", + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "67f085acd86acd7d4e03922d9cf4b26bca66fed5", + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0" + } + ] +} diff --git a/research/p104-literal-slot-defect/TASK.json b/research/p104-literal-slot-defect/TASK.json new file mode 100644 index 0000000000..ef0541f287 --- /dev/null +++ b/research/p104-literal-slot-defect/TASK.json @@ -0,0 +1,94 @@ +{ + "schema_version": 1, + "task_id": "p104-side-correction", + "priority_revision": 6, + "base_commit": "bb4bccbf42844d2801487450727c2f63e10d1d0f", + "original_card": { + "id": "p104-side-correction", + "question": "Can the proposed P104 joint endpoint flags be realized by a chronological correction program with coefficients, dirty restoration and an affordable complete bill?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/p104-native-channel/README.md", + "research/p104-native-channel/PROOF.md", + "docs/research/community-efficient1000-review.md", + "research/p104-joint-unit-flags/README.md" + ], + "methods": [ + "Construct one side-correction word at an explicit chronological cut with the needed frames still available.", + "Derive a lower bound on the side correction and hosting costs that decides whether this channel can beat the selected budget." + ], + "acceptance_gate": "An exact arbitrary-input identity, source/target frame availability and restoration at the chosen cut, plus the complete channel+correction+idle/hosting bill or an explicit favorable bound. The native channel alone is not a supplier. A scoped local result may be retained without a complete supplier. Expanding it into further construction rounds requires the family-level budget and obligation gate in research-family-status.md; an optimistic passing relaxation alone is not acceptance.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read the revision-6 family record and #2981 static joint flags, alongside the reviewed #1991 channel. #2981 is an author-checked source archive, not an independently validated executable correction or a refutation of program-level lifetime floors.", + "scope": "Source-bound orientation only. Read the named package and review before relying on its local evidence; this command is not its replay or supplier admission." + }, + "first_experiment": "After checking live handoffs, pin one named collection from #2981 and attach acquisition/delivery times, source dependencies and coefficient requirements. Test legal access and arbitrary dirty restoration; price any completion against the full channel/endpoint/hosting allowance. Stop with the exact missing implication or a scoped counterexample rather than expanding the static cover census.", + "bottleneck_link": "Completing an already realized changed channel tests a concrete construction opportunity, instead of refining the incumbent packing. A positive local result still needs global and all-size admission.", + "allowed_variations": [ + "One correction factorization, one chronological cut, or one explicit hosting obstruction.", + "A changed correction schedule with an updated full bill and native frame contract." + ], + "scope_change_triggers": [ + "Recompiling the already certified low-rank channel without closing a new obligation.", + "Treating a pending ancestor, local histogram or unpriced side correction as an admitted global supplier.", + "Repeating a correction or physical conversion already supplied by a pending follow-up without adding independent coverage or a different unresolved obligation.", + "Repeating the 208-flag static matching or calling a static nested cover a chronological correction program. Independent audit of that certificate is distinct and remains useful." + ], + "overlap_terms": [ + "P104", + "I-G/2", + "side correction", + "native channel", + "1972", + "1991", + "2586", + "endpoint transport", + "physical dual", + "relay composition", + "2981", + "joint unit flags", + "acquisition delivery", + "static nesting" + ], + "existing_checks": [ + { + "scope": "PR #2981 reports static joint endpoint flags and a matching of 208 departure and arrival flags; archival intake is not independent verification.", + "evidence": "research/p104-joint-unit-flags/README.md", + "remaining": "Independent flag check and a chronological coefficient program with dirty restoration and a complete cost.", + "status": "author-checked", + "source_commit": "3d24b92d8ba057b57cb2d480170ec407520e6882", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + } + ] + }, + "scope_status": "changed", + "actual_scope": "Prove the dimension-free literal-slot commutator of the old correction P with A_T=Pi L_T, and show that a uniform scalar cannot cancel the first-bank defect when two N-port scales differ.", + "scope_change_reason": "The card asks for a chronological P104 correction program and a complete bill. This session does not build one. Eligible handoffs on #1166, after dropping delivered work and open PRs through #4123, number 17. Item index (21-1) mod 17 is the adjacent completed-call pair in comment 19034066. The pair itself stays with that item. This package refines it to the commutator any such pair must cancel if it reuses the old correction.", + "bottleneck_link": "The complex supplier is the binding side. An adjacent completed call was the proposed way to spend the P104 correction. A uniform scalar intertwiner fails when N-port scales differ, so that repair is not a paid-profile improvement. No new kappa is claimed.", + "budget_minutes": 60, + "stop_rule": "Stop once the block commutators and the scalar obstruction are checked, including the two dropped hypotheses. Do not search for an adjacent pair or price a native tariff in this package.", + "outcome": "negative-result", + "evidence": "PROOF.md is the block multiplication. verify.py recomputes it over the rationals for unequal N-port scales, the constant-scale sharpness case, a noncommuting T, and a non-projection H.", + "author": "unpaidmoon", + "ai_assistance": "Cursor Grok 4.7 wrote the proof expansion, verifier, and tests.", + "open_questions": [ + { + "question": "Does one adjacent pair that uses Pi P_enc Pi, rather than P, match every helper role as well as both data banks with a favorable bill?", + "why_it_matters": "The scalar obstruction only rules out the old correction and a uniform multiplier. The handoff still asks for one matched pair.", + "first_step": "Pin one helper entrance and exit from the PR 3954 endpoint and price Pi as a slot exchange before any root census.", + "blocked_by": "This identity has no helper schedule, and linear rank is not a native tariff." + }, + { + "question": "Which portwise diagonal corrections other than K on the image of H cancel the first bank for every N-port amplitude?", + "why_it_matters": "The first-bank defect is exactly -H K a, so the correction on that image is forced. A different alphabet would be a new contract.", + "first_step": "State the allowed diagonal alphabet and test two distinct N-port scales.", + "blocked_by": "A new alphabet is not the old correction P, and no such alphabet is specified by comment 19034066." + } + ] +} diff --git a/research/p104-literal-slot-defect/VERIFY.json b/research/p104-literal-slot-defect/VERIFY.json new file mode 100644 index 0000000000..cc7434179a --- /dev/null +++ b/research/p104-literal-slot-defect/VERIFY.json @@ -0,0 +1,18 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [], + "commands": [ + { + "argv": [ + "{python}", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 60, + "checks": "General ordered commutator; literal commutator under a projection that commutes with T; no scalar when N-port scales differ; scalar -1/2 when they agree; dropped commutation and dropped idempotence both fail closed." + } + ] +} diff --git a/research/p104-literal-slot-defect/verify.py b/research/p104-literal-slot-defect/verify.py new file mode 100644 index 0000000000..8d419819fd --- /dev/null +++ b/research/p104-literal-slot-defect/verify.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python3 +"""Literal-slot defect of the old P104 correction. + +The argument is the block multiplication in PROOF.md. These checks recompute +that multiplication over the rationals, including the cases where a hypothesis +is dropped. +""" + +from fractions import Fraction + + +def F(value): + return value if isinstance(value, Fraction) else Fraction(value) + + +def zeros(rows, cols): + return [[F(0) for _ in range(cols)] for _ in range(rows)] + + +def eye(n): + return [[F(int(i == j)) for j in range(n)] for i in range(n)] + + +def diag(values): + matrix = zeros(len(values), len(values)) + for i, value in enumerate(values): + matrix[i][i] = F(value) + return matrix + + +def add(left, right): + return [ + [left[i][j] + right[i][j] for j in range(len(left[0]))] + for i in range(len(left)) + ] + + +def sub(left, right): + return [ + [left[i][j] - right[i][j] for j in range(len(left[0]))] + for i in range(len(left)) + ] + + +def scale(matrix, factor): + factor = F(factor) + return [[factor * entry for entry in row] for row in matrix] + + +def mul(left, right): + rows, mid = len(left), len(left[0]) + cols = len(right[0]) + out = zeros(rows, cols) + for i in range(rows): + for k in range(mid): + if left[i][k] == 0: + continue + for j in range(cols): + out[i][j] += left[i][k] * right[k][j] + return out + + +def blocks(top_left, top_right, bottom_left, bottom_right): + n = len(top_left) + out = zeros(2 * n, 2 * n) + for i in range(n): + for j in range(n): + out[i][j] = top_left[i][j] + out[i][n + j] = top_right[i][j] + out[n + i][j] = bottom_left[i][j] + out[n + i][n + j] = bottom_right[i][j] + return out + + +def apply(matrix, vector): + return [ + sum((matrix[i][j] * vector[j] for j in range(len(vector))), F(0)) + for i in range(len(matrix)) + ] + + +def inverse(matrix): + n = len(matrix) + augmented = [row[:] + eye(n)[i] for i, row in enumerate(matrix)] + for col in range(n): + pivot = next(r for r in range(col, n) if augmented[r][col] != 0) + augmented[col], augmented[pivot] = augmented[pivot], augmented[col] + pivot_value = augmented[col][col] + augmented[col] = [entry / pivot_value for entry in augmented[col]] + for row in range(n): + if row == col or augmented[row][col] == 0: + continue + factor = augmented[row][col] + augmented[row] = [ + augmented[row][j] - factor * augmented[col][j] for j in range(2 * n) + ] + return [row[n:] for row in augmented] + + +def require(condition, message): + if not condition: + raise SystemExit("FAIL_P104_LITERAL_SLOT_DEFECT " + message) + + +def projection(mask): + return diag(mask) + + +def commutator(left, right): + return sub(mul(left, right), mul(right, left)) + + +def assemble(h_mask, t_values, data): + """Build P, L, Pi and A_T. t_values is a matrix.""" + h = projection(h_mask) + n = len(h_mask) + j0 = sub(eye(n), h) + k = inverse(t_values) + p = blocks(eye(n), zeros(n, n), k, eye(n)) + ht = mul(h, t_values) + l = blocks(data, ht, zeros(n, n), eye(n)) + pi = blocks(j0, h, h, j0) + return h, j0, k, p, l, pi, mul(pi, l) + + +def check_general_ordered(h, k, t_values, data, p, l): + """P L - L P = [[-H T K, 0], [K(D-I), K H T]] with no commutation hypothesis.""" + n = len(h) + expected = blocks( + scale(mul(mul(h, t_values), k), -1), + zeros(n, n), + mul(k, sub(data, eye(n))), + mul(mul(k, h), t_values), + ) + require(commutator(p, l) == expected, "general ordered commutator") + + +def check_simplified(h, k, data, p, l, pi, encoded): + n = len(h) + j0 = sub(eye(n), h) + ordered = blocks(scale(h, -1), zeros(n, n), mul(k, sub(data, eye(n))), h) + require(commutator(p, l) == ordered, "simplified ordered commutator") + literal = blocks( + scale(mul(h, k), -1), + zeros(n, n), + sub(mul(mul(k, j0), sub(data, eye(n))), h), + mul(k, h), + ) + require(commutator(p, encoded) == literal, "literal-slot commutator") + require(mul(pi, pi) == eye(2 * n), "Pi squared") + encoded_correction = mul(mul(l, p), inverse(l)) + require(mul(encoded_correction, l) == mul(l, p), "ordered conjugation") + literal_correction = mul(mul(pi, encoded_correction), pi) + require(mul(literal_correction, encoded) == mul(encoded, p), "literal conjugation") + require(commutator(p, encoded) != zeros(2 * n, 2 * n), "old P does not pass through A_T") + + +def n_port_indices(mask): + return [i for i, bit in enumerate(mask) if bit] + + +def first_bank(commutator_matrix, amplitude): + n = len(amplitude) + image = apply(commutator_matrix, amplitude + [F(0)] * n) + return image[:n] + + +def scalar_multiplier(h, k, p, encoded): + """Return the common first-bank multiplier, or None when the N-ports disagree.""" + mask = [int(h[i][i]) for i in range(len(h))] + indices = n_port_indices(mask) + require(indices, "need an N-port") + comm = commutator(p, encoded) + multipliers = [] + for index in indices: + amplitude = [F(int(i == index)) for i in range(len(h))] + error = first_bank(comm, amplitude) + column = [F(0)] * len(h) + column[index] = F(1) + require(error == apply(scale(k, -1), column), "first bank is -K on an N-port basis vector") + # The complement of this basis vector is untouched. + for other in range(len(h)): + if other != index: + require(error[other] == 0, "first-bank error stays on that port") + multipliers.append(error[index]) + if len(set(multipliers)) != 1: + return None + factor = multipliers[0] + # Every H-supported amplitude, not just basis vectors. + amplitude = [F(0) for _ in range(len(h))] + for index in indices: + amplitude[index] = F(index + 2) + error = first_bank(comm, amplitude) + require(error == [factor * entry for entry in amplitude], "scalar extends linearly on the N-ports") + # A J0 component is not multiplied by that same scalar. + if any(bit == 0 for bit in mask): + mixed = amplitude[:] + mixed[mask.index(0)] = F(7) + mixed_error = first_bank(comm, mixed) + require( + mixed_error != [factor * entry for entry in mixed], + "scalar does not absorb a J0 component", + ) + require( + mixed_error == first_bank(comm, amplitude), + "J0 component does not change the first-bank defect", + ) + return factor + + +def main(): + # Distinct N-port scales. D does not commute with T. + mask = [0, 0, 1, 1] + t_values = diag([4, 5, 2, 3]) + data = [ + [F(1), F(1), F(0), F(0)], + [F(0), F(1), F(0), F(0)], + [F(0), F(0), F(1), F(1)], + [F(0), F(0), F(0), F(1)], + ] + h, _j0, k, p, l, pi, encoded = assemble(mask, t_values, data) + require(mul(data, t_values) != mul(t_values, data), "D is not forced to commute with T") + check_general_ordered(h, k, t_values, data, p, l) + check_simplified(h, k, data, p, l, pi, encoded) + require(scalar_multiplier(h, k, p, encoded) is None, "distinct scales have no scalar") + + # Sharpness: one N-port scale. A scalar cancels the first bank on im H. + constant = diag([4, 5, 2, 2]) + h2, _j2, k2, p2, l2, pi2, encoded2 = assemble(mask, constant, eye(4)) + check_general_ordered(h2, k2, constant, eye(4), p2, l2) + check_simplified(h2, k2, eye(4), p2, l2, pi2, encoded2) + factor = scalar_multiplier(h2, k2, p2, encoded2) + require(factor == Fraction(-1, 2), "constant N-port scale is -1/T") + + # Dropping commutation keeps the unsimplified ordered identity and breaks the simplification. + mixed = [[F(1), F(1)], [F(0), F(1)]] + h3 = diag([0, 1]) + require(mul(h3, mixed) != mul(mixed, h3), "control T does not commute with H") + k3 = inverse(mixed) + n = 2 + p3 = blocks(eye(n), zeros(n, n), k3, eye(n)) + l3 = blocks(eye(n), mul(h3, mixed), zeros(n, n), eye(n)) + check_general_ordered(h3, k3, mixed, eye(n), p3, l3) + simplified = blocks(scale(h3, -1), zeros(n, n), mul(k3, zeros(n, n)), h3) + require(commutator(p3, l3) != simplified, "simplification needs HT = TH") + + # Dropping idempotence breaks Pi^2 = I. This H is not a coordinate projection. + bad = diag([2, 0]) + j_bad = sub(eye(2), bad) + pi_bad = blocks(j_bad, bad, bad, j_bad) + require(mul(pi_bad, pi_bad) != eye(4), "Pi^2 needs a projection") + + # The ordered defect is -A, not -K A. They differ when a port scale is not 1. + require(scale(h, -1) != scale(mul(h, k), -1), "literal defect is not the ordered defect") + + print( + "PASS_P104_LITERAL_SLOT_DEFECT " + "ordered=general literal=projection_and_commutation " + "distinct_scales=no_scalar constant_scale=-1/2 " + "pi_required=1 no_new_kappa" + ) + + +if __name__ == "__main__": + main()