Skip to content

Commit 48373cf

Browse files
authored
Merge pull request #254 from 0xPolygonMiden/grjte-refactor-clarity-3
refactor: change access types to BindingAccess
2 parents b2d2cbf + 86bc466 commit 48373cf

34 files changed

+1247
-723
lines changed

air-script-core/src/access.rs

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,64 @@
11
use super::Identifier;
2+
use std::fmt::Display;
23

3-
/// [VectorAccess] is used to represent an element inside vector at the specified index.
4-
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
5-
pub struct VectorAccess {
6-
name: Identifier,
7-
idx: usize,
4+
/// Defines the type of an access into a binding such as a [ConstantBinding] or a [VariableBinding].
5+
///
6+
/// - Default: accesses the entire bound value, which could be a scalar, vector, or matrix.
7+
/// - Vector: indexes into the bound value at the specified index. The result could be either a
8+
/// single value or a vector, depending on the type of the original binding. This is not allowed
9+
/// for bindings to scalar values and will result in an error.
10+
/// - Matrix: indexes into the bound value at the specified row and column. The result is a single
11+
/// value. This [AccessType] is not allowed for bindings to scalar or vector values and will
12+
/// result in an error.
13+
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
14+
pub enum AccessType {
15+
Default,
16+
Vector(usize),
17+
/// Access into a matrix, with the values referring to the row and column indices respectively.
18+
Matrix(usize, usize),
819
}
920

10-
impl VectorAccess {
11-
/// Creates a new [VectorAccess] instance with the specified identifier name and index.
12-
pub fn new(name: Identifier, idx: usize) -> Self {
13-
Self { name, idx }
14-
}
15-
16-
/// Returns the name of the vector.
17-
pub fn name(&self) -> &str {
18-
self.name.name()
19-
}
20-
21-
/// Returns the index of the vector access.
22-
pub fn idx(&self) -> usize {
23-
self.idx
21+
impl Display for AccessType {
22+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23+
match self {
24+
Self::Default => write!(f, "direct reference by name"),
25+
Self::Vector(_) => write!(f, "vector"),
26+
Self::Matrix(_, _) => write!(f, "matrix"),
27+
}
2428
}
2529
}
2630

27-
/// [MatrixAccess] is used to represent an element inside a matrix at the specified row and column
28-
/// indices.
29-
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
30-
pub struct MatrixAccess {
31+
/// [BindingAccess] is used to indicate referencing all or part of an identifier that is bound to a
32+
/// value, such as a [ConstantBinding] or a [VariableBinding].
33+
///
34+
/// - `name`: is the identifier of the [ConstantBinding] or [VariableBinding] being accessed.
35+
/// - `access_type`: specifies the [AccessType] by which the identifier is being accessed.
36+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
37+
pub struct BindingAccess {
3138
name: Identifier,
32-
row_idx: usize,
33-
col_idx: usize,
39+
access_type: AccessType,
3440
}
3541

36-
impl MatrixAccess {
37-
/// Creates a new [MatrixAccess] instance with the specified identifier name and indices.
38-
pub fn new(name: Identifier, row_idx: usize, col_idx: usize) -> Self {
39-
Self {
40-
name,
41-
row_idx,
42-
col_idx,
43-
}
42+
impl BindingAccess {
43+
pub fn new(name: Identifier, access_type: AccessType) -> Self {
44+
Self { name, access_type }
45+
}
46+
47+
pub fn ident(&self) -> &Identifier {
48+
&self.name
4449
}
4550

46-
/// Returns the name of the matrix.
4751
pub fn name(&self) -> &str {
4852
self.name.name()
4953
}
5054

51-
/// Returns the row index of the matrix access.
52-
pub fn row_idx(&self) -> usize {
53-
self.row_idx
55+
/// Gets the access type of this [BindingAccess].
56+
pub fn access_type(&self) -> &AccessType {
57+
&self.access_type
5458
}
5559

56-
/// Returns the column index of the matrix access.
57-
pub fn col_idx(&self) -> usize {
58-
self.col_idx
60+
pub fn into_parts(self) -> (Identifier, AccessType) {
61+
(self.name, self.access_type)
5962
}
6063
}
6164

air-script-core/src/expression.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
use super::{Identifier, ListFolding, MatrixAccess, TraceAccess, TraceBindingAccess, VectorAccess};
1+
use super::{BindingAccess, Identifier, ListFolding, TraceAccess, TraceBindingAccess};
22

33
/// Arithmetic expressions for evaluation of constraints.
44
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
55
pub enum Expression {
66
Const(u64),
7-
/// Represents any named constant or variable.
8-
Elem(Identifier),
9-
/// Represents an element inside a constant or variable vector. [VectorAccess] contains the
10-
/// name of the vector and the index of the element to access.
11-
VectorAccess(VectorAccess),
12-
/// Represents an element inside a constant or variable matrix. [MatrixAccess] contains the
13-
/// name of the matrix and indices of the element to access.
14-
MatrixAccess(MatrixAccess),
7+
/// Represents a reference to all or part of a constant, variable, or trace binding.
8+
BindingAccess(BindingAccess),
159
TraceAccess(TraceAccess),
1610
TraceBindingAccess(TraceBindingAccess),
1711
/// Represents a random value provided by the verifier. The first inner value is the name of

air-script-core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
mod access;
2-
pub use access::{Iterable, MatrixAccess, Range, VectorAccess};
2+
pub use access::{AccessType, BindingAccess, Iterable, Range};
33

44
mod constant;
55
pub use constant::{ConstantBinding, ConstantValueExpr};

air-script-core/src/trace.rs

Lines changed: 74 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,17 @@ use super::{Identifier, Range};
44
// ================================================================================================
55
pub type TraceSegment = u8;
66

7-
/// [TraceBinding] is used to represent one or more columns in the execution trace that are bound to
8-
/// a name. For single columns, the size is 1. For groups, the size is the number of columns in the
9-
/// group. The offset is the column index in the trace where the first column of the binding starts.
10-
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
11-
pub struct TraceBinding {
12-
binding: Identifier,
13-
trace_segment: TraceSegment,
14-
offset: usize,
15-
size: usize,
16-
}
17-
18-
impl TraceBinding {
19-
/// Creates a new trace binding.
20-
pub fn new(binding: Identifier, trace_segment: usize, offset: usize, size: u64) -> Self {
21-
Self {
22-
binding,
23-
trace_segment: trace_segment as TraceSegment,
24-
offset,
25-
size: size as usize,
26-
}
27-
}
28-
29-
/// Returns the name of the trace binding.
30-
pub fn name(&self) -> &str {
31-
self.binding.name()
32-
}
33-
34-
/// Returns the trace segment of the trace binding.
35-
pub fn trace_segment(&self) -> TraceSegment {
36-
self.trace_segment
37-
}
38-
39-
/// Returns the offset of the trace binding.
40-
pub fn offset(&self) -> usize {
41-
self.offset
42-
}
43-
44-
/// Returns the size of the trace binding.
45-
pub fn size(&self) -> usize {
46-
self.size
47-
}
48-
}
49-
50-
/// [TraceAccess] is used to represent accessing an element in the execution trace during
51-
/// constraint evaluation. The trace_segment specifies
52-
/// how many trace commitments have preceded the specified segment. `col_idx` specifies the index
53-
/// of the column within that trace segment, and `row_offset` specifies the offset from the current
54-
/// row. For example, an element in the "next" row of the "main" trace would be specified by
55-
/// a trace_segment of 0 and a row_offset of 1.
7+
/// [TraceAccess] is used to represent accessing one or more elements in the execution trace during
8+
/// constraint evaluation.
9+
///
10+
/// - `trace_segment`: specifies how many trace commitments have preceded the specified segment.
11+
/// - `col_idx`: specifies the index of the column within that trace segment at which the access
12+
/// starts.
13+
/// - `size`: refers to how many columns are being accessed.
14+
/// - `row_offset`: specifies the offset from the current row.
15+
///
16+
/// For example, a single element in the "next" row of
17+
/// the "main" trace would be specified by a trace_segment of 0, a size of 1, and a row_offset of 1.
5618
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
5719
pub struct TraceAccess {
5820
trace_segment: TraceSegment,
@@ -98,24 +60,79 @@ impl TraceAccess {
9860
}
9961
}
10062

101-
/// [TraceBindingAccess] is used to indicate a column in the trace by specifying its offset within
102-
/// a set of trace columns with the given identifier. If the identifier refers to a single column
103-
/// then the index is always zero.
104-
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
105-
pub struct TraceBindingAccess {
63+
/// [TraceBinding] is used to represent one or more columns in the execution trace that are bound to
64+
/// a name. For single columns, the size is 1. For groups, the size is the number of columns in the
65+
/// group. The offset is the column index in the trace where the first column of the binding starts.
66+
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
67+
pub struct TraceBinding {
10668
binding: Identifier,
107-
col_offset: usize,
108-
size: TraceBindingAccessSize,
109-
row_offset: usize,
69+
trace_segment: TraceSegment,
70+
offset: usize,
71+
size: usize,
72+
}
73+
74+
impl TraceBinding {
75+
/// Creates a new trace binding.
76+
pub fn new(binding: Identifier, trace_segment: usize, offset: usize, size: u64) -> Self {
77+
Self {
78+
binding,
79+
trace_segment: trace_segment as TraceSegment,
80+
offset,
81+
size: size as usize,
82+
}
83+
}
84+
85+
/// Returns the name of the trace binding.
86+
pub fn name(&self) -> &str {
87+
self.binding.name()
88+
}
89+
90+
/// Returns the trace segment of the trace binding.
91+
pub fn trace_segment(&self) -> TraceSegment {
92+
self.trace_segment
93+
}
94+
95+
/// Returns the offset of the trace binding.
96+
pub fn offset(&self) -> usize {
97+
self.offset
98+
}
99+
100+
/// Returns the size of the trace binding.
101+
pub fn size(&self) -> usize {
102+
self.size
103+
}
110104
}
111105

106+
/// Indicates how much of a [TraceBinding] is being accessed.
107+
///
108+
/// TODO: check that this is correct for `Single`.
109+
/// - `Single`: only a single element from the [TraceBinding] is being referenced.
110+
/// - `Slice`: the specified range of the [TraceBinding] is being referenced.
111+
/// - `Full`: the entire [TraceBinding] is being referenced.
112112
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
113113
pub enum TraceBindingAccessSize {
114114
Single,
115115
Slice(Range),
116116
Full,
117117
}
118118

119+
/// [TraceBindingAccess] is used to indicate accessing a [TraceBinding].
120+
///
121+
/// - `binding`: is the identifier of the [TraceBinding] being accessed.
122+
/// - `col_offset`: specifies the column within the [TraceBinding] where the access starts. For
123+
/// example, if a [TraceBinding] has `offset` = 2 and the [TraceBindingAccess] has
124+
/// `col_offset` = 2, then the offset of the access within the trace segment will be 4. If the
125+
/// [TraceBinding] refers to a single column, then this value will be zero.
126+
/// - `size`: specifies how much of the [TraceBinding] is being accessed.
127+
/// - `row_offset`: specifies the offset from the current row.
128+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
129+
pub struct TraceBindingAccess {
130+
binding: Identifier,
131+
col_offset: usize,
132+
size: TraceBindingAccessSize,
133+
row_offset: usize,
134+
}
135+
119136
impl TraceBindingAccess {
120137
pub fn new(
121138
binding: Identifier,

codegen/winterfell/src/air/graph.rs

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use ir::TraceAccess;
2-
31
use super::{
4-
AirIR, ConstantValue, ElemType, IntegrityConstraintDegree, NodeIndex, Operation, Value,
2+
AccessType, AirIR, ElemType, IntegrityConstraintDegree, NodeIndex, Operation, TraceAccess,
3+
Value,
54
};
65

76
// RUST STRING GENERATION FOR THE CONSTRAINT GRAPH
@@ -102,42 +101,33 @@ impl Codegen for Value {
102101
fn to_string(&self, ir: &AirIR, elem_type: ElemType, trace_segment: u8) -> String {
103102
match self {
104103
// TODO: move constant handling to a helper function
105-
Value::Constant(ConstantValue::Inline(0)) => match elem_type {
104+
Value::InlineConstant(0) => match elem_type {
106105
ElemType::Base => "Felt::ZERO".to_string(),
107106
ElemType::Ext => "E::ZERO".to_string(),
108107
},
109-
Value::Constant(ConstantValue::Inline(1)) => match elem_type {
108+
Value::InlineConstant(1) => match elem_type {
110109
ElemType::Base => "Felt::ONE".to_string(),
111110
ElemType::Ext => "E::ONE".to_string(),
112111
},
113-
Value::Constant(ConstantValue::Inline(value)) => match elem_type {
112+
Value::InlineConstant(value) => match elem_type {
114113
ElemType::Base => format!("Felt::new({value})"),
115114
ElemType::Ext => format!("E::from({value}_u64)"),
116115
},
117-
Value::Constant(ConstantValue::Scalar(ident)) => match elem_type {
118-
ElemType::Base => ident.to_string(),
119-
ElemType::Ext => format!("E::from({ident})"),
120-
},
121-
Value::Constant(ConstantValue::Vector(vector_access)) => match elem_type {
122-
ElemType::Base => format!("{}[{}]", vector_access.name(), vector_access.idx()),
123-
ElemType::Ext => {
124-
format!("E::from({}[{}])", vector_access.name(), vector_access.idx())
116+
Value::BoundConstant(binding_access) => {
117+
let name = binding_access.name().to_string();
118+
let access_type = binding_access.access_type();
119+
let base_value = match access_type {
120+
AccessType::Default => name,
121+
AccessType::Vector(idx) => format!("{name}[{idx}]"),
122+
AccessType::Matrix(row_idx, col_idx) => {
123+
format!("{name}[{row_idx}][{col_idx}]",)
124+
}
125+
};
126+
match elem_type {
127+
ElemType::Base => base_value,
128+
ElemType::Ext => format!("E::from({base_value})"),
125129
}
126-
},
127-
Value::Constant(ConstantValue::Matrix(matrix_access)) => match elem_type {
128-
ElemType::Base => format!(
129-
"{}[{}][{}]",
130-
matrix_access.name(),
131-
matrix_access.row_idx(),
132-
matrix_access.col_idx()
133-
),
134-
ElemType::Ext => format!(
135-
"E::from({}[{}][{}])",
136-
matrix_access.name(),
137-
matrix_access.row_idx(),
138-
matrix_access.col_idx()
139-
),
140-
},
130+
}
141131
Value::TraceElement(trace_access) => {
142132
trace_access.to_string(ir, elem_type, trace_segment)
143133
}

codegen/winterfell/src/air/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::{AirIR, Impl, Scope};
2-
use air_script_core::{ConstantBinding, ConstantValueExpr, TraceAccess};
2+
use air_script_core::{AccessType, ConstantBinding, ConstantValueExpr, TraceAccess};
33
use ir::{
44
constraints::{AlgebraicGraph, ConstraintDomain, Operation},
5-
ConstantValue, IntegrityConstraintDegree, NodeIndex, PeriodicColumn, Value,
5+
IntegrityConstraintDegree, NodeIndex, PeriodicColumn, Value,
66
};
77

88
mod constants;

0 commit comments

Comments
 (0)