Skip to content

Fix #54: derive Gate factories and fromArray from a generic make() constructor - #111

Open
corgab wants to merge 2 commits into
mainfrom
fix/54-generic-gate-factory
Open

Fix #54: derive Gate factories and fromArray from a generic make() constructor#111
corgab wants to merge 2 commits into
mainfrom
fix/54-generic-gate-factory

Conversation

@corgab

@corgab corgab commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

Gate's 28 named factories each hand-typed the parameter layout that GateType::shape() already describes generically, and fromArray() re-derived that same shape independently. Adding, renaming, or reshaping a gate touched both. This PR collapses them onto one generic constructor, as the issue proposes.

Plan

  1. Add Gate::make(GateType $type, array $qubits, array $angles = []), which lays qubit indices onto shape()->qubitKeys() and angles onto shape()->angleKeys(), in wire order — the same mapping fromArray() used to do inline. A Measure type delegates to measure(); angles on a measurement are rejected.
  2. Rewrite the 28 named factories as one-line wrappers around make(), and have fromArray() build through it too, instead of assembling $params by hand.
  3. Add CircuitBuilder::gate(GateType $type, array $qubits, array $angles = []) as the fluent counterpart, for building a gate from data (e.g. replaying a stored circuit) without going through a named method.
  4. Add InvalidCircuitException::gateArity() for a qubit/angle count that doesn't match the gate's shape, since that failure mode didn't exist before (a hand-written factory couldn't be called with the wrong argument count — PHP's own type checker caught that).

Changes

  • src/Circuit/Gate.php: make() added; all 28 factories (h() through zz()) reduced to return self::make(GateType::X, [...qubits], [...angles]);; fromArray() collects qubits/angles into arrays and calls make() instead of building $params inline.
  • src/Circuit/CircuitBuilder.php: gate() added, delegating to push(Gate::make(...)).
  • src/Exceptions/InvalidCircuitException.php: gateArity(string $type, string $kind, int $expected, int $given).
  • README.md: "Adding a Gate" now names Gate::make()/CircuitBuilder::gate() as the one generic constructor the named factories wrap, and mentions ->gate() as the entry point for data-driven circuits.
  • Tests: Gate::make() is exercised for every non-measure GateType against its named factory (same toArray(), same param key order), plus Angle normalization, wrong qubit/angle counts, and the measure/measure-all/angle-rejection cases. CircuitBuilder::gate() gets the same parity check against its named method, plus a qubit-range validation test. The existing completeness test (every Gate factory has a matching GateType case) now excludes make() itself alongside fromArray().

Tests

  • vendor/bin/pint --test passes.
  • vendor/bin/pest --compact: 853 tests, 1 skipped (791 before: +62, mostly the per-GateType dataset tests).

Closes #54

🤖 Generated with Claude Code

https://claude.ai/code/session_01E8zT5sUCTC8TgcpsME4WP5


Generated by Claude Code

corgab and others added 2 commits September 9, 2026 06:04
… make() constructor

Gate::make(GateType, qubits, angles) lays parameters out from
GateType::shape(), the same metadata fromArray() already dispatched on;
every named factory is now a one-line wrapper around it, and fromArray()
builds through it too. CircuitBuilder::gate() exposes the same generic
entry point as fluent sugar for building a gate from data. A new
InvalidCircuitException::gateArity() reports a wrong qubit/angle count.
Angle's degree factory is deg(), not degrees(); the new make() test called
a method that doesn't exist, failing CI with a fatal error rather than a
test assertion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E8zT5sUCTC8TgcpsME4WP5
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.

[maintainability] Adding a gate requires 28 hand-written Gate factories and 29 identical CircuitBuilder one-liners

1 participant