vole/vole/refiners/
digraph.rs1use std::sync::Arc;
2
3use super::Refiner;
4use super::{super::domain_state::DomainState, Side};
5use crate::datastructures::digraph::RawDigraph;
6use crate::perm::Permutation;
7use crate::vole::trace;
8use crate::{datastructures::digraph::Digraph, vole::backtracking::Backtrack};
9
10pub struct DigraphTransporter {
11 digraph_left: Arc<Digraph>,
12 digraph_right: Arc<Digraph>,
13 digraph_raw_left: Arc<RawDigraph>,
14 digraph_raw_right: Arc<RawDigraph>,
15}
16
17impl DigraphTransporter {
18 pub fn new_stabilizer(digraph: Arc<Digraph>) -> Self {
19 let raw = Arc::new(digraph.to_raw_unordered());
20 Self {
21 digraph_left: digraph.clone(),
22 digraph_right: digraph,
23 digraph_raw_left: raw.clone(),
24 digraph_raw_right: raw,
25 }
26 }
27
28 pub fn new_transporter(digraph_left: Arc<Digraph>, digraph_right: Arc<Digraph>) -> Self {
29 let digraph_raw_left = Arc::new(digraph_left.to_raw_unordered());
30 let digraph_raw_right = Arc::new(digraph_right.to_raw_unordered());
31 Self {
32 digraph_left,
33 digraph_right,
34 digraph_raw_left,
35 digraph_raw_right,
36 }
37 }
38
39 fn image(&self, p: &Permutation, side: Side) -> Digraph {
40 let digraph = match side {
41 Side::Left => &self.digraph_left,
42 Side::Right => &self.digraph_right,
43 };
44 &(**digraph) ^ p
45 }
46
47 fn compare(&self, lhs: &Digraph, rhs: &Digraph) -> std::cmp::Ordering {
48 lhs.cmp(rhs)
49 }
50}
51
52impl Refiner for DigraphTransporter {
53 gen_any_image_compare!(Digraph);
54
55 fn name(&self) -> String {
56 if self.is_group() {
57 format!("DigraphTransporter of {:?}", self.digraph_left)
58 } else {
59 format!(
60 "DigraphTransporter of {:?} -> {:?}",
61 self.digraph_left, self.digraph_right
62 )
63 }
64 }
65
66 fn check(&self, p: &Permutation) -> bool {
67 for i in 0..self.digraph_left.vertices() {
73 let neighbours = &self.digraph_raw_left[i];
74
75 let i_img = p.apply(i);
76 let img_neighbours = &self.digraph_raw_right[i_img];
77
78 if std::ptr::eq(img_neighbours, neighbours) {
80 for (target, colour) in neighbours {
81 let t_img = p.apply(*target);
82 if t_img != *target {
83 let equal = match img_neighbours.binary_search_by_key(&t_img, |(a, _)| *a) {
84 Ok(x) => img_neighbours[x].1 == *colour,
85 Err(_) => false,
86 };
87 if !equal {
88 return false;
89 }
90 }
91 }
92 } else {
93 for (target, colour) in neighbours {
94 let t_img = p.apply(*target);
95 let equal = match img_neighbours.binary_search_by_key(&t_img, |(a, _)| *a) {
96 Ok(x) => img_neighbours[x].1 == *colour,
97 Err(_) => false,
98 };
99 if !equal {
100 return false;
101 }
102 }
103 }
104 }
105 true
106 }
107
108 fn refine_begin(&mut self, state: &mut DomainState, side: Side) -> trace::Result<()> {
109 state.add_arc_graph(match side {
110 Side::Left => &self.digraph_left,
111 Side::Right => &self.digraph_right,
112 });
113
114 Ok(())
115 }
116
117 fn is_group(&self) -> bool {
118 Arc::ptr_eq(&self.digraph_left, &self.digraph_right)
119 }
120}
121
122impl Backtrack for DigraphTransporter {
123 fn save_state(&mut self) {}
124 fn restore_state(&mut self) {}
125 fn state_depth(&self) -> usize {
126 0
127 }
128}