use crate::AddrMap;
use crate::Real;
#[derive(Clone)]
pub struct Trace<Args, Data, Ret> {
pub args: Args,
pub data: Data,
pub retv: Option<Ret>,
pub logjp: Real,
}
impl<Args, Data, Ret> Trace<Args, Data, Ret> {
pub fn new(args: Args, data: Data, retv: Ret, logjp: Real) -> Self {
Trace {
args,
data,
retv: Some(retv),
logjp,
}
}
pub fn set_retv(&mut self, v: Ret) {
self.retv = Some(v);
}
}
pub trait GenFn<Args, Data, Ret> {
fn simulate(&self, args: Args) -> Trace<Args, Data, Ret>;
fn generate(&self, args: Args, constraints: Data) -> (Trace<Args, Data, Ret>, Real);
fn update(
&self,
trace: Trace<Args, Data, Ret>,
args: Args,
diff: ArgDiff,
constraints: Data, ) -> (Trace<Args, Data, Ret>, Data, Real);
fn regenerate(
&self,
trace: Trace<Args, Data, Ret>,
args: Args,
diff: ArgDiff,
mask: &AddrMap,
) -> (Trace<Args, Data, Ret>, Real) {
panic!("regenerate: impl not found")
}
fn call(&self, args: Args) -> Ret {
self.simulate(args).retv.unwrap()
}
fn propose(&self, args: Args) -> (Data, Real) {
let trace = self.simulate(args);
(trace.data, trace.logjp)
}
fn assess(&self, args: Args, constraints: Data) -> Real {
let (_, weight) = self.generate(args, constraints);
weight
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ArgDiff {
NoChange,
Unknown,
Extend,
}