MIR bool
arrays are cumbersome to use in SAW
#2147
Labels
needs design
Technical design work is needed for issue to progress
subsystem: crucible-mir
Issues related to Rust verification with crucible-mir and/or mir-json
type: bug
Issues reporting bugs or unexpected/unwanted behavior
Milestone
Consider the following Rust function, which uses an array of
bool
s:You would expect that SAW would be able to verify
f
against the following specification:Surprisingly, however, it can't:
The reason this happens is rather unfortunate:
mir_fresh_var
does it take the supplied MIR type and convert it into its corresponding Cryptol type. In the case ofmir_fresh_var "a" (mir_array 8 mir_bool)
, the corresponding Cryptol type is[8]Bit
, i.e.,[8]
.mir_verify
, SAW needs to check that the type of the specification (spec
) matches the type of the original Rust function. It does so by (1) converting each Rust argument type in the function's type signature to its corresponding Crucible type, (2) converting each argument type passed tomir_execute_func
to its corresponding Crucible type, and (3) checking if the Crucible types match.MirVectorRepr
(see here), and the Crucible type corresponding tobool
isBoolRepr
(see here). Therefore, the full Crucible type correspoinding to[bool; 8]
isMirVectorRepr BoolRepr
.mir_execute_func [llvm_term a]
, and the type ofa
is[8]
. The Crucible type corresponding to[8]
isBaseBVRepr (knownNat @8)
: see here. (This is the same Crucible type that you'd get foru8
—more on this later.)MirVectorRepr BoolRepr
andBaseBVRepr (knownNat @8)
are not the same, yielding a type error. (The error message complains about[bool; 8]
andu8
, but these are basically just pretty-printed versions of the Crucible types.)The key step here is in picking a Crucible type for
[8]
. This choice is somewhat arbitrary, as we could just as well pickBaseBVRepr (knownNat @8)
orMirVectorRepr BoolRepr
. Picking the former is usually the more sensible option, as it happens to correspond to the same Crucible type that is assigned to types such asu8
(see here), and these integer types are far more common thatbool
arrays. Unfortunately, this choice comes at the expense of making it impossible to write SAW specifications like the one above.A handful of scattered observations:
The reason why we have to make an arbitrary choice in the first place is because Cryptol doesn't distinguish between an 8-bit word type and an 8-bit sequence of
Bit
s: they're both represented by the same type[8]
. In this sense, Cryptol's type system is more coarse-grained than Crucible's type system, which has separate types for these.SAW's LLVM backend does not have an equivalent problem because LLVM's type system does not have a type that is given the Crucible type
BoolRepr
. The closest thing that LLVM has is thei1
type, but this is translated to the Cryptol type[1]
(a 1-bit word), notBit
. As such, the LLVM typesi8
and[8 x i1]
would be represented by entirely different Cryptol types ([8]
and[8][1]
, respectively).A workaround for this issue is to avoiding using
mir_fresh_var
. One way to do this is by creating fresh variables for each individual element of thebool
array rather than creating a single fresh variable for the entire array, which is what themir_fresh_expanded_value
command does. That is, SAW does successfully verify the following spec:Ultimately, I suspect that fixing this issue will require us to make SAW more flexible about how we embed types into Cryptol, as proposed in #1976. This is because the types
u8
and[bool; 8]
have the same representation in Cryptol, but different Crucible representations. Until then, themir_fresh_expanded_value
trick mentioned above is a serviceable workaround.Lastly, one radical idea: could we fix this issue by changing the Crucible representation of
bool
fromBoolRepr
toBaseBVRepr (knownNat @1)
, similarly to how LLVM'si1
type is handled? Perhaps so, but this would require changing a fair bit of code incrucible-mir
to accommodate this, and it's unclear to me whether that is a good idea. In any case, we want to fix #1976 anyway, so it's likely best to pursue a solution there.The text was updated successfully, but these errors were encountered: