0 | module Hedgehog.Internal.Shrink
6 | import Hedgehog.Internal.Util
11 | halvesInteger : Integer -> Colist Integer
12 | halvesInteger = iterateBefore0 (`safeDiv` 2)
15 | halves : ToInteger a => a -> Colist a
16 | halves = map fromInteger . halvesInteger . toInteger
19 | towardsInteger : (destination, val : Integer) -> Colist Integer
20 | towardsInteger dest x =
24 | let diff := (x `safeDiv` 2) - (dest `safeDiv` 2)
25 | in dest `consNub` map (x -) (halvesInteger diff)
40 | towards : ToInteger a => (destination, val : a) -> Colist a
44 | (towardsInteger (toInteger dest) (toInteger x))
47 | towardsDouble : Double -> Double -> Colist Double
48 | towardsDouble destination x =
52 | let diff := x - destination
54 | in takeWhile ok . map (x -) $
iterate (/ 2) diff
57 | removes : Nat -> List a -> Colist $
List a
59 | removes (S n) x = run (S n) [] x
62 | run : Nat -> List a -> List a -> Colist $
List a
64 | run 0 xs (y :: ys) =
65 | let rest := run n [y] ys
66 | in (y :: ys) :: map (prepRev xs) rest
68 | run (S k) xs (y :: ys) = run k (y :: xs) ys
74 | splits : (a -> b) -> List a -> List (List a, b, List a)
76 | splits f (x :: xs) = run [] x xs
79 | run : List a -> a -> List a -> List (List a, b, List a)
80 | run xs x [] = [(xs,f x,[])]
81 | run xs x l@(y :: ys) = (xs,f x,l) :: run (x::xs) y ys
93 | list : (minLength : Nat) -> List a -> Colist $
List a
94 | list ml xs = let diff = length xs `minus` ml
95 | in concatMapColist (`removes` xs) (halves diff)
98 | interleave : (minLength : Nat) -> List (Cotree a) -> Cotree (List a)
99 | interleave ml ts = MkCotree (map value ts) $
dropThenShrink (list ml ts)
103 | List (List (Cotree a), Coforest a, List (Cotree a))
104 | -> Coforest (List a)
106 | shrinkOne ((xs,[] ,ys) :: rest) = shrinkOne rest
107 | shrinkOne ((xs,t::ts,ys) :: rest) =
108 | interleave ml (prepRev xs (t::ys)) :: shrinkOne ((xs,ts,ys) :: rest)
110 | dropThenShrink : Colist (List $
Cotree a) -> Coforest (List a)
111 | dropThenShrink [] = shrinkOne (splits (\t => t.forest) ts)
112 | dropThenShrink (x :: xs) = interleave ml x :: dropThenShrink xs
118 | HalvesFrom10 : List Int
119 | HalvesFrom10 = take 10 $
halves 10
121 | halvesFrom10Test : HalvesFrom10 = [10,5,2,1]
122 | halvesFrom10Test = Refl
124 | Towards0_100 : List Int
125 | Towards0_100 = take 10 $
towards 0 100
127 | Towards500_1000 : List Int
128 | Towards500_1000 = take 10 $
towards 500 1000
130 | Towards50_26 : List Int
131 | Towards50_26 = take 10 $
towards (-
50) (-
26)
133 | towards0_100Test : Towards0_100 = [0,50,75,88,94,97,99]
134 | towards0_100Test = Refl
136 | towards500_1000Test : Towards500_1000 = [500,750,875,938,969,985,993,997,999]
137 | towards500_1000Test = Refl
139 | towards50_26Test : Towards50_26 = [-
50,-
38,-
32,-
29,-
27]
140 | towards50_26Test = Refl
142 | TowardsFloat0_100 : List Double
143 | TowardsFloat0_100 = take 7 $
towardsDouble 0.0 100
145 | TowardsFloat1_5 : List Double
146 | TowardsFloat1_5 = take 7 $
towardsDouble 1 0.5
148 | towardsFloat0_100Test : TowardsFloat0_100 = [0.0,50.0,75.0,87.5,93.75,96.875,98.4375]
149 | towardsFloat0_100Test = Refl
151 | towardsFloat1_5Test : TowardsFloat1_5 = [1.0,0.75,0.625,0.5625,0.53125,0.515625,0.5078125]
152 | towardsFloat1_5Test = Refl
154 | Removes2_2 : List $
List Int
155 | Removes2_2 = take 10 $
removes 2 [1,2]
157 | removes2_2Test : Removes2_2 = [[]]
158 | removes2_2Test = Refl
160 | Removes2_3 : List $
List Int
161 | Removes2_3 = take 10 $
removes 2 [1,2,3]
163 | removes2_3Test : Removes2_3 = [[3]]
164 | removes2_3Test = Refl
166 | Removes2_4 : List $
List Int
167 | Removes2_4 = take 10 $
removes 2 [1,2,3,4]
169 | removes2_4Test : Removes2_4 = [[3,4],[1,2]]
170 | removes2_4Test = Refl
172 | Removes2_5 : List $
List Int
173 | Removes2_5 = take 10 $
removes 2 [1,2,3,4,5]
175 | removes2_5Test : Removes2_5 = [[3,4,5],[1,2,5]]
176 | removes2_5Test = Refl
178 | Removes2_6 : List $
List Int
179 | Removes2_6 = take 10 $
removes 2 [1,2,3,4,5,6]
181 | removes2_6Test : Removes2_6 = [[3,4,5,6],[1,2,5,6],[1,2,3,4]]
182 | removes2_6Test = Refl
184 | Removes3_10 : List $
List Int
185 | Removes3_10 = take 10 $
removes 3 [1,2,3,4,5,6,7,8,9,10]
187 | removes3_10Test : Removes3_10 = [[4,5,6,7,8,9,10],[1,2,3,7,8,9,10],[1,2,3,4,5,6,10]]
188 | removes3_10Test = Refl
190 | List3 : List $
List Int
191 | List3 = take 10 $
list 0 [1,2,3]
193 | List4 : List $
List Int
194 | List4 = take 10 $
list 0 [1,2,3,4]
196 | List5 : List $
List Int
197 | List5 = take 10 $
list 2 [1,2,3,4,5]
199 | list3Test : List3 = [[],[2,3],[1,3],[1,2]]
202 | list4Test : List4 = [[],[3,4],[1,2],[2,3,4],[1,3,4],[1,2,4],[1,2,3]]
205 | list5Test : List5 = [[4,5],[2,3,4,5],[1,3,4,5],[1,2,4,5],[1,2,3,5],[1,2,3,4]]