pub fn to_matrices(&self) -> (Vec<Variable>, Vec<FieldElement<F>>) {
        let header = self.public_input_header();
        let body = &self.constraints;
        let total_length = (header.len() + body.len()).next_power_of_two();
        let pad = vec![self.padding_constraint(); total_length - header.len() - body.len()];

        let mut full_constraints = header;
        full_constraints.extend_from_slice(body);
        full_constraints.extend_from_slice(&pad);

        let n = full_constraints.len();

        let mut lro = vec![self.null_variable(); n * 3];
        // Make a single vector with | l_1 .. l_m | r_1 .. r_m | o_1 .. o_m | concatenated.
        for (index, constraint) in full_constraints.iter().enumerate() {
            lro[index] = constraint.l;
            lro[index + n] = constraint.r;
            lro[index + n * 2] = constraint.o;
        }

        let mut q = vec![FieldElement::zero(); 5 * n];
        for (index, constraint) in full_constraints.iter().enumerate() {
            let ct = &constraint.constraint_type;
            q[index] = ct.ql.clone();
            q[index + n] = ct.qr.clone();
            q[index + 2 * n] = ct.qm.clone();
            q[index + 3 * n] = ct.qo.clone();
            q[index + 4 * n] = ct.qc.clone();
        }
        (lro, q)
    }
Returns the `LRO` and `Q` matrices. Each matrix has one row per constraint.
The `LRO` matrix has 3 columns with the values of the variables IDs of every
constraint. The `Q` matrix has 5 columns with the coefficients of the
constraint types.
Their layout is:
#######################
# public input header #
#######################
# circuit constraints #
#######################
#       padding       #
#######################
crates/provers/plonk/src/constraint_system/mod.rs