Gonality Game Module
Combinatorial tools for chip firing and gonality studies.
This module provides functions for parking functions, independent sets, treewidth calculations, and scramble numbers as mentioned in the academic literature.
- chipfiring.CFCombinatorics.is_parking_function(sequence: List[int], n: int | None = None) bool[source]
Check if a sequence is a parking function.
A parking function of length n is a sequence (a1, a2, …, an) where ai ∈ {1, 2, …, n} such that if we sort the sequence in non-decreasing order to get (b1, b2, …, bn), then bi ≤ i for all i.
- Parameters:
sequence – The sequence to test
n – Length constraint (if None, uses len(sequence))
- Returns:
True if sequence is a parking function
- Return type:
Examples
>>> is_parking_function([1, 1, 2]) True >>> is_parking_function([1, 3, 2]) False >>> is_parking_function([2, 1, 1]) True
- chipfiring.CFCombinatorics.generate_parking_functions(n: int) List[List[int]][source]
Generate all parking functions of length n.
- Parameters:
n – Length of parking functions to generate
- Returns:
All parking functions of length n
- Return type:
List[List[int]]
Examples
>>> funcs = generate_parking_functions(2) >>> len(funcs) 3 >>> sorted(funcs) [[1, 1], [1, 2], [2, 1]]
- chipfiring.CFCombinatorics.parking_function_count(n: int) int[source]
Return the number of parking functions of length n.
The number of parking functions of length n is (n+1)^(n-1).
- Parameters:
n – Length of parking functions
- Returns:
Number of parking functions of length n
- Return type:
Examples
>>> parking_function_count(1) 1 >>> parking_function_count(2) 3 >>> parking_function_count(3) 16
- chipfiring.CFCombinatorics.is_connected(graph: CFGraph) bool[source]
Check if a graph is connected.
- Parameters:
graph – The graph to check
- Returns:
True if graph is connected
- Return type:
- chipfiring.CFCombinatorics.maximal_independent_sets(graph: CFGraph) List[Set[str]][source]
Find all maximal independent sets in a graph.
An independent set is a set of vertices with no edges between them. A maximal independent set cannot be extended by adding another vertex.
- Parameters:
graph – The graph to analyze
- Returns:
List of maximal independent sets (vertex names)
- Return type:
List[Set[str]]
Examples
>>> vertices = {"0", "1", "2"} >>> edges = [("0", "1", 1)] >>> graph = CFGraph(vertices, edges) >>> mis = maximal_independent_sets(graph) >>> len(mis) >= 1 True
- chipfiring.CFCombinatorics.independence_number(graph: CFGraph) int[source]
Compute the independence number (size of largest independent set).
- Parameters:
graph – The graph to analyze
- Returns:
The independence number
- Return type:
Examples
>>> vertices = {"0", "1", "2"} >>> edges = [("0", "1", 1)] >>> graph = CFGraph(vertices, edges) >>> independence_number(graph) >= 1 True
- chipfiring.CFCombinatorics.minimum_degree(graph: CFGraph) int[source]
Compute the minimum degree of a graph.
This provides a simple lower bound on treewidth and gonality: δ(G) ≤ tw(G) ≤ gon(G)
- Parameters:
graph – The graph to analyze
- Returns:
The minimum degree
- Return type:
Examples
>>> vertices = {"0", "1", "2"} >>> edges = [("0", "1", 1), ("1", "2", 1), ("0", "2", 1)] >>> graph = CFGraph(vertices, edges) >>> minimum_degree(graph) 2
- chipfiring.CFCombinatorics.maximum_degree(graph: CFGraph) int[source]
Compute the maximum degree of a graph.
- Parameters:
graph – The graph to analyze
- Returns:
The maximum degree
- Return type:
Examples
>>> vertices = {"0", "1", "2", "3"} >>> edges = [("0", "1", 1), ("1", "2", 1), ("2", "3", 1)] >>> graph = CFGraph(vertices, edges) >>> maximum_degree(graph) 2
- chipfiring.CFCombinatorics.is_bipartite(graph: CFGraph) bool[source]
Check if a graph is bipartite.
- Parameters:
graph – The graph to check
- Returns:
True if the graph is bipartite
- Return type:
Examples
>>> vertices = {"0", "1", "2", "3"} >>> edges = [("0", "2", 1), ("0", "3", 1), ("1", "2", 1), ("1", "3", 1)] >>> graph = CFGraph(vertices, edges) >>> is_bipartite(graph) True
- chipfiring.CFCombinatorics.bramble_order_lower_bound(graph: CFGraph) int[source]
Compute a lower bound on the maximum bramble order.
Based on the theory from “Chip-firing on the Platonic solids”, this provides a lower bound on treewidth and thus gonality.
- Parameters:
graph – The graph to analyze
- Returns:
Lower bound on maximum bramble order
- Return type:
Examples
>>> vertices = {"0", "1", "2"} >>> edges = [("0", "1", 1), ("1", "2", 1), ("0", "2", 1)] >>> graph = CFGraph(vertices, edges) >>> bramble_order_lower_bound(graph) >= 1 True
- chipfiring.CFCombinatorics.complete_multipartite_gonality(partition_sizes: List[int]) int[source]
Compute the exact gonality of a complete multipartite graph K_{n1,n2,…,nk}.
For k >= 2 partitions: gon(K_{n1,n2,…,nk}) = n - min(ni) where min(ni) is the smallest part. For k = 1 partition: gon(K_n) = n - 1 (complete graph gonality).
- Parameters:
partition_sizes – List of partition sizes
- Returns:
The exact gonality
- Return type:
Examples
>>> complete_multipartite_gonality([2, 2, 2]) # Octahedron K_{2,2,2} 4 >>> complete_multipartite_gonality([3, 4]) # K_{3,4} 4 >>> complete_multipartite_gonality([5]) # K_5 (complete graph) 4
- chipfiring.CFCombinatorics.octahedron_independence_number() int[source]
Compute the independence number of the octahedron (K_{2,2,2}).
As proven in the theory, the octahedron has independence number 2.
- Returns:
The independence number (2)
- Return type:
- chipfiring.CFCombinatorics.octahedron_bramble_construction() Dict[str, any][source]
Construct the bramble of order 5 on the octahedron as described in the theory.
This bramble proves that the treewidth of the octahedron is at least 4.
- Returns:
Information about the bramble construction
- Return type:
Dict[str, any]
- chipfiring.CFCombinatorics.treewidth_upper_bound(graph: CFGraph) int[source]
Compute an upper bound for the treewidth of a graph.
This uses a simple greedy elimination ordering to get an upper bound. The actual treewidth may be smaller.
- Parameters:
graph – The graph to analyze
- Returns:
Upper bound on treewidth
- Return type:
Examples
>>> vertices = {"0", "1", "2", "3"} >>> edges = [("0", "1", 1), ("1", "2", 1), ("2", "3", 1), ("3", "0", 1)] >>> graph = CFGraph(vertices, edges) >>> treewidth_upper_bound(graph) >= 1 True
- chipfiring.CFCombinatorics.scramble_number_upper_bound(graph: CFGraph) int[source]
Compute an upper bound for the scramble number of a graph.
The scramble number is related to gonality and chip firing dynamics. This provides a theoretical upper bound based on graph structure.
- Parameters:
graph – The graph to analyze
- Returns:
Upper bound on scramble number
- Return type:
Examples
>>> vertices = {"0", "1", "2"} >>> edges = [("0", "1", 1), ("1", "2", 1)] >>> graph = CFGraph(vertices, edges) >>> scramble_number_upper_bound(graph) >= 1 True
- chipfiring.CFCombinatorics.genus_upper_bound(graph: CFGraph) int[source]
Compute an upper bound for the genus of a graph.
The genus is related to gonality through various inequalities.
- Parameters:
graph – The graph to analyze
- Returns:
Upper bound on genus
- Return type:
Examples
>>> vertices = {"0", "1", "2", "3"} >>> edges = [("0", "1", 1), ("1", "2", 1), ("2", "3", 1), ("3", "0", 1)] >>> graph = CFGraph(vertices, edges) >>> genus_upper_bound(graph) >= 0 True
- chipfiring.CFCombinatorics.gonality_theoretical_bounds(graph: CFGraph) Dict[str, int][source]
Compute various theoretical bounds for gonality.
This includes bounds from independence number, treewidth, bramble order, and minimum degree as described in the octahedron theory.
- Parameters:
graph – The graph to analyze
- Returns:
Dictionary of bound names to values
- Return type:
Examples
>>> vertices = {"0", "1", "2", "3"} >>> edges = [("0", "1", 1), ("1", "2", 1), ("2", "3", 1), ("3", "0", 1)] >>> graph = CFGraph(vertices, edges) >>> bounds = gonality_theoretical_bounds(graph) >>> 'independence_upper_bound' in bounds True
- chipfiring.CFCombinatorics.analyze_graph_properties(graph: CFGraph) Dict[str, any][source]
Analyze various combinatorial properties relevant to gonality.
- Parameters:
graph – The graph to analyze
- Returns:
Dictionary of properties and their values
- Return type:
Dict[str, any]
Examples
>>> vertices = {"0", "1", "2"} >>> edges = [("0", "1", 1), ("1", "2", 1)] >>> graph = CFGraph(vertices, edges) >>> props = analyze_graph_properties(graph) >>> 'num_vertices' in props True
- chipfiring.CFCombinatorics.graph_complement(graph: CFGraph) CFGraph[source]
Compute the complement of a graph.
- Parameters:
graph – The input graph
- Returns:
The complement graph
- Return type:
- chipfiring.CFCombinatorics.icosahedron_independence_number() int[source]
Compute the independence number of the icosahedron.
As stated in “Chip-firing on the Platonic solids” by Beougher et al., the icosahedron has independence number α(I) = 3.
- Returns:
The independence number (3)
- Return type:
- chipfiring.CFCombinatorics.icosahedron_2_uniform_scramble() Dict[str, any][source]
Implement the 2-uniform scramble construction for the icosahedron.
From the paper: “The icosahedron has a 2-uniform scramble with ||S|| = 8.” This implements the theoretical construction showing the scramble number.
- Returns:
Dict containing scramble construction details
- chipfiring.CFCombinatorics.icosahedron_screewidth_bound() Dict[str, int][source]
Compute screewidth bounds for the icosahedron.
From the paper: “scw(I) ≤ 8” where scw is the screewidth. The screewidth is related to the scramble number.
- Returns:
Dict containing screewidth bounds
- chipfiring.CFCombinatorics.icosahedron_lemma_3_subgraph_bounds() Dict[str, any][source]
Implement Lemma 3 for subgraph outdegree bounds on the icosahedron.
This lemma provides bounds on the outdegree of effective divisors in subgraphs of the icosahedron, contributing to gonality analysis.
- Returns:
Dict containing Lemma 3 analysis
- chipfiring.CFCombinatorics.icosahedron_dhars_burning_algorithm() Dict[str, any][source]
Implement Dhar’s burning algorithm proof for icosahedron gonality.
This demonstrates the debt-free divisor analysis that proves the icosahedron gonality is exactly 9.
- Returns:
Dict containing Dhar’s algorithm analysis
- chipfiring.CFCombinatorics.icosahedron_egg_cut_number() Dict[str, int][source]
Compute the egg-cut number for the icosahedron.
The egg-cut number is related to scramble theory and provides another perspective on gonality bounds.
- Returns:
Dict containing egg-cut number analysis
- chipfiring.CFCombinatorics.icosahedron_hitting_set_analysis() Dict[str, any][source]
Analyze hitting sets for the icosahedron scramble construction.
This implements the hitting set computations that appear in the scramble number analysis.
- Returns:
Dict containing hitting set analysis
- chipfiring.CFCombinatorics.icosahedron_gonality_theoretical_bounds() Dict[str, int][source]
Compute comprehensive theoretical bounds for icosahedron gonality.
This integrates all the theoretical results to show that gonality = 9.
- Returns:
Dict containing all theoretical bounds
Gonality calculation and gonality games for chip-firing graphs.
This module provides functionality for computing graph gonality and playing gonality games, based on the mathematical framework described in “Chip-firing on the Platonic solids: A primer for studying graph gonality” by Beougher et al.
The gonality of a graph G, denoted gon(G), is the minimum number of chips Player A needs to guarantee a win in the Gonality Game, regardless of where Player B places the -1 chip.
- class chipfiring.CFGonality.GonalityGameResult(player_a_wins: bool, initial_placement: CFDivisor, player_b_placement: str, final_divisor: CFDivisor, winnability: bool, winning_sequence: List[str] | None = None)[source]
Bases:
objectRepresents the result of a single gonality game instance.
- Variables:
player_a_wins (bool) – True if Player A wins, False if Player B wins
initial_placement (CFDivisor) – Player A’s initial chip placement
player_b_placement (str) – Vertex name where Player B placed the -1 chip
final_divisor (CFDivisor) – The divisor after Player B’s move
winnability (bool) – Whether the final divisor is winnable via chip-firing
winning_sequence (Optional[List[str]]) – Sequence of vertices fired to win (if applicable)
- class chipfiring.CFGonality.GonalityResult[source]
Bases:
objectRepresents the result of a gonality calculation.
- Variables:
gonality (int) – The computed gonality value
winning_strategies (List[CFDivisor]) – List of N-chip placements that guarantee Player A wins
logs (List[str]) – Detailed logs of the calculation process
verification_games (Dict[int, List[GonalityGameResult]]) – Game results for verification
- class chipfiring.CFGonality.CFGonality(graph: CFGraph)[source]
Bases:
objectMain class for gonality calculations and gonality games.
- __init__(graph: CFGraph)[source]
Initialize gonality calculator for a given graph.
- Parameters:
graph – The CFGraph to analyze
- play_gonality_game(n_chips: int, player_a_placement: CFDivisor, player_b_vertex: str, verbose: bool = False) GonalityGameResult[source]
Play a single instance of the Gonality Game.
- Parameters:
n_chips – Number of chips Player A is allowed to place
player_a_placement – Player A’s chip placement (must have total degree n_chips)
player_b_vertex – Vertex name where Player B places the -1 chip
verbose – Whether to include detailed winning sequence
- Returns:
Complete result of the game instance
- Return type:
- Raises:
ValueError – If player_a_placement doesn’t have exactly n_chips total degree
- _find_winning_sequence(divisor: CFDivisor) List[str][source]
Find a sequence of chip-firing moves that wins the Dollar Game. This is a simplified implementation - a full implementation would use more sophisticated algorithms.
- test_n_chip_strategy(n_chips: int, placement: CFDivisor) Tuple[bool, List[str]][source]
Test if a given N-chip placement guarantees Player A wins against all possible Player B moves.
- Parameters:
n_chips – Number of chips (for validation)
placement – Player A’s chip placement strategy
- Returns:
Tuple of (strategy_works, losing_vertices) where strategy_works is True if the placement beats all Player B responses, and losing_vertices lists vertices where Player B can place -1 to win
- find_all_n_chip_strategies(n_chips: int, max_strategies: int | None = None) List[CFDivisor][source]
Find all N-chip placements that guarantee Player A wins the Gonality Game.
- Parameters:
n_chips – Number of chips Player A can place
max_strategies – Maximum number of strategies to find (None for all)
- Returns:
List of winning CFDivisor placements
- compute_gonality(max_gonality: int | None = None, find_strategies: bool = True) GonalityResult[source]
Compute the gonality of the graph.
The gonality is the minimum number N such that Player A has a winning strategy in the Gonality Game with N chips.
- Parameters:
max_gonality – Maximum gonality to check (defaults to number of vertices)
find_strategies – Whether to find and store winning strategies
- Returns:
Complete result including gonality value and winning strategies
- Return type:
- verify_gonality_bounds(suspected_gonality: int) Tuple[bool, bool, List[str]][source]
Verify gonality bounds by checking that suspected_gonality works but suspected_gonality-1 doesn’t.
- Parameters:
suspected_gonality – The suspected gonality value to verify
- Returns:
Tuple of (upper_bound_verified, lower_bound_verified, messages) where upper_bound_verified means suspected_gonality works, and lower_bound_verified means suspected_gonality-1 doesn’t work
- chipfiring.CFGonality.gonality(graph: CFGraph, max_gonality: int | None = None, find_strategies: bool = True) GonalityResult[source]
Compute the gonality of a graph.
The gonality of a graph G is the minimum number of chips Player A needs to guarantee winning the Gonality Game, regardless of Player B’s strategy.
Algorithm: 1. For N = 1, 2, 3, …, find all possible ways Player A can place N chips 2. For each placement, test if Player A wins against all possible Player B responses 3. Return the minimum N for which Player A has a guaranteed winning strategy
- Parameters:
graph – The CFGraph to analyze
max_gonality – Maximum gonality to check (defaults to number of vertices)
find_strategies – Whether to find and return winning strategies
- Returns:
Object containing gonality value, winning strategies, and logs
- Return type:
Example
>>> from chipfiring import CFGraph, gonality >>> # Create a simple triangle graph >>> vertices = {"A", "B", "C"} >>> edges = [("A", "B", 1), ("B", "C", 1), ("A", "C", 1)] >>> graph = CFGraph(vertices, edges) >>> result = gonality(graph) >>> print(f"Gonality: {result.gonality}") >>> print(f"Winning strategies: {len(result.winning_strategies)}")
- chipfiring.CFGonality.play_gonality_game(graph: CFGraph, n_chips: int, player_a_placement: CFDivisor, player_b_vertex: str, verbose: bool = False) GonalityGameResult[source]
Play a single instance of the Gonality Game.
Game Rules: 1. Player A places n_chips on the vertices of the graph 2. Player B places -1 chip on any vertex 3. Player A wins if they can eliminate all debt through chip-firing moves
- Parameters:
graph – The CFGraph on which to play
n_chips – Number of chips Player A is allowed
player_a_placement – Player A’s chip placement
player_b_vertex – Vertex where Player B places -1 chip
verbose – Whether to include detailed winning information
- Returns:
Complete result of the game
- Return type:
Example
>>> from chipfiring import CFGraph, CFDivisor, play_gonality_game >>> vertices = {"A", "B", "C"} >>> edges = [("A", "B", 1), ("B", "C", 1), ("A", "C", 1)] >>> graph = CFGraph(vertices, edges) >>> placement = CFDivisor(graph, [("A", 2), ("B", 0), ("C", 0)]) >>> result = play_gonality_game(graph, 2, placement, "B") >>> print(f"Player A wins: {result.player_a_wins}")
Enhanced Dhar’s burning algorithm specifically optimized for gonality games.
This module extends the standard Dhar’s burning algorithm with specialized functions for gonality calculations, including optimizations for finding winning strategies and determining gonality bounds efficiently.
- class chipfiring.CFGonalityDhar.GonalityDharAlgorithm(graph: CFGraph, initial_divisor: CFDivisor, q_name: str)[source]
Bases:
DharAlgorithmEnhanced Dhar’s algorithm specialized for gonality game computations.
This class extends the standard DharAlgorithm with methods specifically designed for efficiency in gonality calculations, including batch testing of strategies and optimized burning processes.
- __init__(graph: CFGraph, initial_divisor: CFDivisor, q_name: str)[source]
Initialize the enhanced Dhar algorithm for gonality games.
- Parameters:
graph – A CFGraph object representing the graph
initial_divisor – A CFDivisor object representing the initial chip configuration
q_name – The name of the distinguished vertex (fire source)
- test_strategy_batch(strategies: List[List[str]]) List[bool][source]
Test multiple strategies efficiently using cached burning results.
- Parameters:
strategies – List of strategies, where each strategy is a list of vertex names
- Returns:
Results for each strategy (True if winning, False otherwise)
- Return type:
List[bool]
- test_strategy(strategy: List[str]) bool[source]
Test if a given strategy is winning. A strategy is winning if, after placing chips according to the strategy and having Player B place -1 at q, the resulting configuration is winnable using the same criterion as the EWD algorithm.
- Parameters:
strategy – List of vertex names representing the strategy (chips added to V-{q})
- Returns:
True if the strategy is winning, False otherwise
- Return type:
- _enhanced_burning(config: CFConfig) Set[str][source]
Enhanced burning algorithm optimized for gonality calculations.
- Parameters:
config – CFConfig object with the chip configuration
- Returns:
Names of all burnt vertices (excluding q)
- Return type:
Set[str]
- _should_burn(vertex: Vertex, burnt_vertices: Set[str], config: CFConfig) bool[source]
Determine if a vertex should burn given current burnt set.
- Parameters:
vertex – The vertex to test
burnt_vertices – Set of currently burnt vertex names
config – The chip configuration
- Returns:
True if vertex should burn
- Return type:
- _config_to_tuple(config: CFConfig) tuple[source]
Convert a configuration to a hashable tuple for caching.
- Parameters:
config – CFConfig object
- Returns:
Hashable representation of the configuration
- Return type:
- find_minimal_winning_strategies(max_chips: int) List[List[str]][source]
Find all minimal winning strategies using at most max_chips chips.
- Parameters:
max_chips – Maximum number of chips to use
- Returns:
List of minimal winning strategies
- Return type:
List[List[str]]
- _is_subset_multiset(subset: List[str], superset: List[str]) bool[source]
Check if one multiset is a subset of another.
- Parameters:
subset – Potential subset as list
superset – Potential superset as list
- Returns:
True if subset is a subset of superset
- Return type:
- chipfiring.CFGonalityDhar.enhanced_dhar_gonality_test(graph: CFGraph, q_vertex_name: str, max_gonality: int | None = None) Tuple[int, List[List[str]]][source]
Use enhanced Dhar’s algorithm to compute gonality and find winning strategies. This computes the smallest k such that placing k chips on V-{q} results in a configuration that is winnable after -1 chip is placed on q.
- chipfiring.CFGonalityDhar.batch_gonality_analysis(graphs: List[Tuple[CFGraph, str]], max_gonality: int | None = None) Dict[str, Dict][source]
Analyze gonality for multiple graphs efficiently.
- Parameters:
graphs – List of (graph, q_vertex_name) pairs
max_gonality – Maximum gonality to test for each graph
- Returns:
Results for each graph
- Return type:
Dict[str, Dict]