Skip to content

Constraint Arrays

A convenient formalism

Here, we factor out a convenient notational device that we will use repeatedly.

We fix a total number nconsn_\text{cons} of constraints. In the situations we'll be working with, we'll have nconsn_\text{cons} lists of shifted value indices, indexed by x{0,,ncons1}x \in \{0, \ldots , n_\text{cons} - 1\}; thus for each x{0,,ncons1}x \in \{0, \ldots , n_\text{cons} - 1\}, we will have a list LxzL^z_x.

Our goal here is to define an array, zz, that contains the words "specified by the lists" LxzL^z_x. The array zz will be of length nconsn_\text{cons}; each of its elements z[x]z[x] will be a 64-bit word.

To define zz, we set, for each x{0,,ncons1}x \in \{0, \ldots , n_\text{cons} - 1\}:

z[x](y,op,s)Lxzop(w[y],s).\begin{equation*}z[x] \coloneqq \bigoplus_{(y, \text{op}, s) \in L^z_x} \text{op}(w[y], s).\end{equation*}

Efficient Algorithm

There is a straightforward efficient algorithm that computes the array zz, given the list (Lxz)x=0ncons1\left( L^z_x \right)_{x = 0}^{n_\text{cons} - 1}, which exploits the sparsity of the constraint system. For completeness, we record it here. On input ww and (Lxz)x=0ncons1\left( L^z_x \right)_{x = 0}^{n_\text{cons} - 1}, the prover runs:

  • allocate the array z\mathsf{z}, containing nconsn_\text{cons} 64-bit words, initially all 0.
  • for each x{0,,ncons1}x \in \{0, \ldots , n_\text{cons} - 1\} do:
    • load the xxth list LxzL^z_x from the constraint system.
    • for each shifted value index (y,op,s)Lxz(y, \text{op}, s) \in L^z_x do:
      • update z[x]+=op(w[y],s)\mathsf{z}[x] \mathrel{+}= \text{op}(w[y], s).
  • return z\mathsf{z}.

The array z\mathsf{z} returned by that algorithm equals the constraint array zz.