1use rand::Rng;
17
18use core::fmt;
19use core::hash::Hash;
20use core::ops::Range;
21
22use crate::bits::{BitSetLike, VarBitSet};
23use crate::num::sample_uniform_incl;
24use crate::sample::SizeRange;
25use crate::std_facade::HashMap;
26use crate::std_facade::Vec;
27use crate::strategy::*;
28use crate::test_runner::*;
29
30pub fn range_subset<T>(
41 range: Range<T>,
42 size: impl Into<SizeRange>,
43) -> RangeSubset<T>
44where
45 T: Copy + Ord + fmt::Debug,
46 Range<T>: ExactSizeIterator<Item = T>,
47{
48 let len = range.len();
49 let size = size.into();
50
51 size.assert_nonempty();
52 assert!(
53 size.end_incl() <= len,
54 "Maximum size of subset {} exceeds length of input {}",
55 size.end_incl(),
56 len
57 );
58 RangeSubset { range, size }
59}
60
61#[derive(Debug)]
65pub struct RangeSubset<T> {
66 range: Range<T>,
67 size: SizeRange,
68}
69
70impl<T> Strategy for RangeSubset<T>
71where
72 T: Copy + Eq + Hash + fmt::Debug,
73 Range<T>: ExactSizeIterator<Item = T>,
74{
75 type Tree = RangeSubsetValueTree<T>;
76 type Value = Vec<T>;
77
78 fn new_tree(&self, runner: &mut TestRunner) -> Result<Self::Tree, Reason> {
79 let (min_size, max_size) = (self.size.start(), self.size.end_incl());
80
81 let count = sample_uniform_incl(runner, min_size, max_size);
82
83 let range_len = self.range.len();
84
85 let mut swaps: HashMap<T, T> = HashMap::default();
86
87 let mut values: Vec<T> = Vec::default();
88
89 let rng = runner.rng();
90
91 for i in 0..count {
103 let j: usize = rng.random_range(i..range_len);
104
105 let iv = self.range.clone().nth(i).unwrap();
106 let vi = *swaps.get(&iv).unwrap_or(&iv);
107
108 let jv = self.range.clone().nth(j).unwrap();
109 let vj = *swaps.get(&jv).unwrap_or(&jv);
110
111 swaps.insert(iv, vj);
112 swaps.insert(jv, vi);
113 values.push(vj);
114 }
115
116 let included_values = VarBitSet::saturated(count);
117
118 Ok(RangeSubsetValueTree {
119 values,
120 included_values,
121 shrink: 0,
122 prev_shrink: None,
123 min_size,
124 })
125 }
126}
127
128#[derive(Debug, Clone)]
130pub struct RangeSubsetValueTree<T> {
131 values: Vec<T>,
132 included_values: VarBitSet,
133 shrink: usize,
134 prev_shrink: Option<usize>,
135 min_size: usize,
136}
137
138impl<T> ValueTree for RangeSubsetValueTree<T>
139where
140 T: Copy + Eq + Hash + fmt::Debug,
141 Range<T>: ExactSizeIterator<Item = T>,
142{
143 type Value = Vec<T>;
144
145 fn current(&self) -> Self::Value {
146 self.values
147 .iter()
148 .enumerate()
149 .filter_map(|(index, value)| {
150 self.included_values.test(index).then_some(*value)
151 })
152 .collect()
153 }
154
155 fn simplify(&mut self) -> bool {
156 if self.included_values.len() <= self.min_size {
157 return false;
158 }
159
160 while self.shrink < self.values.len()
161 && !self.included_values.test(self.shrink)
162 {
163 self.shrink += 1;
164 }
165
166 if self.shrink >= self.values.len() {
167 self.prev_shrink = None;
168 false
169 } else {
170 self.prev_shrink = Some(self.shrink);
171 self.included_values.clear(self.shrink);
172 self.shrink += 1;
173 true
174 }
175 }
176
177 fn complicate(&mut self) -> bool {
178 if let Some(shrink) = self.prev_shrink.take() {
179 self.included_values.set(shrink);
180 true
181 } else {
182 false
183 }
184 }
185}
186
187#[cfg(test)]
188mod test {
189 use crate::std_facade::BTreeSet;
190
191 use super::*;
192
193 #[test]
194 fn sample_range() {
195 static INDICES: Range<usize> = 0..8;
196 let mut size_counts: [usize; 8] = [0; 8];
197 let mut value_counts: [usize; 8] = [0; 8];
198
199 let mut runner = TestRunner::deterministic();
200 let input = range_subset(INDICES.clone(), 3..7);
201
202 for _ in 0..2048 {
203 let value = input.new_tree(&mut runner).unwrap().current();
204 assert!(value.len() >= 3 && value.len() < 7);
206 assert_eq!(
208 value.len(),
209 value.iter().cloned().collect::<BTreeSet<_>>().len(),
210 "output contains non-distinct items ({value:?})"
211 );
212
213 size_counts[value.len()] += 1;
214
215 for value in value {
216 value_counts[value] += 1;
217 }
218 }
219
220 for i in 3..7 {
221 assert!(
222 size_counts[i] >= 256 && size_counts[i] < 1024,
223 "size {} was chosen {} times",
224 i,
225 size_counts[i]
226 );
227 }
228
229 for (ix, &v) in value_counts.iter().enumerate() {
230 assert!(
231 v >= 1024 && v < 1500,
232 "Value {} was chosen {} times",
233 ix,
234 v
235 );
236 }
237 }
238
239 #[test]
240 fn test_sample_sanity() {
241 check_strategy_sanity(range_subset(0..5, 1..3), None);
242 }
243
244 #[test]
245 fn subset_empty_range_works() {
246 let mut runner = TestRunner::deterministic();
247 let input = range_subset(0..0, 0..1);
248 assert_eq!(
249 Vec::<usize>::new(),
250 input.new_tree(&mut runner).unwrap().current()
251 );
252 }
253
254 #[test]
255 fn subset_full_range_works() {
256 let range = 1..4;
257 let mut runner = TestRunner::deterministic();
258 let input = range_subset(range.clone(), 3);
259 let mut values = input.new_tree(&mut runner).unwrap().current();
260 values.sort();
261 assert_eq!(Vec::<usize>::from_iter(range), values);
262 }
263}