tasm_lib/rust_shadowing_helper_functions/
array.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::collections::HashMap;

use num::Zero;
use triton_vm::twenty_first::math::b_field_element::BFieldElement;
use triton_vm::twenty_first::math::bfield_codec::BFieldCodec;

use crate::data_type::DataType;

pub fn insert_random_array(
    element_type: &DataType,
    mut array_pointer: BFieldElement,
    array_length: usize,
    memory: &mut HashMap<BFieldElement, BFieldElement>,
) {
    let random_values = element_type.random_elements(array_length);

    for element in random_values {
        for word in element {
            memory.insert(array_pointer, word);
            array_pointer.increment();
        }
    }
}

/// Insert a list of elements into memory encoded as if the list was an array.
pub fn insert_as_array<T: BFieldCodec>(
    mut array_pointer: BFieldElement,
    memory: &mut HashMap<BFieldElement, BFieldElement>,
    array: Vec<T>,
) {
    for element in array {
        for word in element.encode() {
            memory.insert(array_pointer, word);
            array_pointer.increment();
        }
    }
}

/// Read an element from an array
pub fn array_get(
    pointer: BFieldElement,
    index: usize,
    memory: &HashMap<BFieldElement, BFieldElement>,
    element_length: usize,
) -> Vec<BFieldElement> {
    let read_word = |i| {
        let word_offset = (element_length * index + i) as u64;
        let word_index = pointer + BFieldElement::new(word_offset);
        memory[&word_index]
    };

    (0..element_length).map(read_word).collect()
}

pub fn array_from_memory<T: BFieldCodec + Clone>(
    mut pointer: BFieldElement,
    array_length: usize,
    memory: &HashMap<BFieldElement, BFieldElement>,
) -> Vec<T> {
    let mut ret = vec![];
    let element_length = T::static_length().unwrap();
    for _ in 0..array_length {
        let mut element = vec![BFieldElement::zero(); element_length];
        for word in element.iter_mut() {
            *word = *memory.get(&pointer).unwrap_or(&BFieldElement::zero());
            pointer.increment();
        }

        ret.push(*T::decode(&element).unwrap());
    }

    ret
}