use std::collections::BTreeMap;
use snarkvm_fields::PrimeField;
use crate::{
polycommit::sonic_pc::{LabeledPolynomial, PolynomialInfo, PolynomialLabel},
snark::varuna::CircuitId,
};
#[derive(Debug, Clone)]
pub struct FirstOracles<F: PrimeField> {
pub(in crate::snark::varuna) batches: BTreeMap<CircuitId, Vec<WitnessPoly<F>>>,
pub mask_poly: Option<LabeledPolynomial<F>>,
}
impl<F: PrimeField> FirstOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &'_ LabeledPolynomial<F>> {
self.batches.values().flat_map(|b| b.iter()).flat_map(|b| b.iter()).chain(self.mask_poly.as_ref())
}
pub fn into_iter(self) -> impl Iterator<Item = LabeledPolynomial<F>> {
self.batches.into_values().flat_map(|b| b.into_iter()).map(|b| b.0).chain(self.mask_poly)
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
self.batches.values().all(|b| b.iter().all(|b| b.matches_info(info)))
&& self.mask_poly.as_ref().is_none_or(|p| Some(p.info()) == info.get(p.label()))
}
}
#[derive(Debug, Clone)]
pub(in crate::snark::varuna) struct WitnessPoly<F: PrimeField>(pub(in crate::snark::varuna) LabeledPolynomial<F>);
impl<F: PrimeField> WitnessPoly<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[(&self.0)].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.0.info()) == info.get(self.0.label())
}
}
#[derive(Debug)]
pub struct SecondOracles<F: PrimeField> {
pub h_0: LabeledPolynomial<F>,
}
impl<F: PrimeField> SecondOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[&self.h_0].into_iter()
}
pub fn into_iter(self) -> impl Iterator<Item = LabeledPolynomial<F>> {
[self.h_0].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.h_0.info()) == info.get(self.h_0.label())
}
}
#[derive(Debug)]
pub struct ThirdOracles<F: PrimeField> {
pub g_1: LabeledPolynomial<F>,
pub h_1: LabeledPolynomial<F>,
}
impl<F: PrimeField> ThirdOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[&self.g_1, &self.h_1].into_iter()
}
pub fn into_iter(self) -> impl Iterator<Item = LabeledPolynomial<F>> {
[self.g_1, self.h_1].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.h_1.info()) == info.get(self.h_1.label()) && Some(self.g_1.info()) == info.get(self.g_1.label())
}
}
#[derive(Debug)]
pub struct FourthOracles<F: PrimeField> {
pub(in crate::snark::varuna) gs: BTreeMap<CircuitId, MatrixGs<F>>,
}
#[derive(Debug)]
pub(in crate::snark::varuna) struct MatrixGs<F: PrimeField> {
pub(in crate::snark::varuna) g_a: LabeledPolynomial<F>,
pub(in crate::snark::varuna) g_b: LabeledPolynomial<F>,
pub(in crate::snark::varuna) g_c: LabeledPolynomial<F>,
}
impl<F: PrimeField> MatrixGs<F> {
pub fn matches_matrix_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.g_a.info()) == info.get(self.g_a.label())
&& Some(self.g_b.info()) == info.get(self.g_b.label())
&& Some(self.g_c.info()) == info.get(self.g_c.label())
}
}
impl<F: PrimeField> FourthOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
self.gs.values().flat_map(|gs| [&gs.g_a, &gs.g_b, &gs.g_c].into_iter())
}
pub fn into_iter(self) -> impl Iterator<Item = LabeledPolynomial<F>> {
self.gs.into_values().flat_map(|gs| [gs.g_a, gs.g_b, gs.g_c].into_iter())
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
self.gs.values().all(|b| b.matches_matrix_info(info))
}
}
#[derive(Debug)]
pub struct FifthOracles<F: PrimeField> {
pub h_2: LabeledPolynomial<F>,
}
impl<F: PrimeField> FifthOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[&self.h_2].into_iter()
}
pub fn into_iter(self) -> impl Iterator<Item = LabeledPolynomial<F>> {
[self.h_2].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.h_2.info()) == info.get(self.h_2.label())
}
}