From c34d3be5761a9286b02c9a5e10f9c1de5e64446e Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 23:00:03 +0800 Subject: [PATCH 1/6] initial --- scripts/make_helpers.sh | 20 ++++++++++++-------- scripts/pipeline_skill_context.py | 12 ++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/scripts/make_helpers.sh b/scripts/make_helpers.sh index 0a6838571..19a97c1a6 100644 --- a/scripts/make_helpers.sh +++ b/scripts/make_helpers.sh @@ -222,14 +222,18 @@ cleanup_pipeline_worktree() { } # Request Copilot review on all Review pool PRs that don't have one yet. -# request_copilot_reviews [board-cache] +# request_copilot_reviews [board-cache] [board-cache-max-age] request_copilot_reviews() { repo=$1 board_cache=${2-} + board_cache_max_age=${3-} cache_args="" if [ -n "$board_cache" ]; then cache_args="--board-cache $board_cache" fi + if [ -n "$board_cache_max_age" ]; then + cache_args="$cache_args --board-cache-max-age $board_cache_max_age" + fi prs=$(python3 scripts/pipeline_board.py list review --repo "$repo" --format json $cache_args \ | python3 -c " import sys, json @@ -274,15 +278,15 @@ except (FileNotFoundError, json.JSONDecodeError, ValueError): # Always fetch a reasonably fresh board to avoid dispatching items # that moved out of the target column since the last fetch. + # The board cache naturally expires after board_max_age seconds, + # so we don't need to delete it — just let natural expiry handle + # staleness. This avoids redundant 4-page GraphQL fetches when + # multiple commands share the same cache file within one cycle. board_max_age=$interval - if [ "$pending_count" -lt "$cache_threshold" ]; then - # Running low — invalidate cache to discover new items immediately - rm -f "$board_cache" - # For review mode, request Copilot reviews on PRs that don't have one yet - if [ "$mode" = "review" ] && [ -n "$repo" ]; then - request_copilot_reviews "$repo" "$board_cache" - fi + # For review mode, request Copilot reviews on PRs that don't have one yet + if [ "$mode" = "review" ] && [ -n "$repo" ]; then + request_copilot_reviews "$repo" "$board_cache" "$board_max_age" fi next_item=$(poll_project_items "$mode" "$state_file" "$repo" "" text "$board_cache" "$board_max_age") diff --git a/scripts/pipeline_skill_context.py b/scripts/pipeline_skill_context.py index ce58c88c4..177abcc8d 100644 --- a/scripts/pipeline_skill_context.py +++ b/scripts/pipeline_skill_context.py @@ -598,12 +598,20 @@ def emit_result(result: dict, fmt: str) -> None: print(json.dumps(result, indent=2, sort_keys=True)) +_REVIEW_BOARD_CACHE = Path("/tmp/problemreductions-review-board-cache.json") +_FINAL_REVIEW_BOARD_CACHE = Path("/tmp/problemreductions-final-review-board-cache.json") +_PROJECT_BOARD_CACHE = Path("/tmp/problemreductions-project-board-cache.json") +_BOARD_CACHE_MAX_AGE = 120 # seconds — covers multiple calls within one dispatch cycle + + def fetch_review_candidates(repo: str) -> list[dict]: owner = repo.split("/", 1)[0] board_data = pipeline_board.fetch_board_items( owner, PROJECT_BOARD_NUMBER, PROJECT_BOARD_LIMIT, + cache_file=_REVIEW_BOARD_CACHE, + cache_max_age=_BOARD_CACHE_MAX_AGE, ) return pipeline_board.review_candidates( board_data, @@ -664,6 +672,8 @@ def select_final_review_entry( owner, PROJECT_BOARD_NUMBER, PROJECT_BOARD_LIMIT, + cache_file=_FINAL_REVIEW_BOARD_CACHE, + cache_max_age=_BOARD_CACHE_MAX_AGE, ) return pipeline_board.select_next_entry( "final-review", @@ -980,6 +990,8 @@ def fetch_project_board_data(repo: str) -> dict: owner, PROJECT_BOARD_NUMBER, PROJECT_BOARD_LIMIT, + cache_file=_PROJECT_BOARD_CACHE, + cache_max_age=_BOARD_CACHE_MAX_AGE, ) From 806c1d53f718f8dd1dbf4f304aa1909d588dd68f Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 23:32:21 +0800 Subject: [PATCH 2/6] clean up reduction_graph.json --- .claude/CLAUDE.md | 2 +- .claude/skills/add-rule/SKILL.md | 4 +- .claude/skills/issue-to-pr/SKILL.md | 5 +- docs/src/design.md | 3 +- docs/src/getting-started.md | 1 + docs/src/reductions/problem_schemas.json | 760 ------------ docs/src/reductions/reduction_graph.json | 1406 ---------------------- examples/export_schemas.rs | 11 +- scripts/make_helpers.sh | 10 +- scripts/pipeline_checks.py | 4 - scripts/pipeline_skill_context.py | 12 - scripts/test_pipeline_checks.py | 2 - tests/suites/examples.rs | 46 +- 13 files changed, 64 insertions(+), 2202 deletions(-) delete mode 100644 docs/src/reductions/problem_schemas.json delete mode 100644 docs/src/reductions/reduction_graph.json diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index f2d5753f8..b2755e8a6 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -258,7 +258,7 @@ Also add to the `display-name` dictionary: ] ``` -Every directed reduction in the graph needs its own `reduction-rule` entry. The paper auto-checks completeness against `reduction_graph.json`. +Every directed reduction in the graph needs its own `reduction-rule` entry. The paper auto-checks completeness against the generated `reduction_graph.json` export. ## Complexity Verification Requirements diff --git a/.claude/skills/add-rule/SKILL.md b/.claude/skills/add-rule/SKILL.md index 894d11996..3712a3171 100644 --- a/.claude/skills/add-rule/SKILL.md +++ b/.claude/skills/add-rule/SKILL.md @@ -170,8 +170,8 @@ Checklist: notation self-contained, complexity cited, overhead consistent, examp ## Step 6: Regenerate exports and verify ```bash -cargo run --example export_graph # Update reduction_graph.json -cargo run --example export_schemas # Update problem schemas +cargo run --example export_graph # Generate reduction_graph.json for docs/paper builds +cargo run --example export_schemas # Generate problem schemas for docs/paper builds make test clippy # Must pass ``` diff --git a/.claude/skills/issue-to-pr/SKILL.md b/.claude/skills/issue-to-pr/SKILL.md index b37032d97..b35822291 100644 --- a/.claude/skills/issue-to-pr/SKILL.md +++ b/.claude/skills/issue-to-pr/SKILL.md @@ -223,12 +223,11 @@ EOF python3 scripts/pipeline_pr.py comment --repo "$REPO" --pr "$PR" --body-file "$COMMENT_FILE" rm -f "$COMMENT_FILE" -# Repo verification may regenerate tracked exports (notably after `make paper`). +# Repo verification may regenerate ignored doc exports (notably after `make paper`). # Inspect the tree once more before pushing. git status --short -# If expected generated exports changed, stage them before push. -git add docs/src/reductions/problem_schemas.json docs/src/reductions/reduction_graph.json +# Generated doc exports under docs/src/reductions/ are ignored; do not stage them. # The issue plan file must be gone before push. test ! -e docs/plans/.md diff --git a/docs/src/design.md b/docs/src/design.md index 77110650f..3fff7a7cb 100644 --- a/docs/src/design.md +++ b/docs/src/design.md @@ -230,7 +230,8 @@ Exported files: - [reduction_graph.json](reductions/reduction_graph.json) — all problem variants and reduction edges - [problem_schemas.json](reductions/problem_schemas.json) — field definitions for each problem type -Regenerate with `cargo run --example export_graph` and `cargo run --example export_schemas`. +These JSON assets are generated during `make doc`, `make mdbook`, and `make paper`; they are build artifacts, not committed source files. +Generate them manually with `cargo run --example export_graph` and `cargo run --example export_schemas` when you need the raw exports locally. ### Path finding diff --git a/docs/src/getting-started.md b/docs/src/getting-started.md index 2c01d2a2c..2cae2206a 100644 --- a/docs/src/getting-started.md +++ b/docs/src/getting-started.md @@ -207,6 +207,7 @@ problemreductions = { version = "0.2", default-features = false } The library exports machine-readable metadata useful for tooling and research: +These files are generated when you build the docs locally. - [reduction_graph.json](reductions/reduction_graph.json) lists all problem variants and reduction edges - [problem_schemas.json](reductions/problem_schemas.json) lists field definitions for each problem type diff --git a/docs/src/reductions/problem_schemas.json b/docs/src/reductions/problem_schemas.json deleted file mode 100644 index a4ea4b485..000000000 --- a/docs/src/reductions/problem_schemas.json +++ /dev/null @@ -1,760 +0,0 @@ -[ - { - "name": "BMF", - "description": "Boolean matrix factorization", - "fields": [ - { - "name": "matrix", - "type_name": "Vec>", - "description": "Target boolean matrix A" - }, - { - "name": "k", - "type_name": "usize", - "description": "Factorization rank" - } - ] - }, - { - "name": "BicliqueCover", - "description": "Cover bipartite edges with k bicliques", - "fields": [ - { - "name": "left_size", - "type_name": "usize", - "description": "Vertices in left partition" - }, - { - "name": "right_size", - "type_name": "usize", - "description": "Vertices in right partition" - }, - { - "name": "edges", - "type_name": "Vec<(usize, usize)>", - "description": "Bipartite edges" - }, - { - "name": "k", - "type_name": "usize", - "description": "Number of bicliques" - } - ] - }, - { - "name": "BinPacking", - "description": "Assign items to bins minimizing number of bins used, subject to capacity", - "fields": [ - { - "name": "sizes", - "type_name": "Vec", - "description": "Item sizes s_i for each item" - }, - { - "name": "capacity", - "type_name": "W", - "description": "Bin capacity C" - } - ] - }, - { - "name": "CircuitSAT", - "description": "Find satisfying input to a boolean circuit", - "fields": [ - { - "name": "circuit", - "type_name": "Circuit", - "description": "The boolean circuit" - } - ] - }, - { - "name": "ClosestVectorProblem", - "description": "Find the closest lattice point to a target vector", - "fields": [ - { - "name": "basis", - "type_name": "Vec>", - "description": "Basis matrix B as column vectors" - }, - { - "name": "target", - "type_name": "Vec", - "description": "Target vector t" - }, - { - "name": "bounds", - "type_name": "Vec", - "description": "Integer bounds per variable" - } - ] - }, - { - "name": "ExactCoverBy3Sets", - "description": "Determine if a collection of 3-element subsets contains an exact cover", - "fields": [ - { - "name": "universe_size", - "type_name": "usize", - "description": "Size of universe X (must be divisible by 3)" - }, - { - "name": "subsets", - "type_name": "Vec<[usize; 3]>", - "description": "Collection C of 3-element subsets of X" - } - ] - }, - { - "name": "Factoring", - "description": "Factor a composite integer into two factors", - "fields": [ - { - "name": "m", - "type_name": "usize", - "description": "Bits for first factor" - }, - { - "name": "n", - "type_name": "usize", - "description": "Bits for second factor" - }, - { - "name": "target", - "type_name": "u64", - "description": "Number to factor" - } - ] - }, - { - "name": "FlowShopScheduling", - "description": "Determine if a flow-shop schedule for jobs on m processors meets a deadline", - "fields": [ - { - "name": "num_processors", - "type_name": "usize", - "description": "Number of machines m" - }, - { - "name": "task_lengths", - "type_name": "Vec>", - "description": "task_lengths[j][i] = length of job j's task on machine i" - }, - { - "name": "deadline", - "type_name": "u64", - "description": "Global deadline D" - } - ] - }, - { - "name": "GraphPartitioning", - "description": "Find minimum cut balanced bisection of a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The undirected graph G=(V,E)" - } - ] - }, - { - "name": "HamiltonianPath", - "description": "Find a Hamiltonian path in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - } - ] - }, - { - "name": "ILP", - "description": "Optimize linear objective subject to linear constraints", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of integer variables" - }, - { - "name": "constraints", - "type_name": "Vec", - "description": "Linear constraints" - }, - { - "name": "objective", - "type_name": "Vec<(usize, f64)>", - "description": "Sparse objective coefficients" - }, - { - "name": "sense", - "type_name": "ObjectiveSense", - "description": "Optimization direction" - } - ] - }, - { - "name": "IsomorphicSpanningTree", - "description": "Does graph G contain a spanning tree isomorphic to tree T?", - "fields": [ - { - "name": "graph", - "type_name": "SimpleGraph", - "description": "The host graph G" - }, - { - "name": "tree", - "type_name": "SimpleGraph", - "description": "The target tree T (must be a tree with |V(T)| = |V(G)|)" - } - ] - }, - { - "name": "KColoring", - "description": "Find valid k-coloring of a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - } - ] - }, - { - "name": "KSatisfiability", - "description": "SAT with exactly k literals per clause", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of Boolean variables" - }, - { - "name": "clauses", - "type_name": "Vec", - "description": "Clauses each with exactly K literals" - } - ] - }, - { - "name": "Knapsack", - "description": "Select items to maximize total value subject to weight capacity constraint", - "fields": [ - { - "name": "weights", - "type_name": "Vec", - "description": "Nonnegative item weights w_i" - }, - { - "name": "values", - "type_name": "Vec", - "description": "Nonnegative item values v_i" - }, - { - "name": "capacity", - "type_name": "i64", - "description": "Nonnegative knapsack capacity C" - } - ] - }, - { - "name": "LengthBoundedDisjointPaths", - "description": "Find J internally vertex-disjoint s-t paths of length at most K", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "source", - "type_name": "usize", - "description": "The shared source vertex s" - }, - { - "name": "sink", - "type_name": "usize", - "description": "The shared sink vertex t" - }, - { - "name": "num_paths_required", - "type_name": "usize", - "description": "Required number J of disjoint s-t paths" - }, - { - "name": "max_length", - "type_name": "usize", - "description": "Maximum path length K in edges" - } - ] - }, - { - "name": "LongestCommonSubsequence", - "description": "Find the longest string that is a subsequence of every input string", - "fields": [ - { - "name": "strings", - "type_name": "Vec>", - "description": "The input strings" - } - ] - }, - { - "name": "MaxCut", - "description": "Find maximum weight cut in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The graph with edge weights" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - } - ] - }, - { - "name": "MaximalIS", - "description": "Find maximum weight maximal independent set", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MaximumClique", - "description": "Find maximum weight clique in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MaximumIndependentSet", - "description": "Find maximum weight independent set in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MaximumMatching", - "description": "Find maximum weight matching in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - } - ] - }, - { - "name": "MaximumSetPacking", - "description": "Find maximum weight collection of disjoint sets", - "fields": [ - { - "name": "sets", - "type_name": "Vec>", - "description": "Collection of sets over a universe" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Weight for each set" - } - ] - }, - { - "name": "MinimumDominatingSet", - "description": "Find minimum weight dominating set in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MinimumFeedbackArcSet", - "description": "Find minimum weight feedback arc set in a directed graph", - "fields": [ - { - "name": "graph", - "type_name": "DirectedGraph", - "description": "The directed graph G=(V,A)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Arc weights w: A -> R" - } - ] - }, - { - "name": "MinimumFeedbackVertexSet", - "description": "Find minimum weight feedback vertex set in a directed graph", - "fields": [ - { - "name": "graph", - "type_name": "DirectedGraph", - "description": "The directed graph G=(V,A)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MinimumSetCovering", - "description": "Find minimum weight collection covering the universe", - "fields": [ - { - "name": "universe_size", - "type_name": "usize", - "description": "Size of the universe U" - }, - { - "name": "sets", - "type_name": "Vec>", - "description": "Collection of subsets of U" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Weight for each set" - } - ] - }, - { - "name": "MinimumSumMulticenter", - "description": "Find K centers minimizing total weighted distance (p-median problem)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "vertex_weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - }, - { - "name": "edge_lengths", - "type_name": "Vec", - "description": "Edge lengths l: E -> R" - }, - { - "name": "k", - "type_name": "usize", - "description": "Number of centers to place" - } - ] - }, - { - "name": "MinimumTardinessSequencing", - "description": "Schedule unit-length tasks with precedence constraints and deadlines to minimize the number of tardy tasks", - "fields": [ - { - "name": "num_tasks", - "type_name": "usize", - "description": "Number of tasks |T|" - }, - { - "name": "deadlines", - "type_name": "Vec", - "description": "Deadline d(t) for each task (1-indexed finish time)" - }, - { - "name": "precedences", - "type_name": "Vec<(usize, usize)>", - "description": "Precedence pairs (predecessor, successor)" - } - ] - }, - { - "name": "MinimumVertexCover", - "description": "Find minimum weight vertex cover in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "OptimalLinearArrangement", - "description": "Find a vertex ordering on a line with total edge length at most K", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The undirected graph G=(V,E)" - }, - { - "name": "bound", - "type_name": "usize", - "description": "Upper bound K on total edge length" - } - ] - }, - { - "name": "PaintShop", - "description": "Minimize color changes in paint shop sequence", - "fields": [ - { - "name": "sequence", - "type_name": "Vec", - "description": "Car labels (each must appear exactly twice)" - } - ] - }, - { - "name": "PartitionIntoTriangles", - "description": "Partition vertices into triangles (K3 subgraphs)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E) with |V| divisible by 3" - } - ] - }, - { - "name": "QUBO", - "description": "Minimize quadratic unconstrained binary objective", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of binary variables" - }, - { - "name": "matrix", - "type_name": "Vec>", - "description": "Upper-triangular Q matrix" - } - ] - }, - { - "name": "RuralPostman", - "description": "Find a circuit covering required edges with total length at most B (Rural Postman Problem)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge lengths l(e) for each e in E" - }, - { - "name": "required_edges", - "type_name": "Vec", - "description": "Edge indices of the required subset E' ⊆ E" - }, - { - "name": "bound", - "type_name": "W::Sum", - "description": "Upper bound B on total circuit length" - } - ] - }, - { - "name": "Satisfiability", - "description": "Find satisfying assignment for CNF formula", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of Boolean variables" - }, - { - "name": "clauses", - "type_name": "Vec", - "description": "Clauses in conjunctive normal form" - } - ] - }, - { - "name": "SetBasis", - "description": "Determine whether a collection of sets admits a basis of size k under union", - "fields": [ - { - "name": "universe_size", - "type_name": "usize", - "description": "Size of the ground set S" - }, - { - "name": "collection", - "type_name": "Vec>", - "description": "Collection C of target subsets of S" - }, - { - "name": "k", - "type_name": "usize", - "description": "Required number of basis sets" - } - ] - }, - { - "name": "ShortestCommonSupersequence", - "description": "Find a common supersequence of bounded length for a set of strings", - "fields": [ - { - "name": "alphabet_size", - "type_name": "usize", - "description": "Size of the alphabet" - }, - { - "name": "strings", - "type_name": "Vec>", - "description": "Input strings over the alphabet {0, ..., alphabet_size-1}" - }, - { - "name": "bound", - "type_name": "usize", - "description": "Bound on supersequence length (configuration has exactly this many symbols)" - } - ] - }, - { - "name": "SpinGlass", - "description": "Minimize Ising Hamiltonian on a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The interaction graph" - }, - { - "name": "couplings", - "type_name": "Vec", - "description": "Pairwise couplings J_ij" - }, - { - "name": "fields", - "type_name": "Vec", - "description": "On-site fields h_i" - } - ] - }, - { - "name": "SteinerTree", - "description": "Find minimum weight tree connecting terminal vertices", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - }, - { - "name": "terminals", - "type_name": "Vec", - "description": "Terminal vertices T that must be connected" - } - ] - }, - { - "name": "SubgraphIsomorphism", - "description": "Determine if host graph G contains a subgraph isomorphic to pattern graph H", - "fields": [ - { - "name": "graph", - "type_name": "SimpleGraph", - "description": "The host graph G = (V_1, E_1) to search in" - }, - { - "name": "pattern", - "type_name": "SimpleGraph", - "description": "The pattern graph H = (V_2, E_2) to find as a subgraph" - } - ] - }, - { - "name": "SubsetSum", - "description": "Find a subset of positive integers that sums to exactly a target value", - "fields": [ - { - "name": "sizes", - "type_name": "Vec", - "description": "Positive integer sizes s(a) for each element" - }, - { - "name": "target", - "type_name": "BigUint", - "description": "Target sum B" - } - ] - }, - { - "name": "TravelingSalesman", - "description": "Find minimum weight Hamiltonian cycle in a graph (Traveling Salesman Problem)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - } - ] - } -] \ No newline at end of file diff --git a/docs/src/reductions/reduction_graph.json b/docs/src/reductions/reduction_graph.json deleted file mode 100644 index 112c02311..000000000 --- a/docs/src/reductions/reduction_graph.json +++ /dev/null @@ -1,1406 +0,0 @@ -{ - "nodes": [ - { - "name": "BMF", - "variant": {}, - "category": "algebraic", - "doc_path": "models/algebraic/struct.BMF.html", - "complexity": "2^(rows * rank + rank * cols)" - }, - { - "name": "BicliqueCover", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.BicliqueCover.html", - "complexity": "2^num_vertices" - }, - { - "name": "BinPacking", - "variant": { - "weight": "f64" - }, - "category": "misc", - "doc_path": "models/misc/struct.BinPacking.html", - "complexity": "2^num_items" - }, - { - "name": "BinPacking", - "variant": { - "weight": "i32" - }, - "category": "misc", - "doc_path": "models/misc/struct.BinPacking.html", - "complexity": "2^num_items" - }, - { - "name": "CircuitSAT", - "variant": {}, - "category": "formula", - "doc_path": "models/formula/struct.CircuitSAT.html", - "complexity": "2^num_variables" - }, - { - "name": "ClosestVectorProblem", - "variant": { - "weight": "f64" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ClosestVectorProblem.html", - "complexity": "2^num_basis_vectors" - }, - { - "name": "ClosestVectorProblem", - "variant": { - "weight": "i32" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ClosestVectorProblem.html", - "complexity": "2^num_basis_vectors" - }, - { - "name": "ExactCoverBy3Sets", - "variant": {}, - "category": "set", - "doc_path": "models/set/struct.ExactCoverBy3Sets.html", - "complexity": "2^universe_size" - }, - { - "name": "Factoring", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.Factoring.html", - "complexity": "exp((m + n)^(1/3) * log(m + n)^(2/3))" - }, - { - "name": "FlowShopScheduling", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.FlowShopScheduling.html", - "complexity": "factorial(num_jobs)" - }, - { - "name": "GraphPartitioning", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.GraphPartitioning.html", - "complexity": "2^num_vertices" - }, - { - "name": "HamiltonianPath", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.HamiltonianPath.html", - "complexity": "1.657^num_vertices" - }, - { - "name": "ILP", - "variant": { - "variable": "bool" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ILP.html", - "complexity": "2^num_vars" - }, - { - "name": "ILP", - "variant": { - "variable": "i32" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ILP.html", - "complexity": "num_vars^num_vars" - }, - { - "name": "IsomorphicSpanningTree", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.IsomorphicSpanningTree.html", - "complexity": "factorial(num_vertices)" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K2" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "num_vertices + num_edges" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K3" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "1.3289^num_vertices" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K4" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "1.7159^num_vertices" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K5" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "2^num_vertices" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "KN" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "2^num_vertices" - }, - { - "name": "KSatisfiability", - "variant": { - "k": "K2" - }, - "category": "formula", - "doc_path": "models/formula/struct.KSatisfiability.html", - "complexity": "num_variables + num_clauses" - }, - { - "name": "KSatisfiability", - "variant": { - "k": "K3" - }, - "category": "formula", - "doc_path": "models/formula/struct.KSatisfiability.html", - "complexity": "1.307^num_variables" - }, - { - "name": "KSatisfiability", - "variant": { - "k": "KN" - }, - "category": "formula", - "doc_path": "models/formula/struct.KSatisfiability.html", - "complexity": "2^num_variables" - }, - { - "name": "Knapsack", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.Knapsack.html", - "complexity": "2^(num_items / 2)" - }, - { - "name": "LengthBoundedDisjointPaths", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.LengthBoundedDisjointPaths.html", - "complexity": "2^(num_paths_required * num_vertices)" - }, - { - "name": "LongestCommonSubsequence", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.LongestCommonSubsequence.html", - "complexity": "2^min_string_length" - }, - { - "name": "MaxCut", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaxCut.html", - "complexity": "2^(2.372 * num_vertices / 3)" - }, - { - "name": "MaximalIS", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximalIS.html", - "complexity": "3^(num_vertices / 3)" - }, - { - "name": "MaximumClique", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumClique.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "KingsSubgraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "KingsSubgraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "SimpleGraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "TriangularSubgraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "UnitDiskGraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "UnitDiskGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumMatching", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumMatching.html", - "complexity": "num_vertices^3" - }, - { - "name": "MaximumSetPacking", - "variant": { - "weight": "One" - }, - "category": "set", - "doc_path": "models/set/struct.MaximumSetPacking.html", - "complexity": "2^num_sets" - }, - { - "name": "MaximumSetPacking", - "variant": { - "weight": "f64" - }, - "category": "set", - "doc_path": "models/set/struct.MaximumSetPacking.html", - "complexity": "2^num_sets" - }, - { - "name": "MaximumSetPacking", - "variant": { - "weight": "i32" - }, - "category": "set", - "doc_path": "models/set/struct.MaximumSetPacking.html", - "complexity": "2^num_sets" - }, - { - "name": "MinimumDominatingSet", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumDominatingSet.html", - "complexity": "1.4969^num_vertices" - }, - { - "name": "MinimumFeedbackArcSet", - "variant": { - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumFeedbackArcSet.html", - "complexity": "2^num_vertices" - }, - { - "name": "MinimumFeedbackVertexSet", - "variant": { - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumFeedbackVertexSet.html", - "complexity": "1.9977^num_vertices" - }, - { - "name": "MinimumSetCovering", - "variant": { - "weight": "i32" - }, - "category": "set", - "doc_path": "models/set/struct.MinimumSetCovering.html", - "complexity": "2^num_sets" - }, - { - "name": "MinimumSumMulticenter", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumSumMulticenter.html", - "complexity": "2^num_vertices" - }, - { - "name": "MinimumTardinessSequencing", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.MinimumTardinessSequencing.html", - "complexity": "2^num_tasks" - }, - { - "name": "MinimumVertexCover", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumVertexCover.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "OptimalLinearArrangement", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.OptimalLinearArrangement.html", - "complexity": "2^num_vertices" - }, - { - "name": "PaintShop", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.PaintShop.html", - "complexity": "2^num_cars" - }, - { - "name": "PartitionIntoTriangles", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.PartitionIntoTriangles.html", - "complexity": "2^num_vertices" - }, - { - "name": "QUBO", - "variant": { - "weight": "f64" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.QUBO.html", - "complexity": "2^num_vars" - }, - { - "name": "RuralPostman", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.RuralPostman.html", - "complexity": "2^num_vertices * num_vertices^2" - }, - { - "name": "Satisfiability", - "variant": {}, - "category": "formula", - "doc_path": "models/formula/struct.Satisfiability.html", - "complexity": "2^num_variables" - }, - { - "name": "SetBasis", - "variant": {}, - "category": "set", - "doc_path": "models/set/struct.SetBasis.html", - "complexity": "2^(basis_size * universe_size)" - }, - { - "name": "ShortestCommonSupersequence", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.ShortestCommonSupersequence.html", - "complexity": "alphabet_size ^ bound" - }, - { - "name": "SpinGlass", - "variant": { - "graph": "SimpleGraph", - "weight": "f64" - }, - "category": "graph", - "doc_path": "models/graph/struct.SpinGlass.html", - "complexity": "2^num_spins" - }, - { - "name": "SpinGlass", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.SpinGlass.html", - "complexity": "2^num_spins" - }, - { - "name": "SteinerTree", - "variant": { - "graph": "SimpleGraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.SteinerTree.html", - "complexity": "3^num_terminals * num_vertices + 2^num_terminals * num_vertices^2" - }, - { - "name": "SteinerTree", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.SteinerTree.html", - "complexity": "3^num_terminals * num_vertices + 2^num_terminals * num_vertices^2" - }, - { - "name": "SubgraphIsomorphism", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.SubgraphIsomorphism.html", - "complexity": "num_host_vertices ^ num_pattern_vertices" - }, - { - "name": "SubsetSum", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.SubsetSum.html", - "complexity": "2^(num_elements / 2)" - }, - { - "name": "TravelingSalesman", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.TravelingSalesman.html", - "complexity": "2^num_vertices" - } - ], - "edges": [ - { - "source": 3, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_items * num_items + num_items" - }, - { - "field": "num_constraints", - "formula": "2 * num_items" - } - ], - "doc_path": "rules/binpacking_ilp/index.html" - }, - { - "source": 4, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_variables + num_assignments" - }, - { - "field": "num_constraints", - "formula": "num_variables + num_assignments" - } - ], - "doc_path": "rules/circuit_ilp/index.html" - }, - { - "source": 4, - "target": 56, - "overhead": [ - { - "field": "num_spins", - "formula": "num_assignments" - }, - { - "field": "num_interactions", - "formula": "num_assignments" - } - ], - "doc_path": "rules/circuit_spinglass/index.html" - }, - { - "source": 8, - "target": 4, - "overhead": [ - { - "field": "num_variables", - "formula": "6 * num_bits_first * num_bits_second + num_bits_first + num_bits_second" - }, - { - "field": "num_assignments", - "formula": "6 * num_bits_first * num_bits_second + num_bits_first + num_bits_second" - } - ], - "doc_path": "rules/factoring_circuit/index.html" - }, - { - "source": 8, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_bits_first * num_bits_second" - }, - { - "field": "num_constraints", - "formula": "num_bits_first * num_bits_second" - } - ], - "doc_path": "rules/factoring_ilp/index.html" - }, - { - "source": 12, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_constraints", - "formula": "num_constraints + num_vars" - } - ], - "doc_path": "rules/ilp_bool_ilp_i32/index.html" - }, - { - "source": 12, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars + num_constraints * num_vars" - } - ], - "doc_path": "rules/ilp_qubo/index.html" - }, - { - "source": 16, - "target": 19, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/kcoloring_casts/index.html" - }, - { - "source": 19, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2" - }, - { - "field": "num_constraints", - "formula": "num_vertices + num_vertices * num_edges" - } - ], - "doc_path": "rules/coloring_ilp/index.html" - }, - { - "source": 19, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2" - } - ], - "doc_path": "rules/coloring_qubo/index.html" - }, - { - "source": 20, - "target": 22, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_clauses", - "formula": "num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_casts/index.html" - }, - { - "source": 20, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - } - ], - "doc_path": "rules/ksatisfiability_qubo/index.html" - }, - { - "source": 21, - "target": 22, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_clauses", - "formula": "num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_casts/index.html" - }, - { - "source": 21, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars + num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_qubo/index.html" - }, - { - "source": 21, - "target": 60, - "overhead": [ - { - "field": "num_elements", - "formula": "2 * num_vars + 2 * num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_subsetsum/index.html" - }, - { - "source": 22, - "target": 52, - "overhead": [ - { - "field": "num_clauses", - "formula": "num_clauses" - }, - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_literals", - "formula": "num_literals" - } - ], - "doc_path": "rules/sat_ksat/index.html" - }, - { - "source": 23, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_items + num_slack_bits" - } - ], - "doc_path": "rules/knapsack_qubo/index.html" - }, - { - "source": 25, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_chars_first * num_chars_second" - }, - { - "field": "num_constraints", - "formula": "num_chars_first + num_chars_second + (num_chars_first * num_chars_second)^2" - } - ], - "doc_path": "rules/longestcommonsubsequence_ilp/index.html" - }, - { - "source": 26, - "target": 56, - "overhead": [ - { - "field": "num_spins", - "formula": "num_vertices" - }, - { - "field": "num_interactions", - "formula": "num_edges" - } - ], - "doc_path": "rules/spinglass_maxcut/index.html" - }, - { - "source": 28, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices" - }, - { - "field": "num_constraints", - "formula": "num_vertices^2" - } - ], - "doc_path": "rules/maximumclique_ilp/index.html" - }, - { - "source": 28, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * (num_vertices + -1 * 1) * 2^-1 + -1 * num_edges" - } - ], - "doc_path": "rules/maximumclique_maximumindependentset/index.html" - }, - { - "source": 29, - "target": 30, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 29, - "target": 34, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 30, - "target": 35, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 31, - "target": 29, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices * num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * num_vertices" - } - ], - "doc_path": "rules/maximumindependentset_gridgraph/index.html" - }, - { - "source": 31, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 31, - "target": 33, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices * num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * num_vertices" - } - ], - "doc_path": "rules/maximumindependentset_triangular/index.html" - }, - { - "source": 31, - "target": 37, - "overhead": [ - { - "field": "num_sets", - "formula": "num_vertices" - }, - { - "field": "universe_size", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 32, - "target": 28, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * (num_vertices + -1 * 1) * 2^-1 + -1 * num_edges" - } - ], - "doc_path": "rules/maximumindependentset_maximumclique/index.html" - }, - { - "source": 32, - "target": 39, - "overhead": [ - { - "field": "num_sets", - "formula": "num_vertices" - }, - { - "field": "universe_size", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 32, - "target": 46, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/minimumvertexcover_maximumindependentset/index.html" - }, - { - "source": 33, - "target": 35, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 34, - "target": 31, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 34, - "target": 35, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 35, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 36, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_edges" - }, - { - "field": "num_constraints", - "formula": "num_vertices" - } - ], - "doc_path": "rules/maximummatching_ilp/index.html" - }, - { - "source": 36, - "target": 39, - "overhead": [ - { - "field": "num_sets", - "formula": "num_edges" - }, - { - "field": "universe_size", - "formula": "num_vertices" - } - ], - "doc_path": "rules/maximummatching_maximumsetpacking/index.html" - }, - { - "source": 37, - "target": 31, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_sets" - }, - { - "field": "num_edges", - "formula": "num_sets^2" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 37, - "target": 39, - "overhead": [ - { - "field": "num_sets", - "formula": "num_sets" - }, - { - "field": "universe_size", - "formula": "universe_size" - } - ], - "doc_path": "rules/maximumsetpacking_casts/index.html" - }, - { - "source": 38, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_sets" - } - ], - "doc_path": "rules/maximumsetpacking_qubo/index.html" - }, - { - "source": 39, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_sets" - }, - { - "field": "num_constraints", - "formula": "universe_size" - } - ], - "doc_path": "rules/maximumsetpacking_ilp/index.html" - }, - { - "source": 39, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_sets" - }, - { - "field": "num_edges", - "formula": "num_sets^2" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 39, - "target": 38, - "overhead": [ - { - "field": "num_sets", - "formula": "num_sets" - }, - { - "field": "universe_size", - "formula": "universe_size" - } - ], - "doc_path": "rules/maximumsetpacking_casts/index.html" - }, - { - "source": 40, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices" - }, - { - "field": "num_constraints", - "formula": "num_vertices" - } - ], - "doc_path": "rules/minimumdominatingset_ilp/index.html" - }, - { - "source": 43, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_sets" - }, - { - "field": "num_constraints", - "formula": "universe_size" - } - ], - "doc_path": "rules/minimumsetcovering_ilp/index.html" - }, - { - "source": 46, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/minimumvertexcover_maximumindependentset/index.html" - }, - { - "source": 46, - "target": 43, - "overhead": [ - { - "field": "num_sets", - "formula": "num_vertices" - }, - { - "field": "universe_size", - "formula": "num_edges" - } - ], - "doc_path": "rules/minimumvertexcover_minimumsetcovering/index.html" - }, - { - "source": 50, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars^2" - }, - { - "field": "num_constraints", - "formula": "num_vars^2" - } - ], - "doc_path": "rules/qubo_ilp/index.html" - }, - { - "source": 50, - "target": 55, - "overhead": [ - { - "field": "num_spins", - "formula": "num_vars" - } - ], - "doc_path": "rules/spinglass_qubo/index.html" - }, - { - "source": 52, - "target": 4, - "overhead": [ - { - "field": "num_variables", - "formula": "num_vars + num_clauses + 1" - }, - { - "field": "num_assignments", - "formula": "num_clauses + 2" - } - ], - "doc_path": "rules/sat_circuitsat/index.html" - }, - { - "source": 52, - "target": 16, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vars + num_literals" - }, - { - "field": "num_edges", - "formula": "num_vars + num_literals" - } - ], - "doc_path": "rules/sat_coloring/index.html" - }, - { - "source": 52, - "target": 21, - "overhead": [ - { - "field": "num_clauses", - "formula": "4 * num_clauses + num_literals" - }, - { - "field": "num_vars", - "formula": "num_vars + 3 * num_clauses + num_literals" - } - ], - "doc_path": "rules/sat_ksat/index.html" - }, - { - "source": 52, - "target": 31, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_literals" - }, - { - "field": "num_edges", - "formula": "num_literals^2" - } - ], - "doc_path": "rules/sat_maximumindependentset/index.html" - }, - { - "source": 52, - "target": 40, - "overhead": [ - { - "field": "num_vertices", - "formula": "3 * num_vars + num_clauses" - }, - { - "field": "num_edges", - "formula": "3 * num_vars + num_literals" - } - ], - "doc_path": "rules/sat_minimumdominatingset/index.html" - }, - { - "source": 55, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_spins" - } - ], - "doc_path": "rules/spinglass_qubo/index.html" - }, - { - "source": 56, - "target": 26, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_spins" - }, - { - "field": "num_edges", - "formula": "num_interactions" - } - ], - "doc_path": "rules/spinglass_maxcut/index.html" - }, - { - "source": 56, - "target": 55, - "overhead": [ - { - "field": "num_spins", - "formula": "num_spins" - }, - { - "field": "num_interactions", - "formula": "num_interactions" - } - ], - "doc_path": "rules/spinglass_casts/index.html" - }, - { - "source": 61, - "target": 12, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2 + 2 * num_vertices * num_edges" - }, - { - "field": "num_constraints", - "formula": "num_vertices^3 + -1 * 1 * num_vertices^2 + 2 * num_vertices + 4 * num_vertices * num_edges" - } - ], - "doc_path": "rules/travelingsalesman_ilp/index.html" - }, - { - "source": 61, - "target": 50, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2" - } - ], - "doc_path": "rules/travelingsalesman_qubo/index.html" - } - ] -} \ No newline at end of file diff --git a/examples/export_schemas.rs b/examples/export_schemas.rs index f91b7ee68..19024dbb7 100644 --- a/examples/export_schemas.rs +++ b/examples/export_schemas.rs @@ -1,21 +1,24 @@ //! Export problem schemas to a JSON file. //! -//! Run with: `cargo run --example export_schemas` +//! Run with: `cargo run --example export_schemas [output_path]` use problemreductions::registry::collect_schemas; -use std::path::Path; +use std::path::PathBuf; fn main() { let schemas = collect_schemas(); println!("Collected {} problem schemas", schemas.len()); // Single source for both mdBook and paper - let output_path = Path::new("docs/src/reductions/problem_schemas.json"); + let output_path = std::env::args() + .nth(1) + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from("docs/src/reductions/problem_schemas.json")); if let Some(parent) = output_path.parent() { std::fs::create_dir_all(parent).expect("Failed to create output directory"); } let json = serde_json::to_string_pretty(&schemas).expect("Failed to serialize"); - std::fs::write(output_path, &json).expect("Failed to write file"); + std::fs::write(&output_path, &json).expect("Failed to write file"); println!("Exported to: {}", output_path.display()); } diff --git a/scripts/make_helpers.sh b/scripts/make_helpers.sh index 19a97c1a6..18f42a2e2 100644 --- a/scripts/make_helpers.sh +++ b/scripts/make_helpers.sh @@ -276,17 +276,17 @@ except (FileNotFoundError, json.JSONDecodeError, ValueError): print(0) " "$state_file" 2>/dev/null || echo 0) - # Always fetch a reasonably fresh board to avoid dispatching items - # that moved out of the target column since the last fetch. # The board cache naturally expires after board_max_age seconds, # so we don't need to delete it — just let natural expiry handle # staleness. This avoids redundant 4-page GraphQL fetches when # multiple commands share the same cache file within one cycle. board_max_age=$interval - # For review mode, request Copilot reviews on PRs that don't have one yet - if [ "$mode" = "review" ] && [ -n "$repo" ]; then - request_copilot_reviews "$repo" "$board_cache" "$board_max_age" + if [ "$pending_count" -lt "$cache_threshold" ]; then + # For review mode, request Copilot reviews on PRs that don't have one yet + if [ "$mode" = "review" ] && [ -n "$repo" ]; then + request_copilot_reviews "$repo" "$board_cache" "$board_max_age" + fi fi next_item=$(poll_project_items "$mode" "$state_file" "$repo" "" text "$board_cache" "$board_max_age") diff --git a/scripts/pipeline_checks.py b/scripts/pipeline_checks.py index e15717700..d1330733e 100644 --- a/scripts/pipeline_checks.py +++ b/scripts/pipeline_checks.py @@ -17,8 +17,6 @@ "src/example_db/model_builders.rs", "src/example_db/rule_builders.rs", "docs/paper/reductions.typ", - "docs/src/reductions/problem_schemas.json", - "docs/src/reductions/reduction_graph.json", "tests/suites/trait_consistency.rs", ] @@ -28,8 +26,6 @@ "src/example_db/rule_builders.rs", "src/models/", "docs/paper/reductions.typ", - "docs/src/reductions/reduction_graph.json", - "docs/src/reductions/problem_schemas.json", ] IGNORED_RULE_FILES = { diff --git a/scripts/pipeline_skill_context.py b/scripts/pipeline_skill_context.py index 177abcc8d..ce58c88c4 100644 --- a/scripts/pipeline_skill_context.py +++ b/scripts/pipeline_skill_context.py @@ -598,20 +598,12 @@ def emit_result(result: dict, fmt: str) -> None: print(json.dumps(result, indent=2, sort_keys=True)) -_REVIEW_BOARD_CACHE = Path("/tmp/problemreductions-review-board-cache.json") -_FINAL_REVIEW_BOARD_CACHE = Path("/tmp/problemreductions-final-review-board-cache.json") -_PROJECT_BOARD_CACHE = Path("/tmp/problemreductions-project-board-cache.json") -_BOARD_CACHE_MAX_AGE = 120 # seconds — covers multiple calls within one dispatch cycle - - def fetch_review_candidates(repo: str) -> list[dict]: owner = repo.split("/", 1)[0] board_data = pipeline_board.fetch_board_items( owner, PROJECT_BOARD_NUMBER, PROJECT_BOARD_LIMIT, - cache_file=_REVIEW_BOARD_CACHE, - cache_max_age=_BOARD_CACHE_MAX_AGE, ) return pipeline_board.review_candidates( board_data, @@ -672,8 +664,6 @@ def select_final_review_entry( owner, PROJECT_BOARD_NUMBER, PROJECT_BOARD_LIMIT, - cache_file=_FINAL_REVIEW_BOARD_CACHE, - cache_max_age=_BOARD_CACHE_MAX_AGE, ) return pipeline_board.select_next_entry( "final-review", @@ -990,8 +980,6 @@ def fetch_project_board_data(repo: str) -> dict: owner, PROJECT_BOARD_NUMBER, PROJECT_BOARD_LIMIT, - cache_file=_PROJECT_BOARD_CACHE, - cache_max_age=_BOARD_CACHE_MAX_AGE, ) diff --git a/scripts/test_pipeline_checks.py b/scripts/test_pipeline_checks.py index 0ffe11d02..51f54c87d 100644 --- a/scripts/test_pipeline_checks.py +++ b/scripts/test_pipeline_checks.py @@ -135,7 +135,6 @@ def test_file_whitelist_accepts_expected_model_files(self) -> None: "src/unit_tests/models/graph/graph_partitioning.rs", "src/example_db/model_builders.rs", "docs/paper/reductions.typ", - "docs/src/reductions/problem_schemas.json", "tests/suites/trait_consistency.rs", ], ) @@ -165,7 +164,6 @@ def test_file_whitelist_accepts_expected_rule_files(self) -> None: "src/example_db/rule_builders.rs", "src/models/graph/bin_packing.rs", "docs/paper/reductions.typ", - "docs/src/reductions/reduction_graph.json", ], ) diff --git a/tests/suites/examples.rs b/tests/suites/examples.rs index 366d8ae17..dacff97ca 100644 --- a/tests/suites/examples.rs +++ b/tests/suites/examples.rs @@ -1,6 +1,8 @@ // Test remaining example binaries to keep them compiling and correct. // Examples with `pub fn run()` are included directly; others are run as subprocesses. +use std::path::{Path, PathBuf}; + // --- Chained reduction demo (has pub fn run()) --- #[cfg(feature = "ilp-solver")] @@ -25,14 +27,54 @@ fn run_example(name: &str) { assert!(status.success(), "Example {name} failed with {status}"); } +fn temp_output_path(name: &str) -> PathBuf { + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .expect("Clock must be after UNIX_EPOCH") + .as_nanos(); + std::env::temp_dir().join(format!( + "problemreductions_{name}_{}_{}.json", + std::process::id(), + timestamp + )) +} + +fn run_example_with_output(name: &str, output_path: &Path) { + let output = output_path + .to_str() + .unwrap_or_else(|| panic!("Non-UTF-8 temp path for {name}: {output_path:?}")); + let status = std::process::Command::new(env!("CARGO")) + .args([ + "run", + "--example", + name, + "--features", + "ilp-highs", + "--", + output, + ]) + .status() + .unwrap_or_else(|e| panic!("Failed to run example {name}: {e}")); + assert!(status.success(), "Example {name} failed with {status}"); + assert!( + output_path.is_file(), + "Example {name} did not create expected output file at {}", + output_path.display() + ); +} + #[test] fn test_export_graph() { - run_example("export_graph"); + let output_path = temp_output_path("export_graph"); + run_example_with_output("export_graph", &output_path); + let _ = std::fs::remove_file(output_path); } #[test] fn test_export_schemas() { - run_example("export_schemas"); + let output_path = temp_output_path("export_schemas"); + run_example_with_output("export_schemas", &output_path); + let _ = std::fs::remove_file(output_path); } #[test] From a581214ec2cead500dfcdb6bb8666844afb98692 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 23:47:54 +0800 Subject: [PATCH 3/6] refactor-remove-conflicting files --- .claude/skills/add-model/SKILL.md | 11 - .claude/skills/final-review/SKILL.md | 1 - .claude/skills/issue-to-pr/SKILL.md | 2 +- .../structural-reviewer-prompt.md | 1 - .claude/skills/review-pipeline/SKILL.md | 2 +- scripts/pipeline_checks.py | 18 -- scripts/test_pipeline_checks.py | 28 +- src/lib.rs | 3 - src/unit_tests/trait_consistency.rs | 253 ------------------ 9 files changed, 3 insertions(+), 316 deletions(-) delete mode 100644 src/unit_tests/trait_consistency.rs diff --git a/.claude/skills/add-model/SKILL.md b/.claude/skills/add-model/SKILL.md index 6e9b9a01b..6969fd3ea 100644 --- a/.claude/skills/add-model/SKILL.md +++ b/.claude/skills/add-model/SKILL.md @@ -75,7 +75,6 @@ Before implementing, make sure the plan explicitly covers these items that struc - CLI discovery and `pred create ` support are included where applicable - A canonical model example is registered for example-db / `pred create --example` - `docs/paper/reductions.typ` adds both the display-name dictionary entry and the `problem-def(...)` -- `src/unit_tests/trait_consistency.rs` is updated ## Step 1: Determine the category @@ -213,15 +212,6 @@ This test should be written **after** Step 6 (paper entry), once the example ins Link the test file via `#[cfg(test)] #[path = "..."] mod tests;` at the bottom of the model file. -## Step 5.5: Add trait_consistency entry - -Add the new problem to `src/unit_tests/trait_consistency.rs`: - -1. **`test_all_problems_implement_trait_correctly`** — add a `check_problem_trait(...)` call with a small instance -2. **`test_direction`** (optimization problems only) — add an `assert_eq!(...direction(), Direction::Minimize/Maximize)` entry - -This is **required** for every new model — it ensures the Problem trait implementation is well-formed. - ## Step 6: Document in paper Write a `problem-def` entry in `docs/paper/reductions.typ`. **Reference example:** search for `problem-def("MaximumIndependentSet")` to see the gold-standard entry — use it as a template. @@ -294,5 +284,4 @@ If running standalone (not inside `make run-plan`), invoke [review-implementatio | Missing from CLI help table | Must add entry to "Flags by problem type" table in `cli.rs` `after_help` | | Schema lists derived fields | Schema should list constructor params, not internal fields (e.g., `matrix, k` not `matrix, m, n, k`) | | Missing canonical model example | Add a builder in `src/example_db/model_builders.rs` and keep it aligned with paper/example workflows | -| Forgetting trait_consistency | Must add entry in `test_all_problems_implement_trait_correctly` (and `test_direction` for optimization) in `src/unit_tests/trait_consistency.rs` | | Paper example not tested | Must include `test__paper_example` that verifies the exact instance, solution, and solution count shown in the paper | diff --git a/.claude/skills/final-review/SKILL.md b/.claude/skills/final-review/SKILL.md index 6bf9a11bd..8c94a76d7 100644 --- a/.claude/skills/final-review/SKILL.md +++ b/.claude/skills/final-review/SKILL.md @@ -184,7 +184,6 @@ Verify the PR includes all required components. Check: - [ ] Canonical model example function in the model file - [ ] Paper section in `docs/paper/reductions.typ` (`problem-def` entry) - [ ] `display-name` entry in paper -- [ ] `trait_consistency.rs` entry in `src/unit_tests/trait_consistency.rs` (`test_all_problems_implement_trait_correctly`, plus `test_direction` for optimization) - [ ] Aliases: if provided, verify they are standard literature abbreviations (not made up); if empty, confirm no well-known abbreviation is missing; check no conflict with existing aliases **For [Rule] PRs:** diff --git a/.claude/skills/issue-to-pr/SKILL.md b/.claude/skills/issue-to-pr/SKILL.md index b35822291..2b02b4957 100644 --- a/.claude/skills/issue-to-pr/SKILL.md +++ b/.claude/skills/issue-to-pr/SKILL.md @@ -97,7 +97,7 @@ The plan MUST reference the appropriate implementation skill and follow its step Include the concrete details from the issue (problem definition, reduction algorithm, example, etc.) mapped onto each step. **Plan batching:** The paper writing step (add-model Step 6 / add-rule Step 5) MUST be in a **separate batch** from the implementation steps, so it gets its own subagent with fresh context. It depends on the implementation being complete (needs exports). Example batch structure for a `[Model]` plan: -- Batch 1: Steps 1-5.5 (implement model, register, CLI, tests, trait_consistency) +- Batch 1: Steps 1-5.5 (implement model, register, CLI, tests) - Batch 2: Step 6 (write paper entry — depends on batch 1 for exports) **Solver rules:** diff --git a/.claude/skills/review-implementation/structural-reviewer-prompt.md b/.claude/skills/review-implementation/structural-reviewer-prompt.md index a8962fe95..a0ec3f98f 100644 --- a/.claude/skills/review-implementation/structural-reviewer-prompt.md +++ b/.claude/skills/review-implementation/structural-reviewer-prompt.md @@ -43,7 +43,6 @@ Given: problem name `P` = `{PROBLEM_NAME}`, category `C` = `{CATEGORY}`, file st | 15 | Canonical model example registered | `Grep("{P}", "src/example_db/model_builders.rs")` | | 16 | Paper `display-name` entry | `Grep('"{P}"', "docs/paper/reductions.typ")` | | 17 | Paper `problem-def` block | `Grep('problem-def.*"{P}"', "docs/paper/reductions.typ")` | -| 18 | `trait_consistency` entry | `Grep("{P}", "src/unit_tests/trait_consistency.rs")` | ## Rule Checklist diff --git a/.claude/skills/review-pipeline/SKILL.md b/.claude/skills/review-pipeline/SKILL.md index 0f6a290e1..1ebdc99c6 100644 --- a/.claude/skills/review-pipeline/SKILL.md +++ b/.claude/skills/review-pipeline/SKILL.md @@ -329,7 +329,7 @@ Completed: 2/2 | All moved to Final review | Guessing on an issue card with multiple linked repo PRs | Stop, show options to the user, and recommend the most likely correct OPEN PR | | Picking a PR before Copilot has reviewed | Inspect the checked-out diff and PR body first. If the PR is incomplete, comment and move it back to Ready. If it is review-ready, request Copilot review and switch to another item instead of waiting | | Missing project scopes | Run `gh auth refresh -s read:project,project` | -| Skipping review-implementation | Always run structural completeness check in Step 2b — it catches gaps Copilot misses (paper entries, CLI registration, trait_consistency) | +| Skipping review-implementation | Always run structural completeness check in Step 2b — it catches gaps Copilot misses (paper entries, CLI registration, example-db wiring) | | Skipping agentic tests | Always run test-feature even if CI is green | | Not checking out the right branch | Use `gh pr view` to get the exact branch name | | Waiting idle for Copilot | Request the review, leave the PR in Review pool, and keep triaging other items in the same run | diff --git a/scripts/pipeline_checks.py b/scripts/pipeline_checks.py index d1330733e..3178ce131 100644 --- a/scripts/pipeline_checks.py +++ b/scripts/pipeline_checks.py @@ -17,7 +17,6 @@ "src/example_db/model_builders.rs", "src/example_db/rule_builders.rs", "docs/paper/reductions.typ", - "tests/suites/trait_consistency.rs", ] RULE_WHITELIST = [ @@ -193,11 +192,8 @@ def model_completeness(repo_root: Path, name: str) -> dict: test_file = repo_root / "src/unit_tests/models" / category / f"{file_stem}.rs" model_text = read_text(model_file) if model_file is not None else "" - trait_text = read_text(repo_root / "src/unit_tests/trait_consistency.rs") paper_text = read_text(repo_root / "docs/paper/reductions.typ") - is_optimization = f"impl OptimizationProblem for {name}" in model_text - checks = { "model_file": ( check_entry(status="pass", path=str(model_file.relative_to(repo_root))) @@ -236,20 +232,6 @@ def model_completeness(repo_root: Path, name: str) -> dict: if f'"{name}":' in paper_text else check_entry(status="fail", detail="missing display-name entry in paper") ), - "trait_consistency": ( - check_entry(status="pass", path="src/unit_tests/trait_consistency.rs") - if name in trait_text and "test_all_problems_implement_trait_correctly" in trait_text - else check_entry(status="fail", detail="missing trait consistency entry") - ), - "trait_direction": ( - check_entry(status="pass", path="src/unit_tests/trait_consistency.rs") - if not is_optimization - else ( - check_entry(status="pass", path="src/unit_tests/trait_consistency.rs") - if name in trait_text.split("fn test_direction()", 1)[-1] - else check_entry(status="fail", detail="missing optimization direction check") - ) - ), } missing = [check_id for check_id, entry in checks.items() if entry["status"] == "fail"] diff --git a/scripts/test_pipeline_checks.py b/scripts/test_pipeline_checks.py index 51f54c87d..84b14b3f0 100644 --- a/scripts/test_pipeline_checks.py +++ b/scripts/test_pipeline_checks.py @@ -135,7 +135,6 @@ def test_file_whitelist_accepts_expected_model_files(self) -> None: "src/unit_tests/models/graph/graph_partitioning.rs", "src/example_db/model_builders.rs", "docs/paper/reductions.typ", - "tests/suites/trait_consistency.rs", ], ) @@ -186,17 +185,6 @@ def test_model_completeness_reports_all_required_components(self) -> None: repo / "src/unit_tests/models/graph/graph_partitioning.rs", "#[test]\nfn test_graph_partitioning_basic() {}\n", ) - self._write( - repo / "src/unit_tests/trait_consistency.rs", - """ - fn test_all_problems_implement_trait_correctly() { - check_problem_trait(&GraphPartitioning::new(), "GraphPartitioning"); - } - fn test_direction() { - let _ = GraphPartitioning::new().direction(); - } - """, - ) self._write(repo / "src/example_db/model_builders.rs", "pub fn build_model_examples() {}\n") self._write( repo / "docs/paper/reductions.typ", @@ -213,9 +201,8 @@ def test_model_completeness_reports_all_required_components(self) -> None: self.assertTrue(report["ok"]) self.assertEqual(report["missing"], []) self.assertEqual(report["checks"]["paper_display_name"]["status"], "pass") - self.assertEqual(report["checks"]["trait_direction"]["status"], "pass") - def test_model_completeness_flags_missing_paper_and_trait_entries(self) -> None: + def test_model_completeness_flags_missing_paper_entries(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: repo = Path(tmpdir) self._write( @@ -231,7 +218,6 @@ def test_model_completeness_flags_missing_paper_and_trait_entries(self) -> None: repo / "src/unit_tests/models/graph/graph_partitioning.rs", "#[test]\nfn test_graph_partitioning_basic() {}\n", ) - self._write(repo / "src/unit_tests/trait_consistency.rs", "fn test_direction() {}\n") self._write(repo / "src/example_db/model_builders.rs", "pub fn build_model_examples() {}\n") self._write(repo / "docs/paper/reductions.typ", "#let display-name = ()\n") @@ -240,7 +226,6 @@ def test_model_completeness_flags_missing_paper_and_trait_entries(self) -> None: self.assertFalse(report["ok"]) self.assertIn("paper_definition", report["missing"]) self.assertIn("paper_display_name", report["missing"]) - self.assertIn("trait_consistency", report["missing"]) def test_rule_completeness_reports_all_required_components(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: @@ -456,17 +441,6 @@ def test_build_review_context_reports_model_bundle(self) -> None: repo / "src/unit_tests/models/graph/graph_partitioning.rs", "#[test]\nfn test_graph_partitioning_basic() {}\n", ) - self._write( - repo / "src/unit_tests/trait_consistency.rs", - """ - fn test_all_problems_implement_trait_correctly() { - check_problem_trait(&GraphPartitioning::new(), "GraphPartitioning"); - } - fn test_direction() { - let _ = GraphPartitioning::new().direction(); - } - """, - ) self._write( repo / "docs/paper/reductions.typ", """ diff --git a/src/lib.rs b/src/lib.rs index 0b750bbac..52b1e7a57 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,8 +100,5 @@ mod test_property; #[path = "unit_tests/reduction_graph.rs"] mod test_reduction_graph; #[cfg(test)] -#[path = "unit_tests/trait_consistency.rs"] -mod test_trait_consistency; -#[cfg(test)] #[path = "unit_tests/unitdiskmapping_algorithms/mod.rs"] mod test_unitdiskmapping_algorithms; diff --git a/src/unit_tests/trait_consistency.rs b/src/unit_tests/trait_consistency.rs deleted file mode 100644 index e2eefe7d6..000000000 --- a/src/unit_tests/trait_consistency.rs +++ /dev/null @@ -1,253 +0,0 @@ -use crate::models::algebraic::*; -use crate::models::formula::*; -use crate::models::graph::*; -use crate::models::misc::*; -use crate::models::set::*; -use crate::topology::{BipartiteGraph, DirectedGraph, SimpleGraph}; -use crate::traits::Problem; -use crate::variant::K3; - -fn check_problem_trait(problem: &P, name: &str) { - let dims = problem.dims(); - assert!( - !dims.is_empty() || name.contains("empty"), - "{} should have dimensions", - name - ); - for d in &dims { - assert!( - *d >= 1, - "{} should have at least 1 choice per dimension", - name - ); - } -} - -#[test] -fn test_all_problems_implement_trait_correctly() { - check_problem_trait( - &MaximumIndependentSet::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MaximumIndependentSet", - ); - check_problem_trait( - &MinimumVertexCover::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MinimumVertexCover", - ); - check_problem_trait( - &MaxCut::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32]), - "MaxCut", - ); - check_problem_trait( - &KColoring::::new(SimpleGraph::new(3, vec![(0, 1)])), - "KColoring", - ); - check_problem_trait( - &MinimumDominatingSet::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MinimumDominatingSet", - ); - check_problem_trait( - &MaximalIS::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MaximalIS", - ); - check_problem_trait( - &MaximumMatching::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32]), - "MaximumMatching", - ); - check_problem_trait( - &SteinerTree::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 2], - vec![0, 2], - ), - "SteinerTree", - ); - check_problem_trait( - &Satisfiability::new(3, vec![CNFClause::new(vec![1])]), - "SAT", - ); - check_problem_trait( - &SpinGlass::new(3, vec![((0, 1), 1.0)], vec![0.0; 3]), - "SpinGlass", - ); - check_problem_trait(&QUBO::from_matrix(vec![vec![1.0; 3]; 3]), "QUBO"); - check_problem_trait( - &MinimumSetCovering::::new(3, vec![vec![0, 1]]), - "MinimumSetCovering", - ); - check_problem_trait( - &MaximumSetPacking::::new(vec![vec![0, 1]]), - "MaximumSetPacking", - ); - check_problem_trait( - &ExactCoverBy3Sets::new(6, vec![[0, 1, 2], [3, 4, 5]]), - "ExactCoverBy3Sets", - ); - check_problem_trait( - &SetBasis::new(3, vec![vec![0, 1], vec![1, 2]], 2), - "SetBasis", - ); - check_problem_trait(&PaintShop::new(vec!["a", "a"]), "PaintShop"); - check_problem_trait(&BMF::new(vec![vec![true]], 1), "BMF"); - check_problem_trait( - &BicliqueCover::new(BipartiteGraph::new(2, 2, vec![(0, 0)]), 1), - "BicliqueCover", - ); - check_problem_trait(&Factoring::new(6, 2, 2), "Factoring"); - - let circuit = Circuit::new(vec![Assignment::new( - vec!["x".to_string()], - BooleanExpr::constant(true), - )]); - check_problem_trait(&CircuitSAT::new(circuit), "CircuitSAT"); - check_problem_trait( - &MinimumFeedbackArcSet::new( - DirectedGraph::new(3, vec![(0, 1), (1, 2), (2, 0)]), - vec![1i32; 3], - ), - "MinimumFeedbackArcSet", - ); - check_problem_trait( - &MinimumSumMulticenter::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 3], - vec![1i32; 2], - 1, - ), - "MinimumSumMulticenter", - ); - check_problem_trait( - &HamiltonianPath::new(SimpleGraph::new(3, vec![(0, 1), (1, 2)])), - "HamiltonianPath", - ); - check_problem_trait( - &LengthBoundedDisjointPaths::new( - SimpleGraph::new(4, vec![(0, 1), (1, 3), (0, 2), (2, 3)]), - 0, - 3, - 2, - 2, - ), - "LengthBoundedDisjointPaths", - ); - check_problem_trait( - &OptimalLinearArrangement::new(SimpleGraph::new(3, vec![(0, 1), (1, 2)]), 3), - "OptimalLinearArrangement", - ); - check_problem_trait( - &IsomorphicSpanningTree::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2), (0, 2)]), - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - ), - "IsomorphicSpanningTree", - ); - check_problem_trait( - &ShortestCommonSupersequence::new(2, vec![vec![0, 1], vec![1, 0]], 3), - "ShortestCommonSupersequence", - ); - check_problem_trait( - &FlowShopScheduling::new(2, vec![vec![1, 2], vec![3, 4]], 10), - "FlowShopScheduling", - ); - check_problem_trait( - &MinimumTardinessSequencing::new(3, vec![2, 3, 1], vec![(0, 2)]), - "MinimumTardinessSequencing", - ); -} - -#[test] -fn test_direction() { - use crate::traits::OptimizationProblem; - use crate::types::Direction; - - // Minimization problems - assert_eq!( - MinimumVertexCover::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Minimize - ); - assert_eq!( - MinimumDominatingSet::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Minimize - ); - assert_eq!( - MinimumSetCovering::::new(2, vec![vec![0, 1]]).direction(), - Direction::Minimize - ); - assert_eq!( - PaintShop::new(vec!["a", "a"]).direction(), - Direction::Minimize - ); - assert_eq!( - QUBO::from_matrix(vec![vec![1.0]]).direction(), - Direction::Minimize - ); - assert_eq!( - SpinGlass::new(1, vec![], vec![0.0]).direction(), - Direction::Minimize - ); - assert_eq!( - BMF::new(vec![vec![true]], 1).direction(), - Direction::Minimize - ); - assert_eq!(Factoring::new(6, 2, 2).direction(), Direction::Minimize); - assert_eq!( - MinimumTardinessSequencing::new(3, vec![2, 3, 1], vec![(0, 2)]).direction(), - Direction::Minimize - ); - assert_eq!( - BicliqueCover::new(BipartiteGraph::new(2, 2, vec![(0, 0)]), 1).direction(), - Direction::Minimize - ); - assert_eq!( - MinimumFeedbackArcSet::new( - DirectedGraph::new(3, vec![(0, 1), (1, 2), (2, 0)]), - vec![1i32; 3] - ) - .direction(), - Direction::Minimize - ); - assert_eq!( - MinimumSumMulticenter::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 3], - vec![1i32; 2], - 1 - ) - .direction(), - Direction::Minimize - ); - assert_eq!( - SteinerTree::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 2], - vec![0, 2] - ) - .direction(), - Direction::Minimize - ); - - // Maximization problems - assert_eq!( - MaximumIndependentSet::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximalIS::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Maximize - ); - assert_eq!( - MaxCut::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximumMatching::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximumSetPacking::::new(vec![vec![0]]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximumClique::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Maximize - ); -} From 0fc0a02f5e57705ffc9c403b672bc0a470906032 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Tue, 17 Mar 2026 00:07:08 +0800 Subject: [PATCH 4/6] update skills and prompts --- .claude/CLAUDE.md | 4 ++- .claude/skills/add-model/SKILL.md | 26 ++++++++++--------- .../structural-reviewer-prompt.md | 19 +++++++------- src/unit_tests/models/graph/maximal_is.rs | 2 ++ .../models/graph/minimum_dominating_set.rs | 2 ++ 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index b2755e8a6..8c28c5f6f 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -207,7 +207,7 @@ New code must have >95% test coverage. Run `make coverage` to check. ### Naming - Reduction tests: `test__to__closed_loop` -- Model tests: `test__basic`, `test__serialization` +- Model tests: descriptive names — e.g., `test__creation`, `test__evaluate_*`, `test__direction`, `test__solver`, `test__serialization`. Use whichever are relevant; there is no fixed per-model naming set. - Solver tests: `test__` ### Key Testing Patterns @@ -218,6 +218,8 @@ See Key Patterns above for solver API signatures. Follow the reference files for Unit tests in `src/unit_tests/` linked via `#[path]` (see Core Modules above). Integration tests in `tests/suites/`, consolidated through `tests/main.rs`. Canonical example-db coverage lives in `src/unit_tests/example_db.rs`. +Model review automation expects a dedicated file under `src/unit_tests/models/...`. The exact split of creation/evaluation/direction/solver coverage is judged per model during review rather than by a single rigid filename or function-name checklist. + ## Documentation Locations - `README.md` — Project overview and quickstart - `.claude/` — Claude Code instructions and skills diff --git a/.claude/skills/add-model/SKILL.md b/.claude/skills/add-model/SKILL.md index 6969fd3ea..805a3890d 100644 --- a/.claude/skills/add-model/SKILL.md +++ b/.claude/skills/add-model/SKILL.md @@ -195,20 +195,22 @@ This example is now the canonical source for: Create `src/unit_tests/models//.rs`: -Required tests: -- `test__creation` -- construct an instance, verify dimensions -- `test__evaluation` -- verify `evaluate()` on valid and invalid configs -- `test__direction` -- verify optimization direction (if optimization problem) -- `test__serialization` -- round-trip serde test (optional but recommended) -- `test__solver` -- verify brute-force solver finds correct solutions -- `test__paper_example` -- **use the same instance from the paper example** (Step 6), verify the issue's expected outcome is valid/optimal and the solution count matches - -The `test__paper_example` test is critical for consistency between code and paper. It must: -1. Construct the exact same instance shown in the paper's example figure +Recommended coverage (adjust to the model rather than forcing a fixed checklist): +- Add at least one creation/basic test that exercises constructor inputs and key accessors. Include `dims()` or `num_variables()` assertions when they help document the configuration space. +- Add evaluation tests for valid and invalid configs so the feasibility boundary is explicit. +- Add a direction test for optimization problems. +- Add a brute-force solver test when the model is small enough to solve directly in unit tests. +- Add a round-trip serde test when the model is serialized through CLI/example-db flows. +- Add a paper-example test when the paper section includes a worked example and the issue provides a concrete expected outcome. + +The structural completeness automation currently checks for the presence of the dedicated model test file. Reviewers still inspect whether the coverage in that file is appropriate for the model's semantics. + +When you add `test__paper_example`, it should: +1. Construct the same instance shown in the paper's example figure 2. Evaluate the solution from the issue's **Expected Outcome** section as shown in the paper and assert it is valid (and optimal for optimization problems) -3. Use `BruteForce` to find all optimal/satisfying solutions and assert the count matches the paper's claim +3. Use `BruteForce` to confirm the claimed optimum/satisfying solution count when the instance is small enough for unit tests -This test should be written **after** Step 6 (paper entry), once the example instance and expected outcome are finalized. If writing tests before the paper, use the issue's Example Instance + Expected Outcome as the source of truth and come back to verify consistency. +This test is usually written **after** Step 6 (paper entry), once the example instance and expected outcome are finalized. If writing tests before the paper, use the issue's Example Instance + Expected Outcome as the source of truth and come back to verify consistency. Link the test file via `#[cfg(test)] #[path = "..."] mod tests;` at the bottom of the model file. diff --git a/.claude/skills/review-implementation/structural-reviewer-prompt.md b/.claude/skills/review-implementation/structural-reviewer-prompt.md index a0ec3f98f..d2c881d8c 100644 --- a/.claude/skills/review-implementation/structural-reviewer-prompt.md +++ b/.claude/skills/review-implementation/structural-reviewer-prompt.md @@ -33,16 +33,15 @@ Given: problem name `P` = `{PROBLEM_NAME}`, category `C` = `{CATEGORY}`, file st | 5 | `OptimizationProblem` or `SatisfactionProblem` impl | `Grep("(OptimizationProblem|SatisfactionProblem).*for.*{P}", file)` | | 6 | `#[cfg(test)]` + `#[path = "..."]` test link | `Grep("#\\[path =", file)` | | 7 | Test file exists | `Glob("src/unit_tests/models/{C}/{F}.rs")` | -| 8 | Test has creation test | `Grep("fn test_.*creation|fn test_{F}.*basic", test_file)` | -| 9 | Test has evaluation test | `Grep("fn test_.*evaluat", test_file)` | -| 10 | Registered in `{C}/mod.rs` | `Grep("mod {F}", "src/models/{C}/mod.rs")` | -| 11 | Re-exported in `models/mod.rs` | `Grep("{P}", "src/models/mod.rs")` | -| 12 | `declare_variants!` entry exists | `Grep("declare_variants!|default opt|default sat|opt {P}|sat {P}", file)` | -| 13 | CLI `resolve_alias` entry | `Grep("{P}", "problemreductions-cli/src/problem_name.rs")` | -| 14 | CLI `create` support | `Grep('"{P}"', "problemreductions-cli/src/commands/create.rs")` | -| 15 | Canonical model example registered | `Grep("{P}", "src/example_db/model_builders.rs")` | -| 16 | Paper `display-name` entry | `Grep('"{P}"', "docs/paper/reductions.typ")` | -| 17 | Paper `problem-def` block | `Grep('problem-def.*"{P}"', "docs/paper/reductions.typ")` | +| 8 | Test file contains model-specific tests | `Grep("fn test_", test_file)` | +| 9 | Registered in `{C}/mod.rs` | `Grep("mod {F}", "src/models/{C}/mod.rs")` | +| 10 | Re-exported in `models/mod.rs` | `Grep("{P}", "src/models/mod.rs")` | +| 11 | `declare_variants!` entry exists | `Grep("declare_variants!|default opt|default sat|opt {P}|sat {P}", file)` | +| 12 | CLI `resolve_alias` entry | `Grep("{P}", "problemreductions-cli/src/problem_name.rs")` | +| 13 | CLI `create` support | `Grep('"{P}"', "problemreductions-cli/src/commands/create.rs")` | +| 14 | Canonical model example registered | `Grep("{P}", "src/example_db/model_builders.rs")` | +| 15 | Paper `display-name` entry | `Grep('"{P}"', "docs/paper/reductions.typ")` | +| 16 | Paper `problem-def` block | `Grep('problem-def.*"{P}"', "docs/paper/reductions.typ")` | ## Rule Checklist diff --git a/src/unit_tests/models/graph/maximal_is.rs b/src/unit_tests/models/graph/maximal_is.rs index cff5e0cc0..be9cf494f 100644 --- a/src/unit_tests/models/graph/maximal_is.rs +++ b/src/unit_tests/models/graph/maximal_is.rs @@ -11,6 +11,8 @@ fn test_maximal_is_creation() { ); assert_eq!(problem.graph().num_vertices(), 4); assert_eq!(problem.graph().num_edges(), 3); + assert_eq!(problem.num_variables(), 4); + assert_eq!(problem.dims(), vec![2; 4]); } #[test] diff --git a/src/unit_tests/models/graph/minimum_dominating_set.rs b/src/unit_tests/models/graph/minimum_dominating_set.rs index 7e5684bef..b891105c3 100644 --- a/src/unit_tests/models/graph/minimum_dominating_set.rs +++ b/src/unit_tests/models/graph/minimum_dominating_set.rs @@ -13,6 +13,8 @@ fn test_dominating_set_creation() { ); assert_eq!(problem.graph().num_vertices(), 4); assert_eq!(problem.graph().num_edges(), 3); + assert_eq!(problem.num_variables(), 4); + assert_eq!(problem.dims(), vec![2; 4]); } #[test] From 997dcb6d280e30e954d59744f3d23e11cb18e1be Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Tue, 17 Mar 2026 00:08:41 +0800 Subject: [PATCH 5/6] relax model test naming to flexible coverage with >= 3 test floor Replace rigid per-model test function name checklist with flexible coverage guidance enforced by a minimum of 3 test functions. All three files (CLAUDE.md, add-model skill, structural reviewer) are now consistent on the threshold. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/CLAUDE.md | 2 +- .claude/skills/add-model/SKILL.md | 17 ++++++++--------- .../structural-reviewer-prompt.md | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 8c28c5f6f..3d4addc43 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -218,7 +218,7 @@ See Key Patterns above for solver API signatures. Follow the reference files for Unit tests in `src/unit_tests/` linked via `#[path]` (see Core Modules above). Integration tests in `tests/suites/`, consolidated through `tests/main.rs`. Canonical example-db coverage lives in `src/unit_tests/example_db.rs`. -Model review automation expects a dedicated file under `src/unit_tests/models/...`. The exact split of creation/evaluation/direction/solver coverage is judged per model during review rather than by a single rigid filename or function-name checklist. +Model review automation checks for a dedicated test file under `src/unit_tests/models/...` with at least 3 test functions. The exact split of coverage is judged per model during review. ## Documentation Locations - `README.md` — Project overview and quickstart diff --git a/.claude/skills/add-model/SKILL.md b/.claude/skills/add-model/SKILL.md index 805a3890d..e58f4120f 100644 --- a/.claude/skills/add-model/SKILL.md +++ b/.claude/skills/add-model/SKILL.md @@ -195,15 +195,14 @@ This example is now the canonical source for: Create `src/unit_tests/models//.rs`: -Recommended coverage (adjust to the model rather than forcing a fixed checklist): -- Add at least one creation/basic test that exercises constructor inputs and key accessors. Include `dims()` or `num_variables()` assertions when they help document the configuration space. -- Add evaluation tests for valid and invalid configs so the feasibility boundary is explicit. -- Add a direction test for optimization problems. -- Add a brute-force solver test when the model is small enough to solve directly in unit tests. -- Add a round-trip serde test when the model is serialized through CLI/example-db flows. -- Add a paper-example test when the paper section includes a worked example and the issue provides a concrete expected outcome. - -The structural completeness automation currently checks for the presence of the dedicated model test file. Reviewers still inspect whether the coverage in that file is appropriate for the model's semantics. +Every model needs **at least 3 test functions** (the structural reviewer enforces this). Choose from the coverage areas below — pick whichever are relevant to the model: + +- **Creation/basic** — exercise constructor inputs, key accessors, `dims()` / `num_variables()`. +- **Evaluation** — valid and invalid configs so the feasibility boundary is explicit. +- **Direction** — verify optimization direction (optimization problems only). +- **Solver** — brute-force solver finds correct solutions (when the model is small enough). +- **Serialization** — round-trip serde (when the model is used in CLI/example-db flows). +- **Paper example** — verify the worked example from the paper entry (see below). When you add `test__paper_example`, it should: 1. Construct the same instance shown in the paper's example figure diff --git a/.claude/skills/review-implementation/structural-reviewer-prompt.md b/.claude/skills/review-implementation/structural-reviewer-prompt.md index d2c881d8c..11fbba2b7 100644 --- a/.claude/skills/review-implementation/structural-reviewer-prompt.md +++ b/.claude/skills/review-implementation/structural-reviewer-prompt.md @@ -33,7 +33,7 @@ Given: problem name `P` = `{PROBLEM_NAME}`, category `C` = `{CATEGORY}`, file st | 5 | `OptimizationProblem` or `SatisfactionProblem` impl | `Grep("(OptimizationProblem|SatisfactionProblem).*for.*{P}", file)` | | 6 | `#[cfg(test)]` + `#[path = "..."]` test link | `Grep("#\\[path =", file)` | | 7 | Test file exists | `Glob("src/unit_tests/models/{C}/{F}.rs")` | -| 8 | Test file contains model-specific tests | `Grep("fn test_", test_file)` | +| 8 | Test file has >= 3 test functions | `Grep("fn test_", test_file)` — count matches, FAIL if < 3 | | 9 | Registered in `{C}/mod.rs` | `Grep("mod {F}", "src/models/{C}/mod.rs")` | | 10 | Re-exported in `models/mod.rs` | `Grep("{P}", "src/models/mod.rs")` | | 11 | `declare_variants!` entry exists | `Grep("declare_variants!|default opt|default sat|opt {P}|sat {P}", file)` | From 686586c7dc233eb86ec7f8fa3c3833e99920f118 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Tue, 17 Mar 2026 00:10:34 +0800 Subject: [PATCH 6/6] remove conflicting generated files These files were intentionally removed earlier in this branch; re-delete after merge conflict resolution. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/src/reductions/problem_schemas.json | 878 ------------- docs/src/reductions/reduction_graph.json | 1429 ---------------------- src/unit_tests/trait_consistency.rs | 288 ----- 3 files changed, 2595 deletions(-) delete mode 100644 docs/src/reductions/problem_schemas.json delete mode 100644 docs/src/reductions/reduction_graph.json delete mode 100644 src/unit_tests/trait_consistency.rs diff --git a/docs/src/reductions/problem_schemas.json b/docs/src/reductions/problem_schemas.json deleted file mode 100644 index 22e280720..000000000 --- a/docs/src/reductions/problem_schemas.json +++ /dev/null @@ -1,878 +0,0 @@ -[ - { - "name": "BMF", - "description": "Boolean matrix factorization", - "fields": [ - { - "name": "matrix", - "type_name": "Vec>", - "description": "Target boolean matrix A" - }, - { - "name": "k", - "type_name": "usize", - "description": "Factorization rank" - } - ] - }, - { - "name": "BicliqueCover", - "description": "Cover bipartite edges with k bicliques", - "fields": [ - { - "name": "left_size", - "type_name": "usize", - "description": "Vertices in left partition" - }, - { - "name": "right_size", - "type_name": "usize", - "description": "Vertices in right partition" - }, - { - "name": "edges", - "type_name": "Vec<(usize, usize)>", - "description": "Bipartite edges" - }, - { - "name": "k", - "type_name": "usize", - "description": "Number of bicliques" - } - ] - }, - { - "name": "BinPacking", - "description": "Assign items to bins minimizing number of bins used, subject to capacity", - "fields": [ - { - "name": "sizes", - "type_name": "Vec", - "description": "Item sizes s_i for each item" - }, - { - "name": "capacity", - "type_name": "W", - "description": "Bin capacity C" - } - ] - }, - { - "name": "CircuitSAT", - "description": "Find satisfying input to a boolean circuit", - "fields": [ - { - "name": "circuit", - "type_name": "Circuit", - "description": "The boolean circuit" - } - ] - }, - { - "name": "ClosestVectorProblem", - "description": "Find the closest lattice point to a target vector", - "fields": [ - { - "name": "basis", - "type_name": "Vec>", - "description": "Basis matrix B as column vectors" - }, - { - "name": "target", - "type_name": "Vec", - "description": "Target vector t" - }, - { - "name": "bounds", - "type_name": "Vec", - "description": "Integer bounds per variable" - } - ] - }, - { - "name": "DirectedTwoCommodityIntegralFlow", - "description": "Two-commodity integral flow feasibility on a directed graph", - "fields": [ - { - "name": "graph", - "type_name": "DirectedGraph", - "description": "Directed graph G = (V, A)" - }, - { - "name": "capacities", - "type_name": "Vec", - "description": "Capacity c(a) for each arc" - }, - { - "name": "source_1", - "type_name": "usize", - "description": "Source vertex s_1 for commodity 1" - }, - { - "name": "sink_1", - "type_name": "usize", - "description": "Sink vertex t_1 for commodity 1" - }, - { - "name": "source_2", - "type_name": "usize", - "description": "Source vertex s_2 for commodity 2" - }, - { - "name": "sink_2", - "type_name": "usize", - "description": "Sink vertex t_2 for commodity 2" - }, - { - "name": "requirement_1", - "type_name": "u64", - "description": "Flow requirement R_1 for commodity 1" - }, - { - "name": "requirement_2", - "type_name": "u64", - "description": "Flow requirement R_2 for commodity 2" - } - ] - }, - { - "name": "ExactCoverBy3Sets", - "description": "Determine if a collection of 3-element subsets contains an exact cover", - "fields": [ - { - "name": "universe_size", - "type_name": "usize", - "description": "Size of universe X (must be divisible by 3)" - }, - { - "name": "subsets", - "type_name": "Vec<[usize; 3]>", - "description": "Collection C of 3-element subsets of X" - } - ] - }, - { - "name": "Factoring", - "description": "Factor a composite integer into two factors", - "fields": [ - { - "name": "m", - "type_name": "usize", - "description": "Bits for first factor" - }, - { - "name": "n", - "type_name": "usize", - "description": "Bits for second factor" - }, - { - "name": "target", - "type_name": "u64", - "description": "Number to factor" - } - ] - }, - { - "name": "FlowShopScheduling", - "description": "Determine if a flow-shop schedule for jobs on m processors meets a deadline", - "fields": [ - { - "name": "num_processors", - "type_name": "usize", - "description": "Number of machines m" - }, - { - "name": "task_lengths", - "type_name": "Vec>", - "description": "task_lengths[j][i] = length of job j's task on machine i" - }, - { - "name": "deadline", - "type_name": "u64", - "description": "Global deadline D" - } - ] - }, - { - "name": "GraphPartitioning", - "description": "Find minimum cut balanced bisection of a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The undirected graph G=(V,E)" - } - ] - }, - { - "name": "HamiltonianPath", - "description": "Find a Hamiltonian path in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - } - ] - }, - { - "name": "ILP", - "description": "Optimize linear objective subject to linear constraints", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of integer variables" - }, - { - "name": "constraints", - "type_name": "Vec", - "description": "Linear constraints" - }, - { - "name": "objective", - "type_name": "Vec<(usize, f64)>", - "description": "Sparse objective coefficients" - }, - { - "name": "sense", - "type_name": "ObjectiveSense", - "description": "Optimization direction" - } - ] - }, - { - "name": "IsomorphicSpanningTree", - "description": "Does graph G contain a spanning tree isomorphic to tree T?", - "fields": [ - { - "name": "graph", - "type_name": "SimpleGraph", - "description": "The host graph G" - }, - { - "name": "tree", - "type_name": "SimpleGraph", - "description": "The target tree T (must be a tree with |V(T)| = |V(G)|)" - } - ] - }, - { - "name": "KColoring", - "description": "Find valid k-coloring of a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - } - ] - }, - { - "name": "KSatisfiability", - "description": "SAT with exactly k literals per clause", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of Boolean variables" - }, - { - "name": "clauses", - "type_name": "Vec", - "description": "Clauses each with exactly K literals" - } - ] - }, - { - "name": "Knapsack", - "description": "Select items to maximize total value subject to weight capacity constraint", - "fields": [ - { - "name": "weights", - "type_name": "Vec", - "description": "Nonnegative item weights w_i" - }, - { - "name": "values", - "type_name": "Vec", - "description": "Nonnegative item values v_i" - }, - { - "name": "capacity", - "type_name": "i64", - "description": "Nonnegative knapsack capacity C" - } - ] - }, - { - "name": "LengthBoundedDisjointPaths", - "description": "Find J internally vertex-disjoint s-t paths of length at most K", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "source", - "type_name": "usize", - "description": "The shared source vertex s" - }, - { - "name": "sink", - "type_name": "usize", - "description": "The shared sink vertex t" - }, - { - "name": "num_paths_required", - "type_name": "usize", - "description": "Required number J of disjoint s-t paths" - }, - { - "name": "max_length", - "type_name": "usize", - "description": "Maximum path length K in edges" - } - ] - }, - { - "name": "LongestCommonSubsequence", - "description": "Find the longest string that is a subsequence of every input string", - "fields": [ - { - "name": "strings", - "type_name": "Vec>", - "description": "The input strings" - } - ] - }, - { - "name": "MaxCut", - "description": "Find maximum weight cut in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The graph with edge weights" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - } - ] - }, - { - "name": "MaximalIS", - "description": "Find maximum weight maximal independent set", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MaximumClique", - "description": "Find maximum weight clique in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MaximumIndependentSet", - "description": "Find maximum weight independent set in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MaximumMatching", - "description": "Find maximum weight matching in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - } - ] - }, - { - "name": "MaximumSetPacking", - "description": "Find maximum weight collection of disjoint sets", - "fields": [ - { - "name": "sets", - "type_name": "Vec>", - "description": "Collection of sets over a universe" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Weight for each set" - } - ] - }, - { - "name": "MinimumDominatingSet", - "description": "Find minimum weight dominating set in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MinimumFeedbackArcSet", - "description": "Find minimum weight feedback arc set in a directed graph", - "fields": [ - { - "name": "graph", - "type_name": "DirectedGraph", - "description": "The directed graph G=(V,A)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Arc weights w: A -> R" - } - ] - }, - { - "name": "MinimumFeedbackVertexSet", - "description": "Find minimum weight feedback vertex set in a directed graph", - "fields": [ - { - "name": "graph", - "type_name": "DirectedGraph", - "description": "The directed graph G=(V,A)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MinimumSetCovering", - "description": "Find minimum weight collection covering the universe", - "fields": [ - { - "name": "universe_size", - "type_name": "usize", - "description": "Size of the universe U" - }, - { - "name": "sets", - "type_name": "Vec>", - "description": "Collection of subsets of U" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Weight for each set" - } - ] - }, - { - "name": "MinimumSumMulticenter", - "description": "Find K centers minimizing total weighted distance (p-median problem)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "vertex_weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - }, - { - "name": "edge_lengths", - "type_name": "Vec", - "description": "Edge lengths l: E -> R" - }, - { - "name": "k", - "type_name": "usize", - "description": "Number of centers to place" - } - ] - }, - { - "name": "MinimumTardinessSequencing", - "description": "Schedule unit-length tasks with precedence constraints and deadlines to minimize the number of tardy tasks", - "fields": [ - { - "name": "num_tasks", - "type_name": "usize", - "description": "Number of tasks |T|" - }, - { - "name": "deadlines", - "type_name": "Vec", - "description": "Deadline d(t) for each task (1-indexed finish time)" - }, - { - "name": "precedences", - "type_name": "Vec<(usize, usize)>", - "description": "Precedence pairs (predecessor, successor)" - } - ] - }, - { - "name": "MinimumVertexCover", - "description": "Find minimum weight vertex cover in a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Vertex weights w: V -> R" - } - ] - }, - { - "name": "MultipleChoiceBranching", - "description": "Find a branching with partition constraints and weight at least K", - "fields": [ - { - "name": "graph", - "type_name": "DirectedGraph", - "description": "The directed graph G=(V,A)" - }, - { - "name": "weights", - "type_name": "Vec", - "description": "Arc weights w(a) for each arc a in A" - }, - { - "name": "partition", - "type_name": "Vec>", - "description": "Partition of arc indices; each arc index must appear in exactly one group" - }, - { - "name": "threshold", - "type_name": "W::Sum", - "description": "Weight threshold K" - } - ] - }, - { - "name": "OptimalLinearArrangement", - "description": "Find a vertex ordering on a line with total edge length at most K", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The undirected graph G=(V,E)" - }, - { - "name": "bound", - "type_name": "usize", - "description": "Upper bound K on total edge length" - } - ] - }, - { - "name": "PaintShop", - "description": "Minimize color changes in paint shop sequence", - "fields": [ - { - "name": "sequence", - "type_name": "Vec", - "description": "Car labels (each must appear exactly twice)" - } - ] - }, - { - "name": "PartitionIntoTriangles", - "description": "Partition vertices into triangles (K3 subgraphs)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E) with |V| divisible by 3" - } - ] - }, - { - "name": "QUBO", - "description": "Minimize quadratic unconstrained binary objective", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of binary variables" - }, - { - "name": "matrix", - "type_name": "Vec>", - "description": "Upper-triangular Q matrix" - } - ] - }, - { - "name": "RuralPostman", - "description": "Find a circuit covering required edges with total length at most B (Rural Postman Problem)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge lengths l(e) for each e in E" - }, - { - "name": "required_edges", - "type_name": "Vec", - "description": "Edge indices of the required subset E' ⊆ E" - }, - { - "name": "bound", - "type_name": "W::Sum", - "description": "Upper bound B on total circuit length" - } - ] - }, - { - "name": "Satisfiability", - "description": "Find satisfying assignment for CNF formula", - "fields": [ - { - "name": "num_vars", - "type_name": "usize", - "description": "Number of Boolean variables" - }, - { - "name": "clauses", - "type_name": "Vec", - "description": "Clauses in conjunctive normal form" - } - ] - }, - { - "name": "SetBasis", - "description": "Determine whether a collection of sets admits a basis of size k under union", - "fields": [ - { - "name": "universe_size", - "type_name": "usize", - "description": "Size of the ground set S" - }, - { - "name": "collection", - "type_name": "Vec>", - "description": "Collection C of target subsets of S" - }, - { - "name": "k", - "type_name": "usize", - "description": "Required number of basis sets" - } - ] - }, - { - "name": "ShortestCommonSupersequence", - "description": "Find a common supersequence of bounded length for a set of strings", - "fields": [ - { - "name": "alphabet_size", - "type_name": "usize", - "description": "Size of the alphabet" - }, - { - "name": "strings", - "type_name": "Vec>", - "description": "Input strings over the alphabet {0, ..., alphabet_size-1}" - }, - { - "name": "bound", - "type_name": "usize", - "description": "Bound on supersequence length (configuration has exactly this many symbols)" - } - ] - }, - { - "name": "SpinGlass", - "description": "Minimize Ising Hamiltonian on a graph", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The interaction graph" - }, - { - "name": "couplings", - "type_name": "Vec", - "description": "Pairwise couplings J_ij" - }, - { - "name": "fields", - "type_name": "Vec", - "description": "On-site fields h_i" - } - ] - }, - { - "name": "SteinerTree", - "description": "Find minimum weight tree connecting terminal vertices", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - }, - { - "name": "terminals", - "type_name": "Vec", - "description": "Terminal vertices T that must be connected" - } - ] - }, - { - "name": "SubgraphIsomorphism", - "description": "Determine if host graph G contains a subgraph isomorphic to pattern graph H", - "fields": [ - { - "name": "graph", - "type_name": "SimpleGraph", - "description": "The host graph G = (V_1, E_1) to search in" - }, - { - "name": "pattern", - "type_name": "SimpleGraph", - "description": "The pattern graph H = (V_2, E_2) to find as a subgraph" - } - ] - }, - { - "name": "SubsetSum", - "description": "Find a subset of positive integers that sums to exactly a target value", - "fields": [ - { - "name": "sizes", - "type_name": "Vec", - "description": "Positive integer sizes s(a) for each element" - }, - { - "name": "target", - "type_name": "BigUint", - "description": "Target sum B" - } - ] - }, - { - "name": "TravelingSalesman", - "description": "Find minimum weight Hamiltonian cycle in a graph (Traveling Salesman Problem)", - "fields": [ - { - "name": "graph", - "type_name": "G", - "description": "The underlying graph G=(V,E)" - }, - { - "name": "edge_weights", - "type_name": "Vec", - "description": "Edge weights w: E -> R" - } - ] - }, - { - "name": "UndirectedTwoCommodityIntegralFlow", - "description": "Determine whether two integral commodities can satisfy sink demands in an undirected capacitated graph", - "fields": [ - { - "name": "graph", - "type_name": "SimpleGraph", - "description": "Undirected graph G=(V,E)" - }, - { - "name": "capacities", - "type_name": "Vec", - "description": "Edge capacities c(e) in graph edge order" - }, - { - "name": "source_1", - "type_name": "usize", - "description": "Source vertex s_1 for commodity 1" - }, - { - "name": "sink_1", - "type_name": "usize", - "description": "Sink vertex t_1 for commodity 1" - }, - { - "name": "source_2", - "type_name": "usize", - "description": "Source vertex s_2 for commodity 2" - }, - { - "name": "sink_2", - "type_name": "usize", - "description": "Sink vertex t_2 for commodity 2" - }, - { - "name": "requirement_1", - "type_name": "u64", - "description": "Required net inflow R_1 at sink t_1" - }, - { - "name": "requirement_2", - "type_name": "u64", - "description": "Required net inflow R_2 at sink t_2" - } - ] - } -] \ No newline at end of file diff --git a/docs/src/reductions/reduction_graph.json b/docs/src/reductions/reduction_graph.json deleted file mode 100644 index d59141c1c..000000000 --- a/docs/src/reductions/reduction_graph.json +++ /dev/null @@ -1,1429 +0,0 @@ -{ - "nodes": [ - { - "name": "BMF", - "variant": {}, - "category": "algebraic", - "doc_path": "models/algebraic/struct.BMF.html", - "complexity": "2^(rows * rank + rank * cols)" - }, - { - "name": "BicliqueCover", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.BicliqueCover.html", - "complexity": "2^num_vertices" - }, - { - "name": "BinPacking", - "variant": { - "weight": "f64" - }, - "category": "misc", - "doc_path": "models/misc/struct.BinPacking.html", - "complexity": "2^num_items" - }, - { - "name": "BinPacking", - "variant": { - "weight": "i32" - }, - "category": "misc", - "doc_path": "models/misc/struct.BinPacking.html", - "complexity": "2^num_items" - }, - { - "name": "CircuitSAT", - "variant": {}, - "category": "formula", - "doc_path": "models/formula/struct.CircuitSAT.html", - "complexity": "2^num_variables" - }, - { - "name": "ClosestVectorProblem", - "variant": { - "weight": "f64" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ClosestVectorProblem.html", - "complexity": "2^num_basis_vectors" - }, - { - "name": "ClosestVectorProblem", - "variant": { - "weight": "i32" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ClosestVectorProblem.html", - "complexity": "2^num_basis_vectors" - }, - { - "name": "DirectedTwoCommodityIntegralFlow", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.DirectedTwoCommodityIntegralFlow.html", - "complexity": "(max_capacity + 1)^(2 * num_arcs)" - }, - { - "name": "ExactCoverBy3Sets", - "variant": {}, - "category": "set", - "doc_path": "models/set/struct.ExactCoverBy3Sets.html", - "complexity": "2^universe_size" - }, - { - "name": "Factoring", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.Factoring.html", - "complexity": "exp((m + n)^(1/3) * log(m + n)^(2/3))" - }, - { - "name": "FlowShopScheduling", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.FlowShopScheduling.html", - "complexity": "factorial(num_jobs)" - }, - { - "name": "GraphPartitioning", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.GraphPartitioning.html", - "complexity": "2^num_vertices" - }, - { - "name": "HamiltonianPath", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.HamiltonianPath.html", - "complexity": "1.657^num_vertices" - }, - { - "name": "ILP", - "variant": { - "variable": "bool" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ILP.html", - "complexity": "2^num_vars" - }, - { - "name": "ILP", - "variant": { - "variable": "i32" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.ILP.html", - "complexity": "num_vars^num_vars" - }, - { - "name": "IsomorphicSpanningTree", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.IsomorphicSpanningTree.html", - "complexity": "factorial(num_vertices)" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K2" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "num_vertices + num_edges" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K3" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "1.3289^num_vertices" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K4" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "1.7159^num_vertices" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "K5" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "2^num_vertices" - }, - { - "name": "KColoring", - "variant": { - "graph": "SimpleGraph", - "k": "KN" - }, - "category": "graph", - "doc_path": "models/graph/struct.KColoring.html", - "complexity": "2^num_vertices" - }, - { - "name": "KSatisfiability", - "variant": { - "k": "K2" - }, - "category": "formula", - "doc_path": "models/formula/struct.KSatisfiability.html", - "complexity": "num_variables + num_clauses" - }, - { - "name": "KSatisfiability", - "variant": { - "k": "K3" - }, - "category": "formula", - "doc_path": "models/formula/struct.KSatisfiability.html", - "complexity": "1.307^num_variables" - }, - { - "name": "KSatisfiability", - "variant": { - "k": "KN" - }, - "category": "formula", - "doc_path": "models/formula/struct.KSatisfiability.html", - "complexity": "2^num_variables" - }, - { - "name": "Knapsack", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.Knapsack.html", - "complexity": "2^(num_items / 2)" - }, - { - "name": "LengthBoundedDisjointPaths", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.LengthBoundedDisjointPaths.html", - "complexity": "2^(num_paths_required * num_vertices)" - }, - { - "name": "LongestCommonSubsequence", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.LongestCommonSubsequence.html", - "complexity": "2^min_string_length" - }, - { - "name": "MaxCut", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaxCut.html", - "complexity": "2^(2.372 * num_vertices / 3)" - }, - { - "name": "MaximalIS", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximalIS.html", - "complexity": "3^(num_vertices / 3)" - }, - { - "name": "MaximumClique", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumClique.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "KingsSubgraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "KingsSubgraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "SimpleGraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "TriangularSubgraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "UnitDiskGraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumIndependentSet", - "variant": { - "graph": "UnitDiskGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumIndependentSet.html", - "complexity": "2^sqrt(num_vertices)" - }, - { - "name": "MaximumMatching", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MaximumMatching.html", - "complexity": "num_vertices^3" - }, - { - "name": "MaximumSetPacking", - "variant": { - "weight": "One" - }, - "category": "set", - "doc_path": "models/set/struct.MaximumSetPacking.html", - "complexity": "2^num_sets" - }, - { - "name": "MaximumSetPacking", - "variant": { - "weight": "f64" - }, - "category": "set", - "doc_path": "models/set/struct.MaximumSetPacking.html", - "complexity": "2^num_sets" - }, - { - "name": "MaximumSetPacking", - "variant": { - "weight": "i32" - }, - "category": "set", - "doc_path": "models/set/struct.MaximumSetPacking.html", - "complexity": "2^num_sets" - }, - { - "name": "MinimumDominatingSet", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumDominatingSet.html", - "complexity": "1.4969^num_vertices" - }, - { - "name": "MinimumFeedbackArcSet", - "variant": { - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumFeedbackArcSet.html", - "complexity": "2^num_vertices" - }, - { - "name": "MinimumFeedbackVertexSet", - "variant": { - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumFeedbackVertexSet.html", - "complexity": "1.9977^num_vertices" - }, - { - "name": "MinimumSetCovering", - "variant": { - "weight": "i32" - }, - "category": "set", - "doc_path": "models/set/struct.MinimumSetCovering.html", - "complexity": "2^num_sets" - }, - { - "name": "MinimumSumMulticenter", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumSumMulticenter.html", - "complexity": "2^num_vertices" - }, - { - "name": "MinimumTardinessSequencing", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.MinimumTardinessSequencing.html", - "complexity": "2^num_tasks" - }, - { - "name": "MinimumVertexCover", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MinimumVertexCover.html", - "complexity": "1.1996^num_vertices" - }, - { - "name": "MultipleChoiceBranching", - "variant": { - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.MultipleChoiceBranching.html", - "complexity": "2^num_arcs" - }, - { - "name": "OptimalLinearArrangement", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.OptimalLinearArrangement.html", - "complexity": "2^num_vertices" - }, - { - "name": "PaintShop", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.PaintShop.html", - "complexity": "2^num_cars" - }, - { - "name": "PartitionIntoTriangles", - "variant": { - "graph": "SimpleGraph" - }, - "category": "graph", - "doc_path": "models/graph/struct.PartitionIntoTriangles.html", - "complexity": "2^num_vertices" - }, - { - "name": "QUBO", - "variant": { - "weight": "f64" - }, - "category": "algebraic", - "doc_path": "models/algebraic/struct.QUBO.html", - "complexity": "2^num_vars" - }, - { - "name": "RuralPostman", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.RuralPostman.html", - "complexity": "2^num_vertices * num_vertices^2" - }, - { - "name": "Satisfiability", - "variant": {}, - "category": "formula", - "doc_path": "models/formula/struct.Satisfiability.html", - "complexity": "2^num_variables" - }, - { - "name": "SetBasis", - "variant": {}, - "category": "set", - "doc_path": "models/set/struct.SetBasis.html", - "complexity": "2^(basis_size * universe_size)" - }, - { - "name": "ShortestCommonSupersequence", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.ShortestCommonSupersequence.html", - "complexity": "alphabet_size ^ bound" - }, - { - "name": "SpinGlass", - "variant": { - "graph": "SimpleGraph", - "weight": "f64" - }, - "category": "graph", - "doc_path": "models/graph/struct.SpinGlass.html", - "complexity": "2^num_spins" - }, - { - "name": "SpinGlass", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.SpinGlass.html", - "complexity": "2^num_spins" - }, - { - "name": "SteinerTree", - "variant": { - "graph": "SimpleGraph", - "weight": "One" - }, - "category": "graph", - "doc_path": "models/graph/struct.SteinerTree.html", - "complexity": "3^num_terminals * num_vertices + 2^num_terminals * num_vertices^2" - }, - { - "name": "SteinerTree", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.SteinerTree.html", - "complexity": "3^num_terminals * num_vertices + 2^num_terminals * num_vertices^2" - }, - { - "name": "SubgraphIsomorphism", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.SubgraphIsomorphism.html", - "complexity": "num_host_vertices ^ num_pattern_vertices" - }, - { - "name": "SubsetSum", - "variant": {}, - "category": "misc", - "doc_path": "models/misc/struct.SubsetSum.html", - "complexity": "2^(num_elements / 2)" - }, - { - "name": "TravelingSalesman", - "variant": { - "graph": "SimpleGraph", - "weight": "i32" - }, - "category": "graph", - "doc_path": "models/graph/struct.TravelingSalesman.html", - "complexity": "2^num_vertices" - }, - { - "name": "UndirectedTwoCommodityIntegralFlow", - "variant": {}, - "category": "graph", - "doc_path": "models/graph/struct.UndirectedTwoCommodityIntegralFlow.html", - "complexity": "5^num_edges" - } - ], - "edges": [ - { - "source": 3, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_items * num_items + num_items" - }, - { - "field": "num_constraints", - "formula": "2 * num_items" - } - ], - "doc_path": "rules/binpacking_ilp/index.html" - }, - { - "source": 4, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_variables + num_assignments" - }, - { - "field": "num_constraints", - "formula": "num_variables + num_assignments" - } - ], - "doc_path": "rules/circuit_ilp/index.html" - }, - { - "source": 4, - "target": 58, - "overhead": [ - { - "field": "num_spins", - "formula": "num_assignments" - }, - { - "field": "num_interactions", - "formula": "num_assignments" - } - ], - "doc_path": "rules/circuit_spinglass/index.html" - }, - { - "source": 9, - "target": 4, - "overhead": [ - { - "field": "num_variables", - "formula": "6 * num_bits_first * num_bits_second + num_bits_first + num_bits_second" - }, - { - "field": "num_assignments", - "formula": "6 * num_bits_first * num_bits_second + num_bits_first + num_bits_second" - } - ], - "doc_path": "rules/factoring_circuit/index.html" - }, - { - "source": 9, - "target": 14, - "overhead": [ - { - "field": "num_vars", - "formula": "num_bits_first * num_bits_second" - }, - { - "field": "num_constraints", - "formula": "num_bits_first * num_bits_second" - } - ], - "doc_path": "rules/factoring_ilp/index.html" - }, - { - "source": 13, - "target": 14, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_constraints", - "formula": "num_constraints + num_vars" - } - ], - "doc_path": "rules/ilp_bool_ilp_i32/index.html" - }, - { - "source": 13, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars + num_constraints * num_vars" - } - ], - "doc_path": "rules/ilp_qubo/index.html" - }, - { - "source": 17, - "target": 20, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/kcoloring_casts/index.html" - }, - { - "source": 20, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2" - }, - { - "field": "num_constraints", - "formula": "num_vertices + num_vertices * num_edges" - } - ], - "doc_path": "rules/coloring_ilp/index.html" - }, - { - "source": 20, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2" - } - ], - "doc_path": "rules/coloring_qubo/index.html" - }, - { - "source": 21, - "target": 23, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_clauses", - "formula": "num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_casts/index.html" - }, - { - "source": 21, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - } - ], - "doc_path": "rules/ksatisfiability_qubo/index.html" - }, - { - "source": 22, - "target": 23, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_clauses", - "formula": "num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_casts/index.html" - }, - { - "source": 22, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars + num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_qubo/index.html" - }, - { - "source": 22, - "target": 62, - "overhead": [ - { - "field": "num_elements", - "formula": "2 * num_vars + 2 * num_clauses" - } - ], - "doc_path": "rules/ksatisfiability_subsetsum/index.html" - }, - { - "source": 23, - "target": 54, - "overhead": [ - { - "field": "num_clauses", - "formula": "num_clauses" - }, - { - "field": "num_vars", - "formula": "num_vars" - }, - { - "field": "num_literals", - "formula": "num_literals" - } - ], - "doc_path": "rules/sat_ksat/index.html" - }, - { - "source": 24, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_items + num_slack_bits" - } - ], - "doc_path": "rules/knapsack_qubo/index.html" - }, - { - "source": 26, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_chars_first * num_chars_second" - }, - { - "field": "num_constraints", - "formula": "num_chars_first + num_chars_second + (num_chars_first * num_chars_second)^2" - } - ], - "doc_path": "rules/longestcommonsubsequence_ilp/index.html" - }, - { - "source": 27, - "target": 58, - "overhead": [ - { - "field": "num_spins", - "formula": "num_vertices" - }, - { - "field": "num_interactions", - "formula": "num_edges" - } - ], - "doc_path": "rules/spinglass_maxcut/index.html" - }, - { - "source": 29, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices" - }, - { - "field": "num_constraints", - "formula": "num_vertices^2" - } - ], - "doc_path": "rules/maximumclique_ilp/index.html" - }, - { - "source": 29, - "target": 33, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * (num_vertices + -1 * 1) * 2^-1 + -1 * num_edges" - } - ], - "doc_path": "rules/maximumclique_maximumindependentset/index.html" - }, - { - "source": 30, - "target": 31, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 30, - "target": 35, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 31, - "target": 36, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 32, - "target": 30, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices * num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * num_vertices" - } - ], - "doc_path": "rules/maximumindependentset_gridgraph/index.html" - }, - { - "source": 32, - "target": 33, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 32, - "target": 34, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices * num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * num_vertices" - } - ], - "doc_path": "rules/maximumindependentset_triangular/index.html" - }, - { - "source": 32, - "target": 38, - "overhead": [ - { - "field": "num_sets", - "formula": "num_vertices" - }, - { - "field": "universe_size", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 33, - "target": 29, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_vertices * (num_vertices + -1 * 1) * 2^-1 + -1 * num_edges" - } - ], - "doc_path": "rules/maximumindependentset_maximumclique/index.html" - }, - { - "source": 33, - "target": 40, - "overhead": [ - { - "field": "num_sets", - "formula": "num_vertices" - }, - { - "field": "universe_size", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 33, - "target": 47, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/minimumvertexcover_maximumindependentset/index.html" - }, - { - "source": 34, - "target": 36, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 35, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 35, - "target": 36, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 36, - "target": 33, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/maximumindependentset_casts/index.html" - }, - { - "source": 37, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_edges" - }, - { - "field": "num_constraints", - "formula": "num_vertices" - } - ], - "doc_path": "rules/maximummatching_ilp/index.html" - }, - { - "source": 37, - "target": 40, - "overhead": [ - { - "field": "num_sets", - "formula": "num_edges" - }, - { - "field": "universe_size", - "formula": "num_vertices" - } - ], - "doc_path": "rules/maximummatching_maximumsetpacking/index.html" - }, - { - "source": 38, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_sets" - }, - { - "field": "num_edges", - "formula": "num_sets^2" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 38, - "target": 40, - "overhead": [ - { - "field": "num_sets", - "formula": "num_sets" - }, - { - "field": "universe_size", - "formula": "universe_size" - } - ], - "doc_path": "rules/maximumsetpacking_casts/index.html" - }, - { - "source": 39, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_sets" - } - ], - "doc_path": "rules/maximumsetpacking_qubo/index.html" - }, - { - "source": 40, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_sets" - }, - { - "field": "num_constraints", - "formula": "universe_size" - } - ], - "doc_path": "rules/maximumsetpacking_ilp/index.html" - }, - { - "source": 40, - "target": 33, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_sets" - }, - { - "field": "num_edges", - "formula": "num_sets^2" - } - ], - "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" - }, - { - "source": 40, - "target": 39, - "overhead": [ - { - "field": "num_sets", - "formula": "num_sets" - }, - { - "field": "universe_size", - "formula": "universe_size" - } - ], - "doc_path": "rules/maximumsetpacking_casts/index.html" - }, - { - "source": 41, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices" - }, - { - "field": "num_constraints", - "formula": "num_vertices" - } - ], - "doc_path": "rules/minimumdominatingset_ilp/index.html" - }, - { - "source": 44, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_sets" - }, - { - "field": "num_constraints", - "formula": "universe_size" - } - ], - "doc_path": "rules/minimumsetcovering_ilp/index.html" - }, - { - "source": 47, - "target": 33, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vertices" - }, - { - "field": "num_edges", - "formula": "num_edges" - } - ], - "doc_path": "rules/minimumvertexcover_maximumindependentset/index.html" - }, - { - "source": 47, - "target": 44, - "overhead": [ - { - "field": "num_sets", - "formula": "num_vertices" - }, - { - "field": "universe_size", - "formula": "num_edges" - } - ], - "doc_path": "rules/minimumvertexcover_minimumsetcovering/index.html" - }, - { - "source": 52, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vars^2" - }, - { - "field": "num_constraints", - "formula": "num_vars^2" - } - ], - "doc_path": "rules/qubo_ilp/index.html" - }, - { - "source": 52, - "target": 57, - "overhead": [ - { - "field": "num_spins", - "formula": "num_vars" - } - ], - "doc_path": "rules/spinglass_qubo/index.html" - }, - { - "source": 54, - "target": 4, - "overhead": [ - { - "field": "num_variables", - "formula": "num_vars + num_clauses + 1" - }, - { - "field": "num_assignments", - "formula": "num_clauses + 2" - } - ], - "doc_path": "rules/sat_circuitsat/index.html" - }, - { - "source": 54, - "target": 17, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_vars + num_literals" - }, - { - "field": "num_edges", - "formula": "num_vars + num_literals" - } - ], - "doc_path": "rules/sat_coloring/index.html" - }, - { - "source": 54, - "target": 22, - "overhead": [ - { - "field": "num_clauses", - "formula": "4 * num_clauses + num_literals" - }, - { - "field": "num_vars", - "formula": "num_vars + 3 * num_clauses + num_literals" - } - ], - "doc_path": "rules/sat_ksat/index.html" - }, - { - "source": 54, - "target": 32, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_literals" - }, - { - "field": "num_edges", - "formula": "num_literals^2" - } - ], - "doc_path": "rules/sat_maximumindependentset/index.html" - }, - { - "source": 54, - "target": 41, - "overhead": [ - { - "field": "num_vertices", - "formula": "3 * num_vars + num_clauses" - }, - { - "field": "num_edges", - "formula": "3 * num_vars + num_literals" - } - ], - "doc_path": "rules/sat_minimumdominatingset/index.html" - }, - { - "source": 57, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_spins" - } - ], - "doc_path": "rules/spinglass_qubo/index.html" - }, - { - "source": 58, - "target": 27, - "overhead": [ - { - "field": "num_vertices", - "formula": "num_spins" - }, - { - "field": "num_edges", - "formula": "num_interactions" - } - ], - "doc_path": "rules/spinglass_maxcut/index.html" - }, - { - "source": 58, - "target": 57, - "overhead": [ - { - "field": "num_spins", - "formula": "num_spins" - }, - { - "field": "num_interactions", - "formula": "num_interactions" - } - ], - "doc_path": "rules/spinglass_casts/index.html" - }, - { - "source": 63, - "target": 13, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2 + 2 * num_vertices * num_edges" - }, - { - "field": "num_constraints", - "formula": "num_vertices^3 + -1 * 1 * num_vertices^2 + 2 * num_vertices + 4 * num_vertices * num_edges" - } - ], - "doc_path": "rules/travelingsalesman_ilp/index.html" - }, - { - "source": 63, - "target": 52, - "overhead": [ - { - "field": "num_vars", - "formula": "num_vertices^2" - } - ], - "doc_path": "rules/travelingsalesman_qubo/index.html" - } - ] -} \ No newline at end of file diff --git a/src/unit_tests/trait_consistency.rs b/src/unit_tests/trait_consistency.rs deleted file mode 100644 index 11c3a9be7..000000000 --- a/src/unit_tests/trait_consistency.rs +++ /dev/null @@ -1,288 +0,0 @@ -use crate::models::algebraic::*; -use crate::models::formula::*; -use crate::models::graph::*; -use crate::models::misc::*; -use crate::models::set::*; -use crate::topology::{BipartiteGraph, DirectedGraph, SimpleGraph}; -use crate::traits::Problem; -use crate::variant::K3; - -fn check_problem_trait(problem: &P, name: &str) { - let dims = problem.dims(); - assert!( - !dims.is_empty() || name.contains("empty"), - "{} should have dimensions", - name - ); - for d in &dims { - assert!( - *d >= 1, - "{} should have at least 1 choice per dimension", - name - ); - } -} - -#[test] -fn test_all_problems_implement_trait_correctly() { - check_problem_trait( - &MaximumIndependentSet::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MaximumIndependentSet", - ); - check_problem_trait( - &MinimumVertexCover::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MinimumVertexCover", - ); - check_problem_trait( - &MaxCut::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32]), - "MaxCut", - ); - check_problem_trait( - &KColoring::::new(SimpleGraph::new(3, vec![(0, 1)])), - "KColoring", - ); - check_problem_trait( - &MinimumDominatingSet::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MinimumDominatingSet", - ); - check_problem_trait( - &MaximalIS::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32; 3]), - "MaximalIS", - ); - check_problem_trait( - &MaximumMatching::new(SimpleGraph::new(3, vec![(0, 1)]), vec![1i32]), - "MaximumMatching", - ); - check_problem_trait( - &SteinerTree::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 2], - vec![0, 2], - ), - "SteinerTree", - ); - check_problem_trait( - &Satisfiability::new(3, vec![CNFClause::new(vec![1])]), - "SAT", - ); - check_problem_trait( - &SpinGlass::new(3, vec![((0, 1), 1.0)], vec![0.0; 3]), - "SpinGlass", - ); - check_problem_trait(&QUBO::from_matrix(vec![vec![1.0; 3]; 3]), "QUBO"); - check_problem_trait( - &MinimumSetCovering::::new(3, vec![vec![0, 1]]), - "MinimumSetCovering", - ); - check_problem_trait( - &MaximumSetPacking::::new(vec![vec![0, 1]]), - "MaximumSetPacking", - ); - check_problem_trait( - &ExactCoverBy3Sets::new(6, vec![[0, 1, 2], [3, 4, 5]]), - "ExactCoverBy3Sets", - ); - check_problem_trait( - &SetBasis::new(3, vec![vec![0, 1], vec![1, 2]], 2), - "SetBasis", - ); - check_problem_trait(&PaintShop::new(vec!["a", "a"]), "PaintShop"); - check_problem_trait(&BMF::new(vec![vec![true]], 1), "BMF"); - check_problem_trait( - &BicliqueCover::new(BipartiteGraph::new(2, 2, vec![(0, 0)]), 1), - "BicliqueCover", - ); - check_problem_trait(&Factoring::new(6, 2, 2), "Factoring"); - - let circuit = Circuit::new(vec![Assignment::new( - vec!["x".to_string()], - BooleanExpr::constant(true), - )]); - check_problem_trait(&CircuitSAT::new(circuit), "CircuitSAT"); - check_problem_trait( - &MinimumFeedbackArcSet::new( - DirectedGraph::new(3, vec![(0, 1), (1, 2), (2, 0)]), - vec![1i32; 3], - ), - "MinimumFeedbackArcSet", - ); - check_problem_trait( - &MultipleChoiceBranching::new( - DirectedGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 2], - vec![vec![0], vec![1]], - 1, - ), - "MultipleChoiceBranching", - ); - check_problem_trait( - &DirectedTwoCommodityIntegralFlow::new( - DirectedGraph::new(4, vec![(0, 1), (1, 2), (2, 3)]), - vec![1; 3], - 0, - 3, - 0, - 3, - 1, - 1, - ), - "DirectedTwoCommodityIntegralFlow", - ); - check_problem_trait( - &MinimumSumMulticenter::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 3], - vec![1i32; 2], - 1, - ), - "MinimumSumMulticenter", - ); - check_problem_trait( - &HamiltonianPath::new(SimpleGraph::new(3, vec![(0, 1), (1, 2)])), - "HamiltonianPath", - ); - check_problem_trait( - &UndirectedTwoCommodityIntegralFlow::new( - SimpleGraph::new(4, vec![(0, 2), (1, 2), (2, 3)]), - vec![1, 1, 2], - 0, - 3, - 1, - 3, - 1, - 1, - ), - "UndirectedTwoCommodityIntegralFlow", - ); - check_problem_trait( - &LengthBoundedDisjointPaths::new( - SimpleGraph::new(4, vec![(0, 1), (1, 3), (0, 2), (2, 3)]), - 0, - 3, - 2, - 2, - ), - "LengthBoundedDisjointPaths", - ); - check_problem_trait( - &OptimalLinearArrangement::new(SimpleGraph::new(3, vec![(0, 1), (1, 2)]), 3), - "OptimalLinearArrangement", - ); - check_problem_trait( - &IsomorphicSpanningTree::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2), (0, 2)]), - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - ), - "IsomorphicSpanningTree", - ); - check_problem_trait( - &ShortestCommonSupersequence::new(2, vec![vec![0, 1], vec![1, 0]], 3), - "ShortestCommonSupersequence", - ); - check_problem_trait( - &FlowShopScheduling::new(2, vec![vec![1, 2], vec![3, 4]], 10), - "FlowShopScheduling", - ); - check_problem_trait( - &MinimumTardinessSequencing::new(3, vec![2, 3, 1], vec![(0, 2)]), - "MinimumTardinessSequencing", - ); -} - -#[test] -fn test_direction() { - use crate::traits::OptimizationProblem; - use crate::types::Direction; - - // Minimization problems - assert_eq!( - MinimumVertexCover::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Minimize - ); - assert_eq!( - MinimumDominatingSet::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Minimize - ); - assert_eq!( - MinimumSetCovering::::new(2, vec![vec![0, 1]]).direction(), - Direction::Minimize - ); - assert_eq!( - PaintShop::new(vec!["a", "a"]).direction(), - Direction::Minimize - ); - assert_eq!( - QUBO::from_matrix(vec![vec![1.0]]).direction(), - Direction::Minimize - ); - assert_eq!( - SpinGlass::new(1, vec![], vec![0.0]).direction(), - Direction::Minimize - ); - assert_eq!( - BMF::new(vec![vec![true]], 1).direction(), - Direction::Minimize - ); - assert_eq!(Factoring::new(6, 2, 2).direction(), Direction::Minimize); - assert_eq!( - MinimumTardinessSequencing::new(3, vec![2, 3, 1], vec![(0, 2)]).direction(), - Direction::Minimize - ); - assert_eq!( - BicliqueCover::new(BipartiteGraph::new(2, 2, vec![(0, 0)]), 1).direction(), - Direction::Minimize - ); - assert_eq!( - MinimumFeedbackArcSet::new( - DirectedGraph::new(3, vec![(0, 1), (1, 2), (2, 0)]), - vec![1i32; 3] - ) - .direction(), - Direction::Minimize - ); - assert_eq!( - MinimumSumMulticenter::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 3], - vec![1i32; 2], - 1 - ) - .direction(), - Direction::Minimize - ); - assert_eq!( - SteinerTree::new( - SimpleGraph::new(3, vec![(0, 1), (1, 2)]), - vec![1i32; 2], - vec![0, 2] - ) - .direction(), - Direction::Minimize - ); - - // Maximization problems - assert_eq!( - MaximumIndependentSet::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximalIS::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Maximize - ); - assert_eq!( - MaxCut::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximumMatching::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximumSetPacking::::new(vec![vec![0]]).direction(), - Direction::Maximize - ); - assert_eq!( - MaximumClique::new(SimpleGraph::new(2, vec![(0, 1)]), vec![1i32; 2]).direction(), - Direction::Maximize - ); -}