snark_tool/procedure/basic_procedures/
constructions.rs1use crate::graph::graph::GraphConstructor;
2use crate::graph::undirected::UndirectedGraph;
3use crate::procedure::helpers::config_helper;
4use crate::procedure::procedure;
5use crate::procedure::procedure::{GraphProperties, Procedure};
6use crate::procedure::procedure_builder::{ConfigMap, ProcedureBuilder};
7use crate::service::colour::colouriser::Colouriser;
8use crate::service::colour::recursive::dfs_improved::DFSColourizer;
9use crate::service::constructions::dot_product::DotProducts;
10use crate::service::constructions::error::ConstructionError;
11use crate::service::constructions::i_extension::IExtensions;
12use crate::service::constructions::y_extension::YExtensions;
13use std::collections::HashMap;
14use std::str::FromStr;
15use std::{marker, result};
16
17pub type Result<T> = result::Result<T, ConstructionError>;
18
19const CONSTRUCTION_TYPE: &str = "construction-type";
21
22#[derive(Debug)]
23pub enum ConstructionType {
24 DotProduct,
25 IExtension,
26 YExtension,
27}
28
29impl FromStr for ConstructionType {
30 type Err = ConstructionError;
31
32 fn from_str(input: &str) -> Result<Self> {
33 match input {
34 "dot-product" => Ok(ConstructionType::DotProduct),
35 "i-extension" => Ok(ConstructionType::IExtension),
36 "y-extension" => Ok(ConstructionType::YExtension),
37 _ => Err(ConstructionError::new(format!(
38 "unknown construction type: {}",
39 input
40 ))),
41 }
42 }
43}
44
45struct ConstructionProcedure<G> {
46 config: ConstructionProcedureConfig,
47 _ph: marker::PhantomData<G>,
48}
49
50pub struct ConstructionProcedureConfig {
51 construction_type: ConstructionType,
52}
53
54pub struct ConstructionProcedureBuilder {}
55
56impl<G: UndirectedGraph + GraphConstructor + Clone> Procedure<G> for ConstructionProcedure<G> {
57 fn run(&self, graphs: &mut Vec<(G, GraphProperties)>) -> procedure::Result<()> {
58 println!(
59 "running {} procedure",
60 ConstructionProcedureConfig::PROC_TYPE
61 );
62 self.construct(graphs)?;
63 Ok(())
64 }
65}
66
67impl<G: UndirectedGraph + GraphConstructor + Clone> ConstructionProcedure<G> {
68 pub fn construct(&self, graphs: &mut Vec<(G, GraphProperties)>) -> Result<()> {
69 let mut extended_graphs = vec![];
72 for graph in graphs.iter() {
73 match self.config.construction_type {
74 ConstructionType::DotProduct => {
75 let mut dot_products = DotProducts::new(&graph.0, &graph.0);
76 let extended = dot_products.next().unwrap();
77 extended_graphs.push((extended, GraphProperties::new()));
78 }
79 ConstructionType::IExtension => {
80 let colouriser = DFSColourizer::new();
81 let mut i_extensions = IExtensions::new(&graph.0, &colouriser);
82 let extended = i_extensions.next().unwrap();
83 extended_graphs.push((extended, GraphProperties::new()));
84 }
85 ConstructionType::YExtension => {
86 let colouriser = DFSColourizer::new();
87 let mut y_extensions = YExtensions::new(&graph.0, &colouriser);
88 let extended = y_extensions.next().unwrap();
89 extended_graphs.push((extended, GraphProperties::new()));
90 }
91 }
92 }
93 graphs.append(&mut extended_graphs);
94 Ok(())
95 }
96}
97
98impl ConstructionProcedureConfig {
99 pub const PROC_TYPE: &'static str = "construction";
100
101 pub fn new(construction_type: ConstructionType) -> Self {
102 ConstructionProcedureConfig { construction_type }
103 }
104
105 pub fn from_proc_config(config: &HashMap<String, serde_json::Value>) -> Result<Self> {
106 let construction_type_string: String =
107 config_helper::resolve_value(&config, CONSTRUCTION_TYPE, Self::PROC_TYPE)?;
108 let construction_type = ConstructionType::from_str(&construction_type_string)?;
109 let result = ConstructionProcedureConfig { construction_type };
110 Ok(result)
111 }
112
113 pub fn construction_type(&self) -> &ConstructionType {
114 &self.construction_type
115 }
116}
117
118impl<G: UndirectedGraph + 'static + GraphConstructor + Clone> ProcedureBuilder<G>
119 for ConstructionProcedureBuilder
120{
121 fn build_from_map(&self, config: ConfigMap) -> procedure::Result<Box<dyn Procedure<G>>> {
122 let proc_config = ConstructionProcedureConfig::from_proc_config(&config)?;
123 Ok(Box::new(ConstructionProcedure {
124 config: proc_config,
125 _ph: marker::PhantomData,
126 }))
127 }
128}
129
130impl ConstructionProcedureBuilder {
131 pub fn build<G: UndirectedGraph + GraphConstructor + Clone + 'static>(
132 config: ConstructionProcedureConfig,
133 ) -> Box<dyn Procedure<G>> {
134 Box::new(ConstructionProcedure {
135 config,
136 _ph: marker::PhantomData,
137 })
138 }
139}