snarkvm_circuit_environment/helpers/
constraint.rs1use crate::{prelude::*, *};
17use snarkvm_fields::PrimeField;
18use snarkvm_utilities::dev_eprintln;
19
20#[derive(Clone, Debug, Hash)]
21pub struct Constraint<F: PrimeField>(
22 pub(crate) Scope,
23 pub(crate) LinearCombination<F>,
24 pub(crate) LinearCombination<F>,
25 pub(crate) LinearCombination<F>,
26);
27
28impl<F: PrimeField> Constraint<F> {
29 pub(crate) fn num_nonzeros(&self) -> (u64, u64, u64) {
31 let (a, b, c) = (&self.1, &self.2, &self.3);
32 (a.num_nonzeros(), b.num_nonzeros(), c.num_nonzeros())
33 }
34
35 pub(crate) fn is_satisfied(&self) -> bool {
37 let a = self.1.value();
38 let b = self.2.value();
39 let c = self.3.value();
40
41 let satisfied = a * b == c;
42 if !satisfied {
43 dev_eprintln!("Failed constraint at {scope}:\n\t({a} * {b}) != {c}", scope = self.0);
44 }
45 satisfied
46 }
47
48 pub fn to_terms(&self) -> (&LinearCombination<F>, &LinearCombination<F>, &LinearCombination<F>) {
50 (&self.1, &self.2, &self.3)
51 }
52}
53
54impl<F: PrimeField> Display for Constraint<F> {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 let (scope, a, b, c) = (&self.0, &self.1, &self.2, &self.3);
57 let a = a.value();
58 let b = b.value();
59 let c = c.value();
60
61 match (a * b) == c {
62 true => write!(f, "Constraint {scope}:\n\t{a} * {b} == {c}\n"),
63 false => write!(f, "Constraint {scope}:\n\t{a} * {b} != {c} (Unsatisfied)\n"),
64 }
65 }
66}