-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: change access types to BindingAccess #254
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I think this improves things quite a lot! I left some thoughts/comments inline. It is possible that I didn't consider all the implications for some of the - so, let me know if I missed anything.
For some of them, it may make sense to address in future PRs not to complicate this PR even further.
Const(u64), | ||
/// Represents any named constant or variable. | ||
Elem(Identifier), | ||
/// Represents an element inside a constant or variable vector. [VectorAccess] contains the | ||
/// name of the vector and the index of the element to access. | ||
VectorAccess(VectorAccess), | ||
/// Represents an element inside a constant or variable matrix. [MatrixAccess] contains the | ||
/// name of the matrix and indices of the element to access. | ||
MatrixAccess(MatrixAccess), | ||
/// Represents a reference to all or part of a constant, variable, or trace binding. | ||
BindingAccess(BindingAccess), | ||
TraceAccess(TraceAccess), | ||
TraceBindingAccess(TraceBindingAccess), | ||
/// Represents a random value provided by the verifier. The first inner value is the name of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can probably get rid of TraceAccess
, TraceBindingAccess
, and Rand
from here. I'm not sure they need any special handling as compared to regular variables. We should be able to say that something like $main[2]
is BindingAccess { name = "$main", access = Vector(2) }
.
Same could apply to everything else except for something like $main[2]'
. To address this, I think we can modify BindingAccess
to look something like this:
pub struct BindingAccess {
name: Identifier,
access: AccessType,
offset: usize,
}
So, anything of the form <expr>'
would have offset = 1
and just <expr>
would have offset = 0
. Whether non-zero offset is valid against a given symbol could be validated at symbol resolution time.
A couple of other minor things:
- Should we rename
Const
toConstant
? I think we have it asConstant
in some other places. - I don't love the name
BindingAccess
. MaybeSymbolAccess
would be better. TheExpression
enum could look like this:
pub enum Expression {
Constant(u64),
SymbolAccess(SymbolAccess),
Add(Box<Expression>, Box<Expression>),
Sub(Box<Expression>, Box<Expression>),
Mul(Box<Expression>, Box<Expression>),
Exp(Box<Expression>, Box<Expression>),
ListFolding(ListFolding),
}
Not a strong preference though and if you'd prefer to keep BindingAccess
I'm fine with that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I'm fine with renaming
BindingAccess
toSymbolAccess
, but I think it would be cleaner to do it in a separate PR. - I agree that I'd like to remove
Rand
andTraceBindingAccess
and just useBindingAccess
(orSymbolAccess
), but I think this will require a lot of changes and should be addressed in a separate PR as well. Addingoffset
to theBindingAccess
struct should resolve the complication I mentioned in the PR description. - We shouldn't remove
TraceAccess
, as it serves a different function. It is the type used in Value nodes which are leaves in theAlgebraicGraph
. However, we can remove it from use in the parser so it is only used in the IR. I would also do this in a separate PR.
AccessType::Vector(new_idx) => match expr { | ||
Expression::BindingAccess(inner_binding) => match inner_binding.access_type() { | ||
AccessType::Default => { | ||
let new_binding_access = BindingAccess::new( | ||
inner_binding.ident().clone(), | ||
AccessType::Vector(new_idx), | ||
); | ||
Ok(Expression::BindingAccess(new_binding_access)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got lost in this a little. Does this mean that if we have something like:
let x = [1, 2, 3]
let c = x[2]
We replace c = x[2]
with c = 3
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it means we replace c
where it is used by x[2]
. In other words, if we had something like the following:
let x = [1, 2, 3]
let c = x[2]
enf c = 3
this step turns it into:
let x = [1, 2, 3]
let c = x[2]
enf x[2] = 3
Then a subsequent processing turns it into enf 3 = 3
AccessType::Matrix(row_idx, col_idx) => match expr { | ||
Expression::BindingAccess(inner_binding) => match inner_binding.access_type() { | ||
AccessType::Default => { | ||
let new_binding_access = BindingAccess::new( | ||
inner_binding.ident().clone(), | ||
AccessType::Matrix(row_idx, col_idx), | ||
); | ||
Ok(Expression::BindingAccess(new_binding_access)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, I'm not sure I understood what's happening here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- add BindingAccess - replace Elem, VectorAccess, and MatrixAccess with BindingAccess - update codegen handling for new Value types
d9f1934
to
86bc466
Compare
Thank you both for the review! I have addressed the smaller points. I agree with the larger points, and appreciate the suggestions for addressing the consolidation of
|
Currently, there are 5 different variants of
Expression
into which references to bound identifiers within variables or constraints are parsed -Elem
,VectorAccess
,MatrixAccess
,Rand
, andTraceBindingAccess
. These are all handled in essentially the same way within the IR, so consolidating these into a single type allows us to simplify handling in the IR, especially of variables.This PR does the following. Because of the nature of the change, it's hard to split it into a smaller change without errors.
BindingAccess
Elem
,VectorAccess
, andMatrixAccess
withBindingAccess
Value
typesFuture items for discussion:
Expression::Rand
should probably be similarly replaced. This would be fairly straightforward.TraceBindingAccess
intoBindingAccess
as well. This would improve the code clarity significantly, since all trace bindings for the "current" row are already parsed asBindingAccess
, soTraceBindingAccess
only represents references to trace bindings in the "next" row or being accessed as aRange
. This means that the handling within the IR of accessing trace bindings is split into 2 places. The complication with this is that we access ranges of the trace, soAccessType
would need to change, and I'm not sure of the best way to adjust this.