maelstrom_simex/
lib.rs

1//! Provide a mechanism for exhaustively exploring all possible simulations in a simulation space.
2//!
3//! The user is given a [`Simulation`] object, from which they can retrieve values (choices). On
4//! later simulations, different values will be retrieved. The [`SimulationExplorer`] will keep
5//! yielding simulations until all possible values have been returned.
6#![deny(missing_docs)]
7
8use num::integer::{Average, Integer};
9use std::{
10    collections::VecDeque,
11    iter::{Fuse, FusedIterator},
12};
13
14/*  ____  _                 _       _   _             ____  _        _
15 * / ___|(_)_ __ ___  _   _| | __ _| |_(_) ___  _ __ / ___|| |_ __ _| |_ ___
16 * \___ \| | '_ ` _ \| | | | |/ _` | __| |/ _ \| '_ \\___ \| __/ _` | __/ _ \
17 *  ___) | | | | | | | |_| | | (_| | |_| | (_) | | | |___) | || (_| | ||  __/
18 * |____/|_|_| |_| |_|\__,_|_|\__,_|\__|_|\___/|_| |_|____/ \__\__,_|\__\___|
19 *  FIGLET: SimulationState
20 */
21
22/// The underlying state of a simulation. It just consists of the script and our cursor within the
23/// script.
24///
25/// The state is shared by `SimulationExplorer` and `Simulation`, implying that only a single
26/// `Simulation` may be currently ongoing.
27#[derive(Default)]
28#[doc(hidden)]
29struct SimulationState {
30    script: Vec<bool>,
31    cursor: usize,
32}
33
34impl SimulationState {
35    /// Choose a bool.
36    ///
37    /// There are two cases. If we are at the beginning of the script, then we are just replaying
38    /// what happened in the previous script. In that case, we just returned the scripted value and
39    /// increment out cursor.
40    ///
41    /// Otherwise, we're in unexplored territory, and we always return false. Subsequent
42    /// simulations will return true.
43    ///
44    /// In the first case, we have something like this:
45    /// >    Before:
46    /// >        01101
47    /// >          ^
48    /// >          |
49    /// >        cursor
50    /// >
51    /// >    After:
52    /// >        01101
53    /// >          ^
54    /// >          |
55    /// >        cursor
56    ///
57    /// In the second case, we have something like this:
58    /// >    Before:
59    /// >        0101
60    /// >           ^
61    /// >           |
62    /// >         cursor
63    /// >
64    /// >    After:
65    /// >        01010
66    /// >            ^
67    /// >            |
68    /// >          cursor
69    fn choose_bool(&mut self) -> bool {
70        let result = if self.cursor == self.script.len() {
71            self.script.push(false);
72            false
73        } else {
74            self.script[self.cursor]
75        };
76        self.cursor += 1;
77        result
78    }
79
80    /// End the current simulation and prepare for the next simulation, if there was one.
81    ///
82    /// If this function is called while the cursor is still within the script from the previous
83    /// simulation, then we know we've hit some sort of non-determinism, and we panic. In other
84    /// words, the previous simulation walked the exact same script up to (and potentially past)
85    /// this point before it finished. So, if next_simulation is being called before we reach that
86    /// same point, we know that the simulation must not be executing the same code.
87    ///
88    /// To update the script for the next simulation, we first try to reverse the last decision.
89    /// However, if we've already done that, we reverse the decision before that, etc. The net
90    /// result is to add one to the binary representation of the script, and then remove any
91    /// trailing zeros. We remove the whole script, then we're done.
92    ///
93    /// Example one:
94    /// >    Before:
95    /// >        010
96    /// >          ^
97    /// >          |
98    /// >        cursor
99    /// >
100    /// >    After:
101    /// >        011
102    /// >        ^
103    /// >        |
104    /// >      cursor
105    ///
106    /// Example two:
107    /// >    Before:
108    /// >        0101
109    /// >           ^
110    /// >           |
111    /// >         cursor
112    /// >
113    /// >    After:
114    /// >        011
115    /// >        ^
116    /// >        |
117    /// >      cursor
118    ///
119    /// Example three:
120    /// >    Before:
121    /// >        0111
122    /// >           ^
123    /// >           |
124    /// >         cursor
125    /// >
126    /// >    After:
127    /// >        1
128    /// >        ^
129    /// >        |
130    /// >      cursor
131    ///
132    /// Example four:
133    /// >    Before:
134    /// >        1111
135    /// >           ^
136    /// >           |
137    /// >         cursor
138    /// >
139    /// >    After:
140    /// >        Done
141    fn end_current_simulation_and_prepare_next(&mut self) -> bool {
142        assert!(self.cursor == self.script.len());
143        self.cursor = 0;
144        while let Some(last) = self.script.last_mut() {
145            if *last {
146                self.script.pop();
147            } else {
148                *last = true;
149                return true;
150            }
151        }
152        false
153    }
154}
155
156/*  ____  _                 _       _   _             _____            _
157 * / ___|(_)_ __ ___  _   _| | __ _| |_(_) ___  _ __ | ____|_  ___ __ | | ___  _ __ ___ _ __
158 * \___ \| | '_ ` _ \| | | | |/ _` | __| |/ _ \| '_ \|  _| \ \/ / '_ \| |/ _ \| '__/ _ \ '__|
159 *  ___) | | | | | | | |_| | | (_| | |_| | (_) | | | | |___ >  <| |_) | | (_) | | |  __/ |
160 * |____/|_|_| |_| |_|\__,_|_|\__,_|\__|_|\___/|_| |_|_____/_/\_\ .__/|_|\___/|_|  \___|_|
161 *                                                              |_|
162 *  FIGLET: SimulationExplorer
163 */
164
165/// An object that yields successive [`Simulation`]s until there are no more.
166#[derive(Default)]
167pub struct SimulationExplorer {
168    state: Option<SimulationState>,
169}
170
171impl SimulationExplorer {
172    /// Provide the next [`Simulation`], if there is one.
173    pub fn next_simulation(&mut self) -> Option<Simulation<'_>> {
174        match self.state {
175            None => {
176                self.state = Some(SimulationState::default());
177                Some(Simulation {
178                    state: self.state.as_mut().unwrap(),
179                })
180            }
181            Some(ref mut state) => {
182                if state.end_current_simulation_and_prepare_next() {
183                    Some(Simulation { state })
184                } else {
185                    None
186                }
187            }
188        }
189    }
190
191    /// Run all simulations by providing successive [`Simulation`]s to the given closure.
192    pub fn for_each<F, T>(&mut self, f: F)
193    where
194        F: for<'b> FnMut(Simulation<'b>) -> T,
195    {
196        self.map(f).for_each(|_| ())
197    }
198
199    /// Provide successive [`Simulation`]s to the given closure, and provide an iterator over the
200    /// results.
201    pub fn map<F, T>(&mut self, f: F) -> Map<'_, F>
202    where
203        F: for<'b> FnMut(Simulation<'b>) -> T,
204    {
205        Map { simex: self, f }
206    }
207}
208
209/*  ____  _                 _       _   _
210 * / ___|(_)_ __ ___  _   _| | __ _| |_(_) ___  _ __
211 * \___ \| | '_ ` _ \| | | | |/ _` | __| |/ _ \| '_ \
212 *  ___) | | | | | | | |_| | | (_| | |_| | (_) | | | |
213 * |____/|_|_| |_| |_|\__,_|_|\__,_|\__|_|\___/|_| |_|
214 *  FIGLET: Simulation
215 */
216
217/// An object that yields successive choices and which can be used to drive a simulation.
218///
219/// This object points into data owned by the [`SimulationExplorer`], and as such, only one
220/// `Simulation` may be ongoing at a time (from a single `SimulationExplorer`).
221pub struct Simulation<'a> {
222    state: &'a mut SimulationState,
223}
224
225impl<'a> Simulation<'a> {
226    /// Choose a boolean value. Values will be returned in ascending order: `false` then `true`.
227    ///
228    /// This is the primitive upon which all other `choose_` functions are built.
229    ///
230    /// This function has constant time complexity, and increases the size of the `Simulation` by
231    /// small, constant amount.
232    ///
233    /// # Examples
234    /// ```
235    /// use maelstrom_simex::SimulationExplorer;
236    /// let mut simex = SimulationExplorer::default();
237    /// assert!(simex.map(|mut sim| sim.choose_bool()).eq([false, true]))
238    /// ```
239    pub fn choose_bool(&mut self) -> bool {
240        self.state.choose_bool()
241    }
242
243    /// Choose an integer value in the closed range `[min, max]`. Values will be returned in
244    /// ascending order.
245    ///
246    /// This function has time complexity of O(log(max-min)). It also increases the size of the
247    /// `Simulation` by small amount that is O(log(max-min)).
248    ///
249    /// # Panics
250    /// This function will panic if `max` is less than `min`.
251    ///
252    /// # Examples
253    /// ```
254    /// use maelstrom_simex::SimulationExplorer;
255    /// assert!(SimulationExplorer::default()
256    ///     .map(|mut sim| sim.choose_integer(0, 10))
257    ///     .eq(0..=10));
258    /// assert!(SimulationExplorer::default()
259    ///     .map(|mut sim| sim.choose_integer(-1, 1))
260    ///     .eq(-1..=1));
261    /// ```
262    pub fn choose_integer<T: Average + Copy + Integer>(&mut self, min: T, max: T) -> T {
263        assert!(min <= max);
264        self.choose_integer_unchecked(min, max)
265    }
266
267    /// Like `choose_integer`, but no check is done to asser that `min <= max`. If `min > max`,
268    /// then the program will likely crash by running out of memory, or suffer some other similar
269    /// fate.
270    #[doc(hidden)]
271    fn choose_integer_unchecked<T: Average + Copy + Integer>(&mut self, min: T, max: T) -> T {
272        if min == max {
273            min
274        } else if !self.choose_bool() {
275            self.choose_integer_unchecked(min, min.average_floor(&max))
276        } else {
277            self.choose_integer_unchecked(min.average_floor(&max) + T::one(), max)
278        }
279    }
280
281    /// Choose one value out of the given `ExactSizeIterator`. If the iterator is empty, return
282    /// `None`.
283    ///
284    /// Values are returned in the iterator's order.
285    ///
286    /// Let N be the length of the underlying iterator. This function does O(log(N)) work and then
287    /// calls `Iterator::nth`. Thus, the time complexity can be as low as O(log(N)), and as high as
288    /// O(N) (assuming `Iterator::nth` is no worse than O(N)).
289    ///
290    /// This function will increase the size of `Simulation` by a small amount that is O(log(N)).
291    ///
292    /// # Examples
293    /// ```
294    /// use maelstrom_simex::SimulationExplorer;
295    /// assert!(SimulationExplorer::default()
296    ///     .map(|mut sim| sim.choose(0..10).unwrap())
297    ///     .eq(0..10));
298    /// assert!(SimulationExplorer::default()
299    ///     .map(|mut sim| sim.choose([-1, 0, 1]).unwrap())
300    ///     .eq(-1..=1));
301    /// ```
302    pub fn choose<T>(&mut self, i: T) -> Option<T::Item>
303    where
304        T: IntoIterator,
305        T::IntoIter: ExactSizeIterator,
306    {
307        let mut iter = i.into_iter();
308        match iter.len() {
309            0 => None,
310            n => iter.nth(self.choose_integer_unchecked(0, n - 1)),
311        }
312    }
313
314    /// Choose a subset of up to `n` values from the given `ExactSizeIterator`. If the iterator
315    /// contains fewer than `n` values, then all of the iterator's values will be returned.
316    /// Otherwise, a subset of `n` of them will be chosen and returned.
317    ///
318    /// Values are returned in lexicographical order. So, choosing 2 from [1, 2, 3] will return, in
319    /// order: [1, 2], [1, 3], then [2, 3].
320    ///
321    /// This function returns an iterator that returns the values in a lazy manner.
322    ///
323    /// Let N be the length of the underlying iterator. Each call to the `next()` method on the
324    /// returned iterator does O(log(N)) work and then calls `Iterator::nth`. So, if all `n` items
325    /// are retrieved from the iterator, a total of between O(n\* log(N)) and O(N) work will be done.
326    /// The former bound holds when `Iterator:nth` is constant time, and the latter bound holds
327    /// when `Iterator:nth` is linear. The reason it's not O(n\*N) in the latter case is that we
328    /// will only ever consume the underlying iterator once.
329    ///
330    /// This function will increase the size of `Simulation` by a small amount that is O(log(N)).
331    ///
332    /// The returned iterator itself is of O(1) size.
333    ///
334    /// # Examples
335    /// ```
336    /// let mut simex = maelstrom_simex::SimulationExplorer::default();
337    /// let mut combinations = vec![];
338    /// while let Some(mut simulation) = simex.next_simulation() {
339    ///     combinations.push(Vec::from_iter(simulation.choose_n(3, 1..6)));
340    /// }
341    /// assert_eq!(
342    ///     combinations,
343    ///     vec![
344    ///         [1, 2, 3],
345    ///         [1, 2, 4],
346    ///         [1, 2, 5],
347    ///         [1, 3, 4],
348    ///         [1, 3, 5],
349    ///         [1, 4, 5],
350    ///         [2, 3, 4],
351    ///         [2, 3, 5],
352    ///         [2, 4, 5],
353    ///         [3, 4, 5],
354    ///     ]
355    /// );
356    /// ```
357    pub fn choose_n<'b, T>(&'b mut self, n: usize, i: T) -> ChooseN<'a, 'b, T::IntoIter>
358    where
359        T: IntoIterator,
360        T::IntoIter: ExactSizeIterator,
361        'a: 'b,
362    {
363        ChooseN {
364            simulation: self,
365            n,
366            iter: i.into_iter(),
367        }
368    }
369
370    /// Like `Self::choose`, except the iterator doesn't have to implement `ExactSizeIterator`.
371    ///
372    /// Choose one value out of the given `Iterator`. If the iterator is empty, return `None`.
373    ///
374    /// Values are returned in the iterator's order.
375    ///
376    /// Let N be the length of the underlying iterator. The time complexity of this function is
377    /// O(N).
378    ///
379    /// This function will increase the size of `Simulation` by a small amount that is O(log(N)).
380    ///
381    /// # Examples
382    /// ```
383    /// use maelstrom_simex::SimulationExplorer;
384    /// assert!(SimulationExplorer::default()
385    ///     .map(|mut sim| sim.choose_unknown_size(0..10).unwrap())
386    ///     .eq(0..10));
387    /// assert!(SimulationExplorer::default()
388    ///     .map(|mut sim| sim.choose_unknown_size([-1, 0, 1]).unwrap())
389    ///     .eq(-1..=1));
390    /// ```
391    pub fn choose_unknown_size<T: IntoIterator>(&mut self, i: T) -> Option<T::Item> {
392        let mut iter = i.into_iter();
393        let mut a = iter.next()?;
394        for b in iter {
395            if self.choose_bool() {
396                a = b;
397            } else {
398                break;
399            }
400        }
401        Some(a)
402    }
403
404    /// Like `Self::choose_n`, except the iterator doesn't have to implement `ExactSizeIterator`.
405    ///
406    /// Choose a subset of up to `n` values from the given `Iterator`. If the iterator contains
407    /// fewer than `n` values, then all of the iterator's values will be returned. Otherwise, a
408    /// subset of `n` of them will be chosen and returned.
409    ///
410    /// Values are returned in lexicographical order. So, choosing 2 from [1, 2, 3] will return, in
411    /// order: [1, 2], [1, 3], then [2, 3].
412    ///
413    /// This function returns an iterator that returns the values in a lazy manner.
414    ///
415    /// Let N be the length of the underlying iterator. If all `n` items are retrieved from the
416    /// returned iterator, a total of O(N) work will be done.
417    ///
418    /// This function will increase the size of `Simulation` by an amount that is O(N).
419    ///
420    /// The iterator itself is of size O(n).
421    ///
422    /// # Examples
423    /// ```
424    /// let mut simex = maelstrom_simex::SimulationExplorer::default();
425    /// let mut combinations = vec![];
426    /// while let Some(mut simulation) = simex.next_simulation() {
427    ///     combinations.push(Vec::from_iter(simulation.choose_n(3, 1..6)));
428    /// }
429    /// assert_eq!(
430    ///     combinations,
431    ///     vec![
432    ///         [1, 2, 3],
433    ///         [1, 2, 4],
434    ///         [1, 2, 5],
435    ///         [1, 3, 4],
436    ///         [1, 3, 5],
437    ///         [1, 4, 5],
438    ///         [2, 3, 4],
439    ///         [2, 3, 5],
440    ///         [2, 4, 5],
441    ///         [3, 4, 5],
442    ///     ]
443    /// );
444    /// ```
445    pub fn choose_n_unknown_size<'b, T>(
446        &'b mut self,
447        n: usize,
448        i: T,
449    ) -> ChooseNUnknownSize<'a, 'b, T::IntoIter>
450    where
451        T: IntoIterator,
452        'a: 'b,
453    {
454        ChooseNUnknownSize {
455            simulation: self,
456            reservoir: VecDeque::with_capacity(n + 1),
457            n,
458            iter: i.into_iter().fuse(),
459        }
460    }
461}
462
463/*  __  __
464 * |  \/  | __ _ _ __
465 * | |\/| |/ _` | '_ \
466 * | |  | | (_| | |_) |
467 * |_|  |_|\__,_| .__/
468 *              |_|
469 *  FIGLET: Map
470 */
471
472/// An iterator that returns the results of simulations.
473///
474/// This struct is created by the [`map`](SimulationExplorer::map) method on
475/// [`SimulationExplorer`]. See its documentation for more.
476pub struct Map<'a, F> {
477    simex: &'a mut SimulationExplorer,
478    f: F,
479}
480
481impl<F, T> Iterator for Map<'_, F>
482where
483    F: for<'b> FnMut(Simulation<'b>) -> T,
484{
485    type Item = T;
486
487    fn next(&mut self) -> Option<Self::Item> {
488        self.simex.next_simulation().map(|sim| (self.f)(sim))
489    }
490}
491
492impl<F, T> FusedIterator for Map<'_, F> where F: for<'b> FnMut(Simulation<'b>) -> T {}
493
494/*   ____ _                          _   _
495 *  / ___| |__   ___   ___  ___  ___| \ | |
496 * | |   | '_ \ / _ \ / _ \/ __|/ _ \  \| |
497 * | |___| | | | (_) | (_) \__ \  __/ |\  |
498 *  \____|_| |_|\___/ \___/|___/\___|_| \_|
499 *  FIGLET: ChooseN
500 */
501
502/// An iterator that returns chosen values from an underlying [`ExactSizeIterator`].
503///
504/// This struct is created by the [`choose_n`](Simulation::choose_n) method on [`Simulation`]. See
505/// its documentation for more.
506pub struct ChooseN<'a, 'b, T> {
507    simulation: &'b mut Simulation<'a>,
508    n: usize,
509    iter: T,
510}
511
512impl<T> Iterator for ChooseN<'_, '_, T>
513where
514    T: ExactSizeIterator,
515{
516    type Item = T::Item;
517
518    fn next(&mut self) -> Option<Self::Item> {
519        match (self.n, self.iter.len()) {
520            (0, _) | (_, 0) => None,
521            (n, remaining) if n >= remaining => {
522                self.n = n - 1;
523                self.iter.next()
524            }
525            (n, remaining) => {
526                let extra = remaining - n;
527                self.n = n - 1;
528                self.iter
529                    .nth(self.simulation.choose_integer_unchecked(0, extra))
530            }
531        }
532    }
533
534    fn size_hint(&self) -> (usize, Option<usize>) {
535        let len = self.len();
536        (len, Some(len))
537    }
538}
539
540impl<T> FusedIterator for ChooseN<'_, '_, T> where T: ExactSizeIterator {}
541
542impl<T> ExactSizeIterator for ChooseN<'_, '_, T>
543where
544    T: ExactSizeIterator,
545{
546    fn len(&self) -> usize {
547        self.n.min(self.iter.len())
548    }
549}
550
551/*   ____ _                          _   _ _   _       _
552 *  / ___| |__   ___   ___  ___  ___| \ | | | | |_ __ | | ___ __   _____      ___ __
553 * | |   | '_ \ / _ \ / _ \/ __|/ _ \  \| | | | | '_ \| |/ / '_ \ / _ \ \ /\ / / '_ \
554 * | |___| | | | (_) | (_) \__ \  __/ |\  | |_| | | | |   <| | | | (_) \ V  V /| | | |
555 *  \____|_| |_|\___/ \___/|___/\___|_| \_|\___/|_| |_|_|\_\_| |_|\___/ \_/\_/ |_| |_|
556 *  ____  _
557 * / ___|(_)_______
558 * \___ \| |_  / _ \
559 *  ___) | |/ /  __/
560 * |____/|_/___\___|
561 *  FIGLET: ChooseNUnknownSize
562 */
563
564/// An iterator that returns chosen values from an underlying [`Iterator`].
565///
566/// The assumption is that the iterator is not an [`ExactSizeIterator`], otherwise [`ChooseN`]
567/// would have been used.
568///
569/// This struct is created by the [`choose_n_unknown_size`](Simulation::choose_n_unknown_size)
570/// method on [`Simulation`]. See its documentation for more.
571pub struct ChooseNUnknownSize<'a, 'b, T>
572where
573    T: Iterator,
574{
575    simulation: &'b mut Simulation<'a>,
576    reservoir: VecDeque<T::Item>,
577    n: usize,
578    iter: Fuse<T>,
579}
580
581impl<T> Iterator for ChooseNUnknownSize<'_, '_, T>
582where
583    T: Iterator,
584{
585    type Item = T::Item;
586
587    fn next(&mut self) -> Option<Self::Item> {
588        if self.n == 0 {
589            return None;
590        }
591        loop {
592            // Fill the reservoir.
593            while self.reservoir.len() < self.n + 1 {
594                match self.iter.next() {
595                    Some(elem) => self.reservoir.push_back(elem),
596                    None => {
597                        if !self.reservoir.is_empty() {
598                            self.n -= 1;
599                        }
600                        return self.reservoir.pop_front();
601                    }
602                }
603            }
604            // Take the front element from the reservoir and either return it or drop it.
605            let front = self.reservoir.pop_front();
606            if !self.simulation.choose_bool() {
607                self.n -= 1;
608                return front;
609            }
610        }
611    }
612
613    fn size_hint(&self) -> (usize, Option<usize>) {
614        // At a minimum, we will always return the whole of the reservoir, plus whatever else is in
615        // the iterator, all bounded by self.n
616        let (underlying_min, underlying_max) = self.iter.size_hint();
617        let min = underlying_min
618            .saturating_add(self.reservoir.len())
619            .min(self.n);
620        let max = if let Some(underlying_max) = underlying_max {
621            underlying_max
622                .saturating_add(self.reservoir.len())
623                .min(self.n)
624        } else {
625            self.n
626        };
627        (min, Some(max))
628    }
629}
630
631impl<T> FusedIterator for ChooseNUnknownSize<'_, '_, T> where T: Iterator {}
632
633/*  _            _
634 * | |_ ___  ___| |_ ___
635 * | __/ _ \/ __| __/ __|
636 * | ||  __/\__ \ |_\__ \
637 *  \__\___||___/\__|___/
638 *  FIGLET: tests
639 */
640
641#[cfg(test)]
642mod tests {
643    use super::*;
644    use std::mem;
645
646    struct FusedAssertingIterator<T> {
647        inner: T,
648        has_returned_none: bool,
649    }
650
651    impl<T> FusedAssertingIterator<T> {
652        fn from(inner: T) -> Self {
653            FusedAssertingIterator {
654                inner,
655                has_returned_none: false,
656            }
657        }
658    }
659
660    impl<T: Iterator> Iterator for FusedAssertingIterator<T> {
661        type Item = T::Item;
662
663        fn next(&mut self) -> Option<Self::Item> {
664            assert!(!self.has_returned_none);
665            let result = self.inner.next();
666            if result.is_none() {
667                self.has_returned_none = true;
668            }
669            result
670        }
671
672        fn size_hint(&self) -> (usize, Option<usize>) {
673            self.inner.size_hint()
674        }
675    }
676
677    impl<T: ExactSizeIterator> ExactSizeIterator for FusedAssertingIterator<T> {
678        fn len(&self) -> usize {
679            self.inner.len()
680        }
681    }
682
683    #[test]
684    fn next_simulation_on_empty_is_false() {
685        let mut simex = SimulationExplorer::default();
686        assert!(simex.next_simulation().is_some());
687        assert!(simex.next_simulation().is_none());
688        assert!(simex.next_simulation().is_none());
689    }
690
691    #[test]
692    fn general_exercise() {
693        let mut simex = SimulationExplorer::default();
694
695        let mut simulation = simex.next_simulation().unwrap();
696        assert!(!simulation.choose_bool());
697        assert!(!simulation.choose_bool());
698        assert!(!simulation.choose_bool());
699        assert!(!simulation.choose_bool());
700
701        let mut simulation = simex.next_simulation().unwrap();
702        assert!(!simulation.choose_bool());
703        assert!(!simulation.choose_bool());
704        assert!(!simulation.choose_bool());
705        assert!(simulation.choose_bool());
706        assert!(!simulation.choose_bool());
707
708        let mut simulation = simex.next_simulation().unwrap();
709        assert!(!simulation.choose_bool());
710        assert!(!simulation.choose_bool());
711        assert!(!simulation.choose_bool());
712        assert!(simulation.choose_bool());
713        assert!(simulation.choose_bool());
714
715        let mut simulation = simex.next_simulation().unwrap();
716        assert!(!simulation.choose_bool());
717        assert!(!simulation.choose_bool());
718        assert!(simulation.choose_bool());
719
720        let mut simulation = simex.next_simulation().unwrap();
721        assert!(!simulation.choose_bool());
722        assert!(simulation.choose_bool());
723
724        let mut simulation = simex.next_simulation().unwrap();
725        assert!(simulation.choose_bool());
726        assert!(!simulation.choose_bool());
727
728        let mut simulation = simex.next_simulation().unwrap();
729        assert!(simulation.choose_bool());
730        assert!(simulation.choose_bool());
731
732        assert!(simex.next_simulation().is_none());
733    }
734
735    #[test]
736    fn choose_range() {
737        let mut simex = SimulationExplorer::default();
738
739        for i in 10..20 {
740            let mut simulation = simex.next_simulation().unwrap();
741            let j = simulation
742                .choose(FusedAssertingIterator::from(10..20))
743                .unwrap();
744            assert_eq!(i, j);
745        }
746        assert!(simex.next_simulation().is_none());
747    }
748
749    #[test]
750    fn choose_vector() {
751        let mut simex = SimulationExplorer::default();
752
753        for i in 1..=4 {
754            let mut simulation = simex.next_simulation().unwrap();
755            let j = simulation.choose(vec![1, 2, 3, 4]).unwrap();
756            assert_eq!(i, j);
757        }
758        assert!(simex.next_simulation().is_none());
759    }
760
761    #[test]
762    fn choose_empty() {
763        let mut simex = SimulationExplorer::default();
764        let mut simulation = simex.next_simulation().unwrap();
765        assert!(simulation
766            .choose(FusedAssertingIterator::from(0..0))
767            .is_none());
768        assert!(simex.next_simulation().is_none());
769    }
770
771    #[test]
772    fn while_let() {
773        let mut simex = SimulationExplorer::default();
774        let mut actual = vec![];
775        while let Some(mut simulation) = simex.next_simulation() {
776            actual.push(
777                simulation
778                    .choose(FusedAssertingIterator::from(0..10))
779                    .unwrap(),
780            );
781        }
782        assert_eq!(actual, Vec::from_iter(0..10));
783    }
784
785    #[test]
786    fn map() {
787        assert!(SimulationExplorer::default()
788            .map(|mut sim| sim.choose(FusedAssertingIterator::from(0..10)).unwrap())
789            .eq(FusedAssertingIterator::from(0..10)));
790    }
791
792    #[test]
793    fn map_is_fused() {
794        let mut simex = SimulationExplorer::default();
795        let mut iter = simex.map(|_| ());
796        assert_eq!(iter.next(), Some(()));
797        assert_eq!(iter.next(), None);
798        assert_eq!(iter.next(), None);
799        assert_eq!(iter.next(), None);
800    }
801
802    #[test]
803    fn for_each() {
804        let mut vec = vec![];
805        SimulationExplorer::default().for_each(|mut sim| vec.push(sim.choose_integer(1, 5)));
806        assert_eq!(vec, vec![1, 2, 3, 4, 5]);
807    }
808
809    #[test]
810    fn choose_bool() {
811        assert_eq!(
812            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_bool())),
813            vec![false, true],
814        );
815    }
816
817    #[test]
818    fn choose_n() {
819        assert_eq!(
820            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
821                sim.choose_n(3, FusedAssertingIterator::from(0..5))
822            ))),
823            vec![
824                vec![0, 1, 2],
825                vec![0, 1, 3],
826                vec![0, 1, 4],
827                vec![0, 2, 3],
828                vec![0, 2, 4],
829                vec![0, 3, 4],
830                vec![1, 2, 3],
831                vec![1, 2, 4],
832                vec![1, 3, 4],
833                vec![2, 3, 4],
834            ],
835        );
836    }
837
838    #[test]
839    fn choose_n_too_small() {
840        assert_eq!(
841            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
842                sim.choose_n(3, FusedAssertingIterator::from(0..2))
843            ))),
844            vec![vec![0, 1]],
845        );
846    }
847
848    #[test]
849    fn choose_n_from_empty() {
850        assert_eq!(
851            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
852                sim.choose_n(3, FusedAssertingIterator::from(0..0))
853            ))),
854            vec![vec![]],
855        );
856    }
857
858    #[test]
859    fn choose_n_exact() {
860        assert_eq!(
861            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
862                sim.choose_n(3, FusedAssertingIterator::from(0..3))
863            ))),
864            vec![vec![0, 1, 2]],
865        );
866    }
867
868    #[test]
869    fn choose_0_from_some() {
870        assert_eq!(
871            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
872                sim.choose_n(0, FusedAssertingIterator::from(0..5))
873            ))),
874            vec![vec![]],
875        );
876    }
877
878    #[test]
879    fn choose_0_from_none() {
880        assert_eq!(
881            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
882                sim.choose_n(0, FusedAssertingIterator::from(0..0))
883            ))),
884            vec![vec![]],
885        );
886    }
887
888    #[test]
889    fn choose_n_is_fused() {
890        let mut simex = SimulationExplorer::default();
891        let mut simulation = simex.next_simulation().unwrap();
892        let mut iter = simulation.choose_n(1, FusedAssertingIterator::from(0..2));
893        assert_eq!(iter.next(), Some(0));
894        assert_eq!(iter.next(), None);
895        assert_eq!(iter.next(), None);
896        assert_eq!(iter.next(), None);
897    }
898
899    #[test]
900    fn choose_n_exact_size() {
901        let mut simex = SimulationExplorer::default();
902        let mut simulation = simex.next_simulation().unwrap();
903        let mut iter = simulation.choose_n(1, FusedAssertingIterator::from(0..2));
904        assert_eq!(iter.len(), 1);
905        assert_eq!(iter.next(), Some(0));
906        assert_eq!(iter.len(), 0);
907        assert_eq!(iter.next(), None);
908        assert_eq!(iter.len(), 0);
909    }
910
911    #[test]
912    fn choose_n_exact_size_with_short_underlying_iter() {
913        let mut simex = SimulationExplorer::default();
914        let mut simulation = simex.next_simulation().unwrap();
915        let mut iter = simulation.choose_n(100, FusedAssertingIterator::from(0..2));
916        assert_eq!(iter.len(), 2);
917        assert_eq!(iter.next(), Some(0));
918        assert_eq!(iter.len(), 1);
919        assert_eq!(iter.next(), Some(1));
920        assert_eq!(iter.len(), 0);
921        assert_eq!(iter.next(), None);
922        assert_eq!(iter.len(), 0);
923        assert_eq!(iter.next(), None);
924        assert_eq!(iter.len(), 0);
925    }
926
927    #[test]
928    fn choose_unknown_size_empty() {
929        let mut simex = SimulationExplorer::default();
930        let mut simulation = simex.next_simulation().unwrap();
931        assert!(simulation
932            .choose_unknown_size(FusedAssertingIterator::from(0..0))
933            .is_none());
934        assert!(simex.next_simulation().is_none());
935    }
936
937    #[test]
938    fn choose_unknown_size_from_single_element() {
939        assert_eq!(
940            Vec::from_iter(SimulationExplorer::default().map(|mut sim| {
941                sim.choose_unknown_size(FusedAssertingIterator::from(0..1))
942                    .unwrap()
943            })),
944            vec![0],
945        );
946    }
947
948    #[test]
949    fn choose_unknown_size() {
950        assert_eq!(
951            Vec::from_iter(SimulationExplorer::default().map(|mut sim| {
952                sim.choose_unknown_size(FusedAssertingIterator::from(0..10))
953                    .unwrap()
954            })),
955            vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
956        );
957    }
958
959    #[test]
960    fn choose_n_unknown_size() {
961        assert_eq!(
962            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
963                sim.choose_n_unknown_size(3, FusedAssertingIterator::from(0..5))
964            ))),
965            vec![
966                vec![0, 1, 2],
967                vec![0, 1, 3],
968                vec![0, 1, 4],
969                vec![0, 2, 3],
970                vec![0, 2, 4],
971                vec![0, 3, 4],
972                vec![1, 2, 3],
973                vec![1, 2, 4],
974                vec![1, 3, 4],
975                vec![2, 3, 4],
976            ],
977        );
978    }
979
980    #[test]
981    fn choose_n_unknown_size_too_small() {
982        assert_eq!(
983            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
984                sim.choose_n_unknown_size(3, FusedAssertingIterator::from(0..2))
985            ))),
986            vec![vec![0, 1]],
987        );
988    }
989
990    #[test]
991    fn choose_n_unknown_size_from_empty() {
992        assert_eq!(
993            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
994                sim.choose_n_unknown_size(3, FusedAssertingIterator::from(0..0))
995            ))),
996            vec![vec![]],
997        );
998    }
999
1000    #[test]
1001    fn choose_n_unknown_size_exact() {
1002        assert_eq!(
1003            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
1004                sim.choose_n_unknown_size(3, FusedAssertingIterator::from(0..3))
1005            ))),
1006            vec![vec![0, 1, 2]],
1007        );
1008    }
1009
1010    #[test]
1011    fn choose_0_unknown_size_from_some() {
1012        assert_eq!(
1013            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
1014                sim.choose_n_unknown_size(0, FusedAssertingIterator::from(0..5))
1015            ))),
1016            vec![vec![]],
1017        );
1018    }
1019
1020    #[test]
1021    fn choose_0_unknown_size_from_none() {
1022        assert_eq!(
1023            Vec::from_iter(SimulationExplorer::default().map(|mut sim| Vec::from_iter(
1024                sim.choose_n_unknown_size(0, FusedAssertingIterator::from(0..0))
1025            ))),
1026            vec![vec![]],
1027        );
1028    }
1029
1030    struct TestIterator<T> {
1031        script: Vec<(usize, Option<usize>, Option<T>)>,
1032        min: usize,
1033        max: Option<usize>,
1034        next: Option<T>,
1035    }
1036
1037    impl<T> TestIterator<T> {
1038        fn new(mut script: Vec<(usize, Option<usize>, Option<T>)>) -> Self {
1039            let (min, max, next) = script.remove(0);
1040            TestIterator {
1041                script,
1042                min,
1043                max,
1044                next,
1045            }
1046        }
1047    }
1048
1049    impl<T> Iterator for TestIterator<T> {
1050        type Item = T;
1051
1052        fn next(&mut self) -> Option<Self::Item> {
1053            if self.script.is_empty() {
1054                self.next.take()
1055            } else {
1056                let (min, max, mut next) = self.script.remove(0);
1057                mem::swap(&mut next, &mut self.next);
1058                self.min = min;
1059                self.max = max;
1060                next
1061            }
1062        }
1063
1064        fn size_hint(&self) -> (usize, Option<usize>) {
1065            (self.min, self.max)
1066        }
1067    }
1068
1069    #[test]
1070    fn choose_n_unknown_size_size_hint_1() {
1071        let mut simex = SimulationExplorer::default();
1072        let mut simulation = simex.next_simulation().unwrap();
1073        let mut iter = simulation.choose_n_unknown_size(
1074            1,
1075            FusedAssertingIterator::from(TestIterator::new(vec![
1076                (0, None, Some(0)),
1077                (0, None, Some(1)),
1078                (0, None, Some(2)),
1079            ])),
1080        );
1081        assert_eq!(iter.size_hint(), (0, Some(1)));
1082        assert_eq!(iter.next(), Some(0));
1083        assert_eq!(iter.size_hint(), (0, Some(0)));
1084    }
1085
1086    #[test]
1087    fn choose_n_unknown_size_size_hint_2() {
1088        let mut simex = SimulationExplorer::default();
1089        let mut simulation = simex.next_simulation().unwrap();
1090        let mut iter = simulation.choose_n_unknown_size(
1091            1,
1092            FusedAssertingIterator::from(TestIterator::new(vec![
1093                (3, None, Some(0)),
1094                (2, None, Some(1)),
1095                (1, None, Some(2)),
1096            ])),
1097        );
1098        assert_eq!(iter.size_hint(), (1, Some(1)));
1099        assert_eq!(iter.next(), Some(0));
1100        assert_eq!(iter.size_hint(), (0, Some(0)));
1101    }
1102
1103    #[test]
1104    fn choose_n_unknown_size_size_hint_3() {
1105        let mut simex = SimulationExplorer::default();
1106        let mut simulation = simex.next_simulation().unwrap();
1107        let mut iter = simulation.choose_n_unknown_size(
1108            4,
1109            FusedAssertingIterator::from(TestIterator::new(vec![
1110                (1, Some(3), Some(0)),
1111                (1, Some(2), Some(1)),
1112                (1, Some(1), Some(2)),
1113                (0, Some(0), None),
1114            ])),
1115        );
1116        assert_eq!(iter.size_hint(), (1, Some(3)));
1117        assert_eq!(iter.next(), Some(0));
1118        assert_eq!(iter.size_hint(), (2, Some(2)));
1119        assert_eq!(iter.next(), Some(1));
1120        assert_eq!(iter.size_hint(), (1, Some(1)));
1121        assert_eq!(iter.next(), Some(2));
1122        assert_eq!(iter.size_hint(), (0, Some(0)));
1123    }
1124
1125    #[test]
1126    fn choose_n_unknown_size_size_hint_4() {
1127        let mut simex = SimulationExplorer::default();
1128        let mut simulation = simex.next_simulation().unwrap();
1129        let mut iter = simulation.choose_n_unknown_size(
1130            4,
1131            FusedAssertingIterator::from(TestIterator::new(vec![
1132                (0, Some(100), Some(0)),
1133                (0, Some(100), Some(1)),
1134                (0, Some(100), Some(2)),
1135                (0, Some(0), None),
1136            ])),
1137        );
1138        assert_eq!(iter.size_hint(), (0, Some(4)));
1139        assert_eq!(iter.next(), Some(0));
1140        assert_eq!(iter.size_hint(), (2, Some(2)));
1141        assert_eq!(iter.next(), Some(1));
1142        assert_eq!(iter.size_hint(), (1, Some(1)));
1143        assert_eq!(iter.next(), Some(2));
1144        assert_eq!(iter.size_hint(), (0, Some(0)));
1145        assert_eq!(iter.next(), None);
1146        assert_eq!(iter.size_hint(), (0, Some(0)));
1147    }
1148
1149    #[test]
1150    fn choose_n_unknown_size_size_hint_5() {
1151        let mut simex = SimulationExplorer::default();
1152        let mut simulation = simex.next_simulation().unwrap();
1153        let mut iter = simulation.choose_n_unknown_size(
1154            2,
1155            FusedAssertingIterator::from(TestIterator::new(vec![
1156                (0, Some(100), Some(0)),
1157                (0, Some(100), Some(1)),
1158                (0, Some(100), Some(2)),
1159                (0, Some(100), Some(3)),
1160                (0, Some(0), None),
1161            ])),
1162        );
1163        assert_eq!(iter.size_hint(), (0, Some(2)));
1164        assert_eq!(iter.next(), Some(0));
1165        assert_eq!(iter.size_hint(), (1, Some(1)));
1166        assert_eq!(iter.next(), Some(1));
1167        assert_eq!(iter.size_hint(), (0, Some(0)));
1168        assert_eq!(iter.next(), None);
1169        assert_eq!(iter.size_hint(), (0, Some(0)));
1170        assert_eq!(iter.next(), None);
1171        assert_eq!(iter.size_hint(), (0, Some(0)));
1172    }
1173
1174    #[test]
1175    fn choose_n_unknown_size_is_fused() {
1176        let mut simex = SimulationExplorer::default();
1177        let mut simulation = simex.next_simulation().unwrap();
1178        let mut iter = simulation.choose_n_unknown_size(1, FusedAssertingIterator::from(0..2));
1179        assert_eq!(iter.next(), Some(0));
1180        assert_eq!(iter.next(), None);
1181        assert_eq!(iter.next(), None);
1182        assert_eq!(iter.next(), None);
1183    }
1184
1185    #[test]
1186    fn choose_integer_0() {
1187        assert_eq!(
1188            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(0, 0))),
1189            vec![0],
1190        );
1191    }
1192
1193    #[test]
1194    fn choose_integer_max() {
1195        assert_eq!(
1196            Vec::from_iter(
1197                SimulationExplorer::default()
1198                    .map(|mut sim| sim.choose_integer(usize::MAX, usize::MAX))
1199            ),
1200            vec![usize::MAX],
1201        );
1202    }
1203
1204    #[test]
1205    fn choose_integer_0_to_1() {
1206        assert_eq!(
1207            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(0, 1))),
1208            vec![0, 1],
1209        );
1210    }
1211
1212    #[test]
1213    fn choose_integer_1_to_2() {
1214        assert_eq!(
1215            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(1, 2))),
1216            vec![1, 2],
1217        );
1218    }
1219
1220    #[test]
1221    fn choose_integer_0_to_2() {
1222        assert_eq!(
1223            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(0, 2))),
1224            vec![0, 1, 2],
1225        );
1226    }
1227
1228    #[test]
1229    fn choose_integer_1_to_3() {
1230        assert_eq!(
1231            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(1, 3))),
1232            vec![1, 2, 3],
1233        );
1234    }
1235
1236    #[test]
1237    fn choose_integer_1_to_13() {
1238        assert_eq!(
1239            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(1, 13))),
1240            vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
1241        );
1242    }
1243
1244    #[test]
1245    fn choose_integer_neg_1_to_0() {
1246        assert_eq!(
1247            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(-1, 0))),
1248            vec![-1, 0],
1249        );
1250    }
1251
1252    #[test]
1253    fn choose_integer_neg_2_to_neg_1() {
1254        assert_eq!(
1255            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(-2, -1))),
1256            vec![-2, -1],
1257        );
1258    }
1259
1260    #[test]
1261    fn choose_integer_neg_2_to_0() {
1262        assert_eq!(
1263            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(-2, 0))),
1264            vec![-2, -1, 0],
1265        );
1266    }
1267
1268    #[test]
1269    fn choose_integer_neg_3_to_neg_1() {
1270        assert_eq!(
1271            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(-3, -1))),
1272            vec![-3, -2, -1],
1273        );
1274    }
1275
1276    #[test]
1277    fn choose_integer_neg_13_to_neg_1() {
1278        assert_eq!(
1279            Vec::from_iter(
1280                SimulationExplorer::default().map(|mut sim| sim.choose_integer(-13, -1))
1281            ),
1282            vec![-13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1],
1283        );
1284    }
1285
1286    #[test]
1287    fn choose_integer_min_to_max() {
1288        assert!(SimulationExplorer::default()
1289            .map(|mut sim| sim.choose_integer(i16::MIN, i16::MAX))
1290            .eq(i16::MIN..=i16::MAX));
1291    }
1292
1293    #[test]
1294    #[should_panic(expected = "min <= max")]
1295    fn choose_integer_1_to_0() {
1296        assert_eq!(
1297            Vec::from_iter(SimulationExplorer::default().map(|mut sim| sim.choose_integer(1, 0))),
1298            vec![1, 0],
1299        );
1300    }
1301}