use miden_crypto::{
field::TwoAdicField,
stark::dft::{NaiveDft, TwoAdicSubgroupDft},
};
use crate::layout::InputKey;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NodeId(pub(super) usize);
impl NodeId {
pub const fn index(self) -> usize {
self.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum NodeKind<EF> {
Input(InputKey),
Constant(EF),
Add(NodeId, NodeId),
Sub(NodeId, NodeId),
Mul(NodeId, NodeId),
Neg(NodeId),
}
#[derive(Debug, Clone)]
pub struct PeriodicColumnData<EF> {
coeffs: Vec<Vec<EF>>,
}
impl<EF> PeriodicColumnData<EF> {
pub fn from_periodic_columns<F>(periodic_columns: Vec<Vec<F>>) -> Self
where
F: TwoAdicField,
EF: From<F>,
{
if periodic_columns.is_empty() {
return Self { coeffs: Vec::new() };
}
let dft = NaiveDft;
let mut coeffs = Vec::with_capacity(periodic_columns.len());
for col in periodic_columns {
assert!(!col.is_empty(), "periodic column must not be empty");
assert!(col.len().is_power_of_two(), "periodic column length must be a power of two");
let values = dft.idft(col);
let coeff_row = values.into_iter().map(EF::from).collect();
coeffs.push(coeff_row);
}
Self { coeffs }
}
pub fn num_columns(&self) -> usize {
self.coeffs.len()
}
pub fn max_period(&self) -> usize {
self.coeffs.iter().map(|c| c.len()).max().unwrap_or(0)
}
pub fn columns(&self) -> &[Vec<EF>] {
&self.coeffs
}
}
#[derive(Debug)]
pub struct AceDag<EF> {
pub nodes: Vec<NodeKind<EF>>,
pub root: NodeId,
}