Skip to main content

sp1_hypercube/ir/
shape.rs

1use serde::{Deserialize, Serialize};
2use sp1_primitives::consts::WORD_SIZE;
3
4/// Shapes of input type to `SP1Operation`
5///
6/// More like poor man's `facet::Facet`...
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub enum Shape<Expr, ExprExt> {
9    /// A unit type. This should only be used for representing Output shapes.
10    Unit,
11    /// An arithmetic expression.
12    Expr(Expr),
13    /// An arithmetic expression over the extension field.
14    ExprExt(ExprExt),
15    /// A word in the base field.
16    Word([Expr; WORD_SIZE]),
17    /// An array of shapes of arbitrary size.
18    Array(Vec<Box<Shape<Expr, ExprExt>>>),
19    /// A flexible struct type that can represent nested structures.
20    /// Contains the struct name and a vector of (`field_name`, `field_shape`) pairs.
21    Struct(String, Vec<(String, Box<Shape<Expr, ExprExt>>)>),
22}
23
24impl<Expr, ExprExt> Shape<Expr, ExprExt> {
25    /// Converts the shape to its corresponding Lean type.
26    ///
27    /// SAFETY: all elements of [`Shape::Array`] must have the same shape. We use the first item as
28    /// the shape.
29    ///
30    /// SAFETY: [`Shape::Array`] must be non-empty.
31    pub fn to_lean_type(&self) -> String {
32        match self {
33            Shape::Unit => "Unit".to_string(),
34            Shape::Expr(_) => "(Fin KB)".to_string(),
35            Shape::ExprExt(_) => todo!("extension field not implemented yet"),
36            Shape::Word(_) => "(Word (Fin KB))".to_string(),
37            Shape::Array(elems) => {
38                format!("(Vector {} {})", elems.first().unwrap().to_lean_type(), elems.len())
39            }
40            Shape::Struct(name, _) => name.clone(),
41        }
42    }
43}