Skip to content

feat(math): add Latin squares domain with check and transversal search (#1887) - #2021

Open
morluto wants to merge 1 commit into
mainfrom
agent/latin-squares-1887
Open

feat(math): add Latin squares domain with check and transversal search (#1887)#2021
morluto wants to merge 1 commit into
mainfrom
agent/latin-squares-1887

Conversation

@morluto

@morluto morluto commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

Create the domain with two operations, partially addressing #1887.

Operations

  • latin_square.check — Validate whether a square matrix of order n with entries in 0..n-1 is a Latin square (no repeated symbols in any row or column).
  • latin_square.transversal.compute — Exact backtracking search for a transversal (one entry per row, all distinct columns and symbols) in a Latin square.

Tests

9 known-answer and adversarial tests covering:

  • Valid 3x3 and 2x2 Latin squares, single element
  • Row and column violation detection
  • Invalid symbol value rejection
  • Transversal search for orders 1, 2, 3 (with distinct column/symbol verification)

Continue this on Linzumi

@morluto morluto added feature epic: execute Execute: math.run honesty, results, verify path domain: combinatorics Combinatorics, discrete structures, and matroids request: math-operation Request to add or extend a user-facing mathematical operation labels Aug 18, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@morluto morluto left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review verdict: blocked on the request contract and search bound

latin_square.transversal.compute says it searches a Latin square, but TransversalRequest checks only squareness. It accepts out-of-range symbols and matrices with repeated symbols in rows/columns, then returns a result under a stronger mathematical label than the input satisfies. Please reuse/wrap the validated LatinSquareRequest, or deliberately rename the operation to a transversal/rainbow-matching search over arbitrary arrays.

That missing validation also exposes a severe runtime case. The accepted matrix whose every row is

[0, 1, ..., n-2, n-2]

has only n-1 symbols and therefore no full transversal. The naive DFS enumerates a factorial-scale family of partial assignments before proving failure. In an independent instrumentation of this exact algorithm, the n=10 case took 1,863,219 recursive calls and n=11 exceeded 10,000,000 calls; the public bound is n=20 with no work budget or incomplete status.

Validating Latin-ness removes this particular adversarial input, but exact transversal search can still be combinatorial. Please either establish a defensible smaller bound with worst-case tests, or expose a bounded-search contract (max_nodes plus complete/incomplete status) rather than presenting every accepted order-20 request as a routine total operation.

The Latin-square checker itself is correct under its 0..n-1 input contract.

Add latin_squares_ops domain with 3 operations: Latin square
verification, orthogonality check, and transpose. Uses exact combinatorial
checks over bounded n x n matrices.

Closes #1887
@morluto
morluto force-pushed the agent/latin-squares-1887 branch from 553fec1 to 266c17e Compare August 18, 2026 23:07

morluto commented Aug 18, 2026

Copy link
Copy Markdown
Owner Author

Deep review summary

Verdict: REQUEST CHANGES — the transversal request does not require a Latin square, and the advertised order bound is not computationally defensible.

latin_square.transversal.compute says it searches a Latin square, but TransversalRequest validates only squareness. It accepts out-of-range symbols and matrices with repeated symbols in rows or columns, then returns an answer under a stronger mathematical label than the input satisfies. Reuse the validated Latin-square model, or rename the operation as a transversal/rainbow-matching search over arbitrary arrays.

The missing validation also exposes a severe runtime case. An accepted matrix whose every row is

[0, 1, ..., n-2, n-2]

has only n-1 symbols and no full transversal. The naive DFS explores factorially many partial assignments before proving failure. Independent instrumentation of this algorithm required 1,863,219 recursive calls at n=10; n=11 exceeded 10,000,000 calls. The public bound is n=20 with no work budget or incomplete outcome.

Validating Latin-ness removes that specific adversarial matrix, but exact transversal search remains combinatorial. Either establish a much smaller defensible total-operation bound with worst-case tests, or expose a bounded-search contract such as max_nodes with explicit complete/incomplete status.

The Latin-square checker itself is correct under its 0..n-1 contract.

morluto commented Aug 18, 2026

Copy link
Copy Markdown
Owner Author

Follow-up review for current head 266c17e

Verdict remains REQUEST CHANGES, but the earlier transversal-search findings no longer apply because this branch was rewritten.

The current blocker is that LatinSquare is only a square residue matrix; it does not enforce the Latin row/column axioms. That is appropriate for a candidate consumed by latin_square.check, but it is not a safe input type for operations whose precondition is already “Latin square.”

orthogonality.check can therefore certify non-Latin arrays as orthogonal. Concrete order-2 counterexample:

A = ((0,0),
     (1,1))
B = ((0,1),
     (0,1))

Neither array is Latin, yet their superimposed pairs are

(0,0), (0,1), (1,0), (1,1),

all distinct, so the implementation returns is_orthogonal=True. Orthogonal Latin squares require both squares to be Latin in addition to ordered-pair uniqueness.

Use two distinct types:

  • LatinSquareCandidate, validating only shape and symbol range, for .check;
  • LatinSquare, whose constructor replays every row and column, for transpose and orthogonality.

Alternatively, make orthogonality.check return a structured obstruction that first reports a non-Latin operand. transpose.compute should return a validated LatinSquare, not an unbound tuple.

Add the counterexample above plus the invariants:

  • transpose preserves Latin-ness and is an involution;
  • orthogonality implies each operand is Latin and exactly distinct pairs occur;
  • row/column permutations and consistent symbol relabellings preserve Latin-ness;
  • for order 2, no pair of Latin squares is orthogonal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: combinatorics Combinatorics, discrete structures, and matroids epic: execute Execute: math.run honesty, results, verify path feature request: math-operation Request to add or extend a user-facing mathematical operation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant