#[macro_export]
macro_rules! uniform_constraints {
($($body:tt)*) => {
{
#[cfg(debug_assertions)]
{
let _uniformity_guard = $crate::circuit_safety::UniformityGuard::new();
}
$($body)*
}
};
}
#[macro_export]
macro_rules! non_uniform_ok {
($reason:literal, $($body:tt)*) => {
{
#[cfg(debug_assertions)]
{
eprintln!("[CIRCUIT] Non-uniform section (OK): {}", $reason);
}
$($body)*
}
};
}
#[cfg(debug_assertions)]
#[derive(Default)]
pub struct UniformityGuard {
}
#[cfg(debug_assertions)]
impl UniformityGuard {
pub fn new() -> Self {
Self::default()
}
}
#[cfg(debug_assertions)]
impl Drop for UniformityGuard {
fn drop(&mut self) {
}
}
pub trait UniformCircuit {
fn verify_uniformity(&self) -> Result<(), String>;
}
pub fn ensure_witness_count<T>(witnesses: Vec<T>, expected: usize, default: T) -> Vec<T>
where
T: Clone,
{
let mut result = witnesses;
result.truncate(expected);
while result.len() < expected {
result.push(default.clone());
}
debug_assert_eq!(result.len(), expected, "Witness count mismatch");
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ensure_witness_count() {
let witnesses = vec![1, 2, 3];
let padded = ensure_witness_count(witnesses, 5, 0);
assert_eq!(padded, vec![1, 2, 3, 0, 0]);
let witnesses = vec![1, 2, 3, 4, 5];
let truncated = ensure_witness_count(witnesses, 3, 0);
assert_eq!(truncated, vec![1, 2, 3]);
let witnesses = vec![1, 2, 3];
let exact = ensure_witness_count(witnesses, 3, 0);
assert_eq!(exact, vec![1, 2, 3]);
}
}