Commuter

A tool for testing commutative diagrams

As an example, the following tests associativity on a given (subset of) the integers:

```rs

use itertools::Itertools; use commuter::diagram::{Diagram, Set, Map, diagram_commutes, CommutativeDiagramResult};

let generating_integers: Vec = (0..20).collect();

let leftadd = |(a, b, c): &(i32, i32, i32)| (a + b, *c); let rightadd = |(a, b, c): &(i32, i32, i32)| (*a, b + c);

// Build the sets (triplets, pairs, integers) so that summing operations can be well-defined later let triplets: Vec<(i32, i32, i32)> = (generatingintegers) .clone() .iter() .cartesianproduct(generatingintegers.clone()) .cartesianproduct(generating_integers.clone().iter()) .map(|((a, b), c)| (*a, b, *c)) .collect();

// Construct the diagram let diagram = Diagram::new( vec[ Set::new(triplets), // This set gets some generating elements, on which the diagram will be tested Set::<(i32, i32)>::newnogeneratingset(), // We only test on pairs that are generated by the given maps from the triplets, so no explicit elements are added here Set::new(vec[(5, 3), (100, 100)]), // We can also insert some additional generating elements into an intermediate set Set::::newnogeneratingset(), ], vec[ Map::new(0, 1, leftadd, "(+,id)"), Map::new(0, 2, rightadd, "(id,+)"), Map::new(2, 3, |(a, b): &(i32, i32)| a + b, "(+)"), Map::new(1, 3, |(a, b): &(i32, i32)| a + b, "(+)"), ], );

assert!(match diagram_commutes(&diagram).unwrap() { CommutativeDiagramResult::Commutes => true, CommutativeDiagramResult::DoesNotCommute(reason) => panic("{}", reason), });

```