1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8#[allow(dead_code)]
13pub struct MealyMachineRs<S, I, O> {
14 transition: Box<dyn Fn(S, I) -> (S, O)>,
16 state: S,
18}
19#[allow(dead_code)]
20impl<S: Clone + 'static, I: 'static, O: 'static> MealyMachineRs<S, I, O> {
21 pub fn new(state: S, transition: impl Fn(S, I) -> (S, O) + 'static) -> Self {
23 Self {
24 transition: Box::new(transition),
25 state,
26 }
27 }
28 pub fn step(&mut self, input: I) -> O {
30 let old_state = self.state.clone();
31 let (new_state, output) = (self.transition)(old_state, input);
32 self.state = new_state;
33 output
34 }
35 pub fn run_vec(&mut self, inputs: Vec<I>) -> Vec<O> {
37 inputs.into_iter().map(|i| self.step(i)).collect()
38 }
39 pub fn current_state(&self) -> &S {
41 &self.state
42 }
43 pub fn reset(&mut self, state: S) {
45 self.state = state;
46 }
47}
48#[allow(dead_code)]
53pub struct MooreMachineRs<S, I, O> {
54 transition: Box<dyn Fn(&S, I) -> S>,
56 output: Box<dyn Fn(&S) -> O>,
58 state: S,
60}
61#[allow(dead_code)]
62impl<S: 'static, I: 'static, O: 'static> MooreMachineRs<S, I, O> {
63 pub fn new(
65 state: S,
66 transition: impl Fn(&S, I) -> S + 'static,
67 output: impl Fn(&S) -> O + 'static,
68 ) -> Self {
69 Self {
70 transition: Box::new(transition),
71 output: Box::new(output),
72 state,
73 }
74 }
75 pub fn read_output(&self) -> O {
77 (self.output)(&self.state)
78 }
79 pub fn step(&mut self, input: I) {
81 self.state = (self.transition)(&self.state, input);
82 }
83 pub fn run_vec(&mut self, inputs: Vec<I>) -> Vec<O> {
85 let mut results = Vec::with_capacity(inputs.len());
86 for inp in inputs {
87 results.push(self.read_output());
88 self.step(inp);
89 }
90 results
91 }
92 pub fn state(&self) -> &S {
94 &self.state
95 }
96}
97#[allow(dead_code)]
101pub struct StreamWindow<T> {
102 buf: Vec<Option<T>>,
104 size: usize,
106 pos: usize,
108 count: usize,
110}
111#[allow(dead_code)]
112impl<T: Clone> StreamWindow<T> {
113 pub fn new(size: usize) -> Self {
115 Self {
116 buf: vec![None; size],
117 size,
118 pos: 0,
119 count: 0,
120 }
121 }
122 pub fn push(&mut self, val: T) {
124 self.buf[self.pos] = Some(val);
125 self.pos = (self.pos + 1) % self.size;
126 self.count += 1;
127 }
128 pub fn window(&self) -> Vec<T> {
130 let len = self.count.min(self.size);
131 let mut result = Vec::with_capacity(len);
132 let start = if self.count >= self.size { self.pos } else { 0 };
133 for i in 0..len {
134 let idx = (start + i) % self.size;
135 if let Some(ref v) = self.buf[idx] {
136 result.push(v.clone());
137 }
138 }
139 result
140 }
141 pub fn len(&self) -> usize {
143 self.count.min(self.size)
144 }
145 pub fn is_empty(&self) -> bool {
147 self.count == 0
148 }
149 pub fn window_size(&self) -> usize {
151 self.size
152 }
153}
154#[derive(Debug, Clone, Default)]
156pub struct StreamDeclStats {
157 pub core: usize,
159 pub combinators: usize,
161 pub monad: usize,
163 pub theorems: usize,
165}
166impl StreamDeclStats {
167 pub fn compute(env: &Environment) -> Self {
169 let core_names = ["Stream", "Stream.cons", "Stream.head", "Stream.tail"];
170 let combinator_names = [
171 "Stream.map",
172 "Stream.take",
173 "Stream.zip",
174 "Stream.iterate",
175 "Stream.drop",
176 "Stream.nth",
177 "Stream.const",
178 "Stream.filter",
179 ];
180 let monad_names = ["Stream.pure", "Stream.scan", "Stream.interleave"];
181 let theorem_names = ["Stream.head_cons", "Stream.tail_cons"];
182 let count = |names: &[&str]| {
183 names
184 .iter()
185 .filter(|&&n| env.get(&Name::str(n)).is_some())
186 .count()
187 };
188 Self {
189 core: count(&core_names),
190 combinators: count(&combinator_names),
191 monad: count(&monad_names),
192 theorems: count(&theorem_names),
193 }
194 }
195 pub fn total(&self) -> usize {
197 self.core + self.combinators + self.monad + self.theorems
198 }
199}
200#[allow(dead_code)]
204pub struct PriorityMerge<T> {
205 left: LazyStream<T>,
206 right: LazyStream<T>,
207}
208#[allow(dead_code)]
209impl<T: 'static> PriorityMerge<T> {
210 pub fn new(left: LazyStream<T>, right: LazyStream<T>) -> Self {
212 Self { left, right }
213 }
214 pub fn next(&mut self) -> Option<T> {
216 self.left.next().or_else(|| self.right.next())
217 }
218 pub fn take_n(&mut self, n: usize) -> Vec<T> {
220 (0..n).filter_map(|_| self.next()).collect()
221 }
222}
223#[allow(dead_code)]
227pub struct CountMinSketchRs {
228 table: Vec<Vec<u64>>,
230 d: usize,
232 w: usize,
234}
235#[allow(dead_code)]
236impl CountMinSketchRs {
237 pub fn new(d: usize, w: usize) -> Self {
239 Self {
240 table: vec![vec![0u64; w]; d],
241 d,
242 w,
243 }
244 }
245 pub fn update(&mut self, item: u64) {
247 for row in 0..self.d {
248 let col = self.strm_ext_hash(item, row as u64) % self.w;
249 self.table[row][col] += 1;
250 }
251 }
252 pub fn estimate(&self, item: u64) -> u64 {
254 (0..self.d)
255 .map(|row| {
256 let col = self.strm_ext_hash(item, row as u64) % self.w;
257 self.table[row][col]
258 })
259 .min()
260 .unwrap_or(0)
261 }
262 fn strm_ext_hash(&self, item: u64, seed: u64) -> usize {
263 let h = item
264 .wrapping_mul(2654435761)
265 .wrapping_add(seed.wrapping_mul(40503));
266 h as usize
267 }
268 pub fn total_updates(&self) -> u64 {
270 if self.d > 0 {
271 self.table[0].iter().sum()
272 } else {
273 0
274 }
275 }
276}
277pub struct LazyStream<T> {
281 gen: Box<dyn FnMut() -> Option<T>>,
283}
284impl<T> LazyStream<T> {
285 pub fn from_fn(gen: impl FnMut() -> Option<T> + 'static) -> Self {
287 Self { gen: Box::new(gen) }
288 }
289 pub fn constant(val: T) -> Self
291 where
292 T: Clone + 'static,
293 {
294 Self::from_fn(move || Some(val.clone()))
295 }
296 pub fn iterate(mut init: T, mut f: impl FnMut(T) -> T + 'static) -> Self
298 where
299 T: Clone + 'static,
300 {
301 Self::from_fn(move || {
302 let curr = init.clone();
303 init = f(init.clone());
304 Some(curr)
305 })
306 }
307 #[allow(clippy::should_implement_trait)]
309 pub fn next(&mut self) -> Option<T> {
310 (self.gen)()
311 }
312 pub fn take(mut self, n: usize) -> Vec<T> {
314 (0..n).filter_map(|_| self.next()).collect()
315 }
316}
317#[allow(dead_code)]
321pub struct BloomFilterRs {
322 bits: Vec<bool>,
324 k: usize,
326 m: usize,
328}
329#[allow(dead_code)]
330impl BloomFilterRs {
331 pub fn new(m: usize, k: usize) -> Self {
333 Self {
334 bits: vec![false; m],
335 k,
336 m,
337 }
338 }
339 pub fn insert(&mut self, item: u64) {
341 for i in 0..self.k {
342 let idx = self.strm_ext_hash(item, i as u64) % self.m;
343 self.bits[idx] = true;
344 }
345 }
346 pub fn query(&self, item: u64) -> bool {
348 (0..self.k).all(|i| {
349 let idx = self.strm_ext_hash(item, i as u64) % self.m;
350 self.bits[idx]
351 })
352 }
353 fn strm_ext_hash(&self, item: u64, seed: u64) -> usize {
355 let h = item
356 .wrapping_mul(6364136223846793005)
357 .wrapping_add(seed.wrapping_mul(1442695040888963407));
358 h as usize
359 }
360 pub fn count_set(&self) -> usize {
362 self.bits.iter().filter(|&&b| b).count()
363 }
364 pub fn capacity(&self) -> usize {
366 self.m
367 }
368}