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}