problemreductions/rules/
kclique_conjunctivebooleanquery.rs1use crate::models::graph::KClique;
12use crate::models::misc::{CbqRelation, ConjunctiveBooleanQuery, QueryArg};
13use crate::reduction;
14use crate::rules::traits::{ReduceTo, ReductionResult};
15use crate::topology::{Graph, SimpleGraph};
16
17#[derive(Debug, Clone)]
19pub struct ReductionKCliqueToCBQ {
20 target: ConjunctiveBooleanQuery,
21 num_vertices: usize,
22}
23
24impl ReductionResult for ReductionKCliqueToCBQ {
25 type Source = KClique<SimpleGraph>;
26 type Target = ConjunctiveBooleanQuery;
27
28 fn target_problem(&self) -> &ConjunctiveBooleanQuery {
29 &self.target
30 }
31
32 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
38 KClique::<SimpleGraph>::config_from_vertices(self.num_vertices, target_solution)
39 }
40}
41
42#[reduction(
43 overhead = {
44 domain_size = "num_vertices",
45 num_relations = "1",
46 num_variables = "k",
47 num_conjuncts = "k * (k - 1) / 2",
48 }
49)]
50impl ReduceTo<ConjunctiveBooleanQuery> for KClique<SimpleGraph> {
51 type Result = ReductionKCliqueToCBQ;
52
53 fn reduce_to(&self) -> Self::Result {
54 let n = self.num_vertices();
55 let k = self.k();
56
57 let mut tuples = Vec::with_capacity(self.num_edges() * 2);
59 for (u, v) in self.graph().edges() {
60 tuples.push(vec![u, v]);
61 tuples.push(vec![v, u]);
62 }
63 let relation = CbqRelation { arity: 2, tuples };
64
65 let mut conjuncts = Vec::with_capacity(k * k.saturating_sub(1) / 2);
67 for i in 0..k {
68 for j in (i + 1)..k {
69 conjuncts.push((0, vec![QueryArg::Variable(i), QueryArg::Variable(j)]));
70 }
71 }
72
73 let target = ConjunctiveBooleanQuery::new(n, vec![relation], k, conjuncts);
74
75 ReductionKCliqueToCBQ {
76 target,
77 num_vertices: n,
78 }
79 }
80}
81
82#[cfg(feature = "example-db")]
83pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
84 use crate::export::SolutionPair;
85
86 vec![crate::example_db::specs::RuleExampleSpec {
87 id: "kclique_to_conjunctivebooleanquery",
88 build: || {
89 let source = KClique::new(
91 SimpleGraph::new(5, vec![(0, 1), (0, 2), (1, 2), (2, 3), (3, 4)]),
92 3,
93 );
94 crate::example_db::specs::rule_example_with_witness::<_, ConjunctiveBooleanQuery>(
95 source,
96 SolutionPair {
97 source_config: vec![1, 1, 1, 0, 0],
98 target_config: vec![0, 1, 2],
99 },
100 )
101 },
102 }]
103}
104
105#[cfg(test)]
106#[path = "../unit_tests/rules/kclique_conjunctivebooleanquery.rs"]
107mod tests;