Expressing invariant of a an array used to index into another array #900
-
The following invariant (1) seems to correctly allow hax to verify that values of the const LEN: usize = 2;
const FOO_LEN: usize = 3;
const SENTINEL: u8 = 0xff;
#[hax_lib::attributes]
struct Foo {
foo: [u8; FOO_LEN],
// (1) Enforce that all values of `indices` can be used for indexing `foo`
#[refine(hax_lib::forall(|i: usize| hax_lib::implies(
i < indices.len(),
|| indices[i] == SENTINEL || indices[i] as (usize) < FOO_LEN
)))]
indices: [u8; LEN],
}
#[hax_lib::attributes]
impl Foo {
fn new() -> Self {
Self {
foo: [42, 43, 44],
indices: [0, SENTINEL],
}
}
// Invariant (1) required for the following function:
#[requires(i < LEN)]
fn f(&self, i: usize) -> Option<u8> {
if self.indices[i] != SENTINEL {
Some(self.foo[self.indices[i] as usize])
} else {
None
}
}
} Is there a better/shorter/cleaner way of expressing this invariant, maybe without relying on Would there be a simpler way if we didn't have sentinel values in that That same invariant may prove useful in other functions so I think it is best to express that invariant on the struct field rather than on the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi! Indeed, here, the invariant is a bit verbose. hax provides a way of creating newtype-style refinement types: here you want to have a wrapper around You probably wants something like the following: We should document that better however. It is documented in the library here: https://hacspec.org/hax/frontend/hax_lib/attr.refinement_type.html, but we should have a chapter in the book that describes that. Do you think that it's what you need? |
Beta Was this translation helpful? Give feedback.
Hi!
Indeed, here, the invariant is a bit verbose.
Instead of having the invariant on the level of the struct
Foo
, I think that here, putting the invariant on the items of the array would be nicer.hax provides a way of creating newtype-style refinement types: here you want to have a wrapper around
u8
that guarantees the property you need.You probably wants something like the following:
https://hax-playground.cryspen.com/#fstar/latest-main/gist=9a358635fb2712c9484c3f99effdc99a
We should document that better however. It is documented in the library here: https://hacspec.org/hax/frontend/hax_lib/attr.refinement_type.html, but we should have a chapter in the book that describes that.
Do you …