use ff::PrimeField;
use haloumi_core::{
expressions::{EvaluableExpr, ExprBuilder, ExpressionInfo},
info_traits::ConstraintSystemInfo,
};
use haloumi_ir_gen::circuit::resolved::ResolvedIRCircuit;
use haloumi_ir_gen::{IRGenParams, IRGenerationUser, circuit::unresolved::UnresolvedIRCircuit};
#[cfg(feature = "llzk-backend")]
use haloumi_llzk::{LlzkBackend, LlzkOutput, LlzkParams};
#[cfg(feature = "picus-backend")]
use haloumi_picus::{PicusBackend, PicusOutput, PicusParams};
use haloumi_synthesis::{CircuitSynthesis, SynthesisUser, SynthesizedCircuit};
pub type Result<O> = std::result::Result<O, crate::error::Error>;
#[derive(Default, Debug)]
pub struct Driver {
ir_gen: IRGenerationUser,
synthesis: SynthesisUser,
}
impl Driver {
pub fn new() -> Self {
Self {
ir_gen: Default::default(),
synthesis: Default::default(),
}
}
pub fn synthesize<F, C>(
&mut self,
circuit: &C,
) -> Result<SynthesizedCircuit<F, <C::CS as ConstraintSystemInfo<F>>::Polynomial>>
where
C: CircuitSynthesis<F>,
F: PrimeField,
{
Ok(self.synthesis.synthesize(circuit)?)
}
pub fn generate_ir<'syn, 'drv, 'cb, 'sco, F, E>(
&'drv mut self,
syn: &'syn SynthesizedCircuit<F, E>,
params: IRGenParams<'cb, '_, F, E>,
) -> Result<UnresolvedIRCircuit<'drv, 'syn, 'sco, F, E>>
where
F: PrimeField + Ord,
E: Clone + ExprBuilder<F> + ExpressionInfo + EvaluableExpr<F> + std::fmt::Debug,
'syn: 'sco,
'drv: 'sco + 'syn,
'cb: 'sco + 'syn,
{
Ok(self.ir_gen.generate_ir(syn, params)?)
}
#[cfg(feature = "picus-backend")]
pub fn picus(&self, ir: &ResolvedIRCircuit, params: PicusParams) -> Result<PicusOutput> {
Ok(PicusBackend::initialize(params).codegen(ir, ir.ctx())?)
}
#[cfg(feature = "llzk-backend")]
pub fn llzk<'c>(
&self,
ir: &ResolvedIRCircuit,
params: LlzkParams<'c>,
) -> Result<LlzkOutput<'c>> {
Ok(LlzkBackend::initialize(params).codegen(ir, ir.ctx())?)
}
}