// use std::io::{self, BufRead}; use rayon::prelude::*; use sqlx::migrate::MigrateDatabase; use std::collections::HashMap; // use std::sync::{Arc, Mutex}; use std::time::Instant; use tokio; mod graph; use crate::graph::Graph; mod theorems; use crate::theorems::{basic, forbidden, toughness}; mod geng; use crate::geng::GengIterator; struct GraphProfile { g6: String, stats: HashMap, } impl GraphProfile { pub fn new(g6: &String) -> Self { Self { g6: g6.clone(), stats: HashMap::new(), } } pub fn insert(&mut self, key: String, value: bool) { self.stats.insert(key, value); } } #[tokio::main] async fn main() -> Result<(), sqlx::Error> { dotenv::dotenv().ok(); let database_url = std::env::var("DATABASE_URL").expect("Expected DATABASE_URL in env"); if !sqlx::Sqlite::database_exists(&database_url).await? { sqlx::Sqlite::create_database(&database_url).await?; } let db = sqlx::SqlitePool::connect(&database_url).await?; let _ = sqlx::query!( "CREATE TABLE IF NOT EXISTS graphs (g6 VARCHAR NOT NULL);" ) .execute(&db) .await; let gi = GengIterator::new(5); // let mut time = 0; // let mut counters = Arc::new(Mutex::new(Counters::new())); // gi.par_bridge().for_each(|_| {}); let tasks: Vec<_> = gi .map(|g| { let db = db.clone(); tokio::spawn(async move { // counters.graphs += 1; let line = g.to_g6(); let mut profile = GraphProfile::new(&line); // let start = Instant::now(); let closure = g.get_closure(); let is_complete = closure.is_complete(); let toughness = if g.is_complete() { f64::MAX } else { g.get_toughness() }; if toughness >= 1.0 { profile.insert("tough_1".to_string(), true); } if toughness >= 2.0 { profile.insert("tough_2".to_string(), true); } let min_degree = g.min_degree() as f64; if forbidden::theorem3_1(&g) { profile.insert("t3_1".to_string(), true); println!("g6:t3_1:{}", line); } if forbidden::theorem3_2(&g) { profile.insert("t3_2".to_string(), true); println!("g6:t3_2:{}", line); } if forbidden::corollary3_5(&g) { profile.insert("c3_5".to_string(), true); println!("g6:c3_5:{}", line); } if forbidden::theorem85(&g) { profile.insert("t85".to_string(), true); println!("g6:t85:{}", line); } if forbidden::theorem86(&g) { profile.insert("t86".to_string(), true); println!("g6:t86:{}", line); } if forbidden::theorem87(&g) { profile.insert("t87".to_string(), true); println!("g6:t87:{}", line); } if forbidden::theorem88(&g) { profile.insert("t88".to_string(), true); println!("g6:t88:{}", line); } if forbidden::theorem96(&g) { profile.insert("t96".to_string(), true); println!("g6:t96:{}", line); } if forbidden::conjecture17(&g) { profile.insert("conj17".to_string(), true); println!("g6:conj17:{}", line); } if forbidden::theorem_all_2con(&g) { profile.insert("all_2c".to_string(), true); println!("g6:all_2c:{}", line); } if toughness::theorem15(&g, toughness, min_degree) { profile.insert("t15_hamiltonian".to_string(), true); println!("g6:bigalke-jung:{}", line); } if toughness::theorem25(&g, toughness, min_degree) { profile.insert("t25_hamiltonian".to_string(), true); println!("g6:bauer:{}", line); } if basic::dirac_theorem(&g) { profile.insert("dirac_hamiltonian".to_string(), true); println!("g6:dirac:{}", line); } if basic::ore_theorem(&g) { profile.insert("ore_hamiltonian".to_string(), true); println!("g6:ore:{}", line); } if basic::posa_theorem(&g) { profile.insert("posa_hamiltonian".to_string(), true); println!("g6:posa:{}", line); } if is_complete { profile.insert("bch_hamiltonian".to_string(), true); println!("g6:bondy-chvatal:{}", line); } if is_complete && false { println!("Graph: {line}\n{g}"); let components_count = g.count_components(); println!("Components count: {components_count}"); let min_degree = g.min_degree(); println!("Minimal degree: {min_degree}"); let cutset = g.max_independent_cutset(); println!("Maximal independent cutset:\n{}", cutset.graph); println!("Included vertices: {:?}", cutset.vertices); println!("Cutset cardinality: {}", cutset.cardinality); let cycle = basic::bondy_chvatal_hamiltonian_cycle(&g); print!("Hamiltonian cycle: "); let start = 0; let mut current = start; loop { print!("{}", current + 1); print!(" -> "); current = cycle[current]; if current == start { println!("{}", current + 1); break; } } } let _ = sqlx::query!("INSERT INTO graphs (g6) VALUES (?);", line) .execute(&db) .await; }) // let elapsed = start.elapsed(); // time += elapsed.as_nanos(); }) .collect(); futures::future::join_all(tasks).await; /* println!("Total count of graphs: {}", counters.graphs); println!("Count of 1-tough graphs: {}", counters.tough_1); println!("Count of 2-tough graphs: {}", counters.tough_2); println!( "Count of Dirac's Hamiltonian graphs: {}", counters.dirac_hamiltonian ); println!( "Count of Ore's Hamiltonian graphs: {}", counters.ore_hamiltonian ); println!( "Count of Posa's Hamiltonian graphs: {}", counters.posa_hamiltonian ); println!( "Count of Bondy-Chvatal Hamiltonian graphs: {}", counters.bch_hamiltonian ); println!( "Count of Theorem 15 Hamiltonian graphs: {}", counters.t15_hamiltonian ); println!( "Count of Theorem 25 Hamiltonian graphs: {}", counters.t25_hamiltonian ); println!("Time elapsed: {}s", time as f64 / 1e9); */ Ok(()) }