use nebu::Fp3;
use super::decide::{self, Decider};
use super::ivc::Key;
use super::ops::{Arith, Ops};
use super::state::{self, ClaimV, State};
use super::step::{self, StepProof};
use crate::machine::air::KConst;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Publics<V> {
pub ctx: [V; 4],
pub chain: [V; 4],
pub segments: V,
pub ch: [V; 2],
pub k: KConst<V>,
}
impl<V: Copy> Publics<V> {
pub fn items(&self) -> Vec<(V, bool)> {
let mut out: Vec<(V, bool)> = self
.ctx
.iter()
.chain(&self.chain)
.map(|&v| (v, false))
.collect();
out.push((self.segments, false));
out.extend(self.ch.iter().map(|&v| (v, true)));
out.extend(self.k.to_vec().into_iter().map(|v| (v, false)));
out
}
pub fn from_items(v: &[V]) -> Self {
Self {
ctx: [v[0], v[1], v[2], v[3]],
chain: [v[4], v[5], v[6], v[7]],
segments: v[8],
ch: [v[9], v[10]],
k: KConst::from_slice(&v[11..]),
}
}
}
pub const PUBLICS: usize = 11 + crate::machine::air::KCONSTS;
pub fn run<O: Ops>(
o: &mut O,
key: &Key,
pubs: &Publics<O::V>,
state: &State,
step: &StepProof,
dec: &Decider,
) -> ClaimV<O::V> {
let p = &key.params;
let (st, x) = state::absorb_free(o, &p.dims, state);
let fin = step::verify(o, p, &st, x, step);
for i in 0..4 {
o.assert_eq(fin.ctx[i], pubs.ctx[i], "final: context");
o.assert_eq(fin.chain[i], pubs.chain[i], "final: chain");
}
o.assert_eq(fin.step, pubs.segments, "final: step count");
for (&a, &b) in fin.b_first.iter().zip(&fin.b_last) {
o.assert_eq(a, b, "final: cyclic boundary");
}
let mut ins = fin.g.point.clone();
ins.extend_from_slice(&pubs.ch);
ins.extend(pubs.k.to_vec());
let g = o.graph(&key.g, &ins)[0];
o.assert_eq(g, fin.g.value, "final: deferred constraints");
decide::verify(
o,
&key.dcfg,
&fin.acc,
&fin.pv,
key.kw_root,
key.key_ext,
p.n,
dec,
);
fin.pn
}
pub fn constants<O: Ops>(o: &mut O, p: &Publics<Fp3>) -> Publics<O::V> {
let v: Vec<O::V> = p.items().into_iter().map(|(x, _)| o.constant(x)).collect();
Publics::from_items(&v)
}