use super::{
chiplets::hasher,
errors::{AdviceSetError, InputError},
utils::IntoBytes,
Felt, FieldElement, Word,
};
use core::convert::TryInto;
use winter_utils::collections::{BTreeMap, Vec};
mod advice;
pub use advice::AdviceSet;
#[derive(Clone, Debug)]
pub struct ProgramInputs {
stack_init: Vec<Felt>,
advice_tape: Vec<Felt>,
advice_map: BTreeMap<[u8; 32], Vec<Felt>>,
advice_sets: BTreeMap<[u8; 32], AdviceSet>,
}
impl ProgramInputs {
pub fn new(
stack_init: &[u64],
advice_tape: &[u64],
advice_sets: Vec<AdviceSet>,
) -> Result<Self, InputError> {
Self::with_advice_map(stack_init, advice_tape, BTreeMap::new(), advice_sets)
}
pub fn with_advice_map(
stack_init: &[u64],
advice_tape: &[u64],
advice_map: BTreeMap<[u8; 32], Vec<Felt>>,
advice_sets: Vec<AdviceSet>,
) -> Result<Self, InputError> {
let mut init_stack_elements = Vec::with_capacity(stack_init.len());
for &value in stack_init.iter().rev() {
let element = value
.try_into()
.map_err(|_| InputError::NotFieldElement(value, "initial stack value"))?;
init_stack_elements.push(element);
}
let mut advice_tape_elements = Vec::with_capacity(advice_tape.len());
for &value in advice_tape {
let element = value
.try_into()
.map_err(|_| InputError::NotFieldElement(value, "advice tape value"))?;
advice_tape_elements.push(element);
}
let mut advice_sets_elements = BTreeMap::new();
for advice_set in advice_sets {
let key = advice_set.root().into_bytes();
if advice_sets_elements.insert(key, advice_set).is_some() {
return Err(InputError::DuplicateAdviceRoot(key));
};
}
Ok(Self {
stack_init: init_stack_elements,
advice_tape: advice_tape_elements,
advice_map,
advice_sets: advice_sets_elements,
})
}
pub fn from_stack_inputs(stack_init: &[u64]) -> Result<Self, InputError> {
Self::new(stack_init, &[], vec![])
}
pub fn none() -> Self {
Self {
stack_init: Vec::new(),
advice_tape: Vec::new(),
advice_map: BTreeMap::new(),
advice_sets: BTreeMap::new(),
}
}
pub fn stack_init(&self) -> &[Felt] {
&self.stack_init
}
pub fn advice_tape(&self) -> &[Felt] {
&self.advice_tape
}
#[allow(clippy::type_complexity)]
pub fn into_parts(
self,
) -> (
Vec<Felt>,
Vec<Felt>,
BTreeMap<[u8; 32], Vec<Felt>>,
BTreeMap<[u8; 32], AdviceSet>,
) {
let Self {
stack_init,
advice_tape,
advice_map,
advice_sets,
} = self;
(stack_init, advice_tape, advice_map, advice_sets)
}
}