// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub impl[T : Shrink] Shrink for T? with fn shrink(x) {
match x {
None => Iter::empty()
Some(v) =>
Shrink::shrink(v).map(v1 => Some(v1)).concat(Iter::singleton(None))
}
}
///|
pub impl[T : Shrink, E : Shrink] Shrink for Result[T, E] with fn shrink(x) {
match x {
Ok(v) => Shrink::shrink(v).map(v1 => Ok(v1))
Err(e) => Shrink::shrink(e).map(e1 => Err(e1))
}
}
///|
pub impl[X : Shrink] Shrink for Array[X] with fn shrink(xs) {
let view = xs[:]
let n = view.length()
fn shr_sub_terms(arr : ArrayView[X]) {
match arr {
[] => Iter::empty()
[x, .. xs] =>
X::shrink(x)
.map(x_ => [x_, ..xs])
.concat(shr_sub_terms(xs).map(xs_ => [x, ..xs_]))
}
}
[
for k = n; k > 0; k = k / 2 => k
]
.iter()
.flat_map(k => removes_array(k, n, xs))
.concat(shr_sub_terms(view))
}
///|
pub impl[X : Shrink] Shrink for FixedArray[X] with fn shrink(xs) {
Shrink::shrink(xs[:].to_owned()).map(candidate => {
FixedArray::from_array(candidate)
})
}
///|
pub impl[X : Shrink] Shrink for ArrayView[X] with fn shrink(xs) {
let candidates : Iter[Array[X]] = Shrink::shrink(xs.to_owned())
candidates.map(candidate => candidate)
}
///|
pub impl[A : Shrink, B : Shrink] Shrink for (A, B) with fn shrink(x) {
let (a, b) = x
Shrink::shrink(a)
.map(a1 => (a1, b))
.concat(Shrink::shrink(b).map(b1 => (a, b1)))
}
///|
pub impl[A : Shrink, B : Shrink, C : Shrink] Shrink for (A, B, C) with fn shrink(
x,
) {
let (a, b, c) = x
Shrink::shrink((a, (b, c))).map(y => {
let (a1, (b1, c1)) = y
(a1, b1, c1)
})
}
///|
pub impl[A : Shrink, B : Shrink, C : Shrink, D : Shrink] Shrink for (A, B, C, D) with fn shrink(
x,
) {
let (a, b, c, d) = x
Shrink::shrink((a, (b, c, d))).map(y => {
let (a1, (b1, c1, d1)) = y
(a1, b1, c1, d1)
})
}
///|
pub impl[A : Shrink, B : Shrink, C : Shrink, D : Shrink, E : Shrink] Shrink for (
A,
B,
C,
D,
E,
) with fn shrink(x) {
let (a, b, c, d, e) = x
Shrink::shrink((a, (b, c, d, e))).map(y => {
let (a1, (b1, c1, d1, e1)) = y
(a1, b1, c1, d1, e1)
})
}
///|
pub impl[A : Shrink, B : Shrink, C : Shrink, D : Shrink, E : Shrink, F : Shrink] Shrink for (
A,
B,
C,
D,
E,
F,
) with fn shrink(x) {
let (a, b, c, d, e, f) = x
Shrink::shrink((a, (b, c, d, e, f))).map(y => {
let (a1, (b1, c1, d1, e1, f1)) = y
(a1, b1, c1, d1, e1, f1)
})
}
///|
pub impl[
A : Shrink,
B : Shrink,
C : Shrink,
D : Shrink,
E : Shrink,
F : Shrink,
G : Shrink,
] Shrink for (A, B, C, D, E, F, G) with fn shrink(x) {
let (a, b, c, d, e, f, g) = x
Shrink::shrink((a, (b, c, d, e, f, g))).map(y => {
let (a1, (b1, c1, d1, e1, f1, g1)) = y
(a1, b1, c1, d1, e1, f1, g1)
})
}
///|
pub impl[
A : Shrink,
B : Shrink,
C : Shrink,
D : Shrink,
E : Shrink,
F : Shrink,
G : Shrink,
H : Shrink,
] Shrink for (A, B, C, D, E, F, G, H) with fn shrink(x) {
let (a, b, c, d, e, f, g, h) = x
Shrink::shrink((a, (b, c, d, e, f, g, h))).map(y => {
let (a1, (b1, c1, d1, e1, f1, g1, h1)) = y
(a1, b1, c1, d1, e1, f1, g1, h1)
})
}
///|
pub impl[
A : Shrink,
B : Shrink,
C : Shrink,
D : Shrink,
E : Shrink,
F : Shrink,
G : Shrink,
H : Shrink,
I : Shrink,
] Shrink for (A, B, C, D, E, F, G, H, I) with fn shrink(x) {
let (a, b, c, d, e, f, g, h, i) = x
Shrink::shrink((a, (b, c, d, e, f, g, h, i))).map(y => {
let (a1, (b1, c1, d1, e1, f1, g1, h1, i1)) = y
(a1, b1, c1, d1, e1, f1, g1, h1, i1)
})
}