diff --git a/Cargo.lock b/Cargo.lock index 54bcd9b..d73ba74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index 8ae75d7..eafb14a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/number.rs b/src/number.rs index fc910d3..9047219 100644 --- a/src/number.rs +++ b/src/number.rs @@ -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 { diff --git a/src/verusspec/bigint.rs b/src/verusspec/bigint.rs index 8e419ae..08bc4aa 100644 --- a/src/verusspec/bigint.rs +++ b/src/verusspec/bigint.rs @@ -50,6 +50,23 @@ pub assume_specification[ ::is_negative ](x: &BigI res == (x@ < 0), ; +// PartialEq + +pub axiom fn axiom_bigint_obeys_eq_spec() + ensures + ::obeys_eq_spec(), +; + +pub axiom fn axiom_bigint_obeys_partial_cmp_spec() + ensures + ::obeys_partial_cmp_spec(), +; + +pub assume_specification[ ::eq ](x: &BigInt, y: &BigInt) -> (res: bool) + ensures + res == (x@ == y@), +; + // From pub assume_specification[ >::from ](i: i64) -> (res: BigInt) diff --git a/src/verusspec/float.rs b/src/verusspec/float.rs index 79919a4..db3a171 100644 --- a/src/verusspec/float.rs +++ b/src/verusspec/float.rs @@ -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]