Skip to content

Commit

Permalink
wip: simulator
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed Nov 16, 2023
1 parent 5457bbd commit 1f0041f
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 22 deletions.
9 changes: 5 additions & 4 deletions src/btor2/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::btor2::parse::tokenize_line;
use crate::ir;
use crate::ir::{SignalKind, TypeCheck};
use crate::mc::{State, Value, Witness};
use crate::mc::{Value, ValueStore, Witness};
use std::io::{BufRead, Write};

enum ParserState {
Expand All @@ -28,7 +28,7 @@ pub fn parse_witnesses(input: &mut impl BufRead, parse_max: usize) -> Result<Vec
let mut state = ParserState::Start;
let mut out = Vec::with_capacity(1);
let mut wit = Witness::default();
let mut inputs = State::default();
let mut inputs = ValueStore::default();

let finish_witness = |out: &mut Vec<Witness>, wit: &mut Witness| {
out.push(std::mem::replace(wit, Witness::default()));
Expand All @@ -43,8 +43,9 @@ pub fn parse_witnesses(input: &mut impl BufRead, parse_max: usize) -> Result<Vec
assert_eq!(at as usize, wit.inputs.len());
ParserState::ParsingInputsAt(at)
};
let finish_inputs = |wit: &mut Witness, inputs: &mut State| {
wit.inputs.push(std::mem::replace(inputs, State::default()));
let finish_inputs = |wit: &mut Witness, inputs: &mut ValueStore| {
wit.inputs
.push(std::mem::replace(inputs, ValueStore::default()));
};
let start_state = |line: &str| {
let at = u64::from_str_radix(&line[1..], 10).unwrap();
Expand Down
4 changes: 3 additions & 1 deletion src/mc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright 2023 The Regents of the University of California
// released under BSD 3-Clause License
// author: Kevin Laeufer <[email protected]>
mod sim;
mod smt;
mod state;

pub use sim::Simulator;
pub use smt::{
ModelCheckResult, SmtModelChecker, SmtModelCheckerOptions, SmtSolverCmd, BITWUZLA_CMD,
};
pub use state::{State, Value, ValueRef, Witness};
pub use state::{Value, ValueRef, ValueStore, Witness};
21 changes: 21 additions & 0 deletions src/mc/sim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2023 The Regents of the University of California
// released under BSD 3-Clause License
// author: Kevin Laeufer <[email protected]>

use crate::ir::*;
use crate::mc::ValueStore;

/// Interpreter based simulator for a transition system.
pub struct Simulator<'a> {
ctx: &'a Context,
sys: &'a TransitionSystem,
state: ValueStore,
}

impl<'a> Simulator<'a> {
pub fn new(ctx: &'a Context, sys: &'a TransitionSystem) -> Self {
let types = sys.states().map(|s| s.symbol.get_type(ctx));
let state = ValueStore::new(types);
Self { ctx, sys, state }
}
}
4 changes: 2 additions & 2 deletions src/mc/smt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::ir::{Expr, ExprRef, GetNode, SignalInfo, SignalKind, Type, TypeCheck}
use std::borrow::Cow;

use crate::ir::SignalKind::Input;
use crate::mc::{State, Value, Witness};
use crate::mc::{Value, ValueStore, Witness};
use easy_smt as smt;

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -160,7 +160,7 @@ impl SmtModelChecker {
// collect all inputs
let inputs = sys.get_signals(|s| s.kind == SignalKind::Input);
for k in 0..=k_max {
let mut input_values = State::default();
let mut input_values = ValueStore::default();
for (input_idx, (input, _)) in inputs.iter().enumerate() {
let sym_at = enc.get_at(smt_ctx, *input, k);
let value = get_smt_value(smt_ctx, sym_at)?;
Expand Down
30 changes: 15 additions & 15 deletions src/mc/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use num_traits::{Num, Zero};
#[derive(Debug, Default)]
pub struct Witness {
/// The starting state. Contains an optional value for each state.
pub init: State,
pub init: ValueStore,
/// The inputs over time. Each entry contains an optional value for each input.
pub inputs: Vec<State>,
pub inputs: Vec<ValueStore>,
/// Index of all safety properties (bad state predicates) that are violated by this witness.
pub failed_safety: Vec<u32>,
}
Expand Down Expand Up @@ -47,29 +47,29 @@ fn smt_tpe_to_storage_tpe(tpe: Type) -> StorageType {
}
}

/// Represents concrete values which can be updated, but state cannot be added once created.
/// Represents concrete values which can be updated.
#[derive(Debug)]
pub struct State {
pub struct ValueStore {
meta: Vec<Option<StorageMetaData>>,
longs: Vec<u64>,
bigs: Vec<BigUint>,
// TODO: add array support
//arrays: Vec<ArrayValue>,
}

impl Default for State {
impl Default for ValueStore {
fn default() -> Self {
State {
ValueStore {
meta: Vec::default(),
longs: Vec::default(),
bigs: Vec::default(),
}
}
}

impl State {
impl ValueStore {
pub fn new(types: impl Iterator<Item = Type>) -> Self {
let mut state = State::default();
let mut state = ValueStore::default();
let mut long_count = 0;
let mut big_count = 0;
for tpe in types {
Expand Down Expand Up @@ -165,24 +165,24 @@ impl State {
self.meta.is_empty()
}

pub fn iter(&self) -> StateIter<'_> {
StateIter::new(&self)
pub fn iter(&self) -> ValueStoreIter<'_> {
ValueStoreIter::new(&self)
}
}

pub struct StateIter<'a> {
state: &'a State,
pub struct ValueStoreIter<'a> {
state: &'a ValueStore,
underlying: std::slice::Iter<'a, Option<StorageMetaData>>,
}

impl<'a> StateIter<'a> {
fn new(state: &'a State) -> Self {
impl<'a> ValueStoreIter<'a> {
fn new(state: &'a ValueStore) -> Self {
let underlying = state.meta.iter();
Self { state, underlying }
}
}

impl<'a> Iterator for StateIter<'a> {
impl<'a> Iterator for ValueStoreIter<'a> {
type Item = Option<ValueRef<'a>>;

fn next(&mut self) -> Option<Self::Item> {
Expand Down

0 comments on commit 1f0041f

Please sign in to comment.