use crate::{Assignment, ConstraintUnsatisfied, Inject, LinearCombination, Mode, R1CS, Variable, witness_mode};
use snarkvm_curves::AffineCurve;
use snarkvm_fields::traits::*;
use core::{fmt, hash};
pub trait Environment: 'static + Copy + Clone + fmt::Debug + fmt::Display + Eq + PartialEq + hash::Hash {
type Network: console::Network<Affine = Self::Affine, Field = Self::BaseField, Scalar = Self::ScalarField>;
type Affine: AffineCurve<
BaseField = Self::BaseField,
ScalarField = Self::ScalarField,
Coordinates = (Self::BaseField, Self::BaseField),
>;
type BaseField: PrimeField + SquareRootField + Copy;
type ScalarField: PrimeField<BigInteger = <Self::BaseField as PrimeField>::BigInteger> + Copy;
const EDWARDS_A: Self::BaseField = <Self::Network as console::Environment>::EDWARDS_A;
const EDWARDS_D: Self::BaseField = <Self::Network as console::Environment>::EDWARDS_D;
const MONTGOMERY_A: Self::BaseField = <Self::Network as console::Environment>::MONTGOMERY_A;
const MONTGOMERY_B: Self::BaseField = <Self::Network as console::Environment>::MONTGOMERY_B;
const MAX_STRING_BYTES: u32 = <Self::Network as console::Environment>::MAX_STRING_BYTES;
fn zero() -> LinearCombination<Self::BaseField>;
fn one() -> LinearCombination<Self::BaseField>;
fn new_variable(mode: Mode, value: Self::BaseField) -> Variable<Self::BaseField>;
fn new_witness<Fn: FnOnce() -> Output::Primitive, Output: Inject>(mode: Mode, value: Fn) -> Output;
fn scope<S: Into<String>, Fn, Output>(name: S, logic: Fn) -> Output
where
Fn: FnOnce() -> Output;
fn enforce<Fn, A, B, C>(constraint: Fn) -> Result<(), ConstraintUnsatisfied>
where
Fn: FnOnce() -> (A, B, C),
A: Into<LinearCombination<Self::BaseField>>,
B: Into<LinearCombination<Self::BaseField>>,
C: Into<LinearCombination<Self::BaseField>>;
fn assert<Boolean: Into<LinearCombination<Self::BaseField>>>(
boolean: Boolean,
) -> Result<(), ConstraintUnsatisfied> {
Self::enforce(|| (boolean, Self::one(), Self::one()))
}
fn assert_eq<A, B>(a: A, b: B) -> Result<(), ConstraintUnsatisfied>
where
A: Into<LinearCombination<Self::BaseField>>,
B: Into<LinearCombination<Self::BaseField>>,
{
Self::enforce(|| (a, Self::one(), b))
}
fn assert_neq<A, B>(a: A, b: B) -> Result<(), ConstraintUnsatisfied>
where
A: Into<LinearCombination<Self::BaseField>>,
B: Into<LinearCombination<Self::BaseField>>,
{
let (a, b) = (a.into(), b.into());
let mode = witness_mode!(a, b);
let a_minus_b = a - b;
let multiplier = match a_minus_b.value().inverse() {
Some(inverse) => Self::new_variable(mode, inverse).into(),
None => Self::zero(),
};
Self::enforce(|| (a_minus_b, multiplier, Self::one()))
}
fn is_satisfied() -> bool;
fn is_satisfied_in_scope() -> bool;
fn num_constants() -> u64;
fn num_public() -> u64;
fn num_private() -> u64;
fn num_variables() -> u64;
fn num_constraints() -> u64;
fn num_nonzeros() -> (u64, u64, u64);
fn count() -> (u64, u64, u64, u64, (u64, u64, u64)) {
(Self::num_constants(), Self::num_public(), Self::num_private(), Self::num_constraints(), Self::num_nonzeros())
}
fn num_constants_in_scope() -> u64;
fn num_public_in_scope() -> u64;
fn num_private_in_scope() -> u64;
fn num_constraints_in_scope() -> u64;
fn num_nonzeros_in_scope() -> (u64, u64, u64);
fn count_in_scope() -> (u64, u64, u64, u64, (u64, u64, u64)) {
(
Self::num_constants_in_scope(),
Self::num_public_in_scope(),
Self::num_private_in_scope(),
Self::num_constraints_in_scope(),
Self::num_nonzeros_in_scope(),
)
}
fn get_variable_limit() -> Option<u64>;
fn set_variable_limit(limit: Option<u64>);
fn get_constraint_limit() -> Option<u64>;
fn set_constraint_limit(limit: Option<u64>);
fn halt<S: Into<String>, T>(message: S) -> T {
<Self::Network as console::Environment>::halt(message)
}
fn inject_r1cs(r1cs: R1CS<Self::BaseField>);
fn eject_r1cs_and_reset() -> R1CS<Self::BaseField>;
fn eject_assignment_and_reset() -> Assignment<<Self::Network as console::Environment>::Field>;
fn reset();
}