1616/// The deque representation invariant guarantees these indices are in bounds.
1717/// Keep these private so callers cannot bypass bounds checks.
1818#inline
19- #proof_import ("moonbit_builtin_prelude.FixedArray ")
2019fn [T ] UninitializedArray ::unsafe_get(
2120 self : UninitializedArray [T ],
2221 index : Int ,
2322) -> T = " %fixedarray.unsafe_get "
2423
2524///|
2625#inline
27- #proof_import ("moonbit_builtin_prelude.FixedArray ")
2826fn [T ] UninitializedArray ::unsafe_set(
2927 self : UninitializedArray [T ],
3028 index : Int ,
@@ -40,11 +38,12 @@ fn wrap_index(
4038 offset : Int ,
4139 capacity : Int ,
4240) -> Int where {
43- proof_require: wrap_index_pre(head, offset, capacity),
41+ proof_require: buffer_index_in_bounds(head, capacity),
42+ proof_require: valid_wrap_offset(offset, capacity),
4443 proof_ensure: result => wrap_index_post(head, offset, capacity, result),
45- proof_ensure: result => wrap_index_mod_equiv(head, offset, capacity, result),
4644} {
47- proof_assert single_wrap_range(head, offset, capacity)
45+ proof_assert head + offset >= 0
46+ proof_assert head + offset < capacity * 2
4847 let contiguous = capacity - head
4948 if offset < contiguous {
5049 proof_assert (head + offset) % capacity == head + offset
@@ -62,22 +61,23 @@ fn decrement_index(
6261 index : Int ,
6362 capacity : Int ,
6463) -> Int where {
65- proof_require: decrement_index_pre (index, capacity),
64+ proof_require: buffer_index_in_bounds (index, capacity),
6665 proof_ensure: result => decrement_index_post(index, capacity, result),
67- proof_ensure: result => decrement_index_mod_equiv(index, capacity, result),
6866} {
6967 if index == 0 {
68+ proof_assert buffer_index_in_bounds(capacity - 1, capacity)
7069 proof_assert (index + capacity - 1) % capacity == capacity - 1
7170 capacity - 1
7271 } else {
72+ proof_assert buffer_index_in_bounds(index - 1, capacity)
7373 proof_assert (index + capacity - 1) % capacity == index - 1
7474 index - 1
7575 }
7676}
7777
7878///|
7979/// Computes the capacity used by `realloc` after its runtime overflow check.
80- /// The contract proves the index invariant restored after a successful growth.
80+ /// The contract proves the layout invariant restored after a successful growth.
8181#warnings ("-unused_value")
8282#inline
8383fn deque_realloc_capacity(
@@ -101,10 +101,9 @@ fn deque_tail_index(
101101 len : Int ,
102102 capacity : Int ,
103103) -> Int where {
104- proof_require: deque_index_inv (capacity, head, len),
104+ proof_require: deque_layout_inv (capacity, head, len),
105105 proof_require: len > 0,
106106 proof_ensure: result => wrap_index_post(head, len - 1, capacity, result),
107- proof_ensure: result => buffer_index_in_bounds(result, capacity),
108107} {
109108 wrap_index(head, len - 1, capacity)
110109}
@@ -118,11 +117,10 @@ fn deque_element_index(
118117 capacity : Int ,
119118 index : Int ,
120119) -> Int where {
121- proof_require: deque_index_inv (capacity, head, len),
120+ proof_require: deque_layout_inv (capacity, head, len),
122121 proof_require: index >= 0,
123122 proof_require: index < len,
124123 proof_ensure: result => wrap_index_post(head, index, capacity, result),
125- proof_ensure: result => buffer_index_in_bounds(result, capacity),
126124} {
127125 wrap_index(head, index, capacity)
128126}
@@ -134,9 +132,11 @@ fn deque_push_back_core(
134132 len : Int ,
135133 capacity : Int ,
136134) -> Int where {
137- proof_require: deque_index_inv (capacity, head, len),
135+ proof_require: deque_layout_inv (capacity, head, len),
138136 proof_require: len < capacity,
139- proof_ensure: result => deque_push_back_post(capacity, head, len, result),
137+ proof_ensure: result => {
138+ deque_push_back_index_post(capacity, head, len, result)
139+ },
140140} {
141141 wrap_index(head, len, capacity)
142142}
@@ -149,9 +149,11 @@ fn deque_push_front_core(
149149 len : Int ,
150150 capacity : Int ,
151151) -> Int where {
152- proof_require: deque_index_inv (capacity, head, len),
152+ proof_require: deque_layout_inv (capacity, head, len),
153153 proof_require: len < capacity,
154- proof_ensure: result => deque_push_front_post(capacity, head, len, result),
154+ proof_ensure: result => {
155+ deque_push_front_index_post(capacity, head, len, result)
156+ },
155157} {
156158 decrement_index(head, capacity)
157159}
@@ -164,9 +166,11 @@ fn deque_pop_front_core(
164166 len : Int ,
165167 capacity : Int ,
166168) -> Int where {
167- proof_require: deque_index_inv (capacity, head, len),
169+ proof_require: deque_layout_inv (capacity, head, len),
168170 proof_require: len > 0,
169- proof_ensure: result => deque_pop_front_post(capacity, head, len, result),
171+ proof_ensure: result => {
172+ deque_pop_front_index_post(capacity, head, len, result)
173+ },
170174} {
171175 wrap_index(head, 1, capacity)
172176}
@@ -178,9 +182,9 @@ fn deque_pop_back_core(
178182 len : Int ,
179183 capacity : Int ,
180184) -> Int where {
181- proof_require: deque_index_inv (capacity, head, len),
185+ proof_require: deque_layout_inv (capacity, head, len),
182186 proof_require: len > 0,
183- proof_ensure: result => deque_pop_back_post (capacity, head, len, result),
187+ proof_ensure: result => deque_pop_back_index_post (capacity, head, len, result),
184188} {
185189 wrap_index(head, len - 1, capacity)
186190}
0 commit comments