pub fn transform_lc_map(
        &mut self,
        transformer: &mut dyn FnMut(
            &ConstraintSystem<F>,
            usize,
            &mut LinearCombination<F>,
        ) -> (usize, Option<Vec<F>>),
    ) {
        // `transformed_lc_map` stores the transformed linear combinations.
        let mut transformed_lc_map = BTreeMap::new();
        let mut num_times_used = self.lc_num_times_used(false);

        // This loop goes through all the LCs in the map, starting from
        // the early ones. The transformer function is applied to the
        // inlined LC, where new witness variables can be created.
        for (&index, lc) in &self.lc_map {
            let mut transformed_lc = LinearCombination::new();

            // Inline the LC, unwrapping symbolic LCs that may constitute it,
            // and updating them according to transformations in prior iterations.
            for &(coeff, var) in lc.iter() {
                if var.is_lc() {
                    let lc_index = var.get_lc_index().expect("should be lc");

                    // If `var` is a `SymbolicLc`, fetch the corresponding
                    // inlined LC, and substitute it in.
                    //
                    // We have the guarantee that `lc_index` must exist in
                    // `new_lc_map` since a LC can only depend on other
                    // LCs with lower indices, which we have transformed.
                    //
                    let lc = transformed_lc_map
                        .get(&lc_index)
                        .expect("should be inlined");
                    transformed_lc.extend((lc * coeff).0.into_iter());

                    // Delete linear combinations that are no longer used.
                    //
                    // Deletion is safe for both outlining and inlining:
                    // * Inlining: the LC is substituted directly into all use sites, and so once it
                    //   is fully inlined, it is redundant.
                    //
                    // * Outlining: the LC is associated with a new variable `w`, and a new
                    //   constraint of the form `lc_data * 1 = w`, where `lc_data` is the actual
                    //   data in the linear combination. Furthermore, we replace its entry in
                    //   `new_lc_map` with `(1, w)`. Once `w` is fully inlined, then we can delete
                    //   the entry from `new_lc_map`
                    //
                    num_times_used[lc_index.0] -= 1;
                    if num_times_used[lc_index.0] == 0 {
                        // This lc is not used any more, so remove it.
                        transformed_lc_map.remove(&lc_index);
                    }
                } else {
                    // Otherwise, it's a concrete variable and so we
                    // substitute it in directly.
                    transformed_lc.push((coeff, var));
                }
            }
            transformed_lc.compactify();

            // Call the transformer function.
            let (num_new_witness_variables, new_witness_assignments) =
                transformer(&self, num_times_used[index.0], &mut transformed_lc);

            // Insert the transformed LC.
            transformed_lc_map.insert(index, transformed_lc);

            // Update the witness counter.
            self.num_witness_variables += num_new_witness_variables;

            // Supply additional witness assignments if not in the
            // setup mode and if new witness variables are created.
            if !self.is_in_setup_mode() && num_new_witness_variables > 0 {
                assert!(new_witness_assignments.is_some());
                if let Some(new_witness_assignments) = new_witness_assignments {
                    assert_eq!(new_witness_assignments.len(), num_new_witness_variables);
                    self.witness_assignment
                        .extend_from_slice(&new_witness_assignments);
                }
            }
        }
        // Replace the LC map.
        self.lc_map = transformed_lc_map;
    }
/// Transform the map of linear combinations.
/// Specifically, allow the creation of additional witness assignments.
///
/// This method is used as a subroutine of `inline_all_lcs` and `outline_lcs`.
///
/// The transformer function is given a references of this constraint system (&self),
/// number of times used, and a mutable reference of the linear combination to be transformed.
///     (&ConstraintSystem<F>, usize, &mut LinearCombination<F>)
///
/// The transformer function returns the number of new witness variables needed
/// and a vector of new witness assignments (if not in the setup mode).
///     (usize, Option<Vec<F>>)
Transform the map of linear combinations.
Specifically, allow the creation of additional witness assignments.

This method is used as a subroutine of `inline_all_lcs` and `outline_lcs`.

The transformer function is given a references of this constraint system (&self),
number of times used, and a mutable reference of the linear combination to be transformed.

The transformer function returns the number of new witness variables needed
and a vector of new witness assignments (if not in the setup mode).
(usize, Option>)
Transform the map of linear combinations . Specifically allow the creation of additional witness assignments . This method is used as a subroutine of ` inline_all_lcs ` and ` outline_lcs ` . The transformer function is given a references of this constraint system ( &self ) number of times used and a mutable reference of the linear combination to be transformed . The transformer function returns the number of new witness variables needed and a vector of new witness assignments ( if not in the setup mode ) . ( usize Option > )
pub fn transform_lc_map(
        &mut self,
        transformer: &mut dyn FnMut(
            &ConstraintSystem<F>,
            usize,
            &mut LinearCombination<F>,
        ) -> (usize, Option<Vec<F>>),
    ) {
        // `transformed_lc_map` stores the transformed linear combinations.
        let mut transformed_lc_map = BTreeMap::new();
        let mut num_times_used = self.lc_num_times_used(false);
        // This loop goes through all the LCs in the map, starting from
        // the early ones. The transformer function is applied to the
        // inlined LC, where new witness variables can be created.
        for (&index, lc) in &self.lc_map {
            let mut transformed_lc = LinearCombination::new();
            // Inline the LC, unwrapping symbolic LCs that may constitute it,
            // and updating them according to transformations in prior iterations.
            for &(coeff, var) in lc.iter() {
                if var.is_lc() {
                    let lc_index = var.get_lc_index().expect("should be lc");
                    // If `var` is a `SymbolicLc`, fetch the corresponding
                    // inlined LC, and substitute it in.
                    //
                    // We have the guarantee that `lc_index` must exist in
                    // `new_lc_map` since a LC can only depend on other
                    // LCs with lower indices, which we have transformed.
                    //
                    let lc = transformed_lc_map
                        .get(&lc_index)
                        .expect("should be inlined");
                    transformed_lc.extend((lc * coeff).0.into_iter());
                    // Delete linear combinations that are no longer used.
                    //
                    // Deletion is safe for both outlining and inlining:
                    // * Inlining: the LC is substituted directly into all use sites, and so once it
                    //   is fully inlined, it is redundant.
                    //
                    // * Outlining: the LC is associated with a new variable `w`, and a new
                    //   constraint of the form `lc_data * 1 = w`, where `lc_data` is the actual
                    //   data in the linear combination. Furthermore, we replace its entry in
                    //   `new_lc_map` with `(1, w)`. Once `w` is fully inlined, then we can delete
                    //   the entry from `new_lc_map`
                    //
                    num_times_used[lc_index.0] -= 1;
                    if num_times_used[lc_index.0] == 0 {
                        // This lc is not used any more, so remove it.
                        transformed_lc_map.remove(&lc_index);
                    }
                } else {
                    // Otherwise, it's a concrete variable and so we
                    // substitute it in directly.
                    transformed_lc.push((coeff, var));
                }
            }
            transformed_lc.compactify();
            // Call the transformer function.
            let (num_new_witness_variables, new_witness_assignments) =
                transformer(&self, num_times_used[index.0], &mut transformed_lc);
            // Insert the transformed LC.
            transformed_lc_map.insert(index, transformed_lc);
            // Update the witness counter.
            self.num_witness_variables += num_new_witness_variables;
            // Supply additional witness assignments if not in the
            // setup mode and if new witness variables are created.
            if !self.is_in_setup_mode() && num_new_witness_variables > 0 {
                assert!(new_witness_assignments.is_some());
                if let Some(new_witness_assignments) = new_witness_assignments {
                    assert_eq!(new_witness_assignments.len(), num_new_witness_variables);
                    self.witness_assignment
                        .extend_from_slice(&new_witness_assignments);
                }
            }
        }
        // Replace the LC map.
        self.lc_map = transformed_lc_map;
    }
pub fn transform_lc_map ( & mut self , transformer : & mut dyn FnMut ( & ConstraintSystem < F > , usize , & mut LinearCombination < F > , ) -> ( usize , Option < Vec < F > > ) , ) { // `transformed_lc_map` stores the transformed linear combinations. let mut transformed_lc_map = BTreeMap :: new ( ) ; let mut num_times_used = self . lc_num_times_used ( false ) ; // This loop goes through all the LCs in the map, starting from // the early ones. The transformer function is applied to the // inlined LC, where new witness variables can be created. for ( & index , lc ) in & self . lc_map { let mut transformed_lc = LinearCombination :: new ( ) ; // Inline the LC, unwrapping symbolic LCs that may constitute it, // and updating them according to transformations in prior iterations. for & ( coeff , var ) in lc . iter ( ) { if var . is_lc ( ) { let lc_index = var . get_lc_index ( ) . expect ( " " ) ; // If `var` is a `SymbolicLc`, fetch the corresponding // inlined LC, and substitute it in. // // We have the guarantee that `lc_index` must exist in // `new_lc_map` since a LC can only depend on other // LCs with lower indices, which we have transformed. // let lc = transformed_lc_map . get ( & lc_index ) . expect ( " " ) ; transformed_lc . extend ( ( lc * coeff ) . 0 . into_iter ( ) ) ; // Delete linear combinations that are no longer used. // // Deletion is safe for both outlining and inlining: // * Inlining: the LC is substituted directly into all use sites, and so once it //   is fully inlined, it is redundant. // // * Outlining: the LC is associated with a new variable `w`, and a new //   constraint of the form `lc_data * 1 = w`, where `lc_data` is the actual //   data in the linear combination. Furthermore, we replace its entry in //   `new_lc_map` with `(1, w)`. Once `w` is fully inlined, then we can delete //   the entry from `new_lc_map` // num_times_used [ lc_index . 0 ] -= 1 ; if num_times_used [ lc_index . 0 ] == 0 { // This lc is not used any more, so remove it. transformed_lc_map . remove ( & lc_index ) ; } } else { // Otherwise, it's a concrete variable and so we // substitute it in directly. transformed_lc . push ( ( coeff , var ) ) ; } } transformed_lc . compactify ( ) ; // Call the transformer function. let ( num_new_witness_variables , new_witness_assignments ) = transformer ( & self , num_times_used [ index . 0 ] , & mut transformed_lc ) ; // Insert the transformed LC. transformed_lc_map . insert ( index , transformed_lc ) ; // Update the witness counter. self . num_witness_variables += num_new_witness_variables ; // Supply additional witness assignments if not in the // setup mode and if new witness variables are created. if ! self . is_in_setup_mode ( ) && num_new_witness_variables > 0 { assert ! ( new_witness_assignments is_some ( ) ) ; if let Some ( new_witness_assignments ) = new_witness_assignments { assert_eq ! ( new_witness_assignments len ( ) num_new_witness_variables ) ; self . witness_assignment . extend_from_slice ( & new_witness_assignments ) ; } } } // Replace the LC map. self . lc_map = transformed_lc_map ; }
Transform the map of linear combinations.
Transform the map of linear combinations .
&mut self
transformer
&mut dyn FnMut(
            &ConstraintSystem<F>,
            usize,
            &mut LinearCombination<F>,
        ) -> (usize, Option<Vec<F>>)
&mut self
transformer
&mut dyn FnMut(
            &ConstraintSystem<F>,
            usize,
            &mut LinearCombination<F>,
        ) -> (usize, Option<Vec<F>>)