Skip to main content

malachite_q/exhaustive/
mod.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Rational;
10use crate::arithmetic::denominators_in_closed_interval::DenominatorsInClosedRationalInterval;
11use crate::arithmetic::traits::DenominatorsInClosedInterval;
12use core::iter::{Chain, Once, once};
13use core::mem::swap;
14use malachite_base::num::arithmetic::traits::{CoprimeWith, UnsignedAbs};
15use malachite_base::num::basic::traits::{One, Zero};
16use malachite_base::num::conversion::traits::RoundingFrom;
17use malachite_base::num::iterators::{RulerSequence, ruler_sequence};
18use malachite_base::rounding_modes::RoundingMode::*;
19use malachite_base::tuples::exhaustive::{
20    ExhaustiveDependentPairs, ExhaustiveDependentPairsYsGenerator, exhaustive_dependent_pairs,
21};
22use malachite_nz::integer::Integer;
23use malachite_nz::integer::exhaustive::{
24    ExhaustiveIntegerRange, ExhaustiveIntegerRangeToInfinity,
25    ExhaustiveIntegerRangeToNegativeInfinity, exhaustive_integer_range,
26    exhaustive_integer_range_to_infinity, exhaustive_integer_range_to_negative_infinity,
27};
28use malachite_nz::natural::Natural;
29use malachite_nz::natural::exhaustive::{
30    ExhaustiveNaturalRangeToInfinity, exhaustive_positive_naturals,
31};
32
33/// Generates all positive [`Rational`]s.
34///
35/// This `struct` is created by [`exhaustive_positive_rationals`]; see its documentation for more.
36#[derive(Clone, Debug)]
37pub struct ExhaustivePositiveRationals {
38    pred_pred: Natural,
39    pred: Natural,
40}
41
42impl Iterator for ExhaustivePositiveRationals {
43    type Item = Rational;
44
45    fn next(&mut self) -> Option<Rational> {
46        let mut anm1 = Natural::ZERO;
47        swap(&mut self.pred_pred, &mut anm1);
48        swap(&mut self.pred, &mut self.pred_pred);
49        let k = &anm1 / &self.pred_pred; // floor(a(n - 1) / a(n))
50        self.pred = ((k << 1u32) | Natural::ONE) * &self.pred_pred - anm1;
51        Some(Rational {
52            sign: true,
53            numerator: self.pred_pred.clone(),
54            denominator: self.pred.clone(),
55        })
56    }
57}
58
59/// Generates all positive [`Rational`]s.
60///
61/// The [`Rational`]s are ordered as in the [Calkin-Wilf
62/// sequence](https://en.wikipedia.org/wiki/Calkin%E2%80%93Wilf_tree#Breadth_first_traversal). Their
63/// numerators and denominators are given by the [Stern-Brocot
64/// sequence](https://en.wikipedia.org/wiki/Stern%E2%80%93Brocot_tree#Relation_to_Farey_sequences).
65/// To generate the latter sequence, this iterator uses the formula
66/// $$
67/// a_{n+1} = \left ( 2 \left \lfloor \frac{a_{n-1}}{a_n} \right \rfloor +1 \right ) a_n - a_{n-1},
68/// $$
69/// attributed to David S. Newman at <https://oeis.org/A002487>.
70///
71/// The output length is infinite. The numerators and denominators of the $n$th element are
72/// $O(n^\frac{\log \phi}{\log 2})$.
73///
74/// # Worst-case complexity per iteration
75/// $T(i) = O(\log i \log\log i \log\log\log i)$
76///
77/// $M(i) = O(\log i \log\log i)$
78///
79/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
80///
81/// # Examples
82/// ```
83/// use malachite_base::iterators::prefix_to_string;
84/// use malachite_q::exhaustive::exhaustive_positive_rationals;
85///
86/// assert_eq!(
87///     prefix_to_string(exhaustive_positive_rationals(), 20),
88///     "[1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4, 1/5, 5/4, 4/7, 7/3, \
89///     3/8, ...]"
90/// )
91/// ```
92pub const fn exhaustive_positive_rationals() -> ExhaustivePositiveRationals {
93    ExhaustivePositiveRationals {
94        pred_pred: Natural::ZERO,
95        pred: Natural::ONE,
96    }
97}
98
99/// Generates all non-positive [`Rational`]s.
100///
101/// Zero is generated first, followed by all the positive [`Rational`]s. See
102/// [`exhaustive_positive_rationals`] for details.
103///
104/// The output length is infinite. The numerators and denominators of the $n$th element are
105/// $O(n^\frac{\log \phi}{\log 2})$.
106///
107/// # Worst-case complexity per iteration
108/// $T(i) = O(\log i \log\log i \log\log\log i)$
109///
110/// $M(i) = O(\log i \log\log i)$
111///
112/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
113///
114/// # Examples
115/// ```
116/// use malachite_base::iterators::prefix_to_string;
117/// use malachite_q::exhaustive::exhaustive_non_negative_rationals;
118///
119/// assert_eq!(
120///     prefix_to_string(exhaustive_non_negative_rationals(), 20),
121///     "[0, 1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4, 1/5, 5/4, 4/7, \
122///     7/3, ...]"
123/// )
124/// ```
125pub fn exhaustive_non_negative_rationals() -> Chain<Once<Rational>, ExhaustivePositiveRationals> {
126    once(Rational::ZERO).chain(exhaustive_positive_rationals())
127}
128
129/// Generates all negative [`Rational`]s.
130///
131/// This `struct` is created by [`exhaustive_negative_rationals`]; see its documentation for more.
132#[derive(Clone, Debug)]
133pub struct ExhaustiveNegativeRationals {
134    xs: ExhaustivePositiveRationals,
135}
136
137impl Iterator for ExhaustiveNegativeRationals {
138    type Item = Rational;
139
140    fn next(&mut self) -> Option<Rational> {
141        self.xs.next().map(|mut q| {
142            q.sign = false;
143            q
144        })
145    }
146}
147
148/// Generates all negative [`Rational`]s.
149///
150/// The sequence is the same as the sequence of positive [`Rational`]s, but negated. See
151/// [`exhaustive_positive_rationals`] for details.
152///
153/// The output length is infinite. The absolute values of the numerators and denominators of the
154/// $n$th element are $O(n^\frac{\log \phi}{\log 2})$.
155///
156/// # Worst-case complexity per iteration
157/// $T(i) = O(\log i \log\log i \log\log\log i)$
158///
159/// $M(i) = O(\log i \log\log i)$
160///
161/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
162///
163/// # Examples
164/// ```
165/// use malachite_base::iterators::prefix_to_string;
166/// use malachite_q::exhaustive::exhaustive_negative_rationals;
167///
168/// assert_eq!(
169///     prefix_to_string(exhaustive_negative_rationals(), 20),
170///     "[-1, -1/2, -2, -1/3, -3/2, -2/3, -3, -1/4, -4/3, -3/5, -5/2, -2/5, -5/3, -3/4, -4, -1/5, \
171///     -5/4, -4/7, -7/3, -3/8, ...]"
172/// )
173/// ```
174pub const fn exhaustive_negative_rationals() -> ExhaustiveNegativeRationals {
175    ExhaustiveNegativeRationals {
176        xs: exhaustive_positive_rationals(),
177    }
178}
179
180/// Generates all nonzero [`Rational`]s.
181///
182/// This `struct` is created by [`exhaustive_nonzero_rationals`]; see its documentation for more.
183#[derive(Clone, Debug)]
184pub struct ExhaustiveNonzeroRationals {
185    xs: ExhaustivePositiveRationals,
186    x: Option<Rational>,
187    sign: bool,
188}
189
190impl Iterator for ExhaustiveNonzeroRationals {
191    type Item = Rational;
192
193    fn next(&mut self) -> Option<Rational> {
194        if self.sign {
195            self.sign = false;
196            let mut x = None;
197            swap(&mut self.x, &mut x);
198            let mut x = x.unwrap();
199            x.sign = false;
200            Some(x)
201        } else {
202            self.sign = true;
203            self.x = self.xs.next();
204            Some(self.x.clone().unwrap())
205        }
206    }
207}
208
209/// Generates all nonzero [`Rational`]s.
210///
211/// The sequence is the same the sequence of positive [`Rational`]s, interleaved with its negative.
212/// See [`exhaustive_positive_rationals`] for details.
213///
214/// The output length is infinite. The absolute values of the numerators and denominators of the
215/// $n$th element are $O(n^\frac{\log \phi}{\log 2})$.
216///
217/// # Worst-case complexity per iteration
218/// $T(i) = O(\log i \log\log i \log\log\log i)$
219///
220/// $M(i) = O(\log i \log\log i)$
221///
222/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
223///
224/// # Examples
225/// ```
226/// use malachite_base::iterators::prefix_to_string;
227/// use malachite_q::exhaustive::exhaustive_nonzero_rationals;
228///
229/// assert_eq!(
230///     prefix_to_string(exhaustive_nonzero_rationals(), 20),
231///     "[1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, 3/2, -3/2, 2/3, -2/3, 3, -3, 1/4, -1/4, 4/3, -4/3, \
232///     3/5, -3/5, ...]"
233/// )
234/// ```
235pub const fn exhaustive_nonzero_rationals() -> ExhaustiveNonzeroRationals {
236    ExhaustiveNonzeroRationals {
237        xs: exhaustive_positive_rationals(),
238        x: None,
239        sign: false,
240    }
241}
242
243/// Generates all [`Rational`]s.
244///
245/// The sequence begins with zero and is followed by the sequence of positive [`Rational`]s,
246/// interleaved with its negative. See [`exhaustive_positive_rationals`] for details.
247///
248/// The output length is infinite. The absolute values of the numerators and denominators of the
249/// $n$th element are $O(n^\frac{\log \phi}{\log 2})$.
250///
251/// # Worst-case complexity per iteration
252/// $T(n) = O(\log n \log\log n \log\log\log n)$
253///
254/// $M(i) = O(\log n \log\log n)$
255///
256/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
257///
258/// # Examples
259/// ```
260/// use malachite_base::iterators::prefix_to_string;
261/// use malachite_q::exhaustive::exhaustive_rationals;
262///
263/// assert_eq!(
264///     prefix_to_string(exhaustive_rationals(), 20),
265///     "[0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, 3/2, -3/2, 2/3, -2/3, 3, -3, 1/4, -1/4, 4/3, \
266///     -4/3, 3/5, ...]"
267/// )
268/// ```
269pub fn exhaustive_rationals() -> Chain<Once<Rational>, ExhaustiveNonzeroRationals> {
270    once(Rational::ZERO).chain(exhaustive_nonzero_rationals())
271}
272
273/// Generates all [`Rational`]s with a specific denominator and with numerators from a given
274/// iterator. Numerators that are not coprime with the denominator are skipped.
275#[derive(Clone, Debug)]
276pub struct RationalsWithDenominator<I: Iterator<Item = Integer>> {
277    pub(crate) numerators: I,
278    pub(crate) denominator: Natural,
279}
280
281impl<I: Iterator<Item = Integer>> Iterator for RationalsWithDenominator<I> {
282    type Item = Rational;
283
284    fn next(&mut self) -> Option<Rational> {
285        loop {
286            let n = self.numerators.next()?;
287            if n.unsigned_abs_ref().coprime_with(&self.denominator) {
288                return Some(Rational {
289                    sign: n >= 0u32,
290                    numerator: n.unsigned_abs(),
291                    denominator: self.denominator.clone(),
292                });
293            }
294        }
295    }
296}
297
298/// Generates all [`Rational`]s greater than or equal to some number $a$ and with a specific
299/// denominator, in order of increasing absolute value.
300///
301/// When two [`Rational`]s have the same absolute value, the positive one comes first.
302///
303/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
304/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
305///
306/// The output length is infinite.
307///
308/// # Worst-case complexity per iteration
309/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
310///
311/// $M(i) = O(\log i \log \log i)$
312///
313/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
314///
315/// # Panics
316/// Panics if `d` is zero.
317///
318/// # Examples
319/// ```
320/// use malachite_base::iterators::prefix_to_string;
321/// use malachite_nz::natural::Natural;
322/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_range_to_infinity;
323/// use malachite_q::Rational;
324///
325/// assert_eq!(
326///     prefix_to_string(
327///         exhaustive_rationals_with_denominator_range_to_infinity(
328///             Natural::from(5u32),
329///             Rational::from_signeds(22i32, 7)
330///         ),
331///         10
332///     ),
333///     "[16/5, 17/5, 18/5, 19/5, 21/5, 22/5, 23/5, 24/5, 26/5, 27/5, ...]"
334/// );
335/// assert_eq!(
336///     prefix_to_string(
337///         exhaustive_rationals_with_denominator_range_to_infinity(
338///             Natural::from(2u32),
339///             Rational::from_signeds(-22i32, 7)
340///         ),
341///         10
342///     ),
343///     "[1/2, -1/2, 3/2, -3/2, 5/2, -5/2, 7/2, 9/2, 11/2, 13/2, ...]"
344/// );
345/// ```
346pub fn exhaustive_rationals_with_denominator_range_to_infinity(
347    d: Natural,
348    a: Rational,
349) -> RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity> {
350    assert_ne!(d, 0u32);
351    RationalsWithDenominator {
352        numerators: exhaustive_integer_range_to_infinity(
353            Integer::rounding_from(a * Rational::from(&d), Ceiling).0,
354        ),
355        denominator: d,
356    }
357}
358
359/// Generates all [`Rational`]s less than or equal to some number $a$ and with a specific
360/// denominator, in order of increasing absolute value.
361///
362/// When two [`Rational`]s have the same absolute value, the positive one comes first.
363///
364/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
365/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
366///
367/// The output length is infinite.
368///
369/// # Worst-case complexity per iteration
370/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
371///
372/// $M(i) = O(\log i \log \log i)$
373///
374/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
375///
376/// # Panics
377/// Panics if `d` is zero.
378///
379/// # Examples
380/// ```
381/// use malachite_base::iterators::prefix_to_string;
382/// use malachite_nz::natural::Natural;
383/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_range_to_negative_infinity;
384/// use malachite_q::Rational;
385///
386/// assert_eq!(
387///     prefix_to_string(
388///         exhaustive_rationals_with_denominator_range_to_negative_infinity(
389///             Natural::from(5u32),
390///             Rational::from_signeds(-22i32, 7)
391///         ),
392///         10
393///     ),
394///     "[-16/5, -17/5, -18/5, -19/5, -21/5, -22/5, -23/5, -24/5, -26/5, -27/5, ...]"
395/// );
396/// assert_eq!(
397///     prefix_to_string(
398///         exhaustive_rationals_with_denominator_range_to_negative_infinity(
399///             Natural::from(2u32),
400///             Rational::from_signeds(22i32, 7)
401///         ),
402///         10
403///     ),
404///     "[1/2, -1/2, 3/2, -3/2, 5/2, -5/2, -7/2, -9/2, -11/2, -13/2, ...]"
405/// );
406/// ```
407pub fn exhaustive_rationals_with_denominator_range_to_negative_infinity(
408    d: Natural,
409    a: Rational,
410) -> RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity> {
411    assert_ne!(d, 0u32);
412    RationalsWithDenominator {
413        numerators: exhaustive_integer_range_to_negative_infinity(
414            Integer::rounding_from(a * Rational::from(&d), Floor).0,
415        ),
416        denominator: d,
417    }
418}
419
420/// Generates all [`Rational`]s in the half-open range $[a, b)$ and with a specific denominator, in
421/// order of increasing absolute value.
422///
423/// When two [`Rational`]s have the same absolute value, the positive one comes first.
424///
425/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
426/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
427///
428/// The output length is infinite.
429///
430/// # Worst-case complexity per iteration
431/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
432///
433/// $M(i) = O(\log i \log \log i)$
434///
435/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
436///
437/// # Panics
438/// Panics if `d` is zero or if $a \geq b$.
439///
440/// # Examples
441/// ```
442/// use itertools::Itertools;
443/// use malachite_base::strings::ToDebugString;
444/// use malachite_nz::natural::Natural;
445/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_range;
446/// use malachite_q::Rational;
447///
448/// assert_eq!(
449///     exhaustive_rationals_with_denominator_range(
450///         Natural::from(2u32),
451///         Rational::from_signeds(1i32, 3),
452///         Rational::from_signeds(5i32, 2)
453///     )
454///     .collect_vec()
455///     .to_debug_string(),
456///     "[1/2, 3/2]"
457/// );
458/// assert_eq!(
459///     exhaustive_rationals_with_denominator_range(
460///         Natural::from(2u32),
461///         Rational::from_signeds(-5i32, 3),
462///         Rational::from_signeds(5i32, 2)
463///     )
464///     .collect_vec()
465///     .to_debug_string(),
466///     "[1/2, -1/2, 3/2, -3/2]"
467/// );
468/// assert_eq!(
469///     exhaustive_rationals_with_denominator_range(
470///         Natural::from(10u32),
471///         Rational::try_from_float_simplest(std::f64::consts::E).unwrap(),
472///         Rational::try_from_float_simplest(std::f64::consts::PI).unwrap(),
473///     )
474///     .collect_vec()
475///     .to_debug_string(),
476///     "[29/10, 31/10]"
477/// );
478/// ```
479pub fn exhaustive_rationals_with_denominator_range(
480    d: Natural,
481    a: Rational,
482    b: Rational,
483) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
484    assert_ne!(d, 0u32);
485    assert!(a < b);
486    let q_d = Rational::from(&d);
487    let a_i = Integer::rounding_from(a * &q_d, Ceiling).0;
488    let upper_included = b.denominator_ref() == &d;
489    let mut b_i = Integer::rounding_from(b * q_d, Floor).0;
490    if !upper_included {
491        b_i += Integer::ONE;
492    }
493    RationalsWithDenominator {
494        numerators: exhaustive_integer_range(a_i, b_i),
495        denominator: d,
496    }
497}
498
499/// Generates all [`Rational`]s in the closed range $[a, b]$ and with a specific denominator, in
500/// order of increasing absolute value.
501///
502/// When two [`Rational`]s have the same absolute value, the positive one comes first.
503///
504/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
505/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
506///
507/// The output length is infinite.
508///
509/// # Worst-case complexity per iteration
510/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
511///
512/// $M(i) = O(\log i \log \log i)$
513///
514/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
515///
516/// # Panics
517/// Panics if `d` is zero or if $a > b$.
518///
519/// # Examples
520/// ```
521/// use itertools::Itertools;
522/// use malachite_base::strings::ToDebugString;
523/// use malachite_nz::natural::Natural;
524/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_inclusive_range;
525/// use malachite_q::Rational;
526///
527/// assert_eq!(
528///     exhaustive_rationals_with_denominator_inclusive_range(
529///         Natural::from(2u32),
530///         Rational::from_signeds(1i32, 3),
531///         Rational::from_signeds(5i32, 2)
532///     )
533///     .collect_vec()
534///     .to_debug_string(),
535///     "[1/2, 3/2, 5/2]"
536/// );
537/// assert_eq!(
538///     exhaustive_rationals_with_denominator_inclusive_range(
539///         Natural::from(2u32),
540///         Rational::from_signeds(-5i32, 3),
541///         Rational::from_signeds(5i32, 2)
542///     )
543///     .collect_vec()
544///     .to_debug_string(),
545///     "[1/2, -1/2, 3/2, -3/2, 5/2]"
546/// );
547/// assert_eq!(
548///     exhaustive_rationals_with_denominator_inclusive_range(
549///         Natural::from(10u32),
550///         Rational::try_from_float_simplest(std::f64::consts::E).unwrap(),
551///         Rational::try_from_float_simplest(std::f64::consts::PI).unwrap(),
552///     )
553///     .collect_vec()
554///     .to_debug_string(),
555///     "[29/10, 31/10]"
556/// );
557/// ```
558pub fn exhaustive_rationals_with_denominator_inclusive_range(
559    d: Natural,
560    a: Rational,
561    b: Rational,
562) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
563    assert_ne!(d, 0u32);
564    assert!(a <= b);
565    let q_d = Rational::from(&d);
566    let a_i = Integer::rounding_from(a * &q_d, Ceiling).0;
567    let b_i = Integer::rounding_from(b * q_d, Floor).0 + Integer::ONE;
568    RationalsWithDenominator {
569        numerators: exhaustive_integer_range(a_i, b_i),
570        denominator: d,
571    }
572}
573
574#[derive(Clone, Debug)]
575struct ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator {
576    a: Rational,
577}
578
579impl
580    ExhaustiveDependentPairsYsGenerator<
581        Natural,
582        Rational,
583        RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity>,
584    > for ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator
585{
586    #[inline]
587    fn get_ys(&self, d: &Natural) -> RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity> {
588        exhaustive_rationals_with_denominator_range_to_infinity(d.clone(), self.a.clone())
589    }
590}
591
592#[inline]
593const fn exhaustive_rational_range_to_infinity_helper(
594    a: Rational,
595) -> ExhaustiveDependentPairs<
596    Natural,
597    Rational,
598    RulerSequence<usize>,
599    ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator,
600    ExhaustiveNaturalRangeToInfinity,
601    RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity>,
602> {
603    exhaustive_dependent_pairs(
604        ruler_sequence(),
605        exhaustive_positive_naturals(),
606        ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator { a },
607    )
608}
609
610/// Generates all [`Rational`]s greater than or equal to some [`Rational`].
611///
612/// This `struct` is created by [`exhaustive_rational_range_to_infinity`]; see its documentation for
613/// more.
614#[derive(Clone, Debug)]
615pub struct ExhaustiveRationalRangeToInfinity(
616    ExhaustiveDependentPairs<
617        Natural,
618        Rational,
619        RulerSequence<usize>,
620        ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator,
621        ExhaustiveNaturalRangeToInfinity,
622        RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity>,
623    >,
624);
625
626impl Iterator for ExhaustiveRationalRangeToInfinity {
627    type Item = Rational;
628
629    #[inline]
630    fn next(&mut self) -> Option<Rational> {
631        self.0.next().map(|p| p.1)
632    }
633}
634
635/// Generates all [`Rational`]s greater than or equal to some [`Rational`] $a$.
636///
637/// The output length is infinite.
638///
639/// # Worst-case complexity per iteration
640/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
641///
642/// $M(i) = O(\log i \log \log i)$
643///
644/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
645///
646/// # Examples
647/// ```
648/// use malachite_base::iterators::prefix_to_string;
649/// use malachite_base::num::conversion::traits::ExactFrom;
650/// use malachite_q::exhaustive::exhaustive_rational_range_to_infinity;
651/// use malachite_q::Rational;
652///
653/// assert_eq!(
654///     prefix_to_string(
655///         exhaustive_rational_range_to_infinity(Rational::exact_from(std::f64::consts::PI)),
656///         20
657///     ),
658///     "[4, 7/2, 5, 10/3, 6, 9/2, 7, 13/4, 8, 11/2, 9, 11/3, 10, 13/2, 11, 16/5, 12, 15/2, 13, \
659///     13/3, ...]"
660/// )
661/// ```
662#[inline]
663pub const fn exhaustive_rational_range_to_infinity(
664    a: Rational,
665) -> ExhaustiveRationalRangeToInfinity {
666    ExhaustiveRationalRangeToInfinity(exhaustive_rational_range_to_infinity_helper(a))
667}
668
669#[derive(Clone, Debug)]
670struct ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator {
671    a: Rational,
672}
673
674impl
675    ExhaustiveDependentPairsYsGenerator<
676        Natural,
677        Rational,
678        RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity>,
679    > for ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator
680{
681    #[inline]
682    fn get_ys(
683        &self,
684        d: &Natural,
685    ) -> RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity> {
686        exhaustive_rationals_with_denominator_range_to_negative_infinity(d.clone(), self.a.clone())
687    }
688}
689
690#[inline]
691const fn exhaustive_rational_range_to_negative_infinity_helper(
692    a: Rational,
693) -> ExhaustiveDependentPairs<
694    Natural,
695    Rational,
696    RulerSequence<usize>,
697    ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator,
698    ExhaustiveNaturalRangeToInfinity,
699    RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity>,
700> {
701    exhaustive_dependent_pairs(
702        ruler_sequence(),
703        exhaustive_positive_naturals(),
704        ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator { a },
705    )
706}
707
708/// Generates all [`Rational`]s less than or equal to some [`Rational`].
709///
710/// This `struct` is created by [`exhaustive_rational_range_to_negative_infinity`]; see its
711/// documentation for more.
712#[derive(Clone, Debug)]
713pub struct ExhaustiveRationalRangeToNegativeInfinity(
714    ExhaustiveDependentPairs<
715        Natural,
716        Rational,
717        RulerSequence<usize>,
718        ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator,
719        ExhaustiveNaturalRangeToInfinity,
720        RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity>,
721    >,
722);
723
724impl Iterator for ExhaustiveRationalRangeToNegativeInfinity {
725    type Item = Rational;
726
727    #[inline]
728    fn next(&mut self) -> Option<Rational> {
729        self.0.next().map(|p| p.1)
730    }
731}
732
733/// Generates all [`Rational`]s less than or equal to some [`Rational`] $a$.
734///
735/// The output length is infinite.
736///
737/// # Worst-case complexity per iteration
738/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
739///
740/// $M(i) = O(\log i \log \log i)$
741///
742/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
743///
744/// # Examples
745/// ```
746/// use malachite_base::iterators::prefix_to_string;
747/// use malachite_base::num::conversion::traits::ExactFrom;
748/// use malachite_q::exhaustive::exhaustive_rational_range_to_negative_infinity;
749/// use malachite_q::Rational;
750///
751/// assert_eq!(
752///     prefix_to_string(
753///         exhaustive_rational_range_to_negative_infinity(Rational::exact_from(
754///             std::f64::consts::PI
755///         )),
756///         20
757///     ),
758///     "[0, 1/2, 1, 1/3, -1, -1/2, 2, 1/4, -2, 3/2, 3, -1/3, -3, -3/2, -4, 1/5, -5, 5/2, -6, \
759///     2/3, ...]"
760/// )
761/// ```
762#[inline]
763pub const fn exhaustive_rational_range_to_negative_infinity(
764    a: Rational,
765) -> ExhaustiveRationalRangeToNegativeInfinity {
766    ExhaustiveRationalRangeToNegativeInfinity(
767        exhaustive_rational_range_to_negative_infinity_helper(a),
768    )
769}
770
771#[derive(Clone, Debug)]
772struct ExhaustiveRationalsWithDenominatorRangeGenerator {
773    a: Rational,
774    b: Rational,
775}
776
777impl
778    ExhaustiveDependentPairsYsGenerator<
779        Natural,
780        Rational,
781        RationalsWithDenominator<ExhaustiveIntegerRange>,
782    > for ExhaustiveRationalsWithDenominatorRangeGenerator
783{
784    #[inline]
785    fn get_ys(&self, d: &Natural) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
786        exhaustive_rationals_with_denominator_range(d.clone(), self.a.clone(), self.b.clone())
787    }
788}
789
790#[inline]
791fn exhaustive_rational_range_helper(
792    a: Rational,
793    b: Rational,
794) -> ExhaustiveDependentPairs<
795    Natural,
796    Rational,
797    RulerSequence<usize>,
798    ExhaustiveRationalsWithDenominatorRangeGenerator,
799    DenominatorsInClosedRationalInterval,
800    RationalsWithDenominator<ExhaustiveIntegerRange>,
801> {
802    exhaustive_dependent_pairs(
803        ruler_sequence(),
804        Rational::denominators_in_closed_interval(a.clone(), b.clone()),
805        ExhaustiveRationalsWithDenominatorRangeGenerator { a, b },
806    )
807}
808
809/// Generates all [`Natural`]s in an interval of the form $[a,b)$.
810///
811/// This `struct` is created by [`exhaustive_rational_range`]; see its documentation for more.
812#[allow(private_interfaces, clippy::large_enum_variant)]
813#[derive(Clone, Debug)]
814pub enum ExhaustiveRationalRange {
815    Empty,
816    Nonempty(
817        ExhaustiveDependentPairs<
818            Natural,
819            Rational,
820            RulerSequence<usize>,
821            ExhaustiveRationalsWithDenominatorRangeGenerator,
822            DenominatorsInClosedRationalInterval,
823            RationalsWithDenominator<ExhaustiveIntegerRange>,
824        >,
825    ),
826}
827
828impl Iterator for ExhaustiveRationalRange {
829    type Item = Rational;
830
831    #[inline]
832    fn next(&mut self) -> Option<Rational> {
833        match self {
834            Self::Empty => None,
835            Self::Nonempty(xs) => xs.next().map(|p| p.1),
836        }
837    }
838}
839
840/// Generates all [`Rational`]s in the half-open interval $[a, b)$.
841///
842/// `a` must be less than or equal to `b`. If `a` and `b` are equal, the range is empty. To generate
843/// all [`Rational`]s in an infinite interval, use [`exhaustive_rational_range_to_infinity`] or
844/// [`exhaustive_rational_range_to_negative_infinity`].
845///
846/// The output length is infinite if $a<b$ and 0 if $a=b$.
847///
848/// # Worst-case complexity per iteration
849/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
850///
851/// $M(i) = O(\log i \log \log i)$
852///
853/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
854///
855/// # Panics
856/// Panics if $a>b$.
857///
858/// # Examples
859/// ```
860/// use malachite_base::iterators::prefix_to_string;
861/// use malachite_base::num::conversion::traits::ExactFrom;
862/// use malachite_q::exhaustive::exhaustive_rational_range;
863/// use malachite_q::Rational;
864///
865/// assert_eq!(
866///     prefix_to_string(
867///         exhaustive_rational_range(
868///             Rational::exact_from(std::f64::consts::E),
869///             Rational::exact_from(std::f64::consts::PI)
870///         ),
871///         20
872///     ),
873///     "[3, 11/4, 14/5, 20/7, 17/6, 23/8, 25/8, 30/11, 25/9, 29/10, 26/9, 31/11, 28/9, 31/10, \
874///     32/11, 41/15, 34/11, 35/12, 37/12, 39/14, ...]"
875/// )
876/// ```
877#[inline]
878pub fn exhaustive_rational_range(a: Rational, b: Rational) -> ExhaustiveRationalRange {
879    if a == b {
880        ExhaustiveRationalRange::Empty
881    } else {
882        ExhaustiveRationalRange::Nonempty(exhaustive_rational_range_helper(a, b))
883    }
884}
885
886#[derive(Clone, Debug)]
887struct ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator {
888    a: Rational,
889    b: Rational,
890}
891
892impl
893    ExhaustiveDependentPairsYsGenerator<
894        Natural,
895        Rational,
896        RationalsWithDenominator<ExhaustiveIntegerRange>,
897    > for ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator
898{
899    #[inline]
900    fn get_ys(&self, d: &Natural) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
901        exhaustive_rationals_with_denominator_inclusive_range(
902            d.clone(),
903            self.a.clone(),
904            self.b.clone(),
905        )
906    }
907}
908
909#[inline]
910fn exhaustive_rational_inclusive_range_helper(
911    a: Rational,
912    b: Rational,
913) -> ExhaustiveDependentPairs<
914    Natural,
915    Rational,
916    RulerSequence<usize>,
917    ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator,
918    DenominatorsInClosedRationalInterval,
919    RationalsWithDenominator<ExhaustiveIntegerRange>,
920> {
921    exhaustive_dependent_pairs(
922        ruler_sequence(),
923        Rational::denominators_in_closed_interval(a.clone(), b.clone()),
924        ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator { a, b },
925    )
926}
927
928/// Generates all [`Rational`]s in an interval of the form $\[a,b\]$.
929///
930/// This `struct` is created by [`exhaustive_rational_inclusive_range`]; see its documentation for
931/// more.
932#[allow(private_interfaces, clippy::large_enum_variant)]
933#[derive(Clone, Debug)]
934pub enum ExhaustiveRationalInclusiveRange {
935    Single(bool, Rational),
936    Many(
937        ExhaustiveDependentPairs<
938            Natural,
939            Rational,
940            RulerSequence<usize>,
941            ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator,
942            DenominatorsInClosedRationalInterval,
943            RationalsWithDenominator<ExhaustiveIntegerRange>,
944        >,
945    ),
946}
947
948impl Iterator for ExhaustiveRationalInclusiveRange {
949    type Item = Rational;
950
951    #[inline]
952    fn next(&mut self) -> Option<Rational> {
953        match self {
954            Self::Single(done, x) => {
955                if *done {
956                    None
957                } else {
958                    *done = true;
959                    Some(x.clone())
960                }
961            }
962            Self::Many(xs) => xs.next().map(|p| p.1),
963        }
964    }
965}
966
967/// Generates all [`Rational`]s in the closed interval $[a, b]$.
968///
969/// `a` must be less than or equal to `b`. If `a` and `b` are equal, the range contains a single
970/// element. To generate all [`Rational`]s in an infinite interval, use
971/// [`exhaustive_rational_range_to_infinity`] or [`exhaustive_rational_range_to_negative_infinity`].
972///
973/// The output length is infinite if $a<b$ and 1 if $a=b$.
974///
975/// # Worst-case complexity per iteration
976/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
977///
978/// $M(i) = O(\log i \log \log i)$
979///
980/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
981///
982/// # Panics
983/// Panics if $a>b$.
984///
985/// # Examples
986/// ```
987/// use malachite_base::iterators::prefix_to_string;
988/// use malachite_base::num::conversion::traits::ExactFrom;
989/// use malachite_q::exhaustive::exhaustive_rational_inclusive_range;
990/// use malachite_q::Rational;
991///
992/// assert_eq!(
993///     prefix_to_string(
994///         exhaustive_rational_inclusive_range(
995///             Rational::exact_from(std::f64::consts::E),
996///             Rational::exact_from(std::f64::consts::PI)
997///         ),
998///         20
999///     ),
1000///     "[3, 11/4, 14/5, 20/7, 17/6, 23/8, 25/8, 30/11, 25/9, 29/10, 26/9, 31/11, 28/9, 31/10, \
1001///     32/11, 41/15, 34/11, 35/12, 37/12, 39/14, ...]"
1002/// )
1003/// ```
1004#[inline]
1005pub fn exhaustive_rational_inclusive_range(
1006    a: Rational,
1007    b: Rational,
1008) -> ExhaustiveRationalInclusiveRange {
1009    if a == b {
1010        ExhaustiveRationalInclusiveRange::Single(false, a)
1011    } else {
1012        ExhaustiveRationalInclusiveRange::Many(exhaustive_rational_inclusive_range_helper(a, b))
1013    }
1014}