vstd_extra/external/
nonzero.rs1use core::cmp::Ordering;
25use core::ops::BitOr;
26use vstd::prelude::*;
27use vstd::std_specs::cmp::*;
28use vstd::std_specs::ops::BitOrSpecImpl;
29
30verus! {
31
32#[verifier::external_body]
33#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub struct NonZeroUsize {
35 pub inner: core::num::NonZero<usize>,
36}
37
38impl View for NonZeroUsize {
39 type V = usize;
40
41 uninterp spec fn view(&self) -> Self::V;
42}
43
44impl NonZeroUsize {
45 pub uninterp spec fn nonzero_usize_from_usize(n: usize) -> Self;
46
47 pub broadcast axiom fn axiom_nonzero_usize_from_usize_view_eq(n: usize)
48 requires
49 n != 0,
50 ensures
51 (#[trigger] Self::nonzero_usize_from_usize(n)).view() == n,
52 ;
53
54 pub broadcast axiom fn axiom_view_nonzero_usize_from_usize_eq(self)
55 ensures
56 Self::nonzero_usize_from_usize(#[trigger] self.view()) == self,
57 ;
58
59 #[verifier::external_body]
60 pub const fn new(n: usize) -> (ret: Option<Self>)
61 ensures
62 match ret {
63 Some(nz) => nz.view() == n,
64 None => n == 0,
65 },
66 {
67 if let Some(inner) = core::num::NonZeroUsize::new(n) {
68 Some(NonZeroUsize { inner })
69 } else {
70 None
71 }
72 }
73
74 #[verifier::external_body]
75 #[verifier::when_used_as_spec(nonzero_usize_from_usize)]
76 pub const unsafe fn new_unchecked(n: usize) -> (ret: Self)
77 ensures
78 ret.view() == n,
79 ret == Self::nonzero_usize_from_usize(n),
80 {
81 NonZeroUsize { inner: core::num::NonZeroUsize::new_unchecked(n) }
82 }
83
84 #[verifier::external_body]
85 pub const fn get(&self) -> (ret: usize)
86 ensures
87 ret == self.view(),
88 {
89 self.inner.get()
90 }
91
92 broadcast axiom fn lemma_nonzero_neq_zero(self)
93 ensures
94 #[trigger] self.view() != 0,
95 ;
96}
97
98impl Clone for NonZeroUsize {
99 #[verifier::external_body]
100 fn clone(&self) -> (ret: Self)
101 ensures
102 ret.view() == self.view(),
103 {
104 NonZeroUsize { inner: self.inner }
105 }
106}
107
108impl Copy for NonZeroUsize {
109
110}
111
112impl PartialEqSpecImpl for NonZeroUsize {
113 open spec fn obeys_eq_spec() -> bool {
114 true
115 }
116
117 open spec fn eq_spec(&self, other: &Self) -> bool {
118 self.view() == other.view()
119 }
120}
121
122impl PartialOrdSpecImpl for NonZeroUsize {
123 open spec fn obeys_partial_cmp_spec() -> bool {
124 true
125 }
126
127 open spec fn partial_cmp_spec(&self, other: &Self) -> Option<Ordering> {
128 if self.view() < other.view() {
129 Some(Ordering::Less)
130 } else if self.view() > other.view() {
131 Some(Ordering::Greater)
132 } else {
133 Some(Ordering::Equal)
134 }
135 }
136}
137
138impl OrdSpecImpl for NonZeroUsize {
139 open spec fn obeys_cmp_spec() -> bool {
140 true
141 }
142
143 open spec fn cmp_spec(&self, other: &Self) -> Ordering {
144 vstd::std_specs::cmp::PartialOrdSpec::partial_cmp_spec(self, other)->0
145 }
146}
147
148pub broadcast group group_nonzero_axioms {
149 NonZeroUsize::lemma_nonzero_neq_zero,
150 NonZeroUsize::axiom_nonzero_usize_from_usize_view_eq,
151 NonZeroUsize::axiom_view_nonzero_usize_from_usize_eq,
152}
153
154impl BitOrSpecImpl<usize> for NonZeroUsize {
155 open spec fn obeys_bitor_spec() -> bool {
156 true
157 }
158
159 open spec fn bitor_req(self, rhs: usize) -> bool {
160 true
161 }
162
163 open spec fn bitor_spec(self, rhs: usize) -> Self {
164 Self::nonzero_usize_from_usize(self.view() | rhs)
165 }
166}
167
168impl BitOr<usize> for NonZeroUsize {
169 type Output = Self;
170
171 fn bitor(self, rhs: usize) -> (ret: Self::Output)
172 ensures
173 ret.view() == self.view() | rhs,
174 {
175 unsafe { Self::new_unchecked(self.get() | rhs) }
176 }
177}
178
179}