1use std::ops::{Not, Range, RangeBounds};
9
10use super::{
11 BoundBoth, BoundBothIncremental, BoundLower, BoundLowerIncremental, BoundUpper,
12 BoundUpperIncremental, Encode, EncodeIncremental,
13};
14use crate::{
15 encodings::{CollectClauses, EncodeStats, EnforceError, IterInputs, NotEncoded},
16 instances::ManageVars,
17 types::Lit,
18};
19
20#[derive(Debug)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24pub struct Inverted<CE>
25where
26 CE: Encode + 'static,
27{
28 card_enc: CE,
29 n_lits: usize,
30}
31
32impl<CE> Default for Inverted<CE>
33where
34 CE: Encode + Default,
35{
36 fn default() -> Self {
37 Self {
38 card_enc: Default::default(),
39 n_lits: Default::default(),
40 }
41 }
42}
43
44impl<CE> Inverted<CE>
45where
46 CE: Encode + 'static,
47{
48 fn convert_encoding_range(&self, range: Range<usize>) -> Range<usize> {
49 let min = self.n_lits() - (range.end - 1);
50 let max = if self.n_lits() >= range.start {
51 self.n_lits() - range.start + 1
52 } else {
53 0
54 };
55 min..max
56 }
57}
58
59impl<CE> From<Vec<Lit>> for Inverted<CE>
60where
61 CE: Encode + From<Vec<Lit>> + 'static,
62{
63 fn from(lits: Vec<Lit>) -> Self {
64 let n = lits.len();
65 let lits: Vec<Lit> = lits.into_iter().map(Lit::not).collect();
66 Self {
67 card_enc: CE::from(lits),
68 n_lits: n,
69 }
70 }
71}
72
73impl<CE> FromIterator<Lit> for Inverted<CE>
74where
75 CE: Encode + From<Vec<Lit>> + 'static,
76{
77 fn from_iter<T: IntoIterator<Item = Lit>>(iter: T) -> Self {
78 let lits: Vec<Lit> = iter.into_iter().collect();
79 Self::from(lits)
80 }
81}
82
83impl<CE> Extend<Lit> for Inverted<CE>
84where
85 CE: Encode + Extend<Lit> + 'static,
86{
87 fn extend<T: IntoIterator<Item = Lit>>(&mut self, iter: T) {
88 let lits: Vec<Lit> = iter.into_iter().map(Lit::not).collect();
89 self.n_lits += lits.len();
90 self.card_enc.extend(lits);
91 }
92}
93
94impl<CE> Encode for Inverted<CE>
95where
96 CE: Encode,
97{
98 fn n_lits(&self) -> usize {
99 self.n_lits
100 }
101}
102
103impl<CE> IterInputs for Inverted<CE>
104where
105 CE: Encode + IterInputs,
106{
107 type Iter<'a> = InvertedIter<CE::Iter<'a>>;
108
109 fn iter(&self) -> Self::Iter<'_> {
110 self.card_enc.iter().map(Lit::not)
111 }
112}
113
114impl<CE> EncodeIncremental for Inverted<CE>
115where
116 CE: EncodeIncremental,
117{
118 fn reserve(&mut self, var_manager: &mut dyn ManageVars) {
119 self.card_enc.reserve(var_manager);
120 }
121}
122
123impl<CE> BoundUpper for Inverted<CE>
124where
125 CE: BoundLower,
126{
127 fn encode_ub<Col, R>(
128 &mut self,
129 range: R,
130 collector: &mut Col,
131 var_manager: &mut dyn ManageVars,
132 ) -> Result<(), crate::OutOfMemory>
133 where
134 Col: CollectClauses,
135 R: RangeBounds<usize>,
136 {
137 self.card_enc.encode_lb(
138 self.convert_encoding_range(super::prepare_ub_range(self, range)),
139 collector,
140 var_manager,
141 )
142 }
143
144 fn enforce_ub(&self, ub: usize) -> Result<Vec<Lit>, NotEncoded> {
145 let lb = if self.n_lits > ub {
146 self.n_lits - ub
147 } else {
148 return Ok(vec![]);
149 };
150 match self.card_enc.enforce_lb(lb) {
151 Ok(assumps) => Ok(assumps),
152 Err(EnforceError::NotEncoded) => Err(NotEncoded),
153 Err(EnforceError::Unsat) => unreachable!(),
154 }
155 }
156}
157
158#[cfg(feature = "proof-logging")]
159impl<CE> super::cert::BoundUpper for Inverted<CE>
160where
161 CE: super::cert::BoundLower + FromIterator<Lit>,
162{
163 fn encode_ub_cert<Col, R, W>(
164 &mut self,
165 range: R,
166 collector: &mut Col,
167 var_manager: &mut dyn ManageVars,
168 proof: &mut pigeons::Proof<W>,
169 ) -> Result<(), crate::encodings::cert::EncodingError>
170 where
171 Col: crate::encodings::cert::CollectClauses,
172 R: RangeBounds<usize>,
173 W: std::io::Write,
174 {
175 self.card_enc.encode_lb_cert(
176 self.convert_encoding_range(super::prepare_ub_range(self, range)),
177 collector,
178 var_manager,
179 proof,
180 )
181 }
182
183 fn encode_ub_constr_cert<Col, W>(
184 constr: (
185 crate::types::constraints::CardUbConstr,
186 pigeons::AbsConstraintId,
187 ),
188 collector: &mut Col,
189 var_manager: &mut dyn ManageVars,
190 proof: &mut pigeons::Proof<W>,
191 ) -> Result<(), crate::encodings::cert::EncodingError>
192 where
193 Col: crate::encodings::cert::CollectClauses,
194 W: std::io::Write,
195 Self: FromIterator<Lit> + Sized,
196 {
197 let constr = (constr.0.invert(), constr.1);
198 match CE::encode_lb_constr_cert(constr, collector, var_manager, proof) {
199 Ok(()) => Ok(()),
200 Err(crate::encodings::cert::ConstraintEncodingError::OutOfMemory(err)) => {
201 Err(err.into())
202 }
203 Err(crate::encodings::cert::ConstraintEncodingError::Proof(err)) => Err(err.into()),
204 Err(crate::encodings::cert::ConstraintEncodingError::Unsat) => unreachable!(),
205 }
206 }
207}
208
209impl<CE> BoundLower for Inverted<CE>
210where
211 CE: BoundUpper,
212{
213 fn encode_lb<Col, R>(
214 &mut self,
215 range: R,
216 collector: &mut Col,
217 var_manager: &mut dyn ManageVars,
218 ) -> Result<(), crate::OutOfMemory>
219 where
220 Col: CollectClauses,
221 R: RangeBounds<usize>,
222 {
223 self.card_enc.encode_ub(
224 self.convert_encoding_range(super::prepare_lb_range(self, range)),
225 collector,
226 var_manager,
227 )
228 }
229
230 fn enforce_lb(&self, lb: usize) -> Result<Vec<Lit>, EnforceError> {
231 let ub = if self.n_lits >= lb {
232 self.n_lits - lb
233 } else {
234 return Err(EnforceError::Unsat);
235 };
236 Ok(self.card_enc.enforce_ub(ub)?)
237 }
238}
239
240#[cfg(feature = "proof-logging")]
241impl<CE> super::cert::BoundLower for Inverted<CE>
242where
243 CE: super::cert::BoundUpper + FromIterator<Lit>,
244{
245 fn encode_lb_cert<Col, R, W>(
246 &mut self,
247 range: R,
248 collector: &mut Col,
249 var_manager: &mut dyn ManageVars,
250 proof: &mut pigeons::Proof<W>,
251 ) -> Result<(), crate::encodings::cert::EncodingError>
252 where
253 Col: crate::encodings::cert::CollectClauses,
254 R: RangeBounds<usize>,
255 W: std::io::Write,
256 {
257 self.card_enc.encode_ub_cert(
258 self.convert_encoding_range(super::prepare_lb_range(self, range)),
259 collector,
260 var_manager,
261 proof,
262 )
263 }
264
265 fn encode_lb_constr_cert<Col, W>(
266 constr: (
267 crate::types::constraints::CardLbConstr,
268 pigeons::AbsConstraintId,
269 ),
270 collector: &mut Col,
271 var_manager: &mut dyn ManageVars,
272 proof: &mut pigeons::Proof<W>,
273 ) -> Result<(), crate::encodings::cert::ConstraintEncodingError>
274 where
275 Col: crate::encodings::cert::CollectClauses,
276 W: std::io::Write,
277 Self: FromIterator<Lit> + Sized,
278 {
279 let constr = (constr.0.invert(), constr.1);
280 CE::encode_ub_constr_cert(constr, collector, var_manager, proof)?;
281 Ok(())
282 }
283}
284
285impl<CE> BoundBoth for Inverted<CE>
286where
287 CE: BoundBoth,
288{
289 fn encode_both<Col, R>(
290 &mut self,
291 range: R,
292 collector: &mut Col,
293 var_manager: &mut dyn ManageVars,
294 ) -> Result<(), crate::OutOfMemory>
295 where
296 Col: CollectClauses,
297 R: RangeBounds<usize> + Clone,
298 {
299 self.card_enc.encode_both(
300 self.convert_encoding_range(super::prepare_both_range(self, range)),
301 collector,
302 var_manager,
303 )
304 }
305
306 fn enforce_eq(&self, b: usize) -> Result<Vec<Lit>, EnforceError> {
307 let b = if self.n_lits >= b {
308 self.n_lits - b
309 } else {
310 return Err(EnforceError::Unsat);
311 };
312 self.card_enc.enforce_eq(b)
313 }
314}
315
316#[cfg(feature = "proof-logging")]
317impl<CE> super::cert::BoundBoth for Inverted<CE>
318where
319 CE: super::cert::BoundBoth + FromIterator<Lit>,
320{
321 fn encode_both_cert<Col, R, W>(
322 &mut self,
323 range: R,
324 collector: &mut Col,
325 var_manager: &mut dyn ManageVars,
326 proof: &mut pigeons::Proof<W>,
327 ) -> Result<(), crate::encodings::cert::EncodingError>
328 where
329 Col: crate::encodings::cert::CollectClauses,
330 R: RangeBounds<usize> + Clone,
331 W: std::io::Write,
332 {
333 self.card_enc.encode_both_cert(
334 self.convert_encoding_range(super::prepare_both_range(self, range)),
335 collector,
336 var_manager,
337 proof,
338 )
339 }
340}
341
342impl<CE> BoundUpperIncremental for Inverted<CE>
343where
344 CE: BoundLowerIncremental,
345{
346 fn encode_ub_change<Col, R>(
347 &mut self,
348 range: R,
349 collector: &mut Col,
350 var_manager: &mut dyn ManageVars,
351 ) -> Result<(), crate::OutOfMemory>
352 where
353 Col: CollectClauses,
354 R: RangeBounds<usize>,
355 {
356 self.card_enc.encode_lb_change(
357 self.convert_encoding_range(super::prepare_ub_range(self, range)),
358 collector,
359 var_manager,
360 )
361 }
362}
363
364#[cfg(feature = "proof-logging")]
365impl<CE> super::cert::BoundUpperIncremental for Inverted<CE>
366where
367 CE: super::cert::BoundLowerIncremental + FromIterator<Lit>,
368{
369 fn encode_ub_change_cert<Col, R, W>(
370 &mut self,
371 range: R,
372 collector: &mut Col,
373 var_manager: &mut dyn ManageVars,
374 proof: &mut pigeons::Proof<W>,
375 ) -> Result<(), crate::encodings::cert::EncodingError>
376 where
377 Col: crate::encodings::cert::CollectClauses,
378 R: RangeBounds<usize>,
379 W: std::io::Write,
380 {
381 self.card_enc.encode_lb_change_cert(
382 self.convert_encoding_range(super::prepare_ub_range(self, range)),
383 collector,
384 var_manager,
385 proof,
386 )
387 }
388}
389
390impl<CE> BoundLowerIncremental for Inverted<CE>
391where
392 CE: BoundUpperIncremental,
393{
394 fn encode_lb_change<Col, R>(
395 &mut self,
396 range: R,
397 collector: &mut Col,
398 var_manager: &mut dyn ManageVars,
399 ) -> Result<(), crate::OutOfMemory>
400 where
401 Col: CollectClauses,
402 R: RangeBounds<usize>,
403 {
404 self.card_enc.encode_ub_change(
405 self.convert_encoding_range(super::prepare_lb_range(self, range)),
406 collector,
407 var_manager,
408 )
409 }
410}
411
412#[cfg(feature = "proof-logging")]
413impl<CE> super::cert::BoundLowerIncremental for Inverted<CE>
414where
415 CE: super::cert::BoundUpperIncremental + FromIterator<Lit>,
416{
417 fn encode_lb_change_cert<Col, R, W>(
418 &mut self,
419 range: R,
420 collector: &mut Col,
421 var_manager: &mut dyn ManageVars,
422 proof: &mut pigeons::Proof<W>,
423 ) -> Result<(), crate::encodings::cert::EncodingError>
424 where
425 Col: crate::encodings::cert::CollectClauses,
426 R: RangeBounds<usize>,
427 W: std::io::Write,
428 {
429 self.card_enc.encode_ub_change_cert(
430 self.convert_encoding_range(super::prepare_lb_range(self, range)),
431 collector,
432 var_manager,
433 proof,
434 )
435 }
436}
437
438impl<CE> BoundBothIncremental for Inverted<CE>
439where
440 CE: BoundBothIncremental,
441{
442 fn encode_both_change<Col, R>(
443 &mut self,
444 range: R,
445 collector: &mut Col,
446 var_manager: &mut dyn ManageVars,
447 ) -> Result<(), crate::OutOfMemory>
448 where
449 Col: CollectClauses,
450 R: RangeBounds<usize> + Clone,
451 {
452 self.card_enc.encode_both_change(
453 self.convert_encoding_range(super::prepare_both_range(self, range)),
454 collector,
455 var_manager,
456 )
457 }
458}
459
460#[cfg(feature = "proof-logging")]
461impl<CE> super::cert::BoundBothIncremental for Inverted<CE>
462where
463 CE: super::cert::BoundBothIncremental + FromIterator<Lit>,
464{
465 fn encode_both_change_cert<Col, R, W>(
466 &mut self,
467 range: R,
468 collector: &mut Col,
469 var_manager: &mut dyn ManageVars,
470 proof: &mut pigeons::Proof<W>,
471 ) -> Result<(), crate::encodings::cert::EncodingError>
472 where
473 Col: crate::encodings::cert::CollectClauses,
474 R: RangeBounds<usize> + Clone,
475 W: std::io::Write,
476 {
477 self.card_enc.encode_both_change_cert(
478 self.convert_encoding_range(super::prepare_both_range(self, range)),
479 collector,
480 var_manager,
481 proof,
482 )
483 }
484}
485
486impl<CE> EncodeStats for Inverted<CE>
487where
488 CE: Encode + EncodeStats,
489{
490 fn n_clauses(&self) -> usize {
491 self.card_enc.n_clauses()
492 }
493
494 fn n_vars(&self) -> u32 {
495 self.card_enc.n_vars()
496 }
497}
498
499type InvertedIter<ICE> = std::iter::Map<ICE, fn(Lit) -> Lit>;
500
501#[derive(Debug)]
505#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
506pub struct Double<UBE, LBE>
507where
508 UBE: BoundUpper + 'static,
509 LBE: BoundLower + 'static,
510{
511 ub_enc: UBE,
512 lb_enc: LBE,
513}
514
515impl<UBE, LBE> Default for Double<UBE, LBE>
516where
517 UBE: BoundUpper + Default + 'static,
518 LBE: BoundLower + Default + 'static,
519{
520 fn default() -> Self {
521 Self {
522 ub_enc: Default::default(),
523 lb_enc: Default::default(),
524 }
525 }
526}
527
528impl<UBE, LBE> From<Vec<Lit>> for Double<UBE, LBE>
529where
530 UBE: BoundUpper + From<Vec<Lit>> + 'static,
531 LBE: BoundLower + From<Vec<Lit>> + 'static,
532{
533 fn from(lits: Vec<Lit>) -> Self {
534 Self {
535 ub_enc: UBE::from(lits.clone()),
536 lb_enc: LBE::from(lits),
537 }
538 }
539}
540
541impl<UBE, LBE> FromIterator<Lit> for Double<UBE, LBE>
542where
543 UBE: BoundUpper + From<Vec<Lit>> + 'static,
544 LBE: BoundLower + From<Vec<Lit>> + 'static,
545{
546 fn from_iter<T: IntoIterator<Item = Lit>>(iter: T) -> Self {
547 let lits: Vec<Lit> = iter.into_iter().collect();
548 Self::from(lits)
549 }
550}
551
552impl<UBE, LBE> Extend<Lit> for Double<UBE, LBE>
553where
554 UBE: BoundUpper + Extend<Lit> + 'static,
555 LBE: BoundLower + Extend<Lit> + 'static,
556{
557 fn extend<T: IntoIterator<Item = Lit>>(&mut self, iter: T) {
558 let lits: Vec<Lit> = iter.into_iter().collect();
559 self.ub_enc.extend(lits.clone());
560 self.lb_enc.extend(lits);
561 }
562}
563
564impl<UBE, LBE> Encode for Double<UBE, LBE>
565where
566 UBE: BoundUpper,
567 LBE: BoundLower,
568{
569 fn n_lits(&self) -> usize {
570 self.ub_enc.n_lits()
571 }
572}
573
574impl<UBE, LBE> IterInputs for Double<UBE, LBE>
575where
576 UBE: BoundUpper + IterInputs,
577 LBE: BoundLower,
578{
579 type Iter<'a> = UBE::Iter<'a>;
580
581 fn iter(&self) -> Self::Iter<'_> {
582 self.ub_enc.iter()
583 }
584}
585
586impl<UBE, LBE> EncodeIncremental for Double<UBE, LBE>
587where
588 UBE: BoundUpperIncremental,
589 LBE: BoundLowerIncremental,
590{
591 fn reserve(&mut self, var_manager: &mut dyn ManageVars) {
592 self.ub_enc.reserve(var_manager);
593 self.lb_enc.reserve(var_manager);
594 }
595}
596
597impl<UBE, LBE> BoundUpper for Double<UBE, LBE>
598where
599 UBE: BoundUpper,
600 LBE: BoundLower,
601{
602 fn encode_ub<Col, R>(
603 &mut self,
604 range: R,
605 collector: &mut Col,
606 var_manager: &mut dyn ManageVars,
607 ) -> Result<(), crate::OutOfMemory>
608 where
609 Col: CollectClauses,
610 R: RangeBounds<usize>,
611 {
612 self.ub_enc.encode_ub(range, collector, var_manager)
613 }
614
615 fn enforce_ub(&self, ub: usize) -> Result<Vec<Lit>, NotEncoded> {
616 self.ub_enc.enforce_ub(ub)
617 }
618}
619
620#[cfg(feature = "proof-logging")]
621impl<UBE, LBE> super::cert::BoundUpper for Double<UBE, LBE>
622where
623 UBE: super::cert::BoundUpper + FromIterator<Lit>,
624 LBE: super::cert::BoundLower + FromIterator<Lit>,
625{
626 fn encode_ub_cert<Col, R, W>(
627 &mut self,
628 range: R,
629 collector: &mut Col,
630 var_manager: &mut dyn ManageVars,
631 proof: &mut pigeons::Proof<W>,
632 ) -> Result<(), crate::encodings::cert::EncodingError>
633 where
634 Col: crate::encodings::cert::CollectClauses,
635 R: RangeBounds<usize>,
636 W: std::io::Write,
637 {
638 self.ub_enc
639 .encode_ub_cert(range, collector, var_manager, proof)
640 }
641
642 fn encode_ub_constr_cert<Col, W>(
643 constr: (
644 crate::types::constraints::CardUbConstr,
645 pigeons::AbsConstraintId,
646 ),
647 collector: &mut Col,
648 var_manager: &mut dyn ManageVars,
649 proof: &mut pigeons::Proof<W>,
650 ) -> Result<(), crate::encodings::cert::EncodingError>
651 where
652 Col: crate::encodings::cert::CollectClauses,
653 W: std::io::Write,
654 Self: FromIterator<Lit> + Sized,
655 {
656 UBE::encode_ub_constr_cert(constr, collector, var_manager, proof)
657 }
658}
659
660impl<UBE, LBE> BoundLower for Double<UBE, LBE>
661where
662 UBE: BoundUpper,
663 LBE: BoundLower,
664{
665 fn encode_lb<Col, R>(
666 &mut self,
667 range: R,
668 collector: &mut Col,
669 var_manager: &mut dyn ManageVars,
670 ) -> Result<(), crate::OutOfMemory>
671 where
672 Col: CollectClauses,
673 R: RangeBounds<usize>,
674 {
675 self.lb_enc.encode_lb(range, collector, var_manager)
676 }
677
678 fn enforce_lb(&self, lb: usize) -> Result<Vec<Lit>, EnforceError> {
679 self.lb_enc.enforce_lb(lb)
680 }
681}
682
683#[cfg(feature = "proof-logging")]
684impl<UBE, LBE> super::cert::BoundLower for Double<UBE, LBE>
685where
686 UBE: super::cert::BoundUpper + FromIterator<Lit>,
687 LBE: super::cert::BoundLower + FromIterator<Lit>,
688{
689 fn encode_lb_cert<Col, R, W>(
690 &mut self,
691 range: R,
692 collector: &mut Col,
693 var_manager: &mut dyn ManageVars,
694 proof: &mut pigeons::Proof<W>,
695 ) -> Result<(), crate::encodings::cert::EncodingError>
696 where
697 Col: crate::encodings::cert::CollectClauses,
698 R: RangeBounds<usize>,
699 W: std::io::Write,
700 {
701 self.lb_enc
702 .encode_lb_cert(range, collector, var_manager, proof)
703 }
704
705 fn encode_lb_constr_cert<Col, W>(
706 constr: (
707 crate::types::constraints::CardLbConstr,
708 pigeons::AbsConstraintId,
709 ),
710 collector: &mut Col,
711 var_manager: &mut dyn ManageVars,
712 proof: &mut pigeons::Proof<W>,
713 ) -> Result<(), crate::encodings::cert::ConstraintEncodingError>
714 where
715 Col: crate::encodings::cert::CollectClauses,
716 W: std::io::Write,
717 Self: FromIterator<Lit> + Sized,
718 {
719 LBE::encode_lb_constr_cert(constr, collector, var_manager, proof)
720 }
721}
722
723impl<UBE, LBE> BoundBoth for Double<UBE, LBE>
724where
725 UBE: BoundUpper,
726 LBE: BoundLower,
727{
728}
729
730#[cfg(feature = "proof-logging")]
731impl<UBE, LBE> super::cert::BoundBoth for Double<UBE, LBE>
732where
733 UBE: super::cert::BoundUpper + FromIterator<Lit>,
734 LBE: super::cert::BoundLower + FromIterator<Lit>,
735{
736}
737
738impl<UBE, LBE> BoundUpperIncremental for Double<UBE, LBE>
739where
740 UBE: BoundUpperIncremental,
741 LBE: BoundLowerIncremental,
742{
743 fn encode_ub_change<Col, R>(
744 &mut self,
745 range: R,
746 collector: &mut Col,
747 var_manager: &mut dyn ManageVars,
748 ) -> Result<(), crate::OutOfMemory>
749 where
750 Col: CollectClauses,
751 R: RangeBounds<usize>,
752 {
753 self.ub_enc.encode_ub_change(range, collector, var_manager)
754 }
755}
756
757#[cfg(feature = "proof-logging")]
758impl<UBE, LBE> super::cert::BoundUpperIncremental for Double<UBE, LBE>
759where
760 UBE: super::cert::BoundUpperIncremental + BoundUpperIncremental + FromIterator<Lit>,
761 LBE: super::cert::BoundLowerIncremental + BoundLowerIncremental + FromIterator<Lit>,
762{
763 fn encode_ub_change_cert<Col, R, W>(
764 &mut self,
765 range: R,
766 collector: &mut Col,
767 var_manager: &mut dyn ManageVars,
768 proof: &mut pigeons::Proof<W>,
769 ) -> Result<(), crate::encodings::cert::EncodingError>
770 where
771 Col: crate::encodings::cert::CollectClauses,
772 R: RangeBounds<usize>,
773 W: std::io::Write,
774 {
775 self.ub_enc
776 .encode_ub_change_cert(range, collector, var_manager, proof)
777 }
778}
779
780impl<UBE, LBE> BoundLowerIncremental for Double<UBE, LBE>
781where
782 UBE: BoundUpperIncremental,
783 LBE: BoundLowerIncremental,
784{
785 fn encode_lb_change<Col, R>(
786 &mut self,
787 range: R,
788 collector: &mut Col,
789 var_manager: &mut dyn ManageVars,
790 ) -> Result<(), crate::OutOfMemory>
791 where
792 Col: CollectClauses,
793 R: RangeBounds<usize>,
794 {
795 self.lb_enc.encode_lb_change(range, collector, var_manager)
796 }
797}
798
799#[cfg(feature = "proof-logging")]
800impl<UBE, LBE> super::cert::BoundLowerIncremental for Double<UBE, LBE>
801where
802 UBE: super::cert::BoundUpperIncremental + BoundUpperIncremental + FromIterator<Lit>,
803 LBE: super::cert::BoundLowerIncremental + BoundLowerIncremental + FromIterator<Lit>,
804{
805 fn encode_lb_change_cert<Col, R, W>(
806 &mut self,
807 range: R,
808 collector: &mut Col,
809 var_manager: &mut dyn ManageVars,
810 proof: &mut pigeons::Proof<W>,
811 ) -> Result<(), crate::encodings::cert::EncodingError>
812 where
813 Col: crate::encodings::cert::CollectClauses,
814 R: RangeBounds<usize>,
815 W: std::io::Write,
816 {
817 self.lb_enc
818 .encode_lb_change_cert(range, collector, var_manager, proof)
819 }
820}
821
822impl<UBE, LBE> BoundBothIncremental for Double<UBE, LBE>
823where
824 UBE: BoundUpperIncremental,
825 LBE: BoundLowerIncremental,
826{
827}
828
829#[cfg(feature = "proof-logging")]
830impl<UBE, LBE> super::cert::BoundBothIncremental for Double<UBE, LBE>
831where
832 UBE: super::cert::BoundUpperIncremental + BoundUpperIncremental + FromIterator<Lit>,
833 LBE: super::cert::BoundLowerIncremental + BoundLowerIncremental + FromIterator<Lit>,
834{
835}
836
837impl<UBE, LBE> EncodeStats for Double<UBE, LBE>
838where
839 UBE: EncodeStats + BoundUpper,
840 LBE: EncodeStats + BoundLower,
841{
842 fn n_clauses(&self) -> usize {
843 self.ub_enc.n_clauses() + self.lb_enc.n_clauses()
844 }
845
846 fn n_vars(&self) -> u32 {
847 self.ub_enc.n_vars() + self.lb_enc.n_vars()
848 }
849}