pushr/push/
vector.rs

1use crate::push::instructions::Instruction;
2use crate::push::instructions::InstructionCache;
3use crate::push::item::Item;
4use crate::push::random::CodeGenerator;
5use crate::push::state::PushState;
6use crate::push::state::*;
7use crate::push::stack::PushPrint;
8use std::collections::HashMap;
9use std::fmt;
10
11#[derive(Clone, Debug, Default)]
12pub struct BoolVector {
13    pub values: Vec<bool>,
14}
15
16impl BoolVector {
17    pub fn new(arg: Vec<bool>) -> Self {
18        Self { values: arg }
19    }
20
21    pub fn from_int_array(arg: Vec<usize>) -> Self {
22        let mut bv = vec![false; arg.len()];
23        for (i, ival) in arg.iter().enumerate() {
24            bv[i] = ival == &1;
25        }
26        Self { values: bv }
27    }
28}
29
30impl PushPrint for BoolVector {
31   fn to_pstring(&self) -> String {
32       format!("{}", self.to_string())
33   }
34}
35
36impl fmt::Display for BoolVector {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        let mut s = self
39            .values
40            .clone()
41            .into_iter()
42            .fold(String::new(), |acc, num| {
43                acc + &num.to_string().to_uppercase() + ","
44            });
45        s.pop();
46        write!(f, "[{}]", s)
47    }
48}
49
50impl PartialEq for BoolVector {
51    fn eq(&self, other: &Self) -> bool {
52        self.values == other.values
53    }
54}
55
56#[derive(Clone, Debug, Default)]
57pub struct IntVector {
58    pub values: Vec<i32>,
59}
60
61impl IntVector {
62    pub fn new(arg: Vec<i32>) -> Self {
63        Self { values: arg }
64    }
65}
66
67impl PushPrint for IntVector {
68   fn to_pstring(&self) -> String {
69       format!("{}", self.to_string())
70   }
71}
72
73impl fmt::Display for IntVector {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        let mut s = self
76            .values
77            .clone()
78            .into_iter()
79            .fold(String::new(), |acc, num| acc + &num.to_string() + ",");
80        s.pop();
81        write!(f, "[{}]", s)
82    }
83}
84
85impl PartialEq for IntVector {
86    fn eq(&self, other: &Self) -> bool {
87        self.values == other.values
88    }
89}
90
91#[derive(Clone, Debug, Default)]
92pub struct FloatVector {
93    pub values: Vec<f32>,
94}
95
96impl FloatVector {
97    pub fn new(arg: Vec<f32>) -> Self {
98        Self { values: arg }
99    }
100}
101
102impl PushPrint for FloatVector {
103   fn to_pstring(&self) -> String {
104       format!("{}", self.to_string())
105   }
106}
107
108impl fmt::Display for FloatVector {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        let mut s = self
111            .values
112            .clone()
113            .into_iter()
114            .fold(String::new(), |acc, num| acc + &format!("{:.3}", num) + ",");
115        s.pop();
116        write!(f, "[{}]", s)
117    }
118}
119
120impl PartialEq for FloatVector {
121    fn eq(&self, other: &Self) -> bool {
122        self.values == other.values
123    }
124}
125
126pub fn load_vector_instructions(map: &mut HashMap<String, Instruction>) {
127    map.insert(
128        String::from("BOOLVECTOR.GET"),
129        Instruction::new(bool_vector_get),
130    );
131    map.insert(
132        String::from("BOOLVECTOR.SET"),
133        Instruction::new(bool_vector_set),
134    );
135    map.insert(
136        String::from("BOOLVECTOR.AND"),
137        Instruction::new(bool_vector_and),
138    );
139    map.insert(
140        String::from("BOOLVECTOR.OR"),
141        Instruction::new(bool_vector_or),
142    );
143    map.insert(
144        String::from("BOOLVECTOR.NOT"),
145        Instruction::new(bool_vector_not),
146    );
147    map.insert(
148        String::from("BOOLVECTOR.COUNT"),
149        Instruction::new(bool_vector_count),
150    );
151    map.insert(
152        String::from("BOOLVECTOR.DEFINE"),
153        Instruction::new(bool_vector_define),
154    );
155    map.insert(
156        String::from("BOOLVECTOR.DUP"),
157        Instruction::new(bool_vector_dup),
158    );
159    map.insert(
160        String::from("BOOLVECTOR.EQUAL"),
161        Instruction::new(bool_vector_equal),
162    );
163    map.insert(
164        String::from("BOOLVECTOR.FLUSH"),
165        Instruction::new(bool_vector_flush),
166    );
167    map.insert(
168        String::from("BOOLVECTOR.ID"),
169        Instruction::new(bool_vector_id),
170    );
171    map.insert(
172        String::from("BOOLVECTOR.LENGTH"),
173        Instruction::new(bool_vector_length),
174    );
175    map.insert(
176        String::from("BOOLVECTOR.ONES"),
177        Instruction::new(bool_vector_ones),
178    );
179    map.insert(
180        String::from("BOOLVECTOR.POP"),
181        Instruction::new(bool_vector_pop),
182    );
183    map.insert(
184        String::from("BOOLVECTOR.RAND"),
185        Instruction::new(bool_vector_rand),
186    );
187    map.insert(
188        String::from("BOOLVECTOR.ROTATE"),
189        Instruction::new(bool_vector_rand),
190    );
191    map.insert(
192        String::from("BOOLVECTOR.SHOVE"),
193        Instruction::new(bool_vector_shove),
194    );
195    map.insert(
196        String::from("BOOLVECTOR.SORT*ASC"),
197        Instruction::new(bool_vector_sort_asc),
198    );
199    map.insert(
200        String::from("BOOLVECTOR.SORT*DESC"),
201        Instruction::new(bool_vector_sort_desc),
202    );
203    map.insert(
204        String::from("BOOLVECTOR.SWAP"),
205        Instruction::new(bool_vector_swap),
206    );
207    map.insert(
208        String::from("BOOLVECTOR.STACKDEPTH"),
209        Instruction::new(bool_vector_stack_depth),
210    );
211    map.insert(
212        String::from("BOOLVECTOR.YANK"),
213        Instruction::new(bool_vector_yank),
214    );
215    map.insert(
216        String::from("BOOLVECTOR.YANKDUP"),
217        Instruction::new(bool_vector_yank_dup),
218    );
219    map.insert(
220        String::from("BOOLVECTOR.ZEROS"),
221        Instruction::new(bool_vector_zeros),
222    );
223
224    map.insert(
225        String::from("INTVECTOR.APPEND"),
226        Instruction::new(int_vector_append),
227    );
228    map.insert(
229        String::from("INTVECTOR.BOOLINDEX"),
230        Instruction::new(int_vector_bool_index),
231    );
232    map.insert(
233        String::from("INTVECTOR.GET"),
234        Instruction::new(int_vector_get),
235    );
236    map.insert(
237        String::from("INTVECTOR.SET"),
238        Instruction::new(int_vector_set),
239    );
240    map.insert(
241        String::from("INTVECTOR.+"),
242        Instruction::new(int_vector_add),
243    );
244    map.insert(
245        String::from("INTVECTOR.-"),
246        Instruction::new(int_vector_subtract),
247    );
248//    map.insert(
249//        String::from("INTVECTOR.*"),
250//        Instruction::new(int_vector_multiply),
251//    );
252//    map.insert(
253//        String::from("INTVECTOR./"),
254//        Instruction::new(int_vector_divide),
255//    );
256    map.insert(
257        String::from("INTVECTOR.CONTAINS"),
258        Instruction::new(int_vector_contains),
259    );
260    map.insert(
261        String::from("INTVECTOR.DEFINE"),
262        Instruction::new(int_vector_define),
263    );
264    map.insert(
265        String::from("INTVECTOR.DUP"),
266        Instruction::new(int_vector_dup),
267    );
268    map.insert(
269        String::from("INTVECTOR.EMPTY"),
270        Instruction::new(int_vector_empty),
271    );
272    map.insert(
273        String::from("INTVECTOR.EQUAL"),
274        Instruction::new(int_vector_equal),
275    );
276    map.insert(
277        String::from("INTVECTOR.FLUSH"),
278        Instruction::new(int_vector_flush),
279    );
280    map.insert(
281        String::from("INTVECTOR.FROMINT"),
282        Instruction::new(int_vector_from_int),
283    );
284    map.insert(
285        String::from("INTVECTOR.ID"),
286        Instruction::new(int_vector_id),
287    );
288    map.insert(
289        String::from("INTVECTOR.ONES"),
290        Instruction::new(int_vector_ones),
291    );
292    map.insert(
293        String::from("INTVECTOR.MEAN"),
294        Instruction::new(int_vector_mean),
295    );
296    map.insert(
297        String::from("INTVECTOR.LENGTH"),
298        Instruction::new(int_vector_length),
299    );
300    map.insert(
301        String::from("INTVECTOR.LOOP"),
302        Instruction::new(int_vector_loop),
303    );
304    map.insert(
305        String::from("INTVECTOR.POP"),
306        Instruction::new(int_vector_pop),
307    );
308    map.insert(
309        String::from("INTVECTOR.REMOVE"),
310        Instruction::new(int_vector_remove),
311    );
312    map.insert(
313        String::from("INTVECTOR.RAND"),
314        Instruction::new(int_vector_rand),
315    );
316    map.insert(
317        String::from("INTVECTOR.ROTATE"),
318        Instruction::new(int_vector_rotate),
319    );
320    map.insert(
321        String::from("INTVECTOR.SHOVE"),
322        Instruction::new(int_vector_shove),
323    );
324    map.insert(
325        String::from("INTVECTOR.SORT*ASC"),
326        Instruction::new(int_vector_sort_asc),
327    );
328    map.insert(
329        String::from("INTVECTOR.SORT*DESC"),
330        Instruction::new(int_vector_sort_desc),
331    );
332    map.insert(
333        String::from("INTVECTOR.SWAP"),
334        Instruction::new(int_vector_swap),
335    );
336    map.insert(
337        String::from("INTVECTOR.STACKDEPTH"),
338        Instruction::new(int_vector_stack_depth),
339    );
340    map.insert(
341        String::from("INTVECTOR.SET*INSERT"),
342        Instruction::new(int_vector_set_insert),
343    );
344    map.insert(
345        String::from("INTVECTOR.SUM"),
346        Instruction::new(int_vector_sum),
347    );
348    map.insert(
349        String::from("INTVECTOR.YANK"),
350        Instruction::new(int_vector_yank),
351    );
352    map.insert(
353        String::from("INTVECTOR.YANKDUP"),
354        Instruction::new(int_vector_yank_dup),
355    );
356    map.insert(
357        String::from("INTVECTOR.ZEROS"),
358        Instruction::new(int_vector_zeros),
359    );
360
361    map.insert(
362        String::from("FLOATVECTOR.GET"),
363        Instruction::new(float_vector_get),
364    );
365    map.insert(
366        String::from("FLOATVECTOR.SET"),
367        Instruction::new(float_vector_set),
368    );
369    map.insert(
370        String::from("FLOATVECTOR.+"),
371        Instruction::new(float_vector_add),
372    );
373    map.insert(
374        String::from("FLOATVECTOR.-"),
375        Instruction::new(float_vector_subtract),
376    );
377    map.insert(
378        String::from("FLOATVECTOR.*"),
379        Instruction::new(float_vector_multiply),
380    );
381    map.insert(
382        String::from("FLOATVECTOR.*SCALAR"),
383        Instruction::new(float_vector_multiply_scalar),
384    );
385    map.insert(
386        String::from("FLOATVECTOR./"),
387        Instruction::new(float_vector_divide),
388    );
389    map.insert(
390        String::from("FLOATVECTOR.APPEND"),
391        Instruction::new(float_vector_append),
392    );
393    map.insert(
394        String::from("FLOATVECTOR.DEFINE"),
395        Instruction::new(float_vector_define),
396    );
397    map.insert(
398        String::from("FLOATVECTOR.DUP"),
399        Instruction::new(float_vector_dup),
400    );
401    map.insert(
402        String::from("FLOATVECTOR.EMPTY"),
403        Instruction::new(float_vector_empty),
404    );
405    map.insert(
406        String::from("FLOATVECTOR.EQUAL"),
407        Instruction::new(float_vector_equal),
408    );
409    map.insert(
410        String::from("FLOATVECTOR.FLUSH"),
411        Instruction::new(float_vector_flush),
412    );
413    map.insert(
414        String::from("FLOATVECTOR.ID"),
415        Instruction::new(float_vector_id),
416    );
417    map.insert(
418        String::from("FLOATVECTOR.LENGTH"),
419        Instruction::new(float_vector_length),
420    );
421    map.insert(
422        String::from("FLOATVECTOR.MEAN"),
423        Instruction::new(float_vector_mean),
424    );
425    map.insert(
426        String::from("FLOATVECTOR.ONES"),
427        Instruction::new(float_vector_ones),
428    );
429    map.insert(
430        String::from("FLOATVECTOR.POP"),
431        Instruction::new(float_vector_pop),
432    );
433    map.insert(
434        String::from("FLOATVECTOR.RAND"),
435        Instruction::new(float_vector_rand),
436    );
437    map.insert(
438        String::from("FLOATVECTOR.ROTATE"),
439        Instruction::new(float_vector_rotate),
440    );
441    map.insert(
442        String::from("FLOATVECTOR.SINE"),
443        Instruction::new(float_vector_sine),
444    );
445    map.insert(
446        String::from("FLOATVECTOR.SHOVE"),
447        Instruction::new(float_vector_shove),
448    );
449    map.insert(
450        String::from("FLOATVECTOR.SORT*ASC"),
451        Instruction::new(float_vector_sort_asc),
452    );
453    map.insert(
454        String::from("FLOATVECTOR.SORT*DESC"),
455        Instruction::new(float_vector_sort_desc),
456    );
457    map.insert(
458        String::from("FLOATVECTOR.SWAP"),
459        Instruction::new(float_vector_swap),
460    );
461    map.insert(
462        String::from("FLOATVECTOR.STACKDEPTH"),
463        Instruction::new(float_vector_stack_depth),
464    );
465    map.insert(
466        String::from("FLOATVECTOR.SUM"),
467        Instruction::new(float_vector_stack_depth),
468    );
469    map.insert(
470        String::from("FLOATVECTOR.YANK"),
471        Instruction::new(float_vector_yank),
472    );
473    map.insert(
474        String::from("FLOATVECTOR.YANKDUP"),
475        Instruction::new(float_vector_yank_dup),
476    );
477    map.insert(
478        String::from("FLOATVECTOR.ZEROS"),
479        Instruction::new(float_vector_zeros),
480    );
481}
482
483/////////////////////////////////////// BOOLVECTOR //////////////////////////////////////////
484
485/// BOOLVECTOR.ID: Pushes the ID of the BOOLVECTOR stack to the INTEGER stack.
486pub fn bool_vector_id(push_state: &mut PushState, _instruction_set: &InstructionCache) {
487    push_state.int_stack.push(BOOL_VECTOR_STACK_ID);
488}
489
490/// BOOLVECTOR.SET: Replaces the ith element of the top BOOLVECTOR item by the top item of the
491/// BOOLEAN stack. The index i is taken from the INTEGER stack.
492pub fn bool_vector_set(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
493    if let Some(index) = push_state.int_stack.pop() {
494        if let Some(new_element) = push_state.bool_stack.pop() {
495            if let Some(item_to_change) = push_state.bool_vector_stack.get_mut(0) {
496                if item_to_change.values.len() > 0 {
497                    let i =
498                        i32::max(i32::min(index, item_to_change.values.len() as i32 - 1), 0) as usize;
499                    item_to_change.values[i] = new_element;
500                }
501            }
502        }
503    }
504}
505
506/// BOOLVECTOR.AND: Pushes the result of applying element-wise AND of the top item to the
507/// second item on the BOOLVECTOR stack. It applies an offset to the indices of the top
508/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
509/// range of the second item are ignored. If there is no overlap of indices the second item of
510/// the stack is pushed as a result.
511pub fn bool_vector_and(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
512    if let Some(mut bv) = push_state.bool_vector_stack.pop_vec(2) {
513        if let Some(offset) = push_state.int_stack.pop() {
514            // Loop through indices of second item
515            let scd_size = bv[0].values.len();
516            for i in 0..scd_size {
517                let ofs_idx = (i as i32 + offset) as usize;
518                if ofs_idx > scd_size - 1 {
519                    continue; // Out of bounds
520                }
521                bv[0].values[ofs_idx] &= bv[1].values[i];
522            }
523            push_state.bool_vector_stack.push(bv[0].clone());
524        }
525    }
526}
527
528/// BOOLVECTOR.GET: Copies the element at index i of the top BOOLVECTOR item to the BOOLEAN stack
529/// where i taken from the INTEGER stack limited to valid range.
530pub fn bool_vector_get(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
531    if let Some(index) = push_state.int_stack.pop() {
532        if let Some(element) = push_state.bool_vector_stack.get(0) {
533            if element.values.len() >0 {
534                let i = i32::max(i32::min(index, element.values.len() as i32 - 1), 0) as usize;
535                push_state.bool_stack.push(element.values[i].clone());
536            }
537        }
538    }
539}
540
541/// BOOLVECTOR.OR: Pushes the result of applying element-wise OR of the top item to the
542/// second item on the BOOLVECTOR stack. It applies an offset to the indices of the top
543/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
544/// range of the second item are ignored. If there is no overlap of indices the second item of
545/// the stack is pushed as a result.
546pub fn bool_vector_or(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
547    if let Some(mut bv) = push_state.bool_vector_stack.pop_vec(2) {
548        if let Some(offset) = push_state.int_stack.pop() {
549            // Loop through indices of second item
550            let scd_size = bv[0].values.len();
551            for i in 0..scd_size {
552                let ofs_idx = (i as i32 + offset) as usize;
553                if ofs_idx > scd_size - 1 {
554                    continue; // Out of bounds
555                }
556                bv[0].values[ofs_idx] |= bv[1].values[i];
557            }
558            push_state.bool_vector_stack.push(bv[0].clone());
559        }
560    }
561}
562
563/// BOOLVECTOR.NOT Applies the negation operator for the elements of the top item. It only considers
564/// indices larger than the offset. The offset is taken from the INTEGER stack.
565pub fn bool_vector_not(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
566    if let Some(mut bvval) = push_state.bool_vector_stack.pop() {
567        if let Some(offset) = push_state.int_stack.pop() {
568            for i in 0..bvval.values.len() {
569                let ofs_idx = (i as i32 + offset) as usize;
570                if ofs_idx > bvval.values.len() - 1 {
571                    continue; // Out of bounds
572                }
573                bvval.values[ofs_idx] = !bvval.values[ofs_idx];
574            }
575            push_state.bool_vector_stack.push(bvval.clone());
576        }
577    }
578}
579
580/// BOOLVECTOR.DEFINE: Defines the name on top of the NAME stack as an instruction that will
581/// push the top item of the BOOLVECTOR stack onto the EXEC stack.
582pub fn bool_vector_define(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
583    if let Some(name) = push_state.name_stack.pop() {
584        if let Some(bvval) = push_state.bool_vector_stack.pop() {
585            push_state.name_bindings.insert(name, Item::boolvec(bvval));
586        }
587    }
588}
589
590/// BOOLVECTOR.DUP: Duplicates the top item on the  stack. Does not pop its argument (which, if
591/// it did, would negate the effect of the duplication!).
592pub fn bool_vector_dup(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
593    if let Some(bvval) = push_state.bool_vector_stack.copy(0) {
594        push_state.bool_vector_stack.push(bvval);
595    }
596}
597
598/// BOOLVECTOR.=: Pushes TRUE onto the BOOLEAN stack if the top two items are equal, or FALSE
599/// otherwise.
600fn bool_vector_equal(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
601    if let Some(bvvals) = push_state.bool_vector_stack.pop_vec(2) {
602        push_state.bool_stack.push(bvvals[0] == bvvals[1]);
603    }
604}
605
606/// BOOLVECTOR.FLUSH: Empties the BOOLVECTOR stack.
607pub fn bool_vector_flush(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
608    push_state.bool_vector_stack.flush();
609}
610
611/// BOOLVECTOR.LENGTH: Pushes the length of the top BOOLVECTOR item to the INTEGER stack.
612pub fn bool_vector_length(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
613    if let Some(bv) = push_state.bool_vector_stack.get(0) {
614        push_state.int_stack.push(bv.values.len() as i32);
615    }
616}
617
618/// BOOLVECTOR.ONES: Pushes a newly generated BOOLVECTOR with all elements set to true. The size
619/// is taken from the INTEGER stack
620pub fn bool_vector_ones(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
621    if let Some(size) = push_state.int_stack.pop() {
622        if size > 0 {
623            push_state
624                .bool_vector_stack
625                .push(BoolVector::from_int_array(vec![1; size as usize]));
626        }
627    }
628}
629
630/// BOOLVECTOR.POP: Pops the BOOLVECTOR stack.
631pub fn bool_vector_pop(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
632    push_state.bool_vector_stack.pop();
633}
634
635/// BOOLVECTOR.RAND: Pushes a newly generated random BOOLVECTOR. The size is taken from the INTEGER
636/// stack, the sparsity from the FLOAT stack. If the size is <0 or the sparcity not in [0,1] this
637/// acts as a NOOP.
638pub fn bool_vector_rand(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
639    if let Some(size) = push_state.int_stack.pop() {
640        if let Some(sparsity) = push_state.float_stack.pop() {
641            if let Some(rbvval) = CodeGenerator::random_bool_vector(size, sparsity) {
642                push_state.bool_vector_stack.push(rbvval);
643            }
644        }
645    }
646}
647
648/// BOOLVECTOR.ROTATE: Moves all elements of the top item to the adjacent position on the left.
649/// The first item is removed while the last element of the vector is taken from the BOOLEAN stack.
650pub fn bool_vector_rotate(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
651    if let Some(b) = push_state.bool_stack.pop() {
652        if let Some(bv) = push_state.bool_vector_stack.get_mut(0) {
653            bv.values.rotate_left(1);
654            let n = bv.values.len();
655            bv.values[n - 1] = b;
656        }
657    }
658}
659
660/// BOOLVECTOR.SORT*ASC: Sorts the top BOOLVECTOR item in ascending order.
661pub fn bool_vector_sort_asc(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
662    if let Some(bvec) = push_state.bool_vector_stack.get_mut(0) {
663        bvec.values.sort_by(|a, b| a.partial_cmp(b).unwrap());
664    }
665}
666
667/// BOOLVECTOR.SORT*DESC: Sorts the top BOOLVECTOR item in descending order.
668pub fn bool_vector_sort_desc(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
669    if let Some(bvec) = push_state.bool_vector_stack.get_mut(0) {
670        bvec.values.sort_by(|a, b| a.partial_cmp(b).unwrap());
671        bvec.values.reverse();
672    }
673}
674
675/// BOOLVECTOR.COUNT Pushes the count of true elements to the INTEGER stack.
676pub fn bool_vector_count(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
677    if let Some(bvec) = push_state.bool_vector_stack.get(0) {
678        push_state
679            .int_stack
680            .push(bvec.values.iter().filter(|&n| *n == true).count() as i32);
681    }
682}
683
684/// BOOLVECTOR.SHOVE: Inserts the second INTEGER "deep" in the stack, at the position indexed by the
685/// top INTEGER. The index position is calculated after the index is removed.
686pub fn bool_vector_shove(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
687    if let Some(shove_index) = push_state.int_stack.pop() {
688        let corr_index = i32::max(
689            i32::min(
690                (push_state.bool_vector_stack.size() as i32) - 1,
691                shove_index,
692            ),
693            0,
694        ) as usize;
695        push_state.bool_vector_stack.shove(corr_index);
696    }
697}
698
699/// BOOLVECTOR.STACKDEPTH: Pushes the stack depth onto the INTEGER stack (thereby increasing it!).
700pub fn bool_vector_stack_depth(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
701    push_state
702        .int_stack
703        .push(push_state.bool_vector_stack.size() as i32);
704}
705
706/// BOOLVECTOR.SWAP: Swaps the top two BOOLVECTORs.
707pub fn bool_vector_swap(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
708    push_state.bool_vector_stack.shove(1);
709}
710
711/// BOOLVECTOR.YANK: Removes an indexed item from "deep" in the stack and pushes it on top of the
712/// stack. The index is taken from the INTEGER stack, and the indexing is done after the index is
713/// removed.
714pub fn bool_vector_yank(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
715    if let Some(idx) = push_state.int_stack.pop() {
716        let corr_index = i32::max(
717            i32::min((push_state.bool_vector_stack.size() as i32) - 1, idx),
718            0,
719        ) as usize;
720        push_state.bool_vector_stack.yank(corr_index as usize);
721    }
722}
723
724/// BOOLVECTOR.YANKDUP: Pushes a copy of an indexed item "deep" in the stack onto the top of the
725/// stack, without removing the deep item. The index is taken from the INTEGER stack, and the
726/// indexing is done after the index is removed.
727pub fn bool_vector_yank_dup(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
728    if let Some(idx) = push_state.int_stack.pop() {
729        let corr_index = i32::max(
730            i32::min((push_state.bool_vector_stack.size() as i32) - 1, idx),
731            0,
732        ) as usize;
733        if let Some(deep_item) = push_state.bool_vector_stack.copy(corr_index as usize) {
734            push_state.bool_vector_stack.push(deep_item);
735        }
736    }
737}
738
739/// BOOLVECTOR.ZEROS: Pushes a newly generated BOOLVECTOR with all elements set to false. The size
740/// is taken from the INTEGER stack.
741pub fn bool_vector_zeros(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
742    if let Some(size) = push_state.int_stack.pop() {
743        if size > 0 {
744            push_state
745                .bool_vector_stack
746                .push(BoolVector::from_int_array(vec![0; size as usize]));
747        }
748    }
749}
750
751/////////////////////////////////////// INTVECTOR //////////////////////////////////////////
752
753/// INTVECTOR.APPEND: Appends the top integer item to the top intvector item.
754pub fn int_vector_append(push_state: &mut PushState, _instruction_set: &InstructionCache) {
755    if let Some(item) = push_state.int_vector_stack.get_mut(0) {
756        if let Some(to_append) = push_state.int_stack.pop() {
757            item.values.push(to_append);
758        }
759    }
760}
761
762/// INTVECTOR.ID: Pushes the ID of the INTVECTOR stack to the INTEGER stack.
763pub fn int_vector_id(push_state: &mut PushState, _instruction_set: &InstructionCache) {
764    push_state.int_stack.push(INT_VECTOR_STACK_ID);
765}
766
767/// INTVECTOR.BOOLINDEX: Pushes an INTVECTOR item that contains the indices of all true values
768/// of the top BOOLVECTOR item. For example, this instruction pushes INT[0,2] if the top
769/// item on the BOOLVECTOR stack is BOOL[1,0,1]. The BOOLVECTOR item is popped.
770pub fn int_vector_bool_index(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
771    if let Some(bvval) = push_state.bool_vector_stack.pop() {
772        let mut index_vector = vec![];
773        for (i, bval) in bvval.values.iter().enumerate() {
774            if *bval {
775                index_vector.push(i as i32);
776            }
777        }
778        push_state
779            .int_vector_stack
780            .push(IntVector::new(index_vector));
781    }
782}
783
784/// INTVECTOR.GET: Copies the element at index i of the top INTVECTOR item to the INTEGER stack
785/// where i taken from the INTEGER stack and bound to valid range.
786pub fn int_vector_get(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
787    if let Some(index) = push_state.int_stack.pop() {
788        if let Some(element) = push_state.int_vector_stack.get(0) {
789            if element.values.len() >0 {
790                let i = i32::max(i32::min(index, element.values.len() as i32 - 1), 0) as usize;
791                push_state.int_stack.push(element.values[i].clone());
792            }
793        }
794    }
795}
796
797/// INTVECTOR.SET: Replaces the ith element of the top INTVECTOR item by the second item of the
798/// INTVECTOR stack. The top item of the INTEGER stack is the index i bound to valid range.
799pub fn int_vector_set(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
800    if let Some(index) = push_state.int_stack.pop() {
801        if let Some(new_element) = push_state.int_stack.pop() {
802            if let Some(item_to_change) = push_state.int_vector_stack.get_mut(0) {
803                if item_to_change.values.len() >0 {
804                    let i =
805                        i32::max(i32::min(index, item_to_change.values.len() as i32 - 1), 0) as usize;
806                    item_to_change.values[i] = new_element;
807                }
808            }
809        }
810    }
811}
812
813/// INTVECTOR.+: Pushes the result of applying element-wise ADD of the top item to the
814/// second item on the INTVECTOR stack. It applies an offset to the indices of the top
815/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
816/// range of the second item are ignored. If there is no overlap of indices the second item of
817/// the stack is pushed as a result.
818pub fn int_vector_add(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
819    if let Some(mut iv) = push_state.int_vector_stack.pop_vec(2) {
820        if let Some(offset) = push_state.int_stack.pop() {
821            // Loop through indices of second item
822            let scd_size = iv[0].values.len();
823            for i in 0..scd_size {
824                let ofs_idx = (i as i32 + offset) as usize;
825                if ofs_idx > scd_size - 1 {
826                    continue; // Out of bounds
827                }
828                iv[0].values[ofs_idx] += iv[1].values[i];
829            }
830            push_state.int_vector_stack.push(iv[0].clone());
831        }
832    }
833}
834
835/// INTVECTOR.-: Pushes the result of element-wise SUBTRACT of the top item from the
836/// second item on the INTVECTOR stack. It applies an offset to the indices of the top
837/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
838/// range of the second item are ignored. If there is no overlap of indices the second item of
839/// the stack is pushed as a result.
840pub fn int_vector_subtract(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
841    if let Some(mut iv) = push_state.int_vector_stack.pop_vec(2) {
842        if let Some(offset) = push_state.int_stack.pop() {
843            // Loop through indices of second item
844            let scd_size = iv[0].values.len();
845            for i in 0..scd_size {
846                let ofs_idx = (i as i32 + offset) as usize;
847                if ofs_idx > scd_size - 1 {
848                    continue; // Out of bounds
849                }
850                iv[0].values[ofs_idx] -= iv[1].values[i];
851            }
852            push_state.int_vector_stack.push(iv[0].clone());
853        }
854    }
855}
856
857/// INTVECTOR.*: Pushes the result of element-wise MULTIPLY of the top item to the
858/// second item on the INTVECTOR stack. It applies an offset to the indices of the top
859/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
860/// range of the second item are ignored. If there is no overlap of indices the second item of
861/// the stack is pushed as a result.
862pub fn int_vector_multiply(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
863    if let Some(mut iv) = push_state.int_vector_stack.pop_vec(2) {
864        if let Some(offset) = push_state.int_stack.pop() {
865            // Loop through indices of second item
866            let scd_size = iv[0].values.len();
867            for i in 0..scd_size {
868                let ofs_idx = (i as i32 + offset) as usize;
869                if ofs_idx > scd_size - 1 {
870                    continue; // Out of bounds
871                }
872                iv[0].values[ofs_idx] *= iv[1].values[i];
873            }
874            push_state.int_vector_stack.push(iv[0].clone());
875        }
876    }
877}
878
879/// INTVECTOR./: Pushes the result of element-wise DIVIDE of the second item by the
880/// top item on the INTVECTOR stack. It applies an offset to the indices of the top
881/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
882/// range of the second item are ignored. If there is no overlap of indices the second item of
883/// the stack is pushed as a result. If at least one divisor is zero the instruction acts
884/// as NOOP.
885pub fn int_vector_divide(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
886    if let Some(mut iv) = push_state.int_vector_stack.pop_vec(2) {
887        if let Some(offset) = push_state.int_stack.pop() {
888            let mut invalid = false;
889            // Loop through indices of second item
890            let scd_size = iv[0].values.len();
891            for i in 0..scd_size {
892                let ofs_idx = (i as i32 + offset) as usize;
893                if ofs_idx > scd_size - 1 {
894                    continue; // Out of bounds
895                }
896                if iv[1].values[i] == 0 {
897                    invalid = true;
898                } else {
899                    iv[0].values[ofs_idx] /= iv[1].values[i];
900                }
901            }
902            if !invalid {
903                push_state.int_vector_stack.push(iv[0].clone());
904            }
905        }
906    }
907}
908
909/// INTVECTOR.CONTAINS: Pushes true to the BOOLEAN stack if the top INTEGER is included in the
910/// top INTVECTOR item. This instruction acts as a NOOP if there is no INTEGER or INTVECTOR.
911/// The INTVECTOR item is popped.
912pub fn int_vector_contains(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
913    if let Some(element) = push_state.int_stack.pop() {
914        if let Some(array) = push_state.int_vector_stack.pop() {
915            push_state.bool_stack.push(array.values.contains(&element));
916        }
917    }
918}
919
920/// INTVECTOR.DEFINE: Defines the name on top of the NAME stack as an instruction that will
921/// push the top item of the INTVECTOR stack onto the EXEC stack.
922pub fn int_vector_define(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
923    if let Some(name) = push_state.name_stack.pop() {
924        if let Some(ivval) = push_state.int_vector_stack.pop() {
925            push_state.name_bindings.insert(name, Item::intvec(ivval));
926        }
927    }
928}
929
930/// INTVECTOR.DUP: Duplicates the top item on the  stack. Does not pop its argument (which, if
931/// it did, would negate the effect of the duplication!).
932pub fn int_vector_dup(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
933    if let Some(ivval) = push_state.int_vector_stack.copy(0) {
934        push_state.int_vector_stack.push(ivval);
935    }
936}
937
938/// INTVECTOR.EMPTY: Pushes an empty INTVECTOR.
939fn int_vector_empty(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
940    push_state.int_vector_stack.push(IntVector::new(vec![]));
941}
942
943/// INTVECTOR.=: Pushes TRUE onto the BOOLEAN stack if the top two items are equal, or FALSE
944/// otherwise.
945fn int_vector_equal(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
946    if let Some(ivvals) = push_state.int_vector_stack.pop_vec(2) {
947        push_state.bool_stack.push(ivvals[0] == ivvals[1]);
948    }
949}
950
951/// INTVECTOR.FLUSH: Empties the INTVECTOR stack.
952pub fn int_vector_flush(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
953    push_state.int_vector_stack.flush();
954}
955
956/// INTVECTOR.FROMINT: Create an INTVECTOR from the elements of the INTEGER stack. The top
957/// element (min-max corrected) describes the number of elements. The elements 1..n of
958/// the INTEGER stack are pushed as vector to the INTVECTOR stack.
959pub fn int_vector_from_int(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
960    if let Some(vector_size) = push_state.int_stack.pop() {
961        let size = push_state.int_stack.size() as i32;
962        let corr_size = i32::max(i32::min(size, vector_size), 0) as usize;
963        if let Some(ivec) = push_state.int_stack.pop_vec(corr_size) {
964            push_state.int_vector_stack.push(IntVector::new(ivec));
965        }
966    }
967}
968
969/// INTVECTOR.LENGTH: Pushes the length of the top INTVECTOR item to the INTEGER stack.
970pub fn int_vector_length(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
971    if let Some(iv) = push_state.int_vector_stack.get(0) {
972        push_state.int_stack.push(iv.values.len() as i32);
973    }
974}
975
976/// INTVECTOR.LOOP: Excecutes the top element of the EXEC stack once for each element
977/// of the top INTVECTOR item. The element that corresponds to the current loop iteration
978/// is pushed to the INTEGER stack.
979pub fn int_vector_loop(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
980    if let Some(mut array) = push_state.int_vector_stack.pop() {
981        if let Some(body) = push_state.exec_stack.pop() {
982            if !array.values.is_empty() {
983                let next_element = array.values.remove(0);
984                let updated_loop = Item::list(vec![
985                                              body.clone(),
986                                              Item::instruction("INTVECTOR.LOOP".to_string()),
987                                              Item::intvec(array),
988                ]);
989                push_state.exec_stack.push(updated_loop);
990                push_state.exec_stack.push(body);
991                push_state.int_stack.push(next_element);
992            }
993        } 
994    }
995}
996
997/// INTVECTOR.MEAN: Pushes the mean of the top INTVECTOR to the float stack
998pub fn int_vector_mean(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
999    if let Some(numbers) = push_state.int_vector_stack.get(0) {
1000        let sum = numbers.values.iter().sum::<i32>() as f32;
1001        let size = numbers.values.len() as f32;
1002        push_state.float_stack.push(sum / size);
1003    }
1004}
1005
1006/// INTVECTOR.ONES: Pushes a newly generated INTVECTOR with all elements set to 1. The size
1007/// is taken from the INTEGER stack
1008pub fn int_vector_ones(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1009    if let Some(size) = push_state.int_stack.pop() {
1010        if size > 0 {
1011            push_state
1012                .int_vector_stack
1013                .push(IntVector::new(vec![1; size as usize]));
1014        }
1015    }
1016}
1017
1018/// INTVECTOR.POP: Pops the INTVECTOR stack.
1019pub fn int_vector_pop(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1020    push_state.int_vector_stack.pop();
1021}
1022
1023/// INTVECTOR.RAND: Pushes a newly generated random INTVECTOR. The size, min and max values
1024/// taken from the INTEGER stack in that order. If the size is <0 or max < min this act as a NOOP.
1025pub fn int_vector_rand(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1026    if let Some(params) = push_state.int_stack.pop_vec(3) {
1027        // 1 params[2] -> size
1028        // 2 params[1] -> max
1029        // 3 params[0] -> min
1030        if let Some(rbvval) = CodeGenerator::random_int_vector(params[2], params[0], params[1]) {
1031            push_state.int_vector_stack.push(rbvval);
1032        }
1033    }
1034}
1035
1036/// INTVECTOR.REMOVE: Removes any occurance of the top element from the INTEGER stack from 
1037/// the top element of INTVECTOR if it is contained.
1038pub fn int_vector_remove(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1039    if let Some(item) = push_state.int_vector_stack.get_mut(0) {
1040        if let Some(to_remove) = push_state.int_stack.pop() {
1041            item.values.retain(|x| *x != to_remove);
1042        }
1043    }
1044}
1045
1046/// INTVECTOR.ROTATE: Moves all elements of the top item to the adjacent position on the left.
1047/// The first item is removed while the last element of the vector is taken from the INTEGER stack.
1048pub fn int_vector_rotate(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1049    if let Some(i) = push_state.int_stack.pop() {
1050        if let Some(iv) = push_state.int_vector_stack.get_mut(0) {
1051            iv.values.rotate_left(1);
1052            let n = iv.values.len();
1053            iv.values[n - 1] = i;
1054        }
1055    }
1056}
1057
1058/// INTVECTOR.SET*INSERT: Appends the top integer item to the top INTVECTOR item - only if
1059/// it does not already exit in the intvector. If no INTVECTOR item exists, a new one will
1060/// be created
1061pub fn int_vector_set_insert(push_state: &mut PushState, _instruction_set: &InstructionCache) {
1062    if push_state.int_vector_stack.size() == 0 {
1063        push_state.int_vector_stack.push(IntVector::new(vec![]));
1064    }
1065    if let Some(item) = push_state.int_vector_stack.get_mut(0) {
1066        if let Some(to_insert) = push_state.int_stack.pop() {
1067            if !item.values.contains(&to_insert) {
1068                item.values.push(to_insert);
1069            }
1070        }
1071    }
1072}
1073
1074/// INTVECTOR.SHOVE: Inserts the second INTEGER "deep" in the stack, at the position indexed by the
1075/// top INTEGER. The index position is calculated after the index is removed.
1076pub fn int_vector_shove(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1077    if let Some(shove_index) = push_state.int_stack.pop() {
1078        let corr_index = i32::max(
1079            i32::min((push_state.int_vector_stack.size() as i32) - 1, shove_index),
1080            0,
1081        ) as usize;
1082        push_state.int_vector_stack.shove(corr_index as usize);
1083    }
1084}
1085
1086/// INTVECTOR.SORT*ASC: Sorts the top INTVECTOR item in ascending order.
1087pub fn int_vector_sort_asc(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1088    if let Some(ivec) = push_state.int_vector_stack.get_mut(0) {
1089        ivec.values.sort();
1090    }
1091}
1092
1093/// INTVECTOR.SORT*DESC: Sorts the top INTVECTOR item in descending order.
1094pub fn int_vector_sort_desc(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1095    if let Some(ivec) = push_state.int_vector_stack.get_mut(0) {
1096        ivec.values.sort();
1097        ivec.values.reverse();
1098    }
1099}
1100
1101/// INTVECTOR.STACKDEPTH: Pushes the stack depth onto the INTEGER stack (thereby increasing it!).
1102pub fn int_vector_stack_depth(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1103    push_state
1104        .int_stack
1105        .push(push_state.int_vector_stack.size() as i32);
1106}
1107
1108/// INTVECTOR.SUM Pushes the sum of the elements to the INTEGER stack.
1109pub fn int_vector_sum(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1110    if let Some(ivec) = push_state.int_vector_stack.get(0) {
1111        push_state.int_stack.push(ivec.values.iter().sum());
1112    }
1113}
1114
1115/// INTVECTOR.SWAP: Swaps the top two INTVECTORs.
1116pub fn int_vector_swap(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1117    push_state.int_vector_stack.shove(1);
1118}
1119
1120/// INTVECTOR.YANK: Removes an indexed item from "deep" in the stack and pushes it on top of the
1121/// stack. The index is taken from the INTEGER stack, and the indexing is done after the index is
1122/// removed.
1123pub fn int_vector_yank(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1124    if let Some(idx) = push_state.int_stack.pop() {
1125        let corr_index = i32::max(
1126            i32::min((push_state.int_vector_stack.size() as i32) - 1, idx),
1127            0,
1128        ) as usize;
1129        push_state.int_vector_stack.yank(corr_index as usize);
1130    }
1131}
1132
1133/// INTVECTOR.YANKDUP: Pushes a copy of an indexed item "deep" in the stack onto the top of the
1134/// stack, without removing the deep item. The index is taken from the INTEGER stack, and the
1135/// indexing is done after the index is removed.
1136pub fn int_vector_yank_dup(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1137    if let Some(idx) = push_state.int_stack.pop() {
1138        let corr_index = i32::max(
1139            i32::min((push_state.int_vector_stack.size() as i32) - 1, idx),
1140            0,
1141        ) as usize;
1142        if let Some(deep_item) = push_state.int_vector_stack.copy(corr_index as usize) {
1143            push_state.int_vector_stack.push(deep_item);
1144        }
1145    }
1146}
1147
1148/// INTVECTOR.ZEROS: Pushes a newly generated INTVECTOR with all elements set to 0. The size
1149/// is taken from the INTEGER stack
1150pub fn int_vector_zeros(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1151    if let Some(size) = push_state.int_stack.pop() {
1152        if size > 0 {
1153            push_state
1154                .int_vector_stack
1155                .push(IntVector::new(vec![0; size as usize]));
1156        }
1157    }
1158}
1159
1160////////////////////////////////////// FLOATVECTOR //////////////////////////////////////////
1161
1162/// FLOATVECTOR.APPEND: Appends the top FLOAT item to the top FLOATVECTOR item.
1163pub fn float_vector_append(push_state: &mut PushState, _instruction_set: &InstructionCache) {
1164    if let Some(item) = push_state.float_vector_stack.get_mut(0) {
1165        if let Some(to_append) = push_state.float_stack.pop() {
1166            item.values.push(to_append);
1167        }
1168    }
1169}
1170
1171/// FLOATVECTOR.ID: Pushes the ID of the FLOATVECTOR stack to the INTEGER stack.
1172pub fn float_vector_id(push_state: &mut PushState, _instruction_set: &InstructionCache) {
1173    push_state.int_stack.push(FLOAT_VECTOR_STACK_ID);
1174}
1175
1176/// FLOATVECTOR.GET: Copies the element at index i of the top FLOATVECTOR item to the FLOAT stack
1177/// where i is taken from the FLOAT stack limited to valid range.
1178pub fn float_vector_get(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1179    if let Some(index) = push_state.int_stack.pop() {
1180        if let Some(element) = push_state.float_vector_stack.get(0) {
1181            if element.values.len() > 0 {
1182                let i = i32::max(i32::min(index, element.values.len() as i32 - 1), 0) as usize;
1183                push_state.float_stack.push(element.values[i].clone());
1184            }
1185        }
1186    }
1187}
1188
1189/// FLOATVECTOR.SET: Replaces the ith element of the top FLOATVECTOR item by the top item of the
1190/// FLOAT stack. The top item of the INTEGER stack is the index i limited to valid range.
1191pub fn float_vector_set(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1192    if let Some(index) = push_state.int_stack.pop() {
1193        if let Some(new_element) = push_state.float_stack.pop() {
1194            if let Some(item_to_change) = push_state.float_vector_stack.get_mut(0) {
1195                if item_to_change.values.len() > 0 {
1196                    let i = i32::max(i32::min(index, item_to_change.values.len() as i32 - 1), 0) as usize;
1197                    item_to_change.values[i] = new_element;
1198                }
1199            }
1200        }
1201    }
1202}
1203
1204/// FLOATVECTOR.+: Pushes the result of applying element-wise ADD of the top item to the
1205/// second item on the FLOATVECTOR stack. It applies an offset to the indices of the top
1206/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
1207/// range of the second item are ignored. If there is no overlap of indices the second item of
1208/// the stack is pushed as a result.
1209pub fn float_vector_add(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1210    if let Some(mut iv) = push_state.float_vector_stack.pop_vec(2) {
1211        if let Some(offset) = push_state.int_stack.pop() {
1212            // Loop through indices of second item
1213            let scd_size = iv[0].values.len();
1214            for i in 0..scd_size {
1215                let ofs_idx = (i as i32 + offset) as usize;
1216                if ofs_idx > scd_size - 1 {
1217                    continue; // Out of bounds
1218                }
1219                iv[0].values[ofs_idx] += iv[1].values[i];
1220            }
1221            push_state.float_vector_stack.push(iv[0].clone());
1222        }
1223    }
1224}
1225
1226/// FLOATVECTOR.-: Pushes the result of element-wise SUBTRACT of the top item from the
1227/// second item on the INTVECTOR stack. It applies an offset to the indices of the top
1228/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
1229/// range of the second item are ignored. If there is no overlap of indices the second item of
1230/// the stack is pushed as a result.
1231pub fn float_vector_subtract(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1232    if let Some(mut iv) = push_state.float_vector_stack.pop_vec(2) {
1233        if let Some(offset) = push_state.int_stack.pop() {
1234            // Loop through indices of second item
1235            let scd_size = iv[0].values.len();
1236            for i in 0..scd_size {
1237                let ofs_idx = (i as i32 + offset) as usize;
1238                if ofs_idx > scd_size - 1 {
1239                    continue; // Out of bounds
1240                }
1241                iv[0].values[ofs_idx] -= iv[1].values[i];
1242            }
1243            push_state.float_vector_stack.push(iv[0].clone());
1244        }
1245    }
1246}
1247
1248/// FLOATVECTOR.*: Pushes the result of element-wise MULTIPLY of the top item to the
1249/// second item on the INTVECTOR stack. It applies an offset to the indices of the top
1250/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
1251/// range of the second item are ignored. If there is no overlap of indices the second item of
1252/// the stack is pushed as a result.
1253pub fn float_vector_multiply(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1254    if let Some(mut iv) = push_state.float_vector_stack.pop_vec(2) {
1255        if let Some(offset) = push_state.int_stack.pop() {
1256            // Loop through indices of second item
1257            let scd_size = iv[0].values.len();
1258            for i in 0..scd_size {
1259                let ofs_idx = (i as i32 + offset) as usize;
1260                if ofs_idx > scd_size - 1 {
1261                    continue; // Out of bounds
1262                }
1263                iv[0].values[ofs_idx] *= iv[1].values[i];
1264            }
1265            push_state.float_vector_stack.push(iv[0].clone());
1266        }
1267    }
1268}
1269
1270/// FLOATVECTOR./: Pushes the result of element-wise DIVIDE of the second item by the
1271/// top item on the FLOATVECTOR stack. It applies an offset to the indices of the top
1272/// item. The offset is taken from the INTEGER stack. Indices that are outside of the valid
1273/// range of the second item are ignored. If there is no overlap of indices the second item of
1274/// the stack is pushed as a result. If at least one divisor is zero the instruction acts
1275/// as NOOP.
1276pub fn float_vector_divide(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1277    if let Some(mut iv) = push_state.float_vector_stack.pop_vec(2) {
1278        if let Some(offset) = push_state.int_stack.pop() {
1279            let mut invalid = false;
1280            // Loop through indices of second item
1281            let scd_size = iv[0].values.len();
1282            for i in 0..scd_size {
1283                let ofs_idx = (i as i32 + offset) as usize;
1284                if ofs_idx > scd_size - 1 {
1285                    continue; // Out of bounds
1286                }
1287                if iv[1].values[i] == 0.0 {
1288                    invalid = true;
1289                } else {
1290                    iv[0].values[ofs_idx] /= iv[1].values[i];
1291                }
1292            }
1293            if !invalid {
1294                push_state.float_vector_stack.push(iv[0].clone());
1295            }
1296        }
1297    }
1298}
1299
1300/// FLOATVECTOR.DEFINE: Defines the name on top of the NAME stack as an instruction that will
1301/// push the top item of the FLOATVECTOR stack onto the EXEC stack.
1302pub fn float_vector_define(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1303    if let Some(name) = push_state.name_stack.pop() {
1304        if let Some(fvval) = push_state.float_vector_stack.pop() {
1305            push_state.name_bindings.insert(name, Item::floatvec(fvval));
1306        }
1307    }
1308}
1309
1310/// FLOATVECTOR.DUP: Duplicates the top item on the  stack. Does not pop its argument (which, if
1311/// it did, would negate the effect of the duplication!).
1312pub fn float_vector_dup(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1313    if let Some(fvval) = push_state.float_vector_stack.copy(0) {
1314        push_state.float_vector_stack.push(fvval);
1315    }
1316}
1317
1318/// FLOATVECTOR.EMPTY: Pushes an empty FLOATVECTOR.
1319fn float_vector_empty(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1320    push_state.float_vector_stack.push(FloatVector::new(vec![]));
1321}
1322
1323/// FLOATVECTOR.=: Pushes TRUE onto the BOOLEAN stack if the top two items are equal, or FALSE
1324/// otherwise.
1325fn float_vector_equal(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1326    if let Some(fvvals) = push_state.float_vector_stack.pop_vec(2) {
1327        push_state.bool_stack.push(fvvals[0] == fvvals[1]);
1328    }
1329}
1330
1331/// FLOATVECTOR.FLUSH: Empties the FLOATVECTOR stack.
1332pub fn float_vector_flush(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1333    push_state.float_vector_stack.flush();
1334}
1335
1336/// FLOATVECTOR.LENGTH: Pushes the length of the top FLOATVECTOR item to the INTEGER stack.
1337pub fn float_vector_length(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1338    if let Some(fv) = push_state.float_vector_stack.get(0) {
1339        push_state.int_stack.push(fv.values.len() as i32);
1340    }
1341}
1342
1343/// FLOATVECTOR.MEAN: Pushes the mean of the top FLOATVECTOR to the float stack
1344pub fn float_vector_mean(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1345    if let Some(numbers) = push_state.float_vector_stack.get(0) {
1346        let sum = numbers.values.iter().sum::<f32>();
1347        let size = numbers.values.len() as f32;
1348        push_state.float_stack.push(sum / size);
1349    }
1350}
1351
1352/// FLOATVECTOR.*SCALAR: Multiplies the top item of the FLOAT stack with each element of the
1353/// top FLOATVECTOR element.
1354pub fn float_vector_multiply_scalar(
1355    push_state: &mut PushState,
1356    _instruction_cache: &InstructionCache,
1357) {
1358    if let Some(f) = push_state.float_stack.pop() {
1359        if let Some(fv) = push_state.float_vector_stack.get_mut(0) {
1360            fv.values.iter_mut().for_each(|x| *x *= f);
1361        }
1362    }
1363}
1364
1365/// FLOATVECTOR.ONES: Pushes a newly generated FLOATVECTOR with all elements set to 1. The size
1366/// is taken from the INTEGER stack
1367pub fn float_vector_ones(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1368    if let Some(size) = push_state.int_stack.pop() {
1369        if size > 0 {
1370            push_state
1371                .float_vector_stack
1372                .push(FloatVector::new(vec![1.0; size as usize]));
1373        }
1374    }
1375}
1376
1377/// FLOATVECTOR.POP: Pops the FLOATVECTOR stack.
1378pub fn float_vector_pop(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1379    push_state.float_vector_stack.pop();
1380}
1381
1382/// FLOATVECTOR.RAND: Pushes a newly generated random INTVECTOR. The size is taken from the
1383/// INTEGER stack while the parameters for mean and standard deviation are the first (top) and
1384/// second item on the FLOAT stack. If size < 0 or standard deviation < 0 this act as a NOOP.
1385pub fn float_vector_rand(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1386    if let Some(size) = push_state.int_stack.pop() {
1387        if let Some(gauss_params) = push_state.float_stack.pop_vec(2) {
1388            // 1 gauss_params[1]: mean
1389            // 2 gauss_params[0]: stddev
1390            if let Some(rfvval) =
1391                CodeGenerator::random_float_vector(size, gauss_params[1], gauss_params[0])
1392            {
1393                push_state.float_vector_stack.push(rfvval);
1394            }
1395        }
1396    }
1397}
1398
1399/// FLOATVECTOR.ROTATE: Moves all elements of the top item to the adjacent position on the left.
1400/// The first item is removed while the last element of the vector is taken from the FLOAT stack.
1401pub fn float_vector_rotate(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1402    if let Some(f) = push_state.float_stack.pop() {
1403        if let Some(fv) = push_state.float_vector_stack.get_mut(0) {
1404            fv.values.rotate_left(1);
1405            let n = fv.values.len();
1406            fv.values[n - 1] = f;
1407        }
1408    }
1409}
1410
1411/// FLOATVECTOR.SINE: Pushes a FLOATVECTOR item whose elements describe a sine wave. The sine wave
1412/// for the element at index i is calulated as A*sin(2*pi*x*i + phi). The amplitude A (1st),
1413/// the angle velocity x (2nd) and the phase angle phi (3rd) are taken from the FLOAT stack
1414/// (in that order). The vector length is taken from the INTEGER stack.
1415pub fn float_vector_sine(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1416    if let Some(sine_params) = push_state.float_stack.pop_vec(3) {
1417        if let Some(vector_size) = push_state.int_stack.pop() {
1418            let mut sine_vector = vec![];
1419            for i in 0..vector_size as usize {
1420                sine_vector.push(
1421                    sine_params[2]
1422                        * (2.0 * std::f32::consts::PI * sine_params[1] * i as f32 + sine_params[0])
1423                            .sin(),
1424                )
1425            }
1426            push_state
1427                .float_vector_stack
1428                .push(FloatVector::new(sine_vector));
1429        }
1430    }
1431}
1432
1433/// FLOATVECTOR.SHOVE: Inserts the second FLOATVECTOR "deep" in the stack, at the position indexed by the
1434/// top INTEGER. The index position is calculated after the index is removed.
1435pub fn float_vector_shove(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1436    if let Some(shove_index) = push_state.int_stack.pop() {
1437        let corr_index = i32::max(
1438            i32::min(
1439                (push_state.float_vector_stack.size() as i32) - 1,
1440                shove_index,
1441            ),
1442            0,
1443        ) as usize;
1444        push_state.float_vector_stack.shove(corr_index as usize);
1445    }
1446}
1447
1448/// FLOATVECTOR.SORT*ASC: Sorts the top FLOATVECTOR item in ascending order.
1449pub fn float_vector_sort_asc(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1450    if let Some(fvec) = push_state.float_vector_stack.get_mut(0) {
1451        fvec.values.sort_by(|a, b| a.partial_cmp(b).unwrap());
1452    }
1453}
1454
1455/// FLOATVECTOR.SORT*DESC: Sorts the top FLOATVECTOR item in descending order.
1456pub fn float_vector_sort_desc(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1457    if let Some(fvec) = push_state.float_vector_stack.get_mut(0) {
1458        fvec.values.sort_by(|a, b| a.partial_cmp(b).unwrap());
1459        fvec.values.reverse();
1460    }
1461}
1462
1463/// FLOATVECTOR.STACKDEPTH: Pushes the stack depth onto the INTEGER stack (thereby increasing it!).
1464pub fn float_vector_stack_depth(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1465    push_state
1466        .int_stack
1467        .push(push_state.float_vector_stack.size() as i32);
1468}
1469
1470/// FLOATVECTOR.SUM Pushes the sum of the elements to the FLOAT stack.
1471pub fn float_vector_sum(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1472    if let Some(fvec) = push_state.float_vector_stack.get(0) {
1473        push_state.float_stack.push(fvec.values.iter().sum());
1474    }
1475}
1476
1477/// FLOATVECTOR.SWAP: Swaps the top two FLOATVECTORs.
1478pub fn float_vector_swap(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1479    push_state.float_vector_stack.shove(1);
1480}
1481
1482/// FLOATVECTOR.YANK: Removes an indexed item from "deep" in the stack and pushes it on top of the
1483/// stack. The index is taken from the INTEGER stack, and the indexing is done after the index is
1484/// removed.
1485pub fn float_vector_yank(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1486    if let Some(idx) = push_state.int_stack.pop() {
1487        let corr_index = i32::max(
1488            i32::min((push_state.float_vector_stack.size() as i32) - 1, idx),
1489            0,
1490        ) as usize;
1491        push_state.float_vector_stack.yank(corr_index as usize);
1492    }
1493}
1494
1495/// FLOATVECTOR.YANKDUP: Pushes a copy of an indexed item "deep" in the stack onto the top of the
1496/// stack, without removing the deep item. The index is taken from the INTEGER stack, and the
1497/// indexing is done after the index is removed.
1498pub fn float_vector_yank_dup(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1499    if let Some(idx) = push_state.int_stack.pop() {
1500        let corr_index = i32::max(
1501            i32::min((push_state.float_vector_stack.size() as i32) - 1, idx),
1502            0,
1503        ) as usize;
1504        if let Some(deep_item) = push_state.float_vector_stack.copy(corr_index as usize) {
1505            push_state.float_vector_stack.push(deep_item);
1506        }
1507    }
1508}
1509
1510/// FLOATVECTOR.ZEROS: Pushes a newly generated FLOATVECTOR with all elements set to 0. The size
1511/// is taken from the INTEGER stack
1512pub fn float_vector_zeros(push_state: &mut PushState, _instruction_cache: &InstructionCache) {
1513    if let Some(size) = push_state.int_stack.pop() {
1514        if size > 0 {
1515            push_state
1516                .float_vector_stack
1517                .push(FloatVector::new(vec![0.0; size as usize]));
1518        }
1519    }
1520}
1521
1522#[cfg(test)]
1523mod tests {
1524    use super::*;
1525
1526    pub fn icache() -> InstructionCache {
1527        InstructionCache::new(vec![])
1528    }
1529
1530    /////////////////////////////////////// BOOLVECTOR //////////////////////////////////////////
1531
1532    #[test]
1533    fn bool_vector_prints_values() {
1534        let bv = BoolVector::new(vec![true, false, true]);
1535        assert_eq!(bv.to_string(), "[TRUE,FALSE,TRUE]");
1536    }
1537
1538    #[test]
1539    fn bool_vector_and_with_different_overlaps() {
1540        let test_vec1 = BoolVector::from_int_array(vec![1, 1, 1, 1, 0, 0, 0, 0]);
1541        let test_vec2 = BoolVector::from_int_array(vec![1, 0, 1, 0, 1, 0, 1, 0]);
1542
1543        // Full overlap
1544        let mut test_state = PushState::new();
1545        test_state.bool_vector_stack.push(test_vec2.clone());
1546        test_state.bool_vector_stack.push(test_vec1.clone());
1547        test_state.int_stack.push(0);
1548        bool_vector_and(&mut test_state, &icache());
1549        assert_eq!(test_state.bool_vector_stack.size(), 1);
1550        assert_eq!(
1551            test_state.bool_vector_stack.pop().unwrap(),
1552            BoolVector::from_int_array(vec![1, 0, 1, 0, 0, 0, 0, 0])
1553        );
1554
1555        // Positive overlap
1556        let mut test_state = PushState::new();
1557        test_state.bool_vector_stack.push(test_vec2.clone());
1558        test_state.bool_vector_stack.push(test_vec1.clone());
1559        test_state.int_stack.push(-4);
1560        bool_vector_and(&mut test_state, &icache());
1561        assert_eq!(test_state.bool_vector_stack.size(), 1);
1562        assert_eq!(
1563            test_state.bool_vector_stack.pop().unwrap(),
1564            BoolVector::from_int_array(vec![0, 0, 0, 0, 1, 0, 1, 0])
1565        );
1566
1567        // No overlap
1568        let mut test_state = PushState::new();
1569        test_state.bool_vector_stack.push(test_vec2.clone());
1570        test_state.bool_vector_stack.push(test_vec1.clone());
1571        test_state.int_stack.push(8);
1572        bool_vector_and(&mut test_state, &icache());
1573        assert_eq!(test_state.bool_vector_stack.size(), 1);
1574        assert_eq!(
1575            test_state.bool_vector_stack.pop().unwrap(),
1576            BoolVector::from_int_array(vec![1, 0, 1, 0, 1, 0, 1, 0])
1577        );
1578    }
1579
1580    #[test]
1581    fn bool_vector_get_pushes_vector_element() {
1582        let test_vec1 = BoolVector::from_int_array(vec![1, 1, 1, 0, 1, 1, 1, 1]);
1583        let mut test_state = PushState::new();
1584        test_state.bool_vector_stack.push(test_vec1);
1585        test_state.int_stack.push(3);
1586        bool_vector_get(&mut test_state, &icache());
1587        assert_eq!(test_state.bool_stack.pop().unwrap(), false);
1588        // Invalid index is bound to valid range
1589        test_state.int_stack.push(15);
1590        bool_vector_get(&mut test_state, &icache());
1591        assert_eq!(test_state.bool_stack.pop().unwrap(), true);
1592    }
1593
1594    #[test]
1595    fn bool_vector_set_modifies_vector() {
1596        let test_vec1 = BoolVector::from_int_array(vec![1, 1, 1, 1, 1, 1, 1, 1]);
1597        let mut test_state = PushState::new();
1598        test_state.bool_vector_stack.push(test_vec1);
1599        test_state.int_stack.push(5);
1600        test_state.bool_stack.push(false);
1601        bool_vector_set(&mut test_state, &icache());
1602        assert_eq!(
1603            test_state.bool_vector_stack.pop().unwrap(),
1604            BoolVector::from_int_array(vec![1, 1, 1, 1, 1, 0, 1, 1])
1605        );
1606    }
1607
1608    #[test]
1609    fn bool_vector_or_with_different_overlaps() {
1610        let test_vec1 = BoolVector::from_int_array(vec![1, 1, 1, 1, 0, 0, 0, 0]);
1611        let test_vec2 = BoolVector::from_int_array(vec![1, 0, 1, 0, 1, 0, 1, 0]);
1612
1613        // Full overlap
1614        let mut test_state = PushState::new();
1615        test_state.bool_vector_stack.push(test_vec2.clone());
1616        test_state.bool_vector_stack.push(test_vec1.clone());
1617        test_state.int_stack.push(0);
1618        bool_vector_or(&mut test_state, &icache());
1619        assert_eq!(test_state.bool_vector_stack.size(), 1);
1620        assert_eq!(
1621            test_state.bool_vector_stack.pop().unwrap(),
1622            BoolVector::from_int_array(vec![1, 1, 1, 1, 1, 0, 1, 0])
1623        );
1624
1625        // Positive overlap
1626        let mut test_state = PushState::new();
1627        test_state.bool_vector_stack.push(test_vec2.clone());
1628        test_state.bool_vector_stack.push(test_vec1.clone());
1629        test_state.int_stack.push(-4);
1630        bool_vector_or(&mut test_state, &icache());
1631        assert_eq!(test_state.bool_vector_stack.size(), 1);
1632        assert_eq!(
1633            test_state.bool_vector_stack.pop().unwrap(),
1634            BoolVector::from_int_array(vec![1, 0, 1, 0, 1, 0, 1, 0])
1635        );
1636
1637        // No overlap
1638        let mut test_state = PushState::new();
1639        test_state.bool_vector_stack.push(test_vec2.clone());
1640        test_state.bool_vector_stack.push(test_vec1.clone());
1641        test_state.int_stack.push(8);
1642        bool_vector_or(&mut test_state, &icache());
1643        assert_eq!(test_state.bool_vector_stack.size(), 1);
1644        assert_eq!(
1645            test_state.bool_vector_stack.pop().unwrap(),
1646            BoolVector::from_int_array(vec![1, 0, 1, 0, 1, 0, 1, 0])
1647        );
1648    }
1649
1650    #[test]
1651    fn bool_vector_not_with_different_overlaps() {
1652        let test_vec1 = BoolVector::from_int_array(vec![1, 1, 1, 1, 0, 0, 0, 0]);
1653
1654        // Full overlap
1655        let mut test_state = PushState::new();
1656        test_state.bool_vector_stack.push(test_vec1.clone());
1657        test_state.int_stack.push(0);
1658        bool_vector_not(&mut test_state, &icache());
1659        assert_eq!(test_state.bool_vector_stack.size(), 1);
1660        assert_eq!(
1661            test_state.bool_vector_stack.pop().unwrap(),
1662            BoolVector::from_int_array(vec![0, 0, 0, 0, 1, 1, 1, 1])
1663        );
1664
1665        // Positive overlap
1666        let mut test_state = PushState::new();
1667        test_state.bool_vector_stack.push(test_vec1.clone());
1668        test_state.int_stack.push(-4);
1669        bool_vector_not(&mut test_state, &icache());
1670        assert_eq!(test_state.bool_vector_stack.size(), 1);
1671        assert_eq!(
1672            test_state.bool_vector_stack.pop().unwrap(),
1673            BoolVector::from_int_array(vec![0, 0, 0, 0, 0, 0, 0, 0])
1674        );
1675
1676        // No overlap
1677        let mut test_state = PushState::new();
1678        test_state.bool_vector_stack.push(test_vec1.clone());
1679        test_state.int_stack.push(8);
1680        bool_vector_not(&mut test_state, &icache());
1681        assert_eq!(test_state.bool_vector_stack.size(), 1);
1682        assert_eq!(
1683            test_state.bool_vector_stack.pop().unwrap(),
1684            BoolVector::from_int_array(vec![1, 1, 1, 1, 0, 0, 0, 0])
1685        );
1686    }
1687
1688    #[test]
1689    fn bool_vector_define_creates_name_binding() {
1690        let mut test_state = PushState::new();
1691        test_state
1692            .bool_vector_stack
1693            .push(BoolVector::new(vec![true, false]));
1694        test_state.name_stack.push(String::from("TEST"));
1695        bool_vector_define(&mut test_state, &icache());
1696        assert_eq!(
1697            *test_state.name_bindings.get("TEST").unwrap().to_string(),
1698            Item::boolvec(BoolVector::new(vec![true, false])).to_string()
1699        );
1700    }
1701
1702    #[test]
1703    fn bool_vector_equal_pushes_result() {
1704        let mut test_state = PushState::new();
1705        test_state
1706            .bool_vector_stack
1707            .push(BoolVector::new(vec![true]));
1708        test_state
1709            .bool_vector_stack
1710            .push(BoolVector::new(vec![true]));
1711        bool_vector_equal(&mut test_state, &icache());
1712        assert_eq!(test_state.bool_stack.pop().unwrap(), true);
1713    }
1714
1715    #[test]
1716    fn bool_vector_ones_creates_item() {
1717        let mut test_state = PushState::new();
1718        let mut test_size = -11;
1719        test_state.int_stack.push(test_size);
1720        bool_vector_ones(&mut test_state, &icache());
1721        assert_eq!(test_state.bool_vector_stack.size(), 0);
1722        test_size = 11;
1723        test_state.int_stack.push(test_size);
1724        bool_vector_ones(&mut test_state, &icache());
1725        assert_eq!(
1726            test_state.bool_vector_stack.pop().unwrap(),
1727            BoolVector::from_int_array(vec![1; test_size as usize])
1728        );
1729    }
1730
1731    #[test]
1732    fn bool_vector_rand_pushes_new_item() {
1733        let mut test_state = PushState::new();
1734        let test_size = 92;
1735        let test_sparsity = 0.07;
1736        test_state.int_stack.push(test_size);
1737        test_state.float_stack.push(test_sparsity);
1738        bool_vector_rand(&mut test_state, &icache());
1739        if let Some(rbv) = test_state.bool_vector_stack.pop() {
1740            assert_eq!(rbv.values.len(), test_size as usize);
1741            assert_eq!(
1742                rbv.values.iter().filter(|&n| *n == true).count(),
1743                (test_sparsity * test_size as f32) as usize
1744            );
1745        } else {
1746            assert!(false, "Expected to find bool vector");
1747        }
1748    }
1749
1750    #[test]
1751    fn bool_vector_rotate_shifts_elements_left() {
1752        let mut test_state = PushState::new();
1753        test_state
1754            .bool_vector_stack
1755            .push(BoolVector::from_int_array(vec![1, 1, 1, 1, 0, 0, 0, 0]));
1756        test_state.bool_stack.push(true);
1757        bool_vector_rotate(&mut test_state, &icache());
1758        assert_eq!(
1759            test_state.bool_vector_stack.get(0).unwrap(),
1760            &BoolVector::from_int_array(vec![1, 1, 1, 0, 0, 0, 0, 1])
1761        );
1762        test_state.bool_stack.push(false);
1763        bool_vector_rotate(&mut test_state, &icache());
1764        assert_eq!(
1765            test_state.bool_vector_stack.get(0).unwrap(),
1766            &BoolVector::from_int_array(vec![1, 1, 0, 0, 0, 0, 1, 0])
1767        );
1768    }
1769
1770    #[test]
1771    fn bool_vector_shove_inserts_at_right_position() {
1772        let mut test_state = PushState::new();
1773        test_state
1774            .bool_vector_stack
1775            .push(BoolVector::new(vec![false]));
1776        test_state
1777            .bool_vector_stack
1778            .push(BoolVector::new(vec![false]));
1779        test_state
1780            .bool_vector_stack
1781            .push(BoolVector::new(vec![false]));
1782        test_state
1783            .bool_vector_stack
1784            .push(BoolVector::new(vec![true]));
1785        assert_eq!(
1786            test_state.bool_vector_stack.to_string(),
1787            "[TRUE] [FALSE] [FALSE] [FALSE]"
1788        );
1789        test_state.int_stack.push(2);
1790        bool_vector_shove(&mut test_state, &icache());
1791        assert_eq!(
1792            test_state.bool_vector_stack.to_string(),
1793            "[FALSE] [FALSE] [TRUE] [FALSE]"
1794        );
1795        test_state
1796            .bool_vector_stack
1797            .push(BoolVector::new(vec![true]));
1798        test_state.int_stack.push(25);
1799        bool_vector_shove(&mut test_state, &icache());
1800        assert_eq!(
1801            test_state.bool_vector_stack.to_string(),
1802            "[FALSE] [FALSE] [TRUE] [FALSE] [TRUE]"
1803        );
1804        test_state
1805            .bool_vector_stack
1806            .push(BoolVector::new(vec![true]));
1807        test_state.int_stack.push(-2);
1808        assert_eq!(
1809            test_state.bool_vector_stack.to_string(),
1810            "[TRUE] [FALSE] [FALSE] [TRUE] [FALSE] [TRUE]"
1811        );
1812    }
1813
1814    #[test]
1815    fn bool_vector_sort_top_item() {
1816        let mut test_state = PushState::new();
1817        test_state
1818            .bool_vector_stack
1819            .push(BoolVector::new(vec![true, false, false, true, false]));
1820        bool_vector_sort_asc(&mut test_state, &icache());
1821        assert_eq!(test_state.bool_vector_stack.to_string(), "[FALSE,FALSE,FALSE,TRUE,TRUE]");
1822        bool_vector_sort_desc(&mut test_state, &icache());
1823        assert_eq!(test_state.bool_vector_stack.to_string(), "[TRUE,TRUE,FALSE,FALSE,FALSE]");
1824    }
1825
1826    #[test]
1827    fn bool_vector_stack_depth_returns_size() {
1828        let mut test_state = PushState::new();
1829        test_state
1830            .bool_vector_stack
1831            .push(BoolVector::new(vec![true]));
1832        test_state
1833            .bool_vector_stack
1834            .push(BoolVector::new(vec![false]));
1835        test_state
1836            .bool_vector_stack
1837            .push(BoolVector::new(vec![false]));
1838        test_state
1839            .bool_vector_stack
1840            .push(BoolVector::new(vec![true]));
1841        bool_vector_stack_depth(&mut test_state, &icache());
1842        assert_eq!(test_state.int_stack.to_string(), "4");
1843    }
1844
1845    #[test]
1846    fn bool_vector_count_pushes_aggregation_value() {
1847        let mut test_state = PushState::new();
1848        test_state
1849            .bool_vector_stack
1850            .push(BoolVector::new(vec![true, false, false, true, false]));
1851        bool_vector_count(&mut test_state, &icache());
1852        assert_eq!(test_state.int_stack.to_string(), "2");
1853    }
1854
1855    #[test]
1856    fn bool_vector_swaps_top_elements() {
1857        let mut test_state = PushState::new();
1858        test_state
1859            .bool_vector_stack
1860            .push(BoolVector::new(vec![true]));
1861        test_state
1862            .bool_vector_stack
1863            .push(BoolVector::new(vec![false]));
1864        assert_eq!(test_state.bool_vector_stack.to_string(), "[FALSE] [TRUE]");
1865        bool_vector_swap(&mut test_state, &icache());
1866        assert_eq!(test_state.bool_vector_stack.to_string(), "[TRUE] [FALSE]");
1867    }
1868
1869    #[test]
1870    fn bool_vector_yank_brings_item_to_top() {
1871        let mut test_state = PushState::new();
1872        test_state
1873            .bool_vector_stack
1874            .push(BoolVector::new(vec![true]));
1875        test_state
1876            .bool_vector_stack
1877            .push(BoolVector::new(vec![false]));
1878        test_state
1879            .bool_vector_stack
1880            .push(BoolVector::new(vec![true]));
1881        test_state
1882            .bool_vector_stack
1883            .push(BoolVector::new(vec![true]));
1884        test_state
1885            .bool_vector_stack
1886            .push(BoolVector::new(vec![true]));
1887        assert_eq!(
1888            test_state.bool_vector_stack.to_string(),
1889            "[TRUE] [TRUE] [TRUE] [FALSE] [TRUE]"
1890        );
1891        test_state.int_stack.push(3);
1892        bool_vector_yank(&mut test_state, &icache());
1893        assert_eq!(
1894            test_state.bool_vector_stack.to_string(),
1895            "[FALSE] [TRUE] [TRUE] [TRUE] [TRUE]"
1896        );
1897    }
1898
1899    #[test]
1900    fn bool_vector_yank_dup_copies_item_to_top() {
1901        let mut test_state = PushState::new();
1902        test_state
1903            .bool_vector_stack
1904            .push(BoolVector::new(vec![true]));
1905        test_state
1906            .bool_vector_stack
1907            .push(BoolVector::new(vec![false]));
1908        test_state
1909            .bool_vector_stack
1910            .push(BoolVector::new(vec![true]));
1911        test_state
1912            .bool_vector_stack
1913            .push(BoolVector::new(vec![true]));
1914        test_state
1915            .bool_vector_stack
1916            .push(BoolVector::new(vec![true]));
1917        assert_eq!(
1918            test_state.bool_vector_stack.to_string(),
1919            "[TRUE] [TRUE] [TRUE] [FALSE] [TRUE]"
1920        );
1921        test_state.int_stack.push(3);
1922        bool_vector_yank_dup(&mut test_state, &icache());
1923        assert_eq!(
1924            test_state.bool_vector_stack.to_string(),
1925            "[FALSE] [TRUE] [TRUE] [TRUE] [FALSE] [TRUE]"
1926        );
1927    }
1928
1929    #[test]
1930    fn bool_vector_zeros_creates_item() {
1931        let mut test_state = PushState::new();
1932        let mut test_size = -11;
1933        test_state.int_stack.push(test_size);
1934        bool_vector_ones(&mut test_state, &icache());
1935        assert_eq!(test_state.bool_vector_stack.size(), 0);
1936        test_size = 11;
1937        test_state.int_stack.push(test_size);
1938        bool_vector_ones(&mut test_state, &icache());
1939        assert_eq!(
1940            test_state.bool_vector_stack.pop().unwrap(),
1941            BoolVector::from_int_array(vec![1; test_size as usize])
1942        );
1943    }
1944
1945    /////////////////////////////////////// INTVECTOR //////////////////////////////////////////
1946
1947    #[test]
1948    fn int_vector_prints_values() {
1949        let iv = IntVector::new(vec![1, 2, -3]);
1950        assert_eq!(iv.to_string(), "[1,2,-3]");
1951    }
1952
1953    #[test]
1954    fn int_vector_bool_index_pushes_indices_of_active_bits() {
1955        let mut test_state = PushState::new();
1956        test_state
1957            .bool_vector_stack
1958            .push(BoolVector::from_int_array(vec![1, 0, 0, 1, 0]));
1959        int_vector_bool_index(&mut test_state, &icache());
1960        assert_eq!(
1961            test_state.int_vector_stack.pop().unwrap(),
1962            IntVector::new(vec![0, 3])
1963        );
1964    }
1965
1966    #[test]
1967    fn int_vector_get_pushes_vector_element() {
1968        let test_vec1 = IntVector::new(vec![1, 1, 1, 0, 1, 1, 1, 2]);
1969        let mut test_state = PushState::new();
1970        test_state.int_vector_stack.push(test_vec1);
1971        test_state.int_stack.push(3);
1972        int_vector_get(&mut test_state, &icache());
1973        assert_eq!(test_state.int_stack.pop().unwrap(), 0);
1974        // Invalid index is changed to valid range
1975        test_state.int_stack.push(-15);
1976        int_vector_get(&mut test_state, &icache());
1977        assert_eq!(test_state.int_stack.pop().unwrap(), 1);
1978        test_state.int_stack.push(15);
1979        int_vector_get(&mut test_state, &icache());
1980        assert_eq!(test_state.int_stack.pop().unwrap(), 2);
1981    }
1982
1983    #[test]
1984    fn int_vector_set_modifies_vector() {
1985        let test_vec1 = IntVector::new(vec![1, 1, 1, 1, 1, 1, 1, 1]);
1986        let mut test_state = PushState::new();
1987        test_state.int_vector_stack.push(test_vec1);
1988        test_state.int_stack.push(12); // Second item: new element
1989        test_state.int_stack.push(5); // Top item: index
1990        int_vector_set(&mut test_state, &icache());
1991        assert_eq!(
1992            test_state.int_vector_stack.pop().unwrap(),
1993            IntVector::new(vec![1, 1, 1, 1, 1, 12, 1, 1])
1994        );
1995    }
1996
1997    #[test]
1998    fn int_vector_add_with_different_overlaps() {
1999        let test_vec1 = IntVector::new(vec![1, 1, 1, 1, 0, 0, 0, 0]);
2000        let test_vec2 = IntVector::new(vec![1, 0, 1, 0, 1, 0, 1, 0]);
2001
2002        // Full overlap
2003        let mut test_state = PushState::new();
2004        test_state.int_vector_stack.push(test_vec2.clone());
2005        test_state.int_vector_stack.push(test_vec1.clone());
2006        test_state.int_stack.push(0);
2007        int_vector_add(&mut test_state, &icache());
2008        assert_eq!(test_state.int_vector_stack.size(), 1);
2009        assert_eq!(
2010            test_state.int_vector_stack.pop().unwrap(),
2011            IntVector::new(vec![2, 1, 2, 1, 1, 0, 1, 0])
2012        );
2013
2014        // Positive overlap
2015        let mut test_state = PushState::new();
2016        test_state.int_vector_stack.push(test_vec2.clone());
2017        test_state.int_vector_stack.push(test_vec1.clone());
2018        test_state.int_stack.push(-4);
2019        int_vector_add(&mut test_state, &icache());
2020        assert_eq!(test_state.int_vector_stack.size(), 1);
2021        assert_eq!(
2022            test_state.int_vector_stack.pop().unwrap(),
2023            IntVector::new(vec![1, 0, 1, 0, 1, 0, 1, 0])
2024        );
2025
2026        // No overlap
2027        let mut test_state = PushState::new();
2028        test_state.int_vector_stack.push(test_vec2.clone());
2029        test_state.int_vector_stack.push(test_vec1.clone());
2030        test_state.int_stack.push(8);
2031        int_vector_add(&mut test_state, &icache());
2032        assert_eq!(test_state.int_vector_stack.size(), 1);
2033        assert_eq!(
2034            test_state.int_vector_stack.pop().unwrap(),
2035            IntVector::new(vec![1, 0, 1, 0, 1, 0, 1, 0])
2036        );
2037    }
2038
2039    #[test]
2040    fn int_vector_subtract_with_partial_overlap() {
2041        let test_vec1 = IntVector::new(vec![1, 1, 1, 1, 0, 0, 0, 0]);
2042        let test_vec2 = IntVector::new(vec![1, 0, 1, 0, 1, 0, 1, 0]);
2043
2044        // Full overlap
2045        let mut test_state = PushState::new();
2046        test_state.int_vector_stack.push(test_vec2.clone());
2047        test_state.int_vector_stack.push(test_vec1.clone());
2048        test_state.int_stack.push(4);
2049        int_vector_subtract(&mut test_state, &icache());
2050        assert_eq!(test_state.int_vector_stack.size(), 1);
2051        assert_eq!(
2052            test_state.int_vector_stack.pop().unwrap(),
2053            IntVector::new(vec![1, 0, 1, 0, 0, -1, 0, -1])
2054        );
2055    }
2056
2057    #[test]
2058    fn int_vector_multiply_with_partial_overlap() {
2059        let test_vec1 = IntVector::new(vec![-1, -1, -1, -1, 1, 1, 1, 1]);
2060        let test_vec2 = IntVector::new(vec![1, 2, 1, 2, 1, 2, 1, 2]);
2061
2062        // Full overlap
2063        let mut test_state = PushState::new();
2064        test_state.int_vector_stack.push(test_vec2.clone());
2065        test_state.int_vector_stack.push(test_vec1.clone());
2066        test_state.int_stack.push(4);
2067        int_vector_multiply(&mut test_state, &icache());
2068        assert_eq!(test_state.int_vector_stack.size(), 1);
2069        assert_eq!(
2070            test_state.int_vector_stack.pop().unwrap(),
2071            IntVector::new(vec![1, 2, 1, 2, -1, -2, -1, -2])
2072        );
2073    }
2074
2075    #[test]
2076    fn int_vector_divide_with_partial_overlap() {
2077        let test_vec1 = IntVector::new(vec![1, 2, 1, 2, 1, 2, 1, 2]);
2078        let test_vec2 = IntVector::new(vec![2, 2, 2, 2, 1, 1, 1, 1]);
2079
2080        // Full overlap
2081        let mut test_state = PushState::new();
2082        test_state.int_vector_stack.push(test_vec2.clone());
2083        test_state.int_vector_stack.push(test_vec1.clone());
2084        test_state.int_stack.push(4);
2085        int_vector_divide(&mut test_state, &icache());
2086        assert_eq!(test_state.int_vector_stack.size(), 1);
2087        assert_eq!(
2088            test_state.int_vector_stack.pop().unwrap(),
2089            IntVector::new(vec![2, 2, 2, 2, 1, 0, 1, 0])
2090        );
2091    }
2092
2093    #[test]
2094    fn int_vector_contains_pushes_to_bool() {
2095        let mut test_state = PushState::new();
2096        test_state
2097            .int_vector_stack
2098            .push(IntVector::new(vec![3, 4, 1, 2]));
2099        test_state.int_stack.push(4);
2100        int_vector_contains(&mut test_state, &icache());
2101        assert_eq!(test_state.bool_stack.pop().unwrap(), true);
2102        assert_eq!(test_state.int_vector_stack.size(), 0);
2103        test_state.int_stack.push(5);
2104        test_state
2105            .int_vector_stack
2106            .push(IntVector::new(vec![3, 4, 1, 2]));
2107        int_vector_contains(&mut test_state, &icache());
2108        assert_eq!(test_state.bool_stack.pop().unwrap(), false);
2109        assert_eq!(test_state.int_vector_stack.size(), 0);
2110        assert_eq!(test_state.int_stack.size(), 0);
2111    }
2112
2113    #[test]
2114    fn int_vector_define_creates_name_binding() {
2115        let mut test_state = PushState::new();
2116        test_state.int_vector_stack.push(IntVector::new(vec![1, 2]));
2117        test_state.name_stack.push(String::from("TEST"));
2118        int_vector_define(&mut test_state, &icache());
2119        assert_eq!(
2120            *test_state.name_bindings.get("TEST").unwrap().to_string(),
2121            Item::intvec(IntVector::new(vec![1, 2])).to_string()
2122        );
2123    }
2124
2125    #[test]
2126    fn int_vector_equal_pushes_result() {
2127        let mut test_state = PushState::new();
2128        test_state.int_vector_stack.push(IntVector::new(vec![4]));
2129        test_state.int_vector_stack.push(IntVector::new(vec![4]));
2130        int_vector_equal(&mut test_state, &icache());
2131        assert_eq!(test_state.bool_stack.pop().unwrap(), true);
2132    }
2133
2134    #[test]
2135    fn int_vector_from_int_pushes_item() {
2136        let mut test_state = PushState::new();
2137        for i in 0..10 {
2138            test_state.int_stack.push(i);
2139        }
2140        test_state.int_stack.push(11);
2141        int_vector_from_int(&mut test_state, &icache());
2142        assert_eq!(
2143            test_state.int_vector_stack.pop().unwrap(),
2144            IntVector::new(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2145        );
2146    }
2147
2148    #[test]
2149    fn int_vector_ones_creates_item() {
2150        let mut test_state = PushState::new();
2151        let mut test_size = -11;
2152        test_state.int_stack.push(test_size);
2153        int_vector_ones(&mut test_state, &icache());
2154        assert_eq!(test_state.int_vector_stack.size(), 0);
2155        test_size = 11;
2156        test_state.int_stack.push(test_size);
2157        int_vector_ones(&mut test_state, &icache());
2158        assert_eq!(
2159            test_state.int_vector_stack.pop().unwrap(),
2160            IntVector::new(vec![1; test_size as usize])
2161        );
2162    }
2163
2164    #[test]
2165    fn int_vector_rotate_shifts_elements_left() {
2166        let mut test_state = PushState::new();
2167        test_state
2168            .int_vector_stack
2169            .push(IntVector::new(vec![1, 2, 3, 4, 0, 0, 0, 0]));
2170        test_state.int_stack.push(5);
2171        int_vector_rotate(&mut test_state, &icache());
2172        assert_eq!(
2173            test_state.int_vector_stack.get(0).unwrap(),
2174            &IntVector::new(vec![2, 3, 4, 0, 0, 0, 0, 5])
2175        );
2176    }
2177
2178    #[test]
2179    fn int_vector_rand_pushes_new_item() {
2180        let mut test_state = PushState::new();
2181        let test_size = 92;
2182        let test_min = -7;
2183        let test_max = 77;
2184        test_state.int_stack.push(test_min);
2185        test_state.int_stack.push(test_max);
2186        test_state.int_stack.push(test_size);
2187        int_vector_rand(&mut test_state, &icache());
2188        if let Some(riv) = test_state.int_vector_stack.pop() {
2189            assert_eq!(riv.values.len(), test_size as usize);
2190            assert_eq!(
2191                riv.values
2192                    .iter()
2193                    .filter(|&n| (*n >= test_min && *n <= test_max) == true)
2194                    .count(),
2195                test_size as usize
2196            );
2197        } else {
2198            assert!(false, "Expected to find bool vector");
2199        }
2200    }
2201
2202    #[test]
2203    fn int_vector_remove_elements() {
2204        let mut test_state = PushState::new();
2205        let test_input = IntVector::new(vec![1,2,3,2]);
2206        test_state.int_vector_stack.push(test_input.clone());
2207        test_state.int_stack.push(5);
2208        int_vector_remove(&mut test_state, &icache());
2209        assert_eq!(test_state.int_vector_stack.get(0).unwrap(), &IntVector::new(vec![1,2,3,2]));
2210        test_state.int_stack.push(2);
2211        int_vector_remove(&mut test_state, &icache());
2212        assert_eq!(test_state.int_vector_stack.get(0).unwrap(), &IntVector::new(vec![1,3]));
2213    }
2214
2215    #[test]
2216    fn int_vector_set_insert_does_not_allow_duplicates() {
2217        let mut test_state = PushState::new();
2218        let test_input = IntVector::new(vec![1,2,3,4]);
2219        test_state.int_vector_stack.push(test_input.clone());
2220        test_state.int_stack.push(1);
2221        int_vector_set_insert(&mut test_state, &icache());
2222        assert_eq!(test_state.int_vector_stack.get(0).unwrap(), &test_input);
2223        test_state.int_stack.push(5);
2224        int_vector_set_insert(&mut test_state, &icache());
2225        assert_eq!(test_state.int_vector_stack.get(0).unwrap(), &IntVector::new(vec![1,2,3,4,5]));
2226    }
2227
2228    #[test]
2229    fn int_vector_shove_inserts_at_right_position() {
2230        let mut test_state = PushState::new();
2231        test_state.int_vector_stack.push(IntVector::new(vec![4]));
2232        test_state.int_vector_stack.push(IntVector::new(vec![3]));
2233        test_state.int_vector_stack.push(IntVector::new(vec![2]));
2234        test_state.int_vector_stack.push(IntVector::new(vec![1]));
2235        assert_eq!(
2236            test_state.int_vector_stack.to_string(),
2237            "[1] [2] [3] [4]"
2238        );
2239        test_state.int_stack.push(2);
2240        int_vector_shove(&mut test_state, &icache());
2241        assert_eq!(
2242            test_state.int_vector_stack.to_string(),
2243            "[2] [3] [1] [4]"
2244        );
2245    }
2246
2247    #[test]
2248    fn int_vector_sort_top_item() {
2249        let mut test_state = PushState::new();
2250        test_state
2251            .int_vector_stack
2252            .push(IntVector::new(vec![34, 0, -28, 111, -1]));
2253        int_vector_sort_asc(&mut test_state, &icache());
2254        assert_eq!(
2255            test_state.int_vector_stack.to_string(),
2256            "[-28,-1,0,34,111]"
2257        );
2258        int_vector_sort_desc(&mut test_state, &icache());
2259        assert_eq!(
2260            test_state.int_vector_stack.to_string(),
2261            "[111,34,0,-1,-28]"
2262        );
2263    }
2264    #[test]
2265    fn int_vector_stack_depth_returns_size() {
2266        let mut test_state = PushState::new();
2267        test_state.int_vector_stack.push(IntVector::new(vec![4]));
2268        test_state.int_vector_stack.push(IntVector::new(vec![3]));
2269        test_state.int_vector_stack.push(IntVector::new(vec![2]));
2270        test_state.int_vector_stack.push(IntVector::new(vec![1]));
2271        int_vector_stack_depth(&mut test_state, &icache());
2272        assert_eq!(test_state.int_stack.to_string(), "4");
2273    }
2274
2275    #[test]
2276    fn int_vector_swaps_top_elements() {
2277        let mut test_state = PushState::new();
2278        test_state.int_vector_stack.push(IntVector::new(vec![0]));
2279        test_state.int_vector_stack.push(IntVector::new(vec![1]));
2280        assert_eq!(test_state.int_vector_stack.to_string(), "[1] [0]");
2281        int_vector_swap(&mut test_state, &icache());
2282        assert_eq!(test_state.int_vector_stack.to_string(), "[0] [1]");
2283    }
2284
2285    #[test]
2286    fn int_vector_sum_pushes_aggregation_value() {
2287        let mut test_state = PushState::new();
2288        test_state
2289            .int_vector_stack
2290            .push(IntVector::new(vec![1, 3, -2, 5, 7]));
2291        int_vector_sum(&mut test_state, &icache());
2292        assert_eq!(test_state.int_stack.to_string(), "14");
2293    }
2294
2295    #[test]
2296    fn int_vector_yank_brings_item_to_top() {
2297        let mut test_state = PushState::new();
2298        test_state.int_vector_stack.push(IntVector::new(vec![5]));
2299        test_state.int_vector_stack.push(IntVector::new(vec![4]));
2300        test_state.int_vector_stack.push(IntVector::new(vec![3]));
2301        test_state.int_vector_stack.push(IntVector::new(vec![2]));
2302        test_state.int_vector_stack.push(IntVector::new(vec![1]));
2303        assert_eq!(
2304            test_state.int_vector_stack.to_string(),
2305            "[1] [2] [3] [4] [5]"
2306        );
2307        test_state.int_stack.push(3);
2308        int_vector_yank(&mut test_state, &icache());
2309        assert_eq!(
2310            test_state.int_vector_stack.to_string(),
2311            "[4] [1] [2] [3] [5]"
2312        );
2313    }
2314
2315    #[test]
2316    fn int_vector_yank_dup_copies_item_to_top() {
2317        let mut test_state = PushState::new();
2318        test_state.int_vector_stack.push(IntVector::new(vec![5]));
2319        test_state.int_vector_stack.push(IntVector::new(vec![4]));
2320        test_state.int_vector_stack.push(IntVector::new(vec![3]));
2321        test_state.int_vector_stack.push(IntVector::new(vec![2]));
2322        test_state.int_vector_stack.push(IntVector::new(vec![1]));
2323        assert_eq!(
2324            test_state.int_vector_stack.to_string(),
2325            "[1] [2] [3] [4] [5]"
2326        );
2327        test_state.int_stack.push(3);
2328        int_vector_yank_dup(&mut test_state, &icache());
2329        assert_eq!(
2330            test_state.int_vector_stack.to_string(),
2331            "[4] [1] [2] [3] [4] [5]"
2332        );
2333    }
2334
2335    #[test]
2336    fn int_vector_zeros_creates_item() {
2337        let mut test_state = PushState::new();
2338        let mut test_size = -11;
2339        test_state.int_stack.push(test_size);
2340        int_vector_zeros(&mut test_state, &icache());
2341        assert_eq!(test_state.int_vector_stack.size(), 0);
2342        test_size = 11;
2343        test_state.int_stack.push(test_size);
2344        int_vector_zeros(&mut test_state, &icache());
2345        assert_eq!(
2346            test_state.int_vector_stack.pop().unwrap(),
2347            IntVector::new(vec![0; test_size as usize])
2348        );
2349    }
2350
2351    ////////////////////////////////////// FLOATVECTOR //////////////////////////////////////////
2352
2353    #[test]
2354    fn float_vector_prints_values() {
2355        let fv = FloatVector::new(vec![1.2, 3.4, -4.5]);
2356        assert_eq!(fv.to_string(), "[1.200,3.400,-4.500]");
2357    }
2358
2359    #[test]
2360    fn float_vector_get_pushes_vector_element() {
2361        let test_vec1 = FloatVector::new(vec![2.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 4.0]);
2362        let mut test_state = PushState::new();
2363        test_state.float_vector_stack.push(test_vec1);
2364        test_state.int_stack.push(3);
2365        float_vector_get(&mut test_state, &icache());
2366        assert_eq!(test_state.float_stack.pop().unwrap(), 0.0);
2367        // Invalid index is changed to valid index
2368        test_state.int_stack.push(-115);
2369        float_vector_get(&mut test_state, &icache());
2370        assert_eq!(test_state.float_stack.pop().unwrap(), 2.0);
2371        test_state.int_stack.push(15);
2372        float_vector_get(&mut test_state, &icache());
2373        assert_eq!(test_state.float_stack.pop().unwrap(), 4.0);
2374    }
2375
2376    #[test]
2377    fn float_vector_set_modifies_vector() {
2378        let test_vec1 = FloatVector::new(vec![1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]);
2379        let mut test_state = PushState::new();
2380        test_state.float_vector_stack.push(test_vec1);
2381        test_state.float_stack.push(12.0);
2382        test_state.int_stack.push(5); // Top item: index
2383        float_vector_set(&mut test_state, &icache());
2384        assert_eq!(
2385            test_state.float_vector_stack.pop().unwrap(),
2386            FloatVector::new(vec![1.0, 1.0, 1.0, 1.0, 1.0, 12.0, 1.0, 1.0])
2387        );
2388    }
2389
2390    #[test]
2391    fn float_vector_add_with_partial() {
2392        let test_vec1 = FloatVector::new(vec![1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]);
2393        let test_vec2 = FloatVector::new(vec![1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
2394
2395        // Full overlap
2396        let mut test_state = PushState::new();
2397        test_state.float_vector_stack.push(test_vec2.clone());
2398        test_state.float_vector_stack.push(test_vec1.clone());
2399        test_state.int_stack.push(0);
2400        float_vector_add(&mut test_state, &icache());
2401        assert_eq!(test_state.float_vector_stack.size(), 1);
2402        assert_eq!(
2403            test_state.float_vector_stack.pop().unwrap(),
2404            FloatVector::new(vec![2.0, 1.0, 2.0, 1.0, 1.0, 0.0, 1.0, 0.0])
2405        );
2406    }
2407
2408    #[test]
2409    fn float_vector_sine_generates_2pi_angle() {
2410        let mut test_state = PushState::new();
2411        test_state.int_stack.push(1000); // Array length
2412        test_state.float_stack.push(0.0); // Phase angle is 0
2413        test_state.float_stack.push(0.001); // Angle velocity
2414        test_state.float_stack.push(1.0); // Amplitude
2415        float_vector_sine(&mut test_state, &icache());
2416
2417        let sine_vector = test_state.float_vector_stack.pop().unwrap().values;
2418        assert_eq!(sine_vector.len(), 1000);
2419        assert!(f32::abs(sine_vector[0]) < 0.01f32);
2420        assert!(f32::abs(sine_vector[249] - 1.0) < 0.01f32);
2421        assert!(f32::abs(sine_vector[499]) < 0.01f32);
2422        assert!(f32::abs(sine_vector[749] + 1.0) < 0.01f32);
2423        assert!(f32::abs(sine_vector[999]) < 0.01f32);
2424    }
2425
2426    #[test]
2427    fn float_vector_subtract_with_partial_overlap() {
2428        let test_vec1 = FloatVector::new(vec![1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]);
2429        let test_vec2 = FloatVector::new(vec![1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
2430
2431        // Full overlap
2432        let mut test_state = PushState::new();
2433        test_state.float_vector_stack.push(test_vec2.clone());
2434        test_state.float_vector_stack.push(test_vec1.clone());
2435        test_state.int_stack.push(4);
2436        float_vector_subtract(&mut test_state, &icache());
2437        assert_eq!(test_state.float_vector_stack.size(), 1);
2438        assert_eq!(
2439            test_state.float_vector_stack.pop().unwrap(),
2440            FloatVector::new(vec![1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, -1.0])
2441        );
2442    }
2443
2444    #[test]
2445    fn float_vector_multiply_with_partial_overlap() {
2446        let test_vec1 = FloatVector::new(vec![2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]);
2447        let test_vec2 = FloatVector::new(vec![1.0, 3.0, 1.0, 3.0, 1.0, 3.0, 1.0, 3.0]);
2448
2449        // Full overlap
2450        let mut test_state = PushState::new();
2451        test_state.float_vector_stack.push(test_vec2.clone());
2452        test_state.float_vector_stack.push(test_vec1.clone());
2453        test_state.int_stack.push(4);
2454        float_vector_multiply(&mut test_state, &icache());
2455        assert_eq!(test_state.float_vector_stack.size(), 1);
2456        assert_eq!(
2457            test_state.float_vector_stack.pop().unwrap(),
2458            FloatVector::new(vec![1.0, 3.0, 1.0, 3.0, 2.0, 6.0, 2.0, 6.0])
2459        );
2460    }
2461
2462    #[test]
2463    fn float_vector_multiply_scalar_to_each_element() {
2464        let mut test_state = PushState::new();
2465        test_state.int_stack.push(4);
2466        float_vector_ones(&mut test_state, &icache());
2467        test_state.float_stack.push(3.0);
2468        float_vector_multiply_scalar(&mut test_state, &icache());
2469        assert_eq!(
2470            test_state.float_vector_stack.pop().unwrap(),
2471            FloatVector::new(vec![3.0, 3.0, 3.0, 3.0])
2472        );
2473    }
2474
2475    #[test]
2476    fn float_vector_divide_with_partial_overlap() {
2477        let test_vec1 = FloatVector::new(vec![2.0, 2.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0]);
2478        let test_vec2 = FloatVector::new(vec![6.0, 4.0, 6.0, 4.0, 6.0, 4.0, 6.0, 4.0]);
2479
2480        // Full overlap
2481        let mut test_state = PushState::new();
2482        test_state.float_vector_stack.push(test_vec2.clone());
2483        test_state.float_vector_stack.push(test_vec1.clone());
2484        test_state.int_stack.push(4);
2485        float_vector_divide(&mut test_state, &icache());
2486        assert_eq!(test_state.float_vector_stack.size(), 1);
2487        assert_eq!(
2488            test_state.float_vector_stack.pop().unwrap(),
2489            FloatVector::new(vec![6.0, 4.0, 6.0, 4.0, 3.0, 2.0, 3.0, 2.0])
2490        );
2491    }
2492
2493    #[test]
2494    fn float_vector_define_creates_name_binding() {
2495        let mut test_state = PushState::new();
2496        test_state
2497            .float_vector_stack
2498            .push(FloatVector::new(vec![1.0, 2.0]));
2499        test_state.name_stack.push(String::from("TEST"));
2500        float_vector_define(&mut test_state, &icache());
2501        assert_eq!(
2502            *test_state.name_bindings.get("TEST").unwrap().to_string(),
2503            Item::floatvec(FloatVector::new(vec![1.0, 2.0])).to_string()
2504        );
2505    }
2506
2507    #[test]
2508    fn float_vector_equal_pushes_result() {
2509        let mut test_state = PushState::new();
2510        test_state
2511            .float_vector_stack
2512            .push(FloatVector::new(vec![4.0]));
2513        test_state
2514            .float_vector_stack
2515            .push(FloatVector::new(vec![4.0]));
2516        float_vector_equal(&mut test_state, &icache());
2517        assert_eq!(test_state.bool_stack.pop().unwrap(), true);
2518    }
2519
2520    #[test]
2521    fn float_vector_shove_inserts_at_right_position() {
2522        let mut test_state = PushState::new();
2523        test_state
2524            .float_vector_stack
2525            .push(FloatVector::new(vec![4.0]));
2526        test_state
2527            .float_vector_stack
2528            .push(FloatVector::new(vec![3.0]));
2529        test_state
2530            .float_vector_stack
2531            .push(FloatVector::new(vec![2.0]));
2532        test_state
2533            .float_vector_stack
2534            .push(FloatVector::new(vec![1.0]));
2535        assert_eq!(
2536            test_state.float_vector_stack.to_string(),
2537            "[1.000] [2.000] [3.000] [4.000]"
2538        );
2539        test_state.int_stack.push(2);
2540        float_vector_shove(&mut test_state, &icache());
2541        assert_eq!(
2542            test_state.float_vector_stack.to_string(),
2543            "[2.000] [3.000] [1.000] [4.000]"
2544        );
2545    }
2546    #[test]
2547    fn float_vector_ones_creates_item() {
2548        let mut test_state = PushState::new();
2549        let mut test_size = -11;
2550        test_state.int_stack.push(test_size);
2551        float_vector_ones(&mut test_state, &icache());
2552        assert_eq!(test_state.float_vector_stack.size(), 0);
2553        test_size = 11;
2554        test_state.int_stack.push(test_size);
2555        float_vector_ones(&mut test_state, &icache());
2556        assert_eq!(
2557            test_state.float_vector_stack.pop().unwrap(),
2558            FloatVector::new(vec![1.0; test_size as usize])
2559        );
2560    }
2561
2562    #[test]
2563    fn float_vector_rand_pushes_new_item() {
2564        let mut test_state = PushState::new();
2565        let test_size = 1000;
2566        let test_mean = vec![-7.0, 0.0, 12.0];
2567        let test_stddev = vec![0.77, 1.23];
2568        for tm in &test_mean {
2569            for ts in &test_stddev {
2570                test_state.int_stack.push(test_size);
2571                test_state.float_stack.push(*ts);
2572                test_state.float_stack.push(*tm);
2573                float_vector_rand(&mut test_state, &icache());
2574                if let Some(fvs) = test_state.float_vector_stack.pop() {
2575                    assert_eq!(fvs.values.len(), test_size as usize);
2576                    let sum = fvs.values.iter().sum::<f32>();
2577                    let count = fvs.values.len() as f32;
2578                    assert!(f32::abs(sum / count - tm) < *ts);
2579                } else {
2580                    assert!(false, "Expected to find bool vector");
2581                }
2582            }
2583        }
2584    }
2585
2586    #[test]
2587    fn float_vector_sort_top_item() {
2588        let mut test_state = PushState::new();
2589        test_state
2590            .float_vector_stack
2591            .push(FloatVector::new(vec![34.2, 0.0, -28.1, 111.1, -1.5]));
2592        float_vector_sort_asc(&mut test_state, &icache());
2593        assert_eq!(
2594            test_state.float_vector_stack.to_string(),
2595            "[-28.100,-1.500,0.000,34.200,111.100]"
2596        );
2597        float_vector_sort_desc(&mut test_state, &icache());
2598        assert_eq!(
2599            test_state.float_vector_stack.to_string(),
2600            "[111.100,34.200,0.000,-1.500,-28.100]"
2601        );
2602    }
2603
2604    #[test]
2605    fn float_vector_rotate_shifts_elements_left() {
2606        let mut test_state = PushState::new();
2607        test_state.float_vector_stack.push(FloatVector::new(vec![
2608            1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0,
2609        ]));
2610        test_state.float_stack.push(5.0);
2611        float_vector_rotate(&mut test_state, &icache());
2612        assert_eq!(
2613            test_state.float_vector_stack.get(0).unwrap(),
2614            &FloatVector::new(vec![2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 5.0])
2615        );
2616    }
2617
2618    #[test]
2619    fn float_vector_stack_depth_returns_size() {
2620        let mut test_state = PushState::new();
2621        test_state
2622            .float_vector_stack
2623            .push(FloatVector::new(vec![4.0]));
2624        test_state
2625            .float_vector_stack
2626            .push(FloatVector::new(vec![3.0]));
2627        test_state
2628            .float_vector_stack
2629            .push(FloatVector::new(vec![2.0]));
2630        test_state
2631            .float_vector_stack
2632            .push(FloatVector::new(vec![1.0]));
2633        float_vector_stack_depth(&mut test_state, &icache());
2634        assert_eq!(test_state.int_stack.to_string(), "4");
2635    }
2636
2637    #[test]
2638    fn float_vector_sum_pushes_aggregation_value() {
2639        let mut test_state = PushState::new();
2640        test_state
2641            .float_vector_stack
2642            .push(FloatVector::new(vec![1.0, 3.0, -2.0, 5.0, 7.0]));
2643        float_vector_sum(&mut test_state, &icache());
2644        assert_eq!(test_state.float_stack.to_string(), "14.0");
2645    }
2646
2647    #[test]
2648    fn float_vector_swaps_top_elements() {
2649        let mut test_state = PushState::new();
2650        test_state
2651            .float_vector_stack
2652            .push(FloatVector::new(vec![0.0]));
2653        test_state
2654            .float_vector_stack
2655            .push(FloatVector::new(vec![1.0]));
2656        assert_eq!(test_state.float_vector_stack.to_string(), "[1.000] [0.000]");
2657        float_vector_swap(&mut test_state, &icache());
2658        assert_eq!(test_state.float_vector_stack.to_string(), "[0.000] [1.000]");
2659    }
2660
2661    #[test]
2662    fn float_vector_yank_brings_item_to_top() {
2663        let mut test_state = PushState::new();
2664        test_state
2665            .float_vector_stack
2666            .push(FloatVector::new(vec![5.0]));
2667        test_state
2668            .float_vector_stack
2669            .push(FloatVector::new(vec![4.0]));
2670        test_state
2671            .float_vector_stack
2672            .push(FloatVector::new(vec![3.0]));
2673        test_state
2674            .float_vector_stack
2675            .push(FloatVector::new(vec![2.0]));
2676        test_state
2677            .float_vector_stack
2678            .push(FloatVector::new(vec![1.0]));
2679        assert_eq!(
2680            test_state.float_vector_stack.to_string(),
2681            "[1.000] [2.000] [3.000] [4.000] [5.000]"
2682        );
2683        test_state.int_stack.push(3);
2684        float_vector_yank(&mut test_state, &icache());
2685        assert_eq!(
2686            test_state.float_vector_stack.to_string(),
2687            "[4.000] [1.000] [2.000] [3.000] [5.000]"
2688        );
2689    }
2690
2691    #[test]
2692    fn float_vector_yank_dup_copies_item_to_top() {
2693        let mut test_state = PushState::new();
2694        test_state
2695            .float_vector_stack
2696            .push(FloatVector::new(vec![5.0]));
2697        test_state
2698            .float_vector_stack
2699            .push(FloatVector::new(vec![4.0]));
2700        test_state
2701            .float_vector_stack
2702            .push(FloatVector::new(vec![3.0]));
2703        test_state
2704            .float_vector_stack
2705            .push(FloatVector::new(vec![2.0]));
2706        test_state
2707            .float_vector_stack
2708            .push(FloatVector::new(vec![1.0]));
2709        assert_eq!(
2710            test_state.float_vector_stack.to_string(),
2711            "[1.000] [2.000] [3.000] [4.000] [5.000]"
2712        );
2713        test_state.int_stack.push(3);
2714        float_vector_yank_dup(&mut test_state, &icache());
2715        assert_eq!(
2716            test_state.float_vector_stack.to_string(),
2717            "[4.000] [1.000] [2.000] [3.000] [4.000] [5.000]"
2718        );
2719    }
2720
2721    #[test]
2722    fn float_vector_zeros_creates_item() {
2723        let mut test_state = PushState::new();
2724        let mut test_size = -11;
2725        test_state.int_stack.push(test_size);
2726        float_vector_zeros(&mut test_state, &icache());
2727        assert_eq!(test_state.float_vector_stack.size(), 0);
2728        test_size = 11;
2729        test_state.int_stack.push(test_size);
2730        float_vector_zeros(&mut test_state, &icache());
2731        assert_eq!(
2732            test_state.float_vector_stack.pop().unwrap(),
2733            FloatVector::new(vec![0.0; test_size as usize])
2734        );
2735    }
2736}