Skip to content

Commit

Permalink
Add bit vec ord ops (#952)
Browse files Browse the repository at this point in the history
* Add bit vec ord ops

* Add tests for each bv ord
  • Loading branch information
vrindisbacher authored Dec 18, 2024
1 parent 249ce4d commit c48996e
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
32 changes: 32 additions & 0 deletions crates/flux-middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,38 @@ pub static THEORY_FUNCS: LazyLock<UnordMap<Symbol, TheoryFunc>> = LazyLock::new(
rty::FuncSort::new(vec![BitVec(bv_param0)], BitVec(bv_param0)),
),
},
TheoryFunc {
name: Symbol::intern("bv_ule"),
fixpoint_name: Symbol::intern("bvule"),
sort: rty::PolyFuncSort::new(
List::singleton(SortParamKind::BvSize),
rty::FuncSort::new(vec![BitVec(bv_param0), BitVec(bv_param0)], Bool),
),
},
TheoryFunc {
name: Symbol::intern("bv_uge"),
fixpoint_name: Symbol::intern("bvuge"),
sort: rty::PolyFuncSort::new(
List::singleton(SortParamKind::BvSize),
rty::FuncSort::new(vec![BitVec(bv_param0), BitVec(bv_param0)], Bool),
),
},
TheoryFunc {
name: Symbol::intern("bv_ugt"),
fixpoint_name: Symbol::intern("bvugt"),
sort: rty::PolyFuncSort::new(
List::singleton(SortParamKind::BvSize),
rty::FuncSort::new(vec![BitVec(bv_param0), BitVec(bv_param0)], Bool),
),
},
TheoryFunc {
name: Symbol::intern("bv_ult"),
fixpoint_name: Symbol::intern("bvugt"),
sort: rty::PolyFuncSort::new(
List::singleton(SortParamKind::BvSize),
rty::FuncSort::new(vec![BitVec(bv_param0), BitVec(bv_param0)], Bool),
),
},
// Set operations
TheoryFunc {
name: Symbol::intern("set_empty"),
Expand Down
89 changes: 89 additions & 0 deletions tests/tests/pos/surface/bv_ord.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#[flux::opaque]
#[flux::refined_by(x: bitvec<32>)]
pub struct BV32(u32);

impl BV32 {
#[flux::trusted]
#[flux::sig(fn (u32[@x]) -> BV32[bv_int_to_bv32(x)])]
pub fn new(x: u32) -> Self {
BV32(x)
}
}

impl PartialEq for BV32 {
#[flux::trusted]
#[flux::sig(fn (&BV32[@val1], &BV32[@val2]) -> bool[val1 == val2])]
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}

#[flux::trusted]
#[flux::sig(fn (&BV32[@val1], &BV32[@val2]) -> bool[val1 != val2])]
fn ne(&self, other: &Self) -> bool {
self.0 != other.0
}
}

impl PartialOrd for BV32 {
#[flux::trusted]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}

#[flux::trusted]
#[flux::sig(fn (&BV32[@x], &BV32[@y]) -> bool[bv_ule(x, y)])]
fn le(&self, other: &Self) -> bool {
self.0 <= other.0
}

#[flux::trusted]
#[flux::sig(fn (&BV32[@x], &BV32[@y]) -> bool[bv_ult(x, y)])]
fn lt(&self, other: &Self) -> bool {
self.0 < other.0
}

#[flux::trusted]
#[flux::sig(fn (&BV32[@x], &BV32[@y]) -> bool[bv_uge(x, y)])]
fn ge(&self, other: &Self) -> bool {
self.0 >= other.0
}

#[flux::trusted]
#[flux::sig(fn (&BV32[@x], &BV32[@y]) -> bool[bv_ugt(x, y)])]
fn gt(&self, other: &Self) -> bool {
self.0 > other.0
}
}

#[flux::sig(fn (BV32[@x]) -> bool[bv_ule(x, x)])]
pub fn trivial_le(x: BV32) -> bool {
x <= x
}

#[flux::sig(fn (BV32[@x]) -> bool[bv_ult(x, x)])]
pub fn trivial_lt(x: BV32) -> bool {
x < x
}

#[flux::sig(fn (BV32[@x]) -> bool[bv_uge(x, x)])]
pub fn trivial_ge(x: BV32) -> bool {
x <= x
}

#[flux::sig(fn (BV32[@x]) -> bool[bv_ugt(x, x)])]
pub fn trivial_gt(x: BV32) -> bool {
x < x
}

#[flux::sig(fn (BV32[@x], BV32[@y]) -> bool[
bv_ule(x, bv_int_to_bv32(10))
&&
bv_uge(y, bv_int_to_bv32(20))
&&
bv_ult(x, bv_int_to_bv32(11))
&&
bv_ugt(y, bv_int_to_bv32(21))
])]
pub fn real_example(x: BV32, y: BV32) -> bool {
x <= BV32::new(10) && y >= BV32::new(20) && x < BV32::new(11) && y > BV32::new(21)
}

0 comments on commit c48996e

Please sign in to comment.