use crate::expr::{ArrayType, ExprRef, Type};
use baa::{ArrayValue, BitVecValue, BitVecValueRef, Value};
use rand::SeedableRng;
use rand::rngs::SmallRng;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum InitKind {
Zero,
Random(u64),
}
pub trait Simulator {
type SnapshotId;
fn init(&mut self, kind: InitKind);
fn step(&mut self);
fn set<'a>(&mut self, expr: ExprRef, value: impl Into<BitVecValueRef<'a>>);
fn get(&self, expr: ExprRef) -> Value;
fn step_count(&self) -> u64;
fn take_snapshot(&mut self) -> Self::SnapshotId;
fn restore_snapshot(&mut self, id: Self::SnapshotId);
}
pub struct InitValueGenerator {
rng: Option<SmallRng>,
}
impl InitValueGenerator {
pub fn from_kind(kind: InitKind) -> Self {
match kind {
InitKind::Zero => Self { rng: None },
InitKind::Random(seed) => Self {
rng: Some(SmallRng::seed_from_u64(seed)),
},
}
}
pub fn generate(&mut self, tpe: Type) -> Value {
match tpe {
Type::BV(bits) => {
if let Some(rng) = &mut self.rng {
BitVecValue::random(rng, bits).into()
} else {
BitVecValue::zero(bits).into()
}
}
Type::Array(ArrayType {
index_width,
data_width,
}) => {
if let Some(rng) = &mut self.rng {
ArrayValue::random(rng, index_width, data_width).into()
} else {
ArrayValue::new_sparse(index_width, &BitVecValue::zero(data_width)).into()
}
}
}
}
}