problemreductions/rules/
ksatisfiability_quadraticdiophantineequations.rs1use crate::models::algebraic::{QuadraticCongruences, QuadraticDiophantineEquations};
8use crate::models::formula::KSatisfiability;
9use crate::reduction;
10use crate::rules::ksatisfiability_quadraticcongruences::Reduction3SATToQuadraticCongruences;
11use crate::rules::traits::{ReduceTo, ReductionResult};
12use crate::variant::K3;
13use num_bigint::BigUint;
14use num_traits::One;
15
16#[derive(Debug, Clone)]
18pub struct Reduction3SATToQuadraticDiophantineEquations {
19 target: QuadraticDiophantineEquations,
20 congruence_reduction: Reduction3SATToQuadraticCongruences,
21}
22
23impl ReductionResult for Reduction3SATToQuadraticDiophantineEquations {
24 type Source = KSatisfiability<K3>;
25 type Target = QuadraticDiophantineEquations;
26
27 fn target_problem(&self) -> &Self::Target {
28 &self.target
29 }
30
31 fn extract_solution(
32 &self,
33 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
34 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
35 crate::rules::traits::validate_target_witness(
36 self.target_problem(),
37 target_solution,
38 |value| value.0,
39 "target witness does not satisfy the target problem",
40 )?;
41
42 Ok({
43 self.congruence_reduction
44 .extract_solution(target_solution)?
45 })
46 }
47}
48
49fn no_instance() -> QuadraticDiophantineEquations {
50 QuadraticDiophantineEquations::new(1u32, 1u32, 1u32)
51}
52
53fn translate_congruence(source: &QuadraticCongruences) -> QuadraticDiophantineEquations {
54 if source.c() <= &BigUint::one() {
55 return no_instance();
56 }
57
58 let h = source.c().clone() - BigUint::one();
59 let h_squared = &h * &h;
60 if h_squared < *source.a() {
61 return no_instance();
62 }
63
64 let padding = ((&h_squared - source.a()) / source.b()) + BigUint::one();
65 let c = source.a() + (source.b() * &padding);
66
67 QuadraticDiophantineEquations::new(BigUint::one(), source.b().clone(), c)
68}
69
70#[crate::aggregate_reduction(identity)]
71impl crate::rules::AggregateReductionResult for Reduction3SATToQuadraticDiophantineEquations {}
72
73#[reduction(
74 transform = upper_bound {
75 bit_length_a = "1",
76 bit_length_b = "64 * (2 * num_clauses + num_vars + 1)^2 + 3 * num_clauses + 4",
77 bit_length_c = "128 * (2 * num_clauses + num_vars + 1)^2 + 6 * num_clauses + 9",
78 }
79)]
80impl ReduceTo<QuadraticDiophantineEquations> for KSatisfiability<K3> {
81 type Result = Reduction3SATToQuadraticDiophantineEquations;
82
83 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
84 let congruence_reduction = ReduceTo::<QuadraticCongruences>::reduce_to(self)?;
85 let target = translate_congruence(congruence_reduction.target_problem());
86
87 Ok(Reduction3SATToQuadraticDiophantineEquations {
88 target,
89 congruence_reduction,
90 })
91 }
92}
93
94#[cfg(any(test, feature = "example-db"))]
95fn canonical_source() -> KSatisfiability<K3> {
96 use crate::models::formula::CNFClause;
97
98 KSatisfiability::<K3>::new(3, vec![CNFClause::new(vec![1, 2, 3])])
99}
100
101#[cfg(any(test, feature = "example-db"))]
102fn canonical_witness() -> BigUint {
103 BigUint::parse_bytes(b"3851422232510508672725868082377332726402809", 10)
104 .expect("canonical CRT witness must parse")
105}
106
107#[cfg(feature = "example-db")]
108pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
109 use crate::example_db::specs::assemble_rule_example;
110 use crate::export::SolutionPair;
111
112 vec![crate::example_db::specs::RuleExampleSpec {
113 id: "ksatisfiability_to_quadraticdiophantineequations",
114 build: || {
115 let source = canonical_source();
116 let reduction = ReduceTo::<QuadraticDiophantineEquations>::reduce_to(&source)
117 .expect("reduction should succeed");
118 let target_config = canonical_witness();
119
120 assemble_rule_example(
121 &source,
122 reduction.target_problem(),
123 vec![SolutionPair {
124 source_config: serde_json::json!(vec![true, false, false]),
125 target_config: serde_json::to_value(target_config)
126 .expect("solution serialization must succeed"),
127 }],
128 )
129 },
130 }]
131}
132
133#[cfg(test)]
134#[path = "../unit_tests/rules/ksatisfiability_quadraticdiophantineequations.rs"]
135mod tests;