1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Generic `LookupAir` / `LookupBuilder` lookup-argument module.
//!
//! Holds the field-polymorphic core of the closure-based LogUp machinery: the
//! [`LookupAir`] trait, the [`LookupBuilder`] / [`LookupColumn`] / [`LookupGroup`] /
//! [`LookupBatch`] surface, the [`Challenges`] struct, the [`LookupMessage`] encode trait,
//! the two-path adapters ([`ConstraintLookupBuilder`] for symbolic constraint
//! evaluation, [`ProverLookupBuilder`] for concrete-row fraction collection), the
//! [`LookupFractions`] accumulator, and the [`build_logup_aux_trace`] /
//! [`build_lookup_fractions`] drivers.
//!
//! This module is deliberately free of Miden-specific types so it can be extracted into
//! its own crate without further disentangling. The Miden-side wiring (aggregator AIR,
//! bus message structs, aux-trace builder, bus identifiers) is surfaced separately
//! through [`crate::logup`].
pub use ;
pub use ;
pub use Challenges;
pub use ConstraintLookupBuilder;
pub use LookupMessage;
pub use ;
// LOOKUP AIR
// ================================================================================================
/// A declarative LogUp lookup argument.
///
/// Shaped the same way as `p3_air::Air<AB>`: generic over the builder
/// the caller picks, and evaluated once per logical "row pair" (the
/// constraint path visits every row symbolically, the prover path visits
/// every concrete row).
///
/// The trait carries both the static *shape* (column count, payload
/// width bound, bus-id upper bound) and the `eval` method that actually
/// emits the interactions. Adapter constructors take a `&impl
/// LookupAir<Self>` and read the shape via the trait — the `LB` type
/// parameter is pinned to the adapter itself, so there is no
/// ambiguity when the blanket `impl<LB: LookupBuilder> LookupAir<LB>
/// for MyAir` implementations apply.
///
/// ## Contract
///
/// - [`num_columns()`](Self::num_columns) must match the number of `LookupBuilder::next_column`
/// calls issued from [`eval`](Self::eval) — the adapter advances its internal column index each
/// time the closure returns and will panic (or produce undefined constraints) on a mismatch.
/// - [`max_message_width()`](Self::max_message_width) must be ≥ the widest payload any message in
/// the AIR emits. It counts **only** contiguous payload slots — the bus identifier is handled
/// separately through the precomputed bus-prefix table.
/// - [`num_bus_ids()`](Self::num_bus_ids) must be ≥ the largest bus ID any message in the AIR
/// emits, plus one; the adapter precomputes exactly that many bus prefixes and indexes into the
/// table with `bus_id as usize`.