snark_tool/procedure/basic_procedures/
colour.rs1use std::collections::HashMap;
2use std::marker;
3
4use crate::graph::undirected::UndirectedGraph;
5use crate::procedure::error::Error;
6use crate::procedure::helpers::config_helper;
7use crate::procedure::procedure::{GraphProperties, Procedure, Result};
8use crate::procedure::procedure_builder::{ConfigMap, ProcedureBuilder};
9use crate::service::colour::colouriser::Colouriser;
10use crate::service::colour::cvd::cvd;
11use crate::service::colour::cvd::cvd_dfs::CvdDfsColourizer;
12use crate::service::colour::cvd::cvd_sat::CvdSatColourizer;
13use crate::service::colour::matchings::matching_col::MatchingColouriser;
14use crate::service::colour::recursive::dfs_improved::DFSColourizer;
15use crate::service::colour::sat::sat::SATColourizer;
16
17const COLOURISER_TYPE: &str = "colouriser-type";
19
20const COLOURABLE: &str = "colourable";
22
23const DFS: &str = "dfs";
25const SAT: &str = "sat";
26const CVD: &str = "cvd";
27const CVD_DFS: &str = "cvd-dfs";
28const CVD_SAT: &str = "cvd-sat";
29const MATCHING: &str = "matching";
30const AUTO: &str = "auto";
31
32#[derive(Clone)]
33pub enum ColouriserType {
34 Dfs,
35 Sat,
36 Cvd,
37 CvdDfs,
38 CvdSat,
39 Matching,
40 Auto,
41}
42
43impl ColouriserType {
44 pub fn from_string(string: &String) -> Result<ColouriserType> {
45 let col_type;
46 match string.as_str() {
47 DFS => col_type = ColouriserType::Dfs,
48 SAT => col_type = ColouriserType::Sat,
49 CVD => col_type = ColouriserType::Cvd,
50 CVD_DFS => col_type = ColouriserType::CvdDfs,
51 CVD_SAT => col_type = ColouriserType::CvdSat,
52 MATCHING => col_type = ColouriserType::Matching,
53 AUTO => col_type = ColouriserType::Auto,
54 &_ => {
55 return Err(Error::ConfigError(String::from(format!(
56 "unknown colouriser type: {}, did you mean {}, {}, {}, {}, {}, {} or {}?",
57 string, DFS, SAT, MATCHING, CVD, CVD_DFS, CVD_SAT, AUTO
58 ))));
59 }
60 }
61 Ok(col_type)
62 }
63}
64
65struct ColourProcedure<G: UndirectedGraph> {
66 config: ColourProcedureConfig,
67 _ph: marker::PhantomData<G>,
68}
69
70pub struct ColourProcedureConfig {
71 colouriser_type: ColouriserType,
72}
73
74pub struct ColourProcedureBuilder {}
75
76impl<G: UndirectedGraph> Procedure<G> for ColourProcedure<G> {
77 fn run(&self, graphs: &mut Vec<(G, GraphProperties)>) -> Result<()> {
78 println!("running colour procedure");
79 self.colour_graph(graphs)
80 }
81}
82
83impl<G: UndirectedGraph> ColourProcedure<G> {
84 pub fn colour_graph(&self, graphs: &mut Vec<(G, GraphProperties)>) -> Result<()> {
85 let colouriser_type = self.config.colouriser_type();
86 match colouriser_type {
87 ColouriserType::Dfs => {
88 Self::color_by_colourizer::<DFSColourizer>(graphs);
89 }
90 ColouriserType::Sat => {
91 Self::color_by_colourizer::<SATColourizer>(graphs);
92 }
93 ColouriserType::CvdDfs => {
94 Self::color_by_colourizer::<CvdDfsColourizer>(graphs);
95 }
96 ColouriserType::CvdSat => {
97 Self::color_by_colourizer::<CvdSatColourizer>(graphs);
98 }
99 ColouriserType::Matching => {
100 Self::color_by_colourizer::<MatchingColouriser>(graphs);
101 }
102 ColouriserType::Cvd => {
103 Self::color_by_colourizer_cvd(graphs);
104 }
105 _ => {
106 return Err(Error::ConfigError(String::from(
107 "unknown colouriser type for colour procedure",
108 )));
109 }
110 }
111 Ok(())
112 }
113
114 fn color_by_colourizer<C: Colouriser>(graphs: &mut Vec<(G, GraphProperties)>) {
115 for graph in graphs {
116 let result = C::is_colorable(&graph.0);
117 graph
118 .1
119 .insert(COLOURABLE.to_string(), serde_json::Value::Bool(result));
120 }
121 }
122
123 fn color_by_colourizer_cvd(graphs: &mut Vec<(G, GraphProperties)>) {
127 for graph in graphs {
128 let result_option = cvd::is_colorable(&graph.0);
129 if let Some(result) = result_option {
130 graph
131 .1
132 .insert(COLOURABLE.to_string(), serde_json::Value::Bool(result));
133 }
134 }
135 }
136}
137
138impl ColourProcedureConfig {
139 pub const PROC_TYPE: &'static str = "colour";
140
141 pub fn new(colouriser_type: ColouriserType) -> Self {
142 ColourProcedureConfig { colouriser_type }
143 }
144
145 pub fn default() -> Self {
146 ColourProcedureConfig {
147 colouriser_type: ColouriserType::Dfs,
148 }
149 }
150
151 pub fn colouriser_type(&self) -> &ColouriserType {
152 &self.colouriser_type
153 }
154
155 pub fn from_proc_config(config: &HashMap<String, serde_json::Value>) -> Result<Self> {
156 let colouriser_type = config_helper::resolve_value_or_default(
157 &config,
158 COLOURISER_TYPE,
159 DFS.to_string(),
160 Self::PROC_TYPE,
161 )?;
162
163 let result = ColourProcedureConfig {
164 colouriser_type: ColouriserType::from_string(&colouriser_type)?,
165 };
166 Ok(result)
167 }
168}
169
170impl<G: UndirectedGraph + 'static> ProcedureBuilder<G> for ColourProcedureBuilder {
171 fn build_from_map(&self, config: ConfigMap) -> Result<Box<dyn Procedure<G>>> {
172 let proc_config = ColourProcedureConfig::from_proc_config(&config)?;
173 Ok(Box::new(ColourProcedure {
174 config: proc_config,
175 _ph: marker::PhantomData,
176 }))
177 }
178}
179
180impl ColourProcedureBuilder {
181 pub fn build<G: UndirectedGraph + 'static>(
182 config: ColourProcedureConfig,
183 ) -> Box<dyn Procedure<G>> {
184 Box::new(ColourProcedure {
185 config,
186 _ph: marker::PhantomData,
187 })
188 }
189}