Skip to content

Conversation

@LindaGuiga
Copy link
Contributor

This is still work in progress, but I am opening a draft PR so that we can decide early on whether we can agree on this design.

The goal is to create a design for recursive lookups.
The trait RecursiveAirLookupVerification contains the methods necessary for an AIR to check its own lookup constraints. Thus, it enables a RecursiveAir to:

  • get the permutation columns (the auxiliary columns, like the running sum)
  • get the challenges associated to the local lookups
  • for local lookups, check that the auxiliary columns are updated correctly, and that the final cumulative sum (for LogUp) is 0
  • for global lookups, check that the auxiliary columns are updated correctly, and that the final cumulative sum (for LogUp) is the same as the one provided by the prover.

Note that for global lookups (= global interactions), we need the index of the table with which we are interacting, as well as the direction of the lookup (sending or receiving), to determine whether the multiplicities should be negated. This is why I introduced Direction and Table.

In order to facilitate the use of airs without lookups, I introduced a wrapper AirWithoutLookups which implements RecursiveAirLookupVerification.

Copy link
Contributor

@4l0n50 4l0n50 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just took a quick look. It would be nice to see an example, but I guess it needs non-recursive lookups first.

>(
config: &SC,
air: &A,
air: &dyn RecursiveAirWithLookupVerification<SC::Challenge, Comm>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need dynamic dispatch now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's so we can have &[&dyn A] in the multi-table verifier

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, I saw that later and forgot to remove the comment.

folded_constraints,
);

folded_constraints = self.eval_global_constraints(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you need to compute folded_constrais = folded_constraints + alpha * self.eval_global_constraints(..) in the circuit?

Copy link
Contributor Author

@LindaGuiga LindaGuiga Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eval_global_constraints takes folded_constraints as an argument, so what it should do is use that start of the accumulator to keep folding (so it adds the global constraints as though they were part of the AIR constraints themselves)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thkns!

@Nashtare Nashtare added this to the Design and specs milestone Oct 9, 2025
@Nashtare Nashtare added the doc/specs Improvements or additions to documentation label Oct 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc/specs Improvements or additions to documentation

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

4 participants