Skip to content

Builtin operators#197

Closed
katat wants to merge 4 commits into
mainfrom
builtin-ops
Closed

Builtin operators#197
katat wants to merge 4 commits into
mainfrom
builtin-ops

Conversation

@katat
Copy link
Copy Markdown
Contributor

@katat katat commented Oct 2, 2024

To support operators and apply default constraints: <, /, %, <<

@katat katat requested a review from mimoo October 2, 2024 08:28
Copy link
Copy Markdown
Contributor

@mimoo mimoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left some comments, I need to have another pass on the division which seems to be the most tricky part of the logic :o

also I remember that there was a nice way to check if a < b in the field without having to check a 256 bits decomposition but only a 128 bit decomposition. We should check how other implementations do it :o

Comment thread src/constraints/field.rs
// otherwise, the carry bit of sum_bits is 1.

/*
psuedo code:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pseudo*

Comment thread src/constraints/field.rs
(ConstOrCell::Cell(lhs_), ConstOrCell::Const(rhs_)) => {
let pow2 = B::Field::from(2u32).pow(rhs_.into_repr());
let res = compiler.backend.mul_const(lhs_, &pow2, span);
Var::new_var(res, span)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The weird thing to me is that at this point there is no way to tell if there is an overflow, the modulus length also impacts that. Maybe that's fine though... But I'm not sure what people would expect. Is this operator implemented in any other DSL? How do they handle overflows?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, overflow is probably something to take care of here.

One of the compilers restricts the value type to be integer and the shift amount to be u8. I guess the reason it restrict to be integer is for range checking the resulted value.

Comment thread src/constraints/field.rs
// convert to bigint
let pow2 = B::Field::from(2u32).pow(rhs.into_repr());
let res = *lhs * pow2;
Var::new_constant(res, span)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should return an error on overflow perhaps

Comment thread src/constraints/field.rs Outdated
// until we refactor the backend to handle ConstOrCell or some kind of wrapper that encapsulate the different variable types
// convert cst to var for easier handling
let lhs = match lhs {
ConstOrCell::Const(lhs) => compiler.backend.add_constant(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we also wanted to remove this add_constant fn :p

Comment thread src/constraints/field.rs
let rem = Value::VarModVar(lhs.clone(), rhs.clone());
let rem_var = compiler.backend.new_internal_var(rem, span);

// rem < rhs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If lhs < rhs then we will have rem = lhs. So either we forbid lhs < rhs or we add an edge case to make it work as well. Both might lead to extra constraints tho...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this constraint seems not well done. let me research a bit on how others constrain this.

Comment thread src/constraints/field.rs
// lhs + (1 << LEN) - rhs
// proof:
// lhs + (1 << LEN) will add a carry bit, valued 1, to the bit array representing lhs,
// resulted in a bit array of length LEN + 1, named as sum_bits.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to understand this but intuitively this is not going to work when we are too close to the modulus

Comment thread src/backends/mod.rs

env.cached_values.insert(cache_key, res);
Ok(res)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not a single Value::Div(VarOrCst, VarOrCst)?

@katat katat mentioned this pull request Oct 11, 2024
2 tasks
@mimoo
Copy link
Copy Markdown
Contributor

mimoo commented Oct 23, 2024

what's the status here? Do we have these as native functions now or do we still want this PR merged?

@katat
Copy link
Copy Markdown
Contributor Author

katat commented Oct 24, 2024

let's hold this one, until we figured out #214

@katat
Copy link
Copy Markdown
Contributor Author

katat commented Jan 6, 2025

Closing this, as these operators are implemented for hint functions by another PR #253

@katat katat closed this Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants