use network_isomorphism_solver::{
check_isomorphism, contains_subnetwork, find_automorphisms, is_isomorphic, LinkNetwork,
};
mod drug_discovery {
use super::*;
#[test]
fn test_benzene_ring_isomorphism() {
let benzene1 = LinkNetwork::from_notation(
"
C1 bonds C2
C2 bonds C3
C3 bonds C4
C4 bonds C5
C5 bonds C6
C6 bonds C1
",
);
let benzene2 = LinkNetwork::from_notation(
"
A bonds B
B bonds C
C bonds D
D bonds E
E bonds F
F bonds A
",
);
assert!(is_isomorphic(&benzene1, &benzene2));
let result = check_isomorphism(&benzene1, &benzene2);
assert!(result.is_isomorphic);
assert!(result.mapping.is_some());
assert_eq!(result.mapping.unwrap().len(), 6);
}
#[test]
fn test_different_molecular_structures() {
let benzene = LinkNetwork::from_notation(
"
C1 bonds C2
C2 bonds C3
C3 bonds C4
C4 bonds C5
C5 bonds C6
C6 bonds C1
",
);
let chain = LinkNetwork::from_notation(
"
C1 bonds C2
C2 bonds C3
C3 bonds C4
C4 bonds C5
C5 bonds C6
",
);
assert!(!is_isomorphic(&benzene, &chain));
}
#[test]
fn test_functional_group_detection() {
let molecule = LinkNetwork::from_notation(
"
C1 bonds C2
C2 bonds C3
C3 bonds O1
C3 bonds C4
C4 bonds N1
",
);
let carbonyl_pattern = LinkNetwork::from_notation(
"
carbon bonds oxygen
",
);
assert!(contains_subnetwork(&molecule, &carbonyl_pattern));
}
#[test]
fn test_molecular_symmetry() {
let mut symmetric_molecule = LinkNetwork::new();
symmetric_molecule.add_link(1, 2);
let automorphisms = find_automorphisms(&symmetric_molecule);
assert_eq!(automorphisms.len(), 2); }
#[test]
fn test_cyclopropane_isomorphism() {
let cyclopropane1 = LinkNetwork::from_notation(
"
C1 bonds C2
C2 bonds C3
C3 bonds C1
",
);
let cyclopropane2 = LinkNetwork::from_notation(
"
A bonds B
B bonds C
C bonds A
",
);
assert!(is_isomorphic(&cyclopropane1, &cyclopropane2));
let automorphisms = find_automorphisms(&cyclopropane1);
assert_eq!(automorphisms.len(), 6);
}
}
mod circuit_verification {
use super::*;
#[test]
fn test_logic_gate_equivalence() {
let circuit1 = LinkNetwork::from_notation(
"
input1 connects and_gate
input2 connects and_gate
and_gate connects output
",
);
let circuit2 = LinkNetwork::from_notation(
"
A connects X
B connects X
X connects Z
",
);
assert!(is_isomorphic(&circuit1, &circuit2));
}
#[test]
fn test_different_circuit_topologies() {
let series_circuit = LinkNetwork::from_notation(
"
input connects gate1
gate1 connects gate2
gate2 connects output
",
);
let parallel_circuit = LinkNetwork::from_notation(
"
input connects gate1
input connects gate2
gate1 connects output
gate2 connects output
",
);
assert!(!is_isomorphic(&series_circuit, ¶llel_circuit));
}
#[test]
fn test_gate_pattern_detection() {
let complex_circuit = LinkNetwork::from_notation(
"
in1 connects g1
in2 connects g1
g1 connects g2
g2 connects g3
in3 connects g3
g3 connects out
",
);
let fanin_pattern = LinkNetwork::from_notation(
"
a connects x
b connects x
",
);
assert!(contains_subnetwork(&complex_circuit, &fanin_pattern));
}
#[test]
fn test_combinational_logic() {
let and_gate1 = LinkNetwork::from_notation(
"
input1 connects gate
input2 connects gate
gate connects output
",
);
let and_gate2 = LinkNetwork::from_notation(
"
A connects X
B connects X
X connects Y
",
);
assert!(is_isomorphic(&and_gate1, &and_gate2));
let chain1 = LinkNetwork::from_notation(
"
in connects g1
g1 connects g2
g2 connects out
",
);
let chain2 = LinkNetwork::from_notation(
"
A connects B
B connects C
C connects D
",
);
assert!(is_isomorphic(&chain1, &chain2));
}
}
mod computer_vision {
use super::*;
#[test]
fn test_edge_pattern_matching() {
let image_grid = LinkNetwork::from_notation(
"
p1 adjacent p2
p2 adjacent p3
p1 adjacent p4
p2 adjacent p5
p3 adjacent p6
p4 adjacent p5
p5 adjacent p6
p4 adjacent p7
p5 adjacent p8
p6 adjacent p9
p7 adjacent p8
p8 adjacent p9
",
);
let horizontal_edge = LinkNetwork::from_notation(
"
a adjacent b
b adjacent c
",
);
assert!(contains_subnetwork(&image_grid, &horizontal_edge));
}
#[test]
fn test_corner_detection() {
let image = LinkNetwork::from_notation(
"
pixel1 adjacent pixel2
pixel2 adjacent pixel3
pixel1 adjacent pixel4
",
);
let corner_pattern = LinkNetwork::from_notation(
"
a adjacent b
b adjacent c
a adjacent d
",
);
assert!(is_isomorphic(&image, &corner_pattern));
}
#[test]
fn test_shape_matching() {
let square_shape = LinkNetwork::from_notation(
"
corner1 connects corner2
corner2 connects corner3
corner3 connects corner4
corner4 connects corner1
",
);
let rotated_square = LinkNetwork::from_notation(
"
A connects B
B connects C
C connects D
D connects A
",
);
assert!(is_isomorphic(&square_shape, &rotated_square));
let automorphisms = find_automorphisms(&square_shape);
assert_eq!(automorphisms.len(), 8);
}
#[test]
fn test_keypoint_matching() {
let keypoints1 = LinkNetwork::from_notation(
"
k1 matches k2
k2 matches k3
k1 matches k3
",
);
let keypoints2 = LinkNetwork::from_notation(
"
p1 matches p2
p2 matches p3
p3 matches p1
",
);
assert!(is_isomorphic(&keypoints1, &keypoints2));
}
}
mod social_network {
use super::*;
#[test]
fn test_clique_detection() {
let network = LinkNetwork::from_notation(
"
Alice knows Bob
Bob knows Charlie
Charlie knows David
David knows Eve
Alice knows Charlie
",
);
let triangle = LinkNetwork::from_notation(
"
X knows Y
Y knows Z
Z knows X
",
);
assert!(contains_subnetwork(&network, &triangle));
}
#[test]
fn test_community_isomorphism() {
let community1 = LinkNetwork::from_notation(
"
user1 connected user2
user2 connected user3
user3 connected user4
user4 connected user1
",
);
let community2 = LinkNetwork::from_notation(
"
personA connected personB
personB connected personC
personC connected personD
personD connected personA
",
);
assert!(is_isomorphic(&community1, &community2));
}
#[test]
fn test_influencer_pattern() {
let network = LinkNetwork::from_notation(
"
influencer connects follower1
influencer connects follower2
influencer connects follower3
influencer connects follower4
follower1 connects follower2
",
);
let star_pattern = LinkNetwork::from_notation(
"
center connects leaf1
center connects leaf2
center connects leaf3
",
);
assert!(contains_subnetwork(&network, &star_pattern));
}
#[test]
fn test_bot_network_detection() {
let bot_pattern = LinkNetwork::from_notation(
"
bot1 follows target
bot2 follows target
bot3 follows target
",
);
let real_network = LinkNetwork::from_notation(
"
account1 follows celebrity
account2 follows celebrity
account3 follows celebrity
account1 follows account4
",
);
assert!(contains_subnetwork(&real_network, &bot_pattern));
}
}
mod cryptography {
use super::*;
#[test]
fn test_zk_proof_graph_isomorphism() {
let secret_graph = LinkNetwork::from_notation(
"
v1 edge v2
v2 edge v3
v3 edge v4
v4 edge v1
v1 edge v3
",
);
let permuted_graph = LinkNetwork::from_notation(
"
a edge b
b edge c
c edge d
d edge a
a edge c
",
);
let result = check_isomorphism(&secret_graph, &permuted_graph);
assert!(result.is_isomorphic);
assert!(result.mapping.is_some());
}
#[test]
fn test_automorphism_security() {
let mut symmetric_graph = LinkNetwork::new();
symmetric_graph.add_link(1, 2);
symmetric_graph.add_link(2, 3);
symmetric_graph.add_link(3, 1);
let symmetric_autos = find_automorphisms(&symmetric_graph);
assert_eq!(symmetric_autos.len(), 6);
let asymmetric_graph = LinkNetwork::from_notation(
"
a edge b
b edge c
c edge d
",
);
let asymmetric_autos = find_automorphisms(&asymmetric_graph);
assert_eq!(asymmetric_autos.len(), 2); }
#[test]
fn test_non_isomorphic_discrimination() {
let graph1 = LinkNetwork::from_notation(
"
a edge b
b edge c
c edge d
d edge a
",
);
let graph2 = LinkNetwork::from_notation(
"
a edge b
a edge c
a edge d
b edge c
",
);
assert!(!is_isomorphic(&graph1, &graph2));
}
#[test]
fn test_canonical_representation() {
let repr1 = LinkNetwork::from_notation(
"
1 edge 2
2 edge 3
3 edge 1
",
);
let repr2 = LinkNetwork::from_notation(
"
a edge b
b edge c
c edge a
",
);
let repr3 = LinkNetwork::from_notation(
"
x edge y
y edge z
z edge x
",
);
assert!(is_isomorphic(&repr1, &repr2));
assert!(is_isomorphic(&repr2, &repr3));
assert!(is_isomorphic(&repr1, &repr3)); }
}
mod performance {
use super::*;
#[test]
fn test_larger_network_isomorphism() {
let mut net1 = LinkNetwork::new();
let mut net2 = LinkNetwork::new();
for i in 1..10 {
net1.add_link(i, i + 1);
net2.add_link(i + 100, i + 101);
}
assert!(is_isomorphic(&net1, &net2));
}
#[test]
fn test_quick_rejection() {
let mut small = LinkNetwork::new();
small.add_link(1, 2);
let mut large = LinkNetwork::new();
for i in 1..100 {
large.add_link(i, i + 1);
}
assert!(!is_isomorphic(&small, &large));
}
#[test]
fn test_grid_network() {
let grid1 = LinkNetwork::from_notation(
"
n1 e n2
n2 e n3
n4 e n5
n5 e n6
n1 e n4
n2 e n5
n3 e n6
",
);
let grid2 = LinkNetwork::from_notation(
"
a e b
b e c
d e e2
e2 e f
a e d
b e e2
c e f
",
);
assert!(is_isomorphic(&grid1, &grid2));
}
}
mod links_theory {
use super::*;
#[test]
fn test_doublet_notation() {
let network = LinkNetwork::from_notation(
"
A B
B C
C A
",
);
assert_eq!(network.node_count(), 3);
assert_eq!(network.link_count(), 3);
}
#[test]
fn test_triplet_notation() {
let network = LinkNetwork::from_notation(
"
papa loves mama
son loves mama
daughter loves mama
",
);
assert_eq!(network.node_count(), 4);
assert_eq!(network.link_count(), 3);
}
#[test]
fn test_doublet_link_property() {
let mut network = LinkNetwork::new();
network.add_link(1, 2);
let links = network.links();
assert_eq!(links.len(), 1);
assert_eq!(links[0].source, 1);
assert_eq!(links[0].target, 2);
}
#[test]
fn test_links_connect_links() {
let mut network = LinkNetwork::new();
network.add_link(1, 2);
network.add_link(2, 3);
assert_eq!(network.degree(2), 2);
}
#[test]
fn test_notation_comments() {
let network = LinkNetwork::from_notation(
"
# This is a comment
A connects B
# Another comment
B connects C
",
);
assert_eq!(network.node_count(), 3);
assert_eq!(network.link_count(), 2);
}
}
mod version_tests {
use network_isomorphism_solver::VERSION;
#[test]
fn test_version_is_not_empty() {
assert!(!VERSION.is_empty());
}
#[test]
fn test_version_matches_cargo_toml() {
assert!(VERSION.starts_with("0."));
}
}
mod lino_integration {
use super::*;
#[test]
fn test_from_lino_doublet_format() {
let network = LinkNetwork::from_lino("(1 2) (2 3) (3 1)").unwrap();
assert_eq!(network.node_count(), 3);
assert_eq!(network.link_count(), 3);
}
#[test]
fn test_from_lino_named_links() {
let network = LinkNetwork::from_lino("(bond1: A B) (bond2: B C) (bond3: C A)").unwrap();
assert_eq!(network.node_count(), 3);
assert_eq!(network.link_count(), 3);
}
#[test]
fn test_from_lino_triplet_format() {
let network = LinkNetwork::from_lino("(A connects B) (B connects C)").unwrap();
assert_eq!(network.node_count(), 3);
assert_eq!(network.link_count(), 2);
}
#[test]
fn test_from_lino_isomorphic_to_from_notation() {
let lino_network = LinkNetwork::from_lino("(A B) (B C) (C A)").unwrap();
let notation_network =
LinkNetwork::from_notation("A connects B\nB connects C\nC connects A");
assert!(is_isomorphic(&lino_network, ¬ation_network));
}
#[test]
fn test_from_lino_different_representations() {
let network1 = LinkNetwork::from_lino("(1 2) (2 3) (3 1)").unwrap();
let network2 = LinkNetwork::from_lino("(A B) (B C) (C A)").unwrap();
let network3 = LinkNetwork::from_lino("(bond1: X Y) (bond2: Y Z) (bond3: Z X)").unwrap();
assert!(is_isomorphic(&network1, &network2));
assert!(is_isomorphic(&network2, &network3));
assert!(is_isomorphic(&network1, &network3));
}
#[test]
fn test_from_lino_empty_input() {
let network = LinkNetwork::from_lino("ref").unwrap();
assert_eq!(network.node_count(), 0);
assert_eq!(network.link_count(), 0);
}
#[test]
fn test_from_lino_nested_structure() {
let network = LinkNetwork::from_lino("((A B) (B C) (C A))").unwrap();
assert_eq!(network.node_count(), 3);
assert_eq!(network.link_count(), 3);
}
#[test]
fn test_from_lino_parse_error() {
let result = LinkNetwork::from_lino("(unclosed");
assert!(result.is_err());
}
#[test]
fn test_from_lino_molecular_structure() {
let benzene =
LinkNetwork::from_lino("(C1 C2) (C2 C3) (C3 C4) (C4 C5) (C5 C6) (C6 C1)").unwrap();
assert_eq!(benzene.node_count(), 6);
assert_eq!(benzene.link_count(), 6);
let automorphisms = find_automorphisms(&benzene);
assert_eq!(automorphisms.len(), 12);
}
#[test]
fn test_from_lino_circuit() {
let circuit1 = LinkNetwork::from_lino("(input1 gate) (input2 gate) (gate output)").unwrap();
let circuit2 = LinkNetwork::from_lino("(A X) (B X) (X Z)").unwrap();
assert!(is_isomorphic(&circuit1, &circuit2));
}
#[test]
fn test_from_lino_subnetwork_detection() {
let full_network = LinkNetwork::from_lino("(A B) (B C) (C D) (D A) (A C)").unwrap();
let triangle_pattern = LinkNetwork::from_lino("(X Y) (Y Z) (Z X)").unwrap();
assert!(contains_subnetwork(&full_network, &triangle_pattern));
}
#[test]
fn test_links_notation_reexport() {
use network_isomorphism_solver::links_notation::parse_lino;
let parsed = parse_lino("(A B)").unwrap();
assert!(parsed.is_link());
}
}