mod undirected_graph; use std::collections::HashMap; use std::env; use std::process; use undirected_graph::UndirectedGraph; fn main() { let args: Vec<String> = env::args().collect(); if args.len() != 2 { eprintln!("Usage: {} <number-of-spokes>", args[0]); process::exit(1); } let num_spokes_maybe: Result<usize, std::num::ParseIntError> = args[1].parse::<usize>(); if num_spokes_maybe.is_err() { eprintln!("Error parsing the first argument as number-of-spokes."); process::exit(1); } let num_spokes: usize = num_spokes_maybe.unwrap(); if num_spokes < 2 { eprintln!("A wheel graph without tadpoles must have at least two spokes."); process::exit(1); } let mut cocycle_graphs: Vec<UndirectedGraph> = vec![]; let mut cocycle_graph_index: HashMap<UndirectedGraph, usize> = HashMap::new(); let mut cocycle_graph_vertex_orbits: Vec<HashMap<usize, usize>> = vec![]; let mut cocycle_differential_graphs: Vec<UndirectedGraph> = vec![]; let mut cocycle_differential_graph_index: HashMap<UndirectedGraph, usize> = HashMap::new(); let mut cocycle_differential_graph_edge_orbits: Vec<Vec<usize>> = vec![]; // NOTE: Start with the normal form of the wheel graph. let wheel_graph: UndirectedGraph = UndirectedGraph::wheel_graph(num_spokes); let (wheel_graph_sign, wheel_graph_normal, wheel_graph_vertex_orbits, _) = wheel_graph.normal_form(false); if wheel_graph_sign == 0 { eprintln!("The {}-wheel graph has an automorphism that induces an odd permutation on edges, so it is equal to zero in the graph complex.", num_spokes); process::exit(1); } cocycle_graphs.push(wheel_graph_normal.clone()); cocycle_graph_index.insert(wheel_graph_normal.clone(), 0); cocycle_graph_vertex_orbits.push(wheel_graph_vertex_orbits); println!("? ? M"); let mut g_idx: usize = 0; loop { // dbg!(&g_idx); let dg_data: HashMap<UndirectedGraph, (i64, Vec<usize>)> = cocycle_graphs[g_idx].expanding_differential(&cocycle_graph_vertex_orbits[g_idx]); for (dg, (c, dg_edge_orbits)) in dg_data { // eprintln!("{:?}", dg); let dg_idx: usize = if let Some(&idx) = cocycle_differential_graph_index.get(&dg) { // eprintln!("old graph in differential: {}", idx); idx } else { let idx: usize = cocycle_differential_graphs.len(); // eprintln!("new graph in differential: {}", idx); cocycle_differential_graphs.push(dg.clone()); cocycle_differential_graph_edge_orbits.push(dg_edge_orbits.clone()); cocycle_differential_graph_index.insert(dg.clone(), idx); idx }; // TODO: Make the output lexicographically ordered? Strictly speaking this is not the SMS format right now. println!("{} {} {}", dg_idx + 1, g_idx + 1, c); let cg_data: HashMap<UndirectedGraph, HashMap<usize, usize>> = dg.contractions(&dg_edge_orbits); for (cg, cg_vertex_orbits) in cg_data { // eprintln!("{:?}", cg); if !cocycle_graph_index.contains_key(&cg) { let idx: usize = cocycle_graphs.len(); // eprintln!("new graph in cocycle: {}", idx); cocycle_graphs.push(cg.clone()); cocycle_graph_vertex_orbits.push(cg_vertex_orbits); cocycle_graph_index.insert(cg.clone(), idx); } } } g_idx += 1; if g_idx >= cocycle_graphs.len() { break; } } println!("0 0 0"); println!("# Move this line to the top:"); println!( "{} {} M", cocycle_differential_graphs.len(), cocycle_graphs.len() ); eprintln!( "Matrix size: {} x {}", cocycle_differential_graphs.len(), cocycle_graphs.len() ); // TODO: Also output the ordered bases of graphs. }