problemreductions/rules/
rootedtreearrangement_rootedtreestorageassignment.rs1use crate::models::graph::RootedTreeArrangement;
13use crate::models::set::RootedTreeStorageAssignment;
14use crate::reduction;
15use crate::rules::traits::{ReduceTo, ReductionResult};
16use crate::topology::{Graph, SimpleGraph};
17
18#[derive(Debug, Clone)]
20pub struct ReductionRootedTreeArrangementToRootedTreeStorageAssignment {
21 target: RootedTreeStorageAssignment,
22 num_vertices: usize,
24}
25
26impl ReductionResult for ReductionRootedTreeArrangementToRootedTreeStorageAssignment {
27 type Source = RootedTreeArrangement<SimpleGraph>;
28 type Target = RootedTreeStorageAssignment;
29
30 fn target_problem(&self) -> &Self::Target {
31 &self.target
32 }
33
34 fn extract_solution(
40 &self,
41 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
42 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
43 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
44
45 Ok({
46 let n = self.num_vertices;
47 let mut source_config = target_solution.to_vec();
50 source_config.extend(0..n);
52 source_config
53 })
54 }
55}
56
57#[reduction(
58 transform = exact {
59 universe_size = "num_vertices",
60 num_subsets = "num_edges",
61 }
62)]
63impl ReduceTo<RootedTreeStorageAssignment> for RootedTreeArrangement<SimpleGraph> {
64 type Result = ReductionRootedTreeArrangementToRootedTreeStorageAssignment;
65
66 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
67 let n = self.num_vertices();
68 let edges = self.graph().edges();
69 let num_edges = edges.len();
70
71 let subsets: Vec<Vec<usize>> = edges.iter().map(|&(u, v)| vec![u, v]).collect();
73
74 let num_edges = i64::try_from(num_edges).map_err(|_| {
79 crate::rules::ReductionError::integer_overflow::<
80 RootedTreeArrangement<SimpleGraph>,
81 RootedTreeStorageAssignment,
82 >("converting the number of edges to i64")
83 })?;
84 let bound = match self.bound().checked_sub(num_edges) {
85 Some(b) => b,
86 None => {
87 let gadget_n = 3;
93 let gadget_subsets = vec![vec![0, 1], vec![1, 2], vec![0, 2]];
94 let target = RootedTreeStorageAssignment::new(gadget_n, gadget_subsets, 0);
95
96 return Ok(
97 ReductionRootedTreeArrangementToRootedTreeStorageAssignment {
98 target,
99 num_vertices: gadget_n,
100 },
101 );
102 }
103 };
104
105 let target = RootedTreeStorageAssignment::new(n, subsets, bound);
106
107 Ok(
108 ReductionRootedTreeArrangementToRootedTreeStorageAssignment {
109 target,
110 num_vertices: n,
111 },
112 )
113 }
114}
115
116#[cfg(feature = "example-db")]
117pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
118 use crate::export::SolutionPair;
119
120 vec![crate::example_db::specs::RuleExampleSpec {
121 id: "rootedtreearrangement_to_rootedtreestorageassignment",
122 build: || {
123 let source =
130 RootedTreeArrangement::new(SimpleGraph::new(4, vec![(0, 1), (1, 2), (2, 3)]), 5);
131 let source_config = vec![0, 0, 1, 2, 0, 1, 2, 3];
132 let target_config = vec![0, 0, 1, 2];
133 crate::example_db::specs::rule_example_with_witness::<_, RootedTreeStorageAssignment>(
134 source,
135 SolutionPair {
136 source_config: serde_json::to_value(source_config)
137 .expect("solution serialization must succeed"),
138 target_config: serde_json::to_value(target_config)
139 .expect("solution serialization must succeed"),
140 },
141 )
142 },
143 }]
144}
145
146#[cfg(test)]
147#[path = "../unit_tests/rules/rootedtreearrangement_rootedtreestorageassignment.rs"]
148mod tests;