use ark_ff::Field;
use crate::lc_diff;
use super::{lc, ConstraintSystem, Label, SynthesisError, Variable};
use ark_std::rc::Rc;
use core::fmt::Debug;
#[derive(Clone)]
pub struct InstanceOutliner<F: Field> {
pub pred_label: Label,
pub func: OutliningFunc<F>,
}
type OutliningFunc<F> =
Rc<dyn Fn(&mut ConstraintSystem<F>, &[Variable]) -> Result<(), SynthesisError>>;
impl<F: Field> Debug for InstanceOutliner<F> {
fn fmt(&self, f: &mut ark_std::fmt::Formatter<'_>) -> ark_std::fmt::Result {
write!(
f,
"InstanceOutliner {{ pred_label: {:?} }}",
self.pred_label
)
}
}
pub fn outline_r1cs<F: Field>(
cs: &mut ConstraintSystem<F>,
instance_witness_map: &[Variable],
) -> crate::gr1cs::Result<()> {
let one = instance_witness_map[0];
cs.enforce_r1cs_constraint(|| lc![one], || lc![one], || lc![Variable::One])?;
for (instance, witness) in instance_witness_map.iter().enumerate().skip(1) {
cs.enforce_r1cs_constraint(
|| lc![one],
|| lc![*witness],
|| lc![Variable::instance(instance)],
)?;
}
Ok(())
}
pub fn outline_sr1cs<F: Field>(
cs: &mut ConstraintSystem<F>,
instance_witness_map: &[Variable],
) -> crate::gr1cs::Result<()> {
for (instance, witness) in instance_witness_map.iter().enumerate() {
cs.enforce_sr1cs_constraint(
|| lc_diff![Variable::instance(instance), *witness],
|| lc![],
)?;
}
Ok(())
}