More specs for Number

This commit is contained in:
Jay Lorch
2026-03-11 17:43:20 -07:00
parent faa3efb8b8
commit 7e1afe0e86
5 changed files with 55 additions and 6 deletions

8
Cargo.lock generated
View File

@@ -1619,9 +1619,9 @@ checksum = "1ee0548b407f2cbfb0228b65cd91e09be63cfd4e883b5a997b3a4e2158febe8f"
[[package]]
name = "verus_builtin_macros"
version = "0.0.0-2026-03-01-0109"
version = "0.0.0-2026-03-08-0103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b7bc3f4a9f628702b5af08de7a3fb4605001a4abf2e8af6c12d04075410846d"
checksum = "5521119b3fd13d0b1748a0fef287a9aeeb247dd702cd7b15f96e5b9eb95f002b"
dependencies = [
"proc-macro2 1.0.106",
"quote 1.0.44",
@@ -1672,9 +1672,9 @@ checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
[[package]]
name = "vstd"
version = "0.0.0-2026-03-01-0109"
version = "0.0.0-2026-03-08-0103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acfd39a5498898d5f9acc93313abfa9938ff4d23006468518cd83e8f6bb063d7"
checksum = "e19bb62988a03cc130a39566b58ece7677ecb26e70a05ca95bf06f7169ca6af5"
dependencies = [
"verus_builtin",
"verus_builtin_macros",

View File

@@ -136,7 +136,7 @@ indexmap = { version = "2.12.1", default-features = false, features = ["serde"],
bincode = { version = "2.0.1", default-features = false, features = ["alloc", "serde"], optional = true }
# Use Verus for verification
vstd = { version = "0.0.0-2026-03-01-0109" }
vstd = { version = "0.0.0-2026-03-08-0103" }
[dev-dependencies]
anyhow = "1.0.45"

View File

@@ -539,8 +539,31 @@ impl FromStr for Number {
}
}
verus! {
#[cfg(verus_keep_ghost)]
impl PartialEqSpecImpl for Number {
open spec fn obeys_eq_spec() -> bool
{
false
}
open spec fn eq_spec(&self, other: &Self) -> bool
{
*self == *other
}
}
impl PartialEq for Number {
fn eq(&self, other: &Self) -> bool {
fn eq(&self, other: &Self) -> (result: bool)
ensures
match (self@, other@) {
(NumberView::Integer(n1), NumberView::Integer(n2)) => result == (n1 == n2),
_ => true,
},
{
proof { axiom_bigint_obeys_eq_spec(); }
if let (Some(a), Some(b)) = (self.to_bigint_owned(), other.to_bigint_owned()) {
return a == b;
}
@@ -554,6 +577,8 @@ impl PartialEq for Number {
}
}
}
impl Eq for Number {}
impl Ord for Number {

View File

@@ -50,6 +50,23 @@ pub assume_specification[ <BigInt as num_traits::Signed>::is_negative ](x: &BigI
res == (x@ < 0),
;
// PartialEq
pub axiom fn axiom_bigint_obeys_eq_spec()
ensures
<BigInt as vstd::std_specs::cmp::PartialEqSpec>::obeys_eq_spec(),
;
pub axiom fn axiom_bigint_obeys_partial_cmp_spec()
ensures
<BigInt as vstd::std_specs::cmp::PartialOrdSpec>::obeys_partial_cmp_spec(),
;
pub assume_specification[ <BigInt as core::cmp::PartialEq>::eq ](x: &BigInt, y: &BigInt) -> (res: bool)
ensures
res == (x@ == y@),
;
// From
pub assume_specification[ <BigInt as core::convert::From<i64>>::from ](i: i64) -> (res: BigInt)

View File

@@ -95,6 +95,13 @@ pub assume_specification [ f64::abs ](f: f64) -> (res: f64)
res == spec_f64_abs(f),
;
pub uninterp spec fn spec_f64_is_nan(f: f64) -> bool;
pub assume_specification [ f64::is_nan ](f: f64) -> (res: bool)
ensures
res == spec_f64_is_nan(f),
;
pub uninterp spec fn spec_f64_neg_infinity() -> f64;
#[inline]