pub trait AllocVar<V: ?Sized, F: Field>: Sized {
// Required method
fn new_variable<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
mode: AllocationMode,
) -> Result<Self, SynthesisError>;
// Provided methods
fn new_constant(
cs: impl Into<Namespace<F>>,
t: impl Borrow<V>,
) -> Result<Self, SynthesisError> { ... }
fn new_input<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError> { ... }
fn new_witness<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError> { ... }
fn new_variable_with_inferred_mode<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError> { ... }
}
Expand description
Specifies how variables of type Self
should be allocated in a
ConstraintSystem
.
Required Methods§
Sourcefn new_variable<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
mode: AllocationMode,
) -> Result<Self, SynthesisError>
fn new_variable<T: Borrow<V>>( cs: impl Into<Namespace<F>>, f: impl FnOnce() -> Result<T, SynthesisError>, mode: AllocationMode, ) -> Result<Self, SynthesisError>
Allocates a new variable of type Self
in the ConstraintSystem
cs
.
The mode of allocation is decided by mode
.
Provided Methods§
Sourcefn new_constant(
cs: impl Into<Namespace<F>>,
t: impl Borrow<V>,
) -> Result<Self, SynthesisError>
fn new_constant( cs: impl Into<Namespace<F>>, t: impl Borrow<V>, ) -> Result<Self, SynthesisError>
Allocates a new constant of type Self
in the ConstraintSystem
cs
.
This should not allocate any new variables or constraints in cs
.
Sourcefn new_input<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError>
fn new_input<T: Borrow<V>>( cs: impl Into<Namespace<F>>, f: impl FnOnce() -> Result<T, SynthesisError>, ) -> Result<Self, SynthesisError>
Allocates a new public input of type Self
in the ConstraintSystem
cs
.
Sourcefn new_witness<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError>
fn new_witness<T: Borrow<V>>( cs: impl Into<Namespace<F>>, f: impl FnOnce() -> Result<T, SynthesisError>, ) -> Result<Self, SynthesisError>
Allocates a new private witness of type Self
in the ConstraintSystem
cs
.
Sourcefn new_variable_with_inferred_mode<T: Borrow<V>>(
cs: impl Into<Namespace<F>>,
f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError>
fn new_variable_with_inferred_mode<T: Borrow<V>>( cs: impl Into<Namespace<F>>, f: impl FnOnce() -> Result<T, SynthesisError>, ) -> Result<Self, SynthesisError>
Allocates a new constant or private witness of type Self
in the
ConstraintSystem
cs
with the allocation mode inferred from cs
.
A constant is allocated if cs
is None
, and a private witness is
allocated otherwise.
A common use case is the creation of non-deterministic advice (a.k.a. hints) in the circuit, where this method can avoid boilerplate code while allowing optimization on circuit size.
For example, to compute x_var / y_var
where y_var
is a non-zero
variable, one can write:
use ark_ff::PrimeField;
use ark_r1cs_std::{alloc::AllocVar, fields::{fp::FpVar, FieldVar}, R1CSVar};
use ark_relations::r1cs::SynthesisError;
fn div<F: PrimeField>(x_var: &FpVar<F>, y_var: &FpVar<F>) -> Result<FpVar<F>, SynthesisError> {
let cs = x_var.cs().or(y_var.cs());
let z_var = FpVar::new_variable_with_inferred_mode(cs, || Ok(x_var.value()? / y_var.value()?))?;
z_var.mul_equals(y_var, x_var)?;
Ok(z_var)
}
In this example, if either x_var
or y_var
is a witness variable,
then z_var
is also a witness variable. On the other hand, z_var
is a constant if both x_var
and y_var
are constants (i.e., cs
is None
), and future operations on z_var
do not generate any
constraints.
(Note that we use division as an example for simplicity. You may
call x_var.mul_by_inverse(y_var)?
directly, which internally works
similarly to the above code.)
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl<F: Field> AllocVar<(), F> for ()
impl<F: Field> AllocVar<(), F> for ()
Dummy impl for ()
.
fn new_variable<T: Borrow<()>>( _cs: impl Into<Namespace<F>>, _f: impl FnOnce() -> Result<T, SynthesisError>, _mode: AllocationMode, ) -> Result<Self, SynthesisError>
Source§impl<I, F: Field, A: AllocVar<I, F>> AllocVar<[I], F> for Vec<A>
impl<I, F: Field, A: AllocVar<I, F>> AllocVar<[I], F> for Vec<A>
This blanket implementation just allocates variables in Self
element by element.
fn new_variable<T: Borrow<[I]>>( cs: impl Into<Namespace<F>>, f: impl FnOnce() -> Result<T, SynthesisError>, mode: AllocationMode, ) -> Result<Self, SynthesisError>
Source§impl<I, F: Field, A: AllocVar<I, F>, const N: usize> AllocVar<[I; N], F> for [A; N]
impl<I, F: Field, A: AllocVar<I, F>, const N: usize> AllocVar<[I; N], F> for [A; N]
This blanket implementation just allocates variables in Self
element by element.
fn new_variable<T: Borrow<[I; N]>>( cs: impl Into<Namespace<F>>, f: impl FnOnce() -> Result<T, SynthesisError>, mode: AllocationMode, ) -> Result<Self, SynthesisError>
Source§impl<I, F: Field, A: AllocVar<I, F>, const N: usize> AllocVar<[I], F> for [A; N]
impl<I, F: Field, A: AllocVar<I, F>, const N: usize> AllocVar<[I], F> for [A; N]
This blanket implementation just allocates variables in Self
element by element.