extern crate suppositions;
#[macro_use]
extern crate log;
extern crate env_logger;
use std::cmp::min;
use suppositions::*;
use suppositions::generators::*;
#[derive(Debug, Clone)]
pub enum Op {
FillSmallJug,
FillBigJug,
EmptySmallJug,
EmptyBigJug,
SmallToBig,
BigToSmall,
}
#[derive(Debug, Default, Clone)]
pub struct State {
big: usize,
small: usize,
}
impl State {
fn apply(&mut self, op: &Op) {
match op {
&Op::FillSmallJug => {
self.small = 3;
}
&Op::FillBigJug => self.big = 5,
&Op::EmptySmallJug => self.small = 0,
&Op::EmptyBigJug => self.big = 0,
&Op::SmallToBig => {
let old = self.clone();
self.big = min(old.big + self.small, 5);
self.small -= self.big - old.big
}
&Op::BigToSmall => {
let old = self.clone();
self.small = min(old.big + self.small, 3);
self.big -= self.small - old.small
}
}
}
fn assert_invariants(&self) {
assert!(self.big <= 5);
assert!(self.small <= 3);
}
fn finished(&self) -> bool {
self.big == 4
}
}
fn ops() -> Box<GeneratorObject<Item = Op>> {
let g = one_of(consts(Op::FillSmallJug))
.or(consts(Op::FillBigJug))
.or(consts(Op::EmptySmallJug))
.or(consts(Op::EmptyBigJug))
.or(consts(Op::SmallToBig))
.or(consts(Op::BigToSmall));
Box::new(g)
}
fn main() {
env_logger::init().expect("env_logger::init");
CheckConfig::default()
.num_tests(10000)
.property(vecs(ops()).mean_length(1000))
.check(|xs| {
debug!("Testing: {:?}", xs);
let mut sts = Vec::new();
let mut st = State::default();
for o in xs.iter() {
st.apply(o);
sts.push((o.clone(), st.clone()));
st.assert_invariants();
if st.finished() {
debug!("Success! {:?}", st);
return Err(st);
}
}
debug!("No result");
return Ok(());
});
panic!("No solution found")
}