Repository navigation
[Critical] Make graph semantics explicit: simple vs multi graph types - #1194
Conversation
Reject self-loops and repeated undirected edges in SimpleGraph::try_new, shared by new and serde. Reuse validation for bipartite pairs and propagate fallible graph construction through model create specs. Keep complement-edge formulas exact. Make SAT graph builders emit unique pairs, combine MaxCut contributions, fold constant SpinGlass diagonals into the decision bound, and use simple NO gadgets for empty clauses. Update definitions and graph-type documentation, restrict tests to the accepted simple domain, and verify topology, CLI, MCP, and catalogue create paths. Keep the standalone macro attribute documentation as text for doctests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe TSP and bottleneck TSP as simple-graph problems and remove obsolete degenerate-tour explanations from their reduction proofs. Review the other loop and parallel-arc definition additions. Retain explicit semantics for flow, feedback-set, and mixed postman inputs; restore simple input definitions for the six catalog formulations whose broader constructor acceptance still needs a maintainer decision. Leave model validation and reduction behavior unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename the loop- and parallel-record topologies to MultiDirectedGraph and MultiMixedGraph. Add SimpleDirectedGraph as a validated, JSON-compatible wrapper and migrate the six simple-digraph models and their constructors. Expose arc multiplicity through MultiDirectedGraph::arc_count, keep per-arc vector order, and share the existing loop/duplicate checker across simple topologies. Validate augmentation candidates with that checker and allow undirected loops through MixedChinesePostman CLI/MCP creation. Adapt four obsolete simple-model fixtures, retain exhaustive Kernel/ILP verification over every three-vertex simple digraph, and update graph docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nches Test multiplicity, incidence, equality, serde validation, and weighted loop creation through the CLI and real MCP protocol. Remove unreachable TSP multigraph recovery and undirected-flow self-loop handling. Drop the redundant NAE edge-sum overflow branch after its checked total bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share equivalent create-path graph validation across eleven models and remove checks that simple graph invariants make redundant. Reuse borrowed arc iteration, avoid neighbor-vector allocations, and build incoming branching constraints in one pass. Remove obsolete loop-support text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Emit an infeasible ILP for graphs with fewer than three vertices and require target feasibility before extracting a tour. Preserve the exact variable count and adjust the constraint bound for the contradictory row. Add exhaustive graph-isomorphism differential tests through five vertices, signed and zero weights, invalid-witness rejection, and exact boundary-cost checks. Document the correctness and overhead arguments in the paper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep every TSP graph and weight case while checking exact assignments directly, reusing source tours and precomputing vertex relabelings. Reuse the parameter fixture database and target measurements, and prefer smaller authored rule sources over display-model examples. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Retain every test and named graph case. Use exact ILP infeasibility checks for the adversarial reductions, mathematical lower bounds for expensive canonical examples, and verified QUBO slack/energy certificates from optimized ILP prefixes. Keep exhaustive rooted-tree graph and threshold coverage while pruning invalid reference permutations. Bound the large mapping, determinism and compression fixtures, and verify the full Tutte ordering alongside an independent small exact-search oracle. Remove the two obsolete Tutte ignore attributes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1194 +/- ##
==========================================
+ Coverage 96.90% 97.01% +0.11%
==========================================
Files 1095 1097 +2
Lines 144972 145176 +204
==========================================
+ Hits 140484 140842 +358
+ Misses 4488 4334 -154 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Agentic Review ReportRecommendation: request changes. One Critical finding, one Important finding, and one Minor finding. Reviewed head Structural and semantic pass
Quality pass
|
Use fallible topology constructors at schema and typed create boundaries, including bipartite models, and check vertex-count inference for overflow. Exercise ordinary schema models and typed MCP inputs without process panics. Restore positive minimization boundary and singleton-interval checks using the fixed-objective fixture, and retain the cheap spanning-tree budget case that was lost when its parallel edge fixture became a simple path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reuse the existing permutation decoder and Cartesian iterator, consolidate fixture and MCP assertion loops, and stream the rooted-tree oracle costs. Avoid temporary TSP edge triples and simplify equivalent solver budgets. Keep every test and case, typed create errors, and independent certificate checks intact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GiggleLiu
left a comment
There was a problem hiding this comment.
Agentic Review Report
Reviewed PR #1194 at 878b10d15449f02f8b6203bcc6dd92f05c07b39e against merge base 875b6e86d5a87e5f66c2f6743be9d22abe917a09.
Structural and semantic
No remaining blocking findings in the inspected changes. Shared simple-graph validation rejects loops and repeated endpoint pairs, canonicalizing endpoint order only for undirected graphs. Constructors and serde preserve the invariant. SimpleDigraph exposes only an immutable underlying multigraph. Multi graph types retain arc occurrences and their original ordering.
The substantive reduction changes are sound: removing duplicate unweighted edges preserves constraints; combining parallel NAE cut weights preserves every cut value; discarded SpinGlass diagonal terms are subtracted from the decision threshold; the empty SAT clause creates a K4; the empty 3-SAT clause sets an impossible negative cover bound. TSP instances with fewer than three vertices now emit a contradictory ILP row, and extraction requires a feasible assignment. Its variable count remains exact and the additional row is included in the upper bound. Other loop/dedup simplifications follow from the new simple-graph input invariant.
The earlier review's Critical CLI panic is addressed at problemreductions-cli/src/commands/create/schema_support.rs:1129 with try_new. The added CLI tests assert exit 1 and absence of panic text for ordinary schema paths. The earlier Important minimization-boundary coverage issue is addressed with FixedObjective in src/unit_tests/solvers/decision_search.rs:70. The body now discloses the narrowed full-Tutte test and invalid-input test removals.
Quality
git diff --check passed. Inspected the new topology rejection tests, CLI error checks, TSP empty cases, exhaustive small graph/order tests, signed-weight cases, and invalid auxiliary-product rejection. Nine CI checks on the reviewed head succeeded, including tests, formatting, Clippy, coverage, and platform builds. The earlier independent review reports a full workspace and CLI/MCP exercise on an earlier head; that evidence is supplementary and is not claimed as a fresh runtime check here.
Feature test
No Rust build or CLI installation was run by this reviewer because the parent is serializing memory-intensive builds. This is a static review backed by current-head CI. It does not repeat the author's exhaustive experiment or paper rendering.
Findings
None that block merging. The public removal of DirectedGraph and MixedGraph, and constructors changing to SimpleDigraph, are breaking API changes already disclosed by the PR. Ship them in the next pre-1.0 minor release, not a 0.6.x patch.
Safe to merge the reviewed head after checking it remains current and resolving any mechanical merge conflicts.
GitHub PR audit
GATE: PASS
- harm.secrets: OK. No credential material introduced.
- harm.dangerous-files: OK. Source, documentation, and tests only.
- harm.generated-artifacts: OK. No blacklisted exports or build outputs.
- harm.cache: OK. No cache directories.
- harm.debug-leftovers: OK. Diagnostic output occurs in tests, not production probes.
- pr.description-quality: OK. Scope, breaking changes, narrowed tests, and validation are disclosed.
- pr.traceable: OK. The body explains the graph-invariant defect and each repair.
Merge-resolution follow-up
Independently checked merge commit 7126de6b3 against the original reviewed head. All 477 changed Rust files retain identical noncomment tokens after optional trailing-comma normalization. The only non-Rust differences are two Typst comments and one JavaScript comment from main. This resolves the comment-cleanup conflicts without changing reviewed behavior.
Integration update
Merged the already accepted main comment cleanup into this PR without changing its executable Rust tokens. At 7126de6b3, all 477 affected Rust files match the reviewed head after removing comments, whitespace and optional trailing commas. Formatting and diff-whitespace checks pass. The Typst and JavaScript merge changes are comments only. Fresh CI is required on this updated head before merge.
Summary
Graph semantics now live in the type. A problem that allows self-loops or parallel edges uses a multi type and says so at the start of its definition.
Graph types. The naming rule is
<Simple|Multi><Graph|Digraph|MixedGraph>.SimpleGraphtry_new,newand serdeSimpleDigraphMultiDigraphMultiDigrapharcs()DirectedGraph;has_arcreplaced byarc_countMultiMixedGraphMixedGraphPlanarGraphandBipartiteGraphreuse it. 21 per-model self-loop checks are removed.SimpleDigraph: AcyclicPartition, DirectedHamiltonianPath, Kernel, MinimumDummyActivitiesPert, MultipleChoiceBranching, StrongConnectivityAugmentation.MultiDigraph:MultiMixedGraph: MixedChinesePostman. CLI/MCP create now accept its loops too.Reductions that used to emit loops or duplicate edges now emit simple graphs:
num_clauses; edge bound becomes3·num_clausesnum_edgesbecomes an upper boundnum_edges = n(n−1)/2 − m, which is now sound because inputs are simple.0 = 1. Extraction also rejects infeasible assignments.Test speed.
Tests removed because their inputs are now invalid. These 13 tests exercised loops or repeated edges on simple-graph models:
test_self_loops_consume_cover_budgetpolynomial_encoding_preserves_parallel_edge_costs_and_self_loopstest_kcoloring_to_bicliquecover_native_loops_are_infeasibletest_kcoloring_to_bicliquecover_repeated_reversed_edgestest_kcoloring_to_tdcs_native_loops_are_notest_domatic_normalization_ignores_parallel_edges_and_loopstest_reduction_shape_with_repeated_edgestest_minimumvertexcover_to_ensemblecomputation_loops_and_parallel_edgesmatching_partition_ignores_loops_and_repeated_adjacenciestest_single_vertex_candidate_selection_must_still_respect_budgettest_tours_with_parallel_edges_and_loopssink_self_loop_cannot_supply_net_flowsink_self_loop_cannot_supply_either_commodityReview fixes.
try_new, so malformed graph input returns a construction error (exit 1) instead of panicking (exit 101). That covers 9 call sites, including twoBipartiteGraphpanics found during the audit.i64boundary cases are restored withFixedObjective.Breaking change. The public
DirectedGraphandMixedGraphare removed, and several model constructors now takeSimpleDigraph. The next release therefore needs a minor version bump.Test plan
SimpleDigraphrejects loops and parallel arcs and accepts (u,v) together with (v,u); the multi types accept both0-0and0-1,1-0, MaximumDomaticNumber0-1,1-0all exit 1)make fmt,make clippy,make check(7,059 tests),make cli,make paper🤖 Generated with Claude Code