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