0 | module Goop.Theroy.BisectableHistory
3 | import Data.Nat.Views
7 | import Goop.Theroy.Types
23 | record Item (a : Type) (output : Type) (item_digest : output) where
25 | {auto 0 impl : Digest output a}
27 | {auto witness : item_digest = digest @{impl} item}
41 | digestEq : {d1, d2 : output} -> d1 = d2
42 | -> (item1 : Item a output d1) -> (item2 : Item a output d2)
44 | digestEq prf item1 item2 = believe_me $
the (1 = 1) Refl
62 | data Set : (output : Type) -> (n : Nat) -> (a : Type) -> Type
68 | data NotInSet : (item : Item a output d)
69 | -> (set : Set output n a)
74 | contains : {auto cmp : (x, y : output) -> Dec (x = y)}
75 | -> Set output n a -> output -> Bool
87 | data Set : (output : Type) -> (n : Nat) -> (a : Type) -> Type where
88 | Nil : Set output 0 a
89 | (::) : {digest_value : output} -> (x : Item a output digest_value)
90 | -> (xs : Set output n a) -> {auto 0 not_in_rest : NotInSet x xs}
91 | -> Set output (S n) a
94 | data NotInSet : (item : Item a output d)
95 | -> (set : Set output n a)
97 | NotInHere : {digest_value : output} -> (x : Item a output digest_value)
98 | -> (xs : Set output n a)
99 | -> {auto cmp : (x, y : output) -> Dec (x = y)}
100 | -> So (Basics.not $
Set.contains xs digest_value)
104 | contains {cmp} [] y = False
105 | contains {cmp} ((::) {digest_value} x xs) y =
106 | case cmp digest_value y of
108 | No _ => contains xs y
114 | namespace SetMonoid
121 | (++) : Digest output a => {m, n : Nat}
122 | -> (lhs : Set output n a) -> (rhs : Set output m a)
123 | -> (n' : Nat ** Set output n' a)
124 | (++) [] rhs = (
_ ** rhs)
125 | (++) @{impl} ((::) {digest_value} x xs) rhs =
126 | let (
n' ** rest)
= xs ++ rhs
127 | _ = outputDecEq @{impl}
128 | in case choose $
contains rest digest_value of
129 | Left _ => (
n' ** rest)
131 | let _ = NotInHere x rest
132 | in (
_ ** x :: rest)
137 | record AnySet (output : Type) (a : Type) where
138 | constructor MkAnySet
140 | inner : Set output inner_n a
144 | Digest output a => Semigroup (AnySet output a) where
146 | let (
_ ** res)
= x.inner ++ y.inner
151 | Semigroup (AnySet output a) => Monoid (AnySet output a) where
152 | neutral = MkAnySet Nil
161 | contents : Set output n a -> LazyList output
163 | contents ((::) {digest_value} x xs) =
164 | digest_value :: contents xs
168 | size : Set output n a -> Nat
170 | size (x :: xs) = S (size xs)
174 | sizeCorrect : (xs : Set output n a) -> size xs = n
175 | sizeCorrect [] = Refl
176 | sizeCorrect (x :: xs) = rewrite sizeCorrect xs in Refl
180 | merkleValue : Digest output a => Set output n a -> output
181 | merkleValue @{impl} x = merkle @{impl} (contents x)
185 | merkleValueEq : Digest output a => (x, y : Set output n a)
186 | -> (merkleValue x = merkleValue y)
188 | merkleValueEq x y prf = believe_me $
the (1 = 1) Refl
209 | data History : (output : Type) -> (merkle_val : output) -> (n : Nat) -> (a : Type) -> Type
213 | contents : History output mv n a -> LazyList (AnySet output a)
217 | set : Digest output a => History output mv n a -> AnySet output a
226 | data Entry : (output : Type) -> (digest_value : output) -> (a : Type) -> Type
230 | set : Digest output a => Entry output dv a -> AnySet output a
239 | data History : (output : Type) -> (merkle_val : output) -> (n : Nat) -> (a : Type) -> Type where
240 | Nil : {auto i : Digest output a} -> History output (merkle @{i} []) 0 a
241 | (::) : {auto i : Digest output a}
242 | -> {digest_x : output} -> (x : Entry output digest_x a)
243 | -> {merkle_xs : output} -> (xs : History output merkle_xs n a)
244 | -> History output (merkle @{i} [digest_x, merkle_xs]) (S n) a
248 | contents (x :: xs) =
249 | set x :: contents xs
253 | foldr (<+>) neutral (contents hs)
257 | merkleValue : (hs : History output mv n a) -> output
258 | merkleValue (Nil {i}) = merkle @{i} []
259 | merkleValue ((::) {i} {digest_x} x {merkle_xs} xs) = merkle @{i} [digest_x, merkle_xs]
263 | merkleValueCorrect : (hs : History output mv n a) -> merkleValue hs = mv
264 | merkleValueCorrect [] = Refl
265 | merkleValueCorrect (x :: xs) = Refl
269 | merkleValueEq : mv1 = mv2
270 | -> (x : History output mv1 n a)
271 | -> (y : History output mv2 n a)
273 | merkleValueEq prf x y = believe_me $
the (1 = 1) Refl
277 | heads : (hs : History output mv n a) -> Vect n output
279 | heads orig@(x :: xs) = merkleValue orig :: heads xs
288 | data Entry : (output : Type) -> (digest_value : output) -> (a : Type) -> Type where
289 | IncludeSet : {auto i : Digest output a}
290 | -> {merkle_value : output} -> {n : Nat} -> (x : Set output n a)
291 | -> {auto witness : merkle_value = merkleValue x}
292 | -> Entry output merkle_value a
293 | IncludeHistory : {merkle_value : _} -> {n : Nat} -> (hs : History output merkle_value n a)
294 | -> Entry output merkle_value a
298 | set (IncludeSet x) = MkAnySet x
299 | set (IncludeHistory hs) = set hs
303 | digestValue : (e : Entry output digest_value a) -> output
304 | digestValue (IncludeSet x) = digest_value
305 | digestValue (IncludeHistory hs) = digest_value
309 | digestValueCorrect : (e : Entry output digest_value a) -> digestValue e = digest_value
310 | digestValueCorrect (IncludeSet x) = Refl
311 | digestValueCorrect (IncludeHistory hs) = Refl
315 | digestValueEq : mv1 = mv2
316 | -> (x : Entry output mv1 a)
317 | -> (y : Entry output mv2 a)
319 | digestValueEq prf x y = believe_me $
the (1 = 1) Refl
332 | data Contains : (mv_target : output) -> (n : Nat) -> (hs : History output mv_head m a)
334 | Here : {auto i : Digest output a}
335 | -> (head : Entry output dv_head a)
336 | -> (0 tail : History output mv_tail m a)
337 | -> Contains (merkleValue (head :: tail)) 0 (head :: tail)
338 | There : {auto i : Digest output a}
339 | -> (0 head : Entry output dv_head a)
340 | -> (0 tail : History output mv_tail m a)
341 | -> (rest : Contains mv_target n tail)
342 | -> Contains mv_target (S n) (head :: tail)
346 | Digest output a => Uninhabited (Contains mv_target n (the (History output _ _ a) [])) where
347 | uninhabited (Here head tail
) impossible
348 | uninhabited (There head tail rest
) impossible
352 | decContains : (mv_target : output) -> (hs : History output mv_head m a)
353 | -> Dec (n : Nat ** Contains mv_target n hs)
354 | decContains mv_target [] = No $
\(_ ** oops) => uninhabited oops
355 | decContains mv_target ((::) @{i} x xs) =
356 | case outputDecEq @{i} mv_target (merkleValue (x :: xs)) of
357 | Yes prf => Yes (
0 ** rewrite prf in Here x xs)
359 | case decContains mv_target xs of
360 | Yes (
n' ** rest)
=>
361 | Yes (
S n' ** There x xs rest)
362 | No not_there => No $
\(
n' ** oops)
=>
364 | (Here x xs) => not_here Refl
365 | (There x xs rest) => not_there (
_ ** rest)
369 | length : Contains mv_target n hs -> Nat
370 | length (Here head tail) = 0
371 | length (There head tail rest) = S (length rest)
375 | lengthCorrect : (c : Contains mv_target n hs) -> length c = n
376 | lengthCorrect (Here head tail) = Refl
377 | lengthCorrect (There head tail rest) = rewrite lengthCorrect rest in Refl
382 | seek : (hs : History output mv_head m a) -> Contains mv_target n hs
383 | -> History output mv_target (m `minus` n) a
384 | seek [] c = absurd c
387 | Here _ _ => x :: xs
388 | There _ _ rest => seek xs rest
392 | dropLast : (hs : History output mv_head m a) -> Contains mv_target (S n) hs
393 | -> (
new_target ** Contains new_target n hs)
394 | dropLast [] x = absurd x
395 | dropLast ((::) {i} x xs) c =
399 | Here head tail => (
_ ** Here {i} x xs)
400 | There head tail y =>
401 | let (
new_target ** rest')
= dropLast xs rest
402 | in (
new_target ** There {i} _ _ rest')
406 | containsHead : (hs : History output mv_head (S m) a) -> Contains mv_head 0 hs
407 | containsHead (x :: xs) = Here x xs
411 | containsNonEmpty : (hs : History output mv_head m a) -> Contains mv_target m' hs -> IsSucc m
412 | containsNonEmpty [] c = absurd c
413 | containsNonEmpty (x :: xs) c = ItIsSucc
430 | record Range (output : Type) (n : Nat) (a : Type) where
431 | constructor MkRange
433 | {mv_start, mv_end : output}
434 | end : History output mv_end m a
435 | contains_start : Contains mv_start n end
444 | maybeRange : {n : _} -> (mv_start, mv_end : output) -> (hs : History output mv_head n a)
445 | -> Maybe (n' : Nat ** Range output n' a)
446 | maybeRange mv_start mv_end hs =
448 | case decContains mv_end hs of
449 | Yes (
n_end ** contains_end)
=>
451 | let hs' = seek hs contains_end
453 | in case decContains mv_start hs' of
454 | Yes (
n_start ** contains_start)
=>
456 | Just (
_ ** MkRange hs' contains_start)
462 | (.start) : (x : Range output n a) -> History output x.mv_start (x.m `minus` n) a
463 | (.start) (MkRange end contains_start) = seek end contains_start
472 | truncate : Range output n a -> Range output 0 a
473 | truncate (MkRange {m} end contains_start) with (containsNonEmpty end contains_start)
474 | truncate (MkRange {m = (S m')} end contains_start) | ItIsSucc =
475 | MkRange end (containsHead end)
480 | dropLast : Range output (S n) a -> Range output n a
481 | dropLast (MkRange end contains_start) =
482 | let (
_ ** contains_start')
= dropLast end contains_start
483 | in MkRange end contains_start'
488 | dropFirst : Range output (S n) a -> Range output n a
489 | dropFirst (MkRange [] contains_start) = absurd contains_start
490 | dropFirst (MkRange (x :: xs) contains_start) =
491 | case contains_start of
492 | There x xs rest => MkRange xs rest
497 | take : {m : _} -> (n : Nat) -> Range output (m + n) a -> Range output n a
498 | take {m = 0} n x = x
499 | take {m = (S k)} n x =
500 | let rest = dropLast x
506 | drop : (n : Nat) -> n `LTE` n' => Range output n' a -> Range output (n' `minus` n) a
507 | drop 0 @{LTEZero} x = rewrite minusZeroRight n' in x
508 | drop (S left) @{(LTESucc y)} x =
509 | let x' = dropFirst x
517 | namespace BisectMulti
520 | record BisectedRange (output : Type) (n : Nat) (a : Type) where
521 | constructor MkBisectedRange
523 | end_half : Range output x a
524 | start_half : Range output y a
525 | {auto witness : x + y = n}
530 | bisect : {n : Nat} -> n `GT` 1 => Range output n a -> BisectedRange output n a
531 | bisect {n} x with (half n)
532 | bisect {n = (S (k + k))} x | (HalfOdd k) =
533 | let end_half = take k {m = S k} x
534 | start_half = drop k @{ltePlusPlus _} x
535 | in rewrite plusSuccRightSucc k k in
536 | MkBisectedRange {x = k} {y = (S k)} end_half $
537 | rewrite sym $
minusPrf k in start_half
539 | ltePlusPlus : (j : Nat) -> LTE j (S (plus j j))
540 | ltePlusPlus 0 = LTEZero
541 | ltePlusPlus (S j) = LTESucc $
543 | rewrite sym $
plusSuccRightSucc j j in
545 | minusPrf : (j : Nat) -> minus (S (plus j j)) j = S j
547 | rewrite plusSuccRightSucc j j in
548 | rewrite minusPlus j {n = (S j)} in
550 | bisect {n = (k + k)} x | (HalfEven k) =
551 | let end_half = take k x
552 | start_half = drop k @{ltePlusPlus _} x
553 | in MkBisectedRange {x = k} {y = k} end_half $
554 | rewrite sym $
minusPlus k {n = k} in start_half
556 | ltePlusPlus : (j : Nat) -> LTE j (plus j j)
557 | ltePlusPlus 0 = LTEZero
558 | ltePlusPlus (S j) = LTESucc $
559 | rewrite sym $
plusSuccRightSucc j j in
560 | lteSuccRight $
ltePlusPlus j
562 | namespace BisectSingle
565 | bisect : Range output 1 a -> (Range output 0 a, Range output 0 a)
566 | bisect x = (take {m = 1} 0 x, drop 1 x)
570 | data BisectResult : (output : Type) -> (n : Nat) -> (a : Type) -> Type where
572 | Multi : n `GT` 1 => BisectedRange output n a -> BisectResult output n a
574 | Single : (x, y : Range output 0 a) -> BisectResult output 1 a
576 | None : Range output 0 a -> BisectResult output 0 a
579 | bisect : {n : _} -> Range output n a -> BisectResult output n a
580 | bisect {n = 0} x = None x
581 | bisect {n = (S 0)} x =
582 | let (x, y) = BisectSingle.bisect x
584 | bisect {n = (S (S k))} x = Multi $
BisectMulti.bisect x