use std::env; use std::process; use std::fs::File; use std::io::prelude::*; use inline_python::*; fn main() -> std::io::Result<()> { let args: Vec<_> = env::args().collect(); if args.len() < 4 { println!("Need clique size, complete graph order, and output filename."); process::exit(1); } let sclique: usize = args[1].clone().to_string().parse::().unwrap(); let order: usize = args[2].clone().to_string().parse::().unwrap(); let output_name: &String = &args[3]; println!("{} {} {}", sclique, order, output_name); let mut buffer = File::create(output_name)?; let mut edges: Vec<[u32; 2]> = Vec::new(); let c = Context::new(); c.run(python! { import networkx as nx; import itertools as it G = nx.complete_graph('order); def issize(val): return len(val)<='sclique B = [c for c in list(it.takewhile(issize, nx.enumerate_all_cliques(G))) if len(c)=='sclique]; }); let cliques = c.get::>>("B"); write!(buffer, "p cnf {} {}\n", ((order * (order - 1)) / 2), 2*cliques.len())?; for clique in cliques { let mut line: String = "".to_owned(); let mut linen: String = "".to_owned(); for a in 0..sclique { for b in a+1..sclique { let edge: [u32; 2] = [clique[a], clique[b]]; let result = edges.iter().position(|&val| val==edge); let eindex = match result { Some(val) => val+1, None => { edges.push(edge); println!("{} = {:?}", edges.len(), edge); edges.len() } }; line.push_str(&format!("{} ", eindex).to_owned()); linen.push_str(&format!("-{} ", eindex).to_owned()); } } line.push_str("0\n"); linen.push_str("0\n"); write!(buffer, "{}", line)?; write!(buffer, "{}", linen)?; } Ok(()) }