3 | import Control.Relation
4 | import Data.Linear.Bifunctor
5 | import Data.Linear.LEither
6 | import public Data.Linear.Notation
8 | import TypeAligned.Sum
9 | import public TypeAligned.ZeroOne
10 | import TypeAligned.TwoThree
13 | %prefix_record_projections off
16 | data TypeAligned : Rel a -> Rel a
21 | record Multiple (p : Rel a) (u : a) (z : a) where
22 | constructor MkMultiple
25 | 1 front : ZeroOne p v w
26 | 1 body : TypeAligned (TwoThree p) w x
27 | 1 back : ZeroOne p x y
32 | data TypeAligned1 : Rel a -> Rel a where
33 | One : {0 p : Rel a} -> p x y -@ TypeAligned1 p x y
34 | Ton : Multiple p x y -@ TypeAligned1 p x y
38 | data TypeAligned : Rel a -> Rel a where
39 | None : (0 eq : x = y) -> TypeAligned p x y
40 | Some : TypeAligned1 p x y -@ TypeAligned p x y
44 | head : (m : Multiple p u z) -> p u m.v
45 | head (MkMultiple h _ _ _ _) = h
48 | front : (m : Multiple p u z) -> ZeroOne p m.v m.w
49 | front (MkMultiple _ f _ _ _) = f
52 | body : (m : Multiple p u z) -> TypeAligned (TwoThree p) m.w m.x
53 | body (MkMultiple _ _ b _ _) = b
56 | back : (m : Multiple p u z) -> ZeroOne p m.x m.y
57 | back (MkMultiple _ _ _ b _) = b
60 | last : (m : Multiple p u z) -> p m.y z
61 | last (MkMultiple _ _ _ _ l) = l
63 | parameters {0 p : Rel a}
67 | 0 (.x) : TypeAligned1 p w z -> a
73 | 0 (.y) : TypeAligned1 p w z -> a
79 | 0 (.x) : TypeAligned p w z -> a
85 | 0 (.y) : TypeAligned p w z -> a
92 | head, (.head) : (ne : TypeAligned1 p w z) -> p w ne.x
94 | head (Ton m) = m.head
99 | last, (.last) : (ne : TypeAligned1 p w z) -> p ne.y z
101 | last (Ton m) = m.last
106 | Nil, Lin : TypeAligned p x x
112 | nonEmptyOnce : TypeAligned p x y -@ ZeroOne (TypeAligned1 p) x y
113 | nonEmptyOnce (None eq) = Zero (irrelevantEq eq)
114 | nonEmptyOnce (Some ne) = One ne
118 | nonEmpty : TypeAligned p x y -> ZeroOne (TypeAligned1 p) x y
119 | nonEmpty xy = nonEmptyOnce xy
122 | heqNonEmpty : (TypeAligned1 p w x -> TypeAligned1 p y z -> Bool) -> TypeAligned p w x -> TypeAligned p y z -> Bool
123 | heqNonEmpty heqNe = hne
125 | hne : TypeAligned p w x -> TypeAligned p y z -> Bool
126 | hne (None _) (None _) = True
127 | hne (None _) _ = False
128 | hne (Some neL) (Some neR) = heqNe neL neR
129 | hne (Some _) _ = False
133 | fromNonEmptyOnce : {0 p : Rel a} -> TypeAligned1 p x y -@ TypeAligned p x y
134 | fromNonEmptyOnce = Some
138 | fromNonEmpty : {0 p : Rel a} -> TypeAligned1 p x y -> TypeAligned p x y
139 | fromNonEmpty ne = fromNonEmptyOnce ne
141 | parameters {0 p : Rel a}
142 | parameters (1 xy : p x y)
146 | singletonce : TypeAligned1 p x y
147 | singletonce = One xy
151 | singletonce : TypeAligned p x y
152 | singletonce = Some singletonce
154 | parameters (xy : p x y)
158 | singleton : TypeAligned1 p x y
159 | singleton = singletonce xy
163 | singleton : TypeAligned p x y
164 | singleton = fromNonEmpty singleton
169 | consOnce : {0 p : Rel a} -> p x y -@ TypeAligned1 p y z -@ TypeAligned1 p x z
172 | parameters {0 p : Rel a}
173 | parameters (1 xy : p x y)
176 | consOnce : Multiple p y z -@ Multiple p x z
177 | consOnce (MkMultiple head (Zero eqvw) body back last) =
178 | MkMultiple { head = xy, front = One (rewrite sym eqvw in head), body = body, back = back, last = last }
179 | consOnce (MkMultiple head (One vw) (None eqwx) (Zero eqxy) last) =
181 | { head = xy, front = One head, body = Nil, back = One (rewrite sym (trans eqwx eqxy) in vw), last = last }
182 | consOnce (MkMultiple head (One vw) (None eqwx) (One bxy) last) =
184 | { head = xy, front = ZeroEq, body = singletonce (twice head (rewrite sym eqwx in vw)), back = One bxy, last = last }
185 | consOnce (MkMultiple head (One vw) (Some ne) back last) =
187 | { head = xy, front = ZeroEq, body = fromNonEmptyOnce (consOnce (twice head vw) ne), back = back, last = last }
191 | cons2Once : TypeAligned1 p y z -@ Multiple p x z
192 | cons2Once (One yz) = MkMultiple { head = xy, front = ZeroEq, body = Nil, back = ZeroEq, last = yz}
193 | cons2Once (Ton yz) = consOnce yz
197 | cons1Once : TypeAligned p y z -@ TypeAligned1 p x z
198 | cons1Once (None Refl) = One xy
199 | cons1Once (Some ne) = consOnce xy ne
203 | consOnce : TypeAligned p y z -@ TypeAligned p x z
204 | consOnce ta = Some (cons1Once ta)
206 | parameters (xy : p x y)
209 | cons, (::) : Multiple p y z -> Multiple p x z
210 | cons yz = consOnce xy yz
215 | cons2 : TypeAligned1 p y z -> Multiple p x z
216 | cons2 yz = cons2Once xy yz
220 | cons, (::) : TypeAligned1 p y z -> TypeAligned1 p x z
221 | cons yz = Ton (cons2 yz)
226 | cons1 : TypeAligned p y z -> TypeAligned1 p x z
227 | cons1 yz = cons1Once xy yz
231 | cons, (::) : TypeAligned p y z -> TypeAligned p x z
232 | cons yz = Some (cons1 yz)
237 | consOnce xy ne = Ton (cons2Once xy ne)
242 | unconsOnce : (1 ne : TypeAligned1 p w z) -> LPair (p w ne.x) (TypeAligned p ne.x z)
247 | unconsOnce : (1 uz : Multiple p u z) -> LPair (p u uz.v) (TypeAligned1 p uz.v z)
248 | unconsOnce (MkMultiple {v} {w} {x} {y} head front body back last) = head # tail front body back last
250 | tail : ZeroOne p v w -@ TypeAligned (TwoThree p) w x -@ ZeroOne p x y -@ p y z -@ TypeAligned1 p v z
251 | tail (Zero eqvw) (None eqwx) (Zero eqxy) last = One (rewrite trans (trans eqvw eqwx) eqxy in last)
252 | tail (Zero eqvw) (None eqwx) (One back) last =
253 | Ton (MkMultiple { head = rewrite trans eqvw eqwx in back, front = ZeroEq, body = Nil, back = ZeroEq, last = last})
254 | tail (Zero eqvw) (Some ne) back last = Ton (rewrite eqvw in body (unconsOnce ne) back last)
256 | body : LPair (TwoThree p w ne.x) (TypeAligned (TwoThree p) ne.x x) -@ ZeroOne p x y -@ p y z -@ Multiple p w z
257 | body (Left (MkDuo fst snd) # bodyTail) back last =
258 | MkMultiple { head = fst, front = One snd, body = bodyTail, back = back, last = last }
259 | body (Right (MkTrio fst3 snd3 thrd) # bodyTail) back last =
260 | MkMultiple { head = fst3, front = ZeroEq, body = consOnce (twice snd3 thrd) bodyTail, back = back, last = last }
261 | tail (One vw) body back last = Ton (MkMultiple { head = vw, front = ZeroEq, body = body, back = back, last = last })
265 | unconsOnce (One uz) = uz # Nil
266 | unconsOnce (Ton m) = mapSnd fromNonEmptyOnce (unconsOnce m)
270 | unconsOnce : (1 ta : TypeAligned p w z) -> LEither (w = z) (LPair (p w ta.x) (TypeAligned p ta.x z))
271 | unconsOnce (None eq) = Left (irrelevantEq eq)
272 | unconsOnce (Some ne) = Right (unconsOnce ne)
276 | uncons : (uz : Multiple p u z) -> (p u uz.v, TypeAligned1 p uz.v z)
277 | uncons uz = uc (unconsOnce uz)
279 | uc : LPair (p u uz.v) (TypeAligned1 p uz.v z) -> (p u uz.v, TypeAligned1 p uz.v z)
280 | uc (head # tail) = (head, tail)
283 | tail : (uz : Multiple p u z) -> TypeAligned1 p uz.v z
284 | tail uz = snd (uncons uz)
289 | uncons : (ne : TypeAligned1 p w z) -> (p w ne.x, TypeAligned p ne.x z)
290 | uncons (One xz) = (xz, Nil)
291 | uncons (Ton xz) = map fromNonEmpty (uncons xz)
295 | tail : (ne : TypeAligned1 p w z) -> TypeAligned p ne.x z
296 | tail ne = snd (uncons ne)
300 | uncons : (ta : TypeAligned p w z) -> Either (w = z) (p w ta.x, TypeAligned p ta.x z)
301 | uncons (None eq) = Left (irrelevantEq eq)
302 | uncons (Some xz) = Right (uncons xz)
306 | head : (ta : TypeAligned p w z) -> Either (w = z) (p w ta.x)
307 | head ta = map fst (uncons ta)
311 | tail : (ta : TypeAligned p w z) -> Either (w = z) (TypeAligned p ta.x z)
312 | tail ta = map snd (uncons ta)
317 | heqCons : ({0 w, x, y, z : a} -> p w x -> p y z -> Bool) -> TypeAligned1 p w x -> TypeAligned1 p y z -> Bool
320 | hc : {0 w, x, y, z : a} -> TypeAligned1 p w x -> TypeAligned1 p y z -> Bool
321 | hc l r = hp (uncons l) (uncons r)
323 | hp : {0 w, x, y, z : a} -> (p w l.x, TypeAligned p l.x x) -> (p y r.x, TypeAligned p r.x z) -> Bool
324 | hp (headL, tailL) (headR, tailR) = heqP headL headR && assert_total (heqNonEmpty hc tailL tailR)
328 | heqCons : ({0 w, x, y, z : a} -> p w x -> p y z -> Bool) -> TypeAligned p w x -> TypeAligned p y z -> Bool
329 | heqCons heqP = heqNonEmpty (heqCons heqP)
334 | snocOnce : TypeAligned1 p x y -@ p y z -@ TypeAligned1 p x z
339 | snocOnce : Multiple p x y -@ p y z -@ Multiple p x z
340 | snocOnce (MkMultiple head front body (Zero eqxy) last) yz =
341 | MkMultiple { head = head, front = front, body = body, back = One (rewrite eqxy in last), last = yz }
342 | snocOnce (MkMultiple head (Zero eqvw) (None eqwx) (One back) last) yz =
343 | MkMultiple { head = head, front = One (rewrite trans eqvw eqwx in back), body = Lin, back = One last, last = yz }
344 | snocOnce (MkMultiple head (One front) (None eqwx) (One back) last) yz =
346 | { head = head, front = One front, body = singletonce (twice (rewrite eqwx in back) last), back = ZeroEq, last = yz }
347 | snocOnce (MkMultiple head front (Some body) (One back) last) yz =
349 | { head = head, front = front, body = fromNonEmptyOnce (snocOnce body (twice back last)), back = ZeroEq, last = yz }
353 | snoc2Once : TypeAligned1 p x y -@ p y z -@ Multiple p x z
354 | snoc2Once (One xy) yz = MkMultiple { head = xy, front = ZeroEq, body = Lin, back = ZeroEq, last = yz }
355 | snoc2Once (Ton m) yz = snocOnce m yz
358 | snocOnce xy yz = Ton (snoc2Once xy yz)
362 | snoc1Once : TypeAligned p x y -@ p y z -@ TypeAligned1 p x z
363 | snoc1Once (None Refl) yz = One yz
364 | snoc1Once (Some xy) yz = snocOnce xy yz
368 | snocOnce : TypeAligned p x y -@ p y z -@ TypeAligned p x z
369 | snocOnce xy yz = Some (snoc1Once xy yz)
373 | snoc, (:<) : Multiple p x y -> p y z -> Multiple p x z
374 | snoc xy yz = snocOnce xy yz
379 | snoc2 : TypeAligned1 p x y -> p y z -> Multiple p x z
380 | snoc2 xy yz = snoc2Once xy yz
384 | snoc, (:<) : TypeAligned1 p x y -> p y z -> TypeAligned1 p x z
385 | snoc xy yz = Ton (snoc2 xy yz)
390 | snoc1 : TypeAligned p x y -> p y z -> TypeAligned1 p x z
391 | snoc1 xy yz = snoc1Once xy yz
395 | snoc, (:<) : TypeAligned p x y -> p y z -> TypeAligned p x z
396 | snoc xy yz = Some (snoc1 xy yz)
402 | unsnocOnce : (1 ne : TypeAligned1 p w z) -> LPair (TypeAligned p w ne.y) (p ne.y z)
407 | unsnocOnce : (1 m : Multiple p u z) -> LPair (TypeAligned1 p u m.y) (p m.y z)
408 | unsnocOnce (MkMultiple {v} {w} {x} {y} head front body back last) = init head front body back # last
410 | init : p u v -@ ZeroOne p v w -@ TypeAligned (TwoThree p) w x -@ ZeroOne p x y -@ TypeAligned1 p u y
411 | init head (Zero eqvw) (None eqwx) (Zero eqxy) = One (rewrite sym (trans eqvw (trans eqwx eqxy)) in head)
412 | init head (One front) (None eqwx) (Zero eqxy) =
414 | (MkMultiple { head = head, front = ZeroEq, body = Lin, back = ZeroEq, last = rewrite sym (trans eqwx eqxy) in front })
415 | init head front (Some ne) (Zero eqxy) = Ton (rewrite sym eqxy in body head front (unsnocOnce ne))
417 | body : p u v -@ ZeroOne p v w -@ LPair (TypeAligned (TwoThree p) w ne.y) (TwoThree p ne.y x) -@ Multiple p u x
418 | body head front (init # Left (MkDuo fst snd)) =
419 | MkMultiple { head = head, front = front, body = init, back = One fst, last = snd }
420 | body head front (init # Right (MkTrio fst3 snd3 thrd)) =
421 | MkMultiple { head = head, front = front, body = snocOnce init (twice fst3 snd3), back = ZeroEq, last = thrd }
422 | init head front body (One back) = Ton (MkMultiple { head = head, front = front, body = body, back = ZeroEq, last = back })
426 | unsnocOnce (One wz) = Lin # wz
427 | unsnocOnce (Ton m) = mapFst fromNonEmptyOnce (unsnocOnce m)
431 | unsnocOnce : (1 ta : TypeAligned p w z) -> LEither (w = z) (LPair (TypeAligned p w ta.y) (p ta.y z))
432 | unsnocOnce (None eq) = Left (irrelevantEq eq)
433 | unsnocOnce (Some ne) = Right (unsnocOnce ne)
437 | unsnoc : (uz : Multiple p u z) -> (TypeAligned1 p u uz.y, p uz.y z)
438 | unsnoc uz = us (unsnocOnce uz)
440 | us : LPair (TypeAligned1 p u uz.y) (p uz.y z) -> (TypeAligned1 p u uz.y, p uz.y z)
441 | us (init # last) = (init, last)
444 | init : (uz : Multiple p u z) -> TypeAligned1 p u uz.y
445 | init uz = fst (unsnoc uz)
450 | unsnoc : (ne : TypeAligned1 p w z) -> (TypeAligned p w ne.y, p ne.y z)
451 | unsnoc (One xz) = (Lin, xz)
452 | unsnoc (Ton xz) = mapFst fromNonEmpty (unsnoc xz)
456 | init : (ne : TypeAligned1 p w z) -> TypeAligned p w ne.y
457 | init ne = fst (unsnoc ne)
461 | unsnoc : (ta : TypeAligned p w z) -> Either (w = z) (TypeAligned p w ta.y, p ta.y z)
462 | unsnoc (None eq) = Left (irrelevantEq eq)
463 | unsnoc (Some xz) = Right (unsnoc xz)
467 | init : (ta : TypeAligned p w z) -> Either (w = z) (TypeAligned p w ta.y)
468 | init ta = map fst (unsnoc ta)
472 | last : (ta : TypeAligned p w z) -> Either (w = z) (p ta.y z)
473 | last ta = map snd (unsnoc ta)
478 | heqSnoc : ({0 w, x, y, z : a} -> p w x -> p y z -> Bool) -> TypeAligned1 p w x -> TypeAligned1 p y z -> Bool
481 | hs : {0 w, x, y, z : a} -> TypeAligned1 p w x -> TypeAligned1 p y z -> Bool
482 | hs l r = hp (unsnoc l) (unsnoc r)
484 | hp : {0 w, x, y, z : a} -> (TypeAligned p w l.y, p l.y x) -> (TypeAligned p y r.y, p r.y z) -> Bool
485 | hp (initL, lastL) (initR, lastR) = assert_total (heqNonEmpty hs initL initR) && heqP lastL lastR
489 | heqSnoc : ({0 w, x, y, z : a} -> p w x -> p y z -> Bool) -> TypeAligned p w x -> TypeAligned p y z -> Bool
490 | heqSnoc heqP = heqNonEmpty (heqSnoc heqP)
494 | appendOnce : TypeAligned p x y -@ TypeAligned p y z -@ TypeAligned p x z
499 | appendOnce : Multiple p x y -@ Multiple p y z -@ Multiple p x z
501 | (MkMultiple {w=lw} {x=lx} {y=ly} lhead lfront lbody lback llast)
502 | (MkMultiple {v} {w=rw} {x=rx} rhead rfront rbody rback rlast)
507 | , body = assert_total (body lbody lback llast rhead rfront rbody)
513 | TypeAligned (TwoThree p) lw lx -@ ZeroOne p lx ly -@ p ly y -@
514 | p y v -@ ZeroOne p v rw -@ TypeAligned (TwoThree p) rw rx -@
515 | TypeAligned (TwoThree p) lw rx
516 | body i (Zero eqlxy) l h (Zero eqrvw) t =
517 | appendOnce i (consOnce (twice (rewrite eqlxy in l) (rewrite sym eqrvw in h)) t)
518 | body i (Zero eqlxy) l h (One rvw) t =
519 | appendOnce i (consOnce (thrice (rewrite eqlxy in l) h rvw) t)
520 | body i (One lxy) l h (Zero eqrvw) t =
521 | appendOnce (snocOnce i (thrice lxy l (rewrite sym eqrvw in h))) t
522 | body i (One lxy) l h (One rvw) t =
523 | appendOnce (snocOnce i (twice lxy l)) (consOnce (twice h rvw) t)
527 | append2Once : TypeAligned1 p x y -@ TypeAligned1 p y z -@ Multiple p x z
528 | append2Once (One l) = cons2Once l
529 | append2Once (Ton l) = prepend l
531 | prepend : Multiple p x y -@ TypeAligned1 p y z -@ Multiple p x z
532 | prepend l (One r) = snocOnce l r
533 | prepend l (Ton r) = appendOnce l r
537 | appendOnce : TypeAligned1 p x y -@ TypeAligned1 p y z -@ TypeAligned1 p x z
538 | appendOnce l r = Ton (append2Once l r)
541 | appendOnce (None Refl) r = r
542 | appendOnce l (None Refl) = l
543 | appendOnce (Some l) (Some r) = Some (appendOnce l r)
547 | append, (++) : Multiple p x y -> Multiple p y z -> Multiple p x z
548 | append xy yz = appendOnce xy yz
553 | append2 : TypeAligned1 p x y -> TypeAligned1 p y z -> Multiple p x z
554 | append2 l r = append2Once l r
558 | append, (++) : TypeAligned1 p x y -> TypeAligned1 p y z -> TypeAligned1 p x z
559 | append l r = Ton (append2 l r)
564 | append, (++) : TypeAligned p x y -> TypeAligned p y z -> TypeAligned p x z
565 | append l r = appendOnce l r
568 | parameters {0 f : a -> b} {0 q : Rel b}
574 | ({0 x, y : a} -> p x y -@ q (f x) (f y)) -> ({0 x, y, z : b} -> q x y -@ q y z -@ q x z) ->
575 | TypeAligned1 p x y -@ q (f x) (f y)
582 | ({0 x, y : a} -> p x y -@ q (f x) (f y)) -> ({0 x, y, z : b} -> q x y -@ q y z -@ q x z) ->
583 | Multiple p u z -@ q (f u) (f z)
584 | mapReduceOnce pq trans (MkMultiple {v} {w} {x} {y} head front body back last) =
585 | trans (left (pq head) front) (middleOut body (right back (pq last)))
587 | middleOut : TypeAligned (TwoThree p) w x -@ q (f x) (f z) -@ q (f w) (f z)
588 | middleOut (None eqwx) qRight = rewrite eqwx in qRight
589 | middleOut (Some wx) qRight = trans (mapReduceOnce (mapReduceOnce {q} pq trans) trans wx) qRight
590 | left : q (f u) (f v) -@ ZeroOne p v w -@ q (f u) (f w)
591 | left qHead (Zero eqvw) = rewrite sym eqvw in qHead
592 | left qHead (One vw) = trans qHead (pq vw)
593 | right : ZeroOne p x y -@ q (f y) (f z) -@ q (f x) (f z)
594 | right (Zero eqxy) qLast = rewrite eqxy in qLast
595 | right (One xy) qLast = trans (pq xy) qLast
599 | mapReduceOnce pq _ (One xy) = pq xy
600 | mapReduceOnce pq trans (Ton xy) = mapReduceOnce pq trans xy
604 | (pq : {0 x, y : a} -> p x y -@ q (f x) (f y))
605 | (trans : {0 x, y, z : b} -> q x y -@ q y z -@ q x z)
608 | mapReduceLOnce : q (f x) (f x) -> TypeAligned p x y -@ q (f x) (f y)
609 | mapReduceLOnce refl (None Refl) = refl
610 | mapReduceLOnce _ (Some ne) = mapReduceOnce pq trans ne
614 | mapReduceROnce : q (f y) (f y) -> TypeAligned p x y -@ q (f x) (f y)
615 | mapReduceROnce refl (None Refl) = refl
616 | mapReduceROnce _ (Some ne) = mapReduceOnce pq trans ne
623 | ({0 x, y : a} -> p x y -> q (f x) (f y)) -> ({0 x, y, z : b} -> q x y -> q y z -> q x z) ->
624 | TypeAligned1 p x y -> q (f x) (f y)
631 | ({0 x, y : a} -> p x y -> q (f x) (f y)) -> ({0 x, y, z : b} -> q x y -> q y z -> q x z) ->
632 | Multiple p u z -> q (f u) (f z)
633 | mapReduce pq trans uz = middleOut uz.body
635 | qHead : q (f u) (f uz.v)
637 | left : ZeroOne p uz.v uz.w -> q (f u) (f uz.w)
638 | left (Zero eqvw) = rewrite sym eqvw in qHead
639 | left (One vw) = trans qHead (pq vw)
640 | qLast : q (f uz.y) (f z)
642 | right : ZeroOne p uz.x uz.y -> q (f uz.x) (f z)
643 | right (Zero eqxy) = rewrite eqxy in qLast
644 | right (One xy) = trans (pq xy) qLast
645 | qLeft : q (f u) (f uz.w)
646 | qLeft = left uz.front
647 | qRight : q (f uz.x) (f z)
648 | qRight = right uz.back
649 | middleOut : TypeAligned (TwoThree p) uz.w uz.x -> q (f u) (f z)
650 | middleOut (None eqwx) = trans qLeft (rewrite eqwx in qRight)
651 | middleOut (Some wx) = trans qLeft (trans (mapReduce (mapReduce {q} pq trans) trans (assert_smaller uz wx)) qRight)
655 | mapReduce pq _ (One xy) = pq xy
656 | mapReduce pq trans (Ton xy) = mapReduce pq trans xy
660 | (pq : {0 x, y : a} -> p x y -> q (f x) (f y))
661 | (trans : {0 x, y, z : b} -> q x y -> q y z -> q x z)
664 | mapReduceL : q (f x) (f x) -> TypeAligned p x y -> q (f x) (f y)
665 | mapReduceL refl (None Refl) = refl
666 | mapReduceL _ (Some ne) = mapReduce pq trans ne
670 | mapReduceR : q (f y) (f y) -> TypeAligned p x y -> q (f x) (f y)
671 | mapReduceR refl (None Refl) = refl
672 | mapReduceR _ (Some ne) = mapReduce pq trans ne
674 | parameters {0 f : a -> b}
678 | {0 p : Rel a} -> {0 q : Rel b} -> ({0 x, y : a} -> p x y -@ q (f x) (f y)) ->
679 | TypeAligned p x y -@ TypeAligned q (f x) (f y)
682 | parameters {0 p : Rel a} {0 q : Rel b} (pq : {0 x, y : a} -> p x y -@ q (f x) (f y))
685 | mapOnce : Multiple p x y -@ Multiple q (f x) (f y)
686 | mapOnce (MkMultiple head front body back last) =
689 | , front = mapOnce pq front
690 | , body = assert_total (mapOnce (mapOnce pq) body)
691 | , back = mapOnce pq back
698 | mapOnce : TypeAligned1 p x y -@ TypeAligned1 q (f x) (f y)
699 | mapOnce (One xy) = One (pq xy)
700 | mapOnce (Ton m) = Ton (mapOnce m)
703 | mapOnce pq (None eq) = None (cong f eq)
704 | mapOnce pq (Some ne) = Some (mapOnce pq ne)
709 | {0 p : Rel a} -> {0 q : Rel b} -> ({0 x, y : a} -> p x y -> q (f x) (f y)) ->
710 | TypeAligned p x y -> TypeAligned q (f x) (f y)
713 | parameters {0 p : Rel a} {0 q : Rel b} (pq : {0 x, y : a} -> p x y -> q (f x) (f y))
716 | map : Multiple p x y -> Multiple q (f x) (f y)
719 | { head = pq xy.head
720 | , front = map pq xy.front
721 | , body = assert_total (map (map pq) xy.body)
722 | , back = map pq xy.back
723 | , last = pq xy.last
729 | map : TypeAligned1 p x y -> TypeAligned1 q (f x) (f y)
730 | map (One xy) = One (pq xy)
731 | map (Ton m) = Ton (map m)
734 | map _ (None eq) = None (cong f eq)
735 | map pq (Some ne) = Some (map pq ne)
737 | parameters {0 p : Rel a} (trans : {0 x, y, z : a} -> p x y -@ p y z -@ p x z)
740 | reduceOnce : Multiple p u z -@ p u z
741 | reduceOnce uz = mapReduceOnce {q=p} id trans uz
746 | reduceOnce : TypeAligned1 p x y -@ p x y
747 | reduceOnce (One xy) = xy
748 | reduceOnce (Ton xy) = reduceOnce xy
752 | reduceLOnce : p x x -> TypeAligned p x y -@ p x y
753 | reduceLOnce refl (None Refl) = refl
754 | reduceLOnce _ (Some ne) = reduceOnce ne
758 | reduceROnce : p y y -> TypeAligned p x y -@ p x y
759 | reduceROnce refl (None Refl) = refl
760 | reduceROnce _ (Some ne) = reduceOnce ne
762 | parameters {0 p : Rel a} (trans : {0 x, y, z : a} -> p x y -> p y z -> p x z)
765 | reduce : Multiple p u z -> p u z
766 | reduce uz = mapReduce {q=p} id trans uz
771 | reduce : TypeAligned1 p x y -> p x y
772 | reduce (One xy) = xy
773 | reduce (Ton xy) = reduce xy
777 | reduceL : p x x -> TypeAligned p x y -> p x y
778 | reduceL refl (None Refl) = refl
779 | reduceL _ (Some ne) = reduce ne
783 | reduceR : p y y -> TypeAligned p x y -> p x y
784 | reduceR refl (None Refl) = refl
785 | reduceR _ (Some ne) = reduce ne
787 | %prefix_record_projections on
788 | record StringRel (x : a) (y : a) where
789 | constructor MkStringRel
790 | 1 unStringRel : String
792 | Show (StringRel x y) where
793 | show sr = show sr.unStringRel
795 | showRel : {0 p : Rel a} -> Show (p x y) => p x y -> StringRel x y
796 | showRel p = MkStringRel (show p)
798 | transCommaSpace : StringRel x y -> StringRel y z -> StringRel x z
799 | transCommaSpace l r = MkStringRel (l.unStringRel ++ ", " ++ r.unStringRel)
803 | {0 p : Rel a} -> ({0 x, y : a} -> Show (p x y)) => Show (TypeAligned1 p x y) where
804 | show ne = "[" ++ unStringRel {x} (mapReduce {q=StringRel} showRel transCommaSpace ne) ++ "]"
808 | {0 p : Rel a} -> ({0 x, y : a} -> Show (p x y)) => Show (TypeAligned p x y) where
809 | show ta = "[" ++ unStringRel {x} (mapReduceR {q=StringRel} showRel transCommaSpace (MkStringRel "") ta) ++ "]"
814 | {0 p : Rel a} -> ({0 x, y : a} -> Show (p x y)) => Show (Multiple p x y) where
816 | "[" ++ show m.head ++ ", "
818 | ++ assert_total (showOpt (nonEmpty m.body))
820 | ++ show m.last ++ "]"
822 | showOpt : {0 p : Rel a} -> {0 x, y : a} -> Show (p x y) => ZeroOne p x y -> String
823 | showOpt (Zero _) = ""
824 | showOpt (One p) = show p ++ ", "
828 | Reflexive a (TypeAligned p) where
829 | reflexive = None Refl
833 | Transitive a (Multiple p) where
834 | transitive = append
838 | Transitive a (TypeAligned1 p) where
839 | transitive = append
843 | Transitive a (TypeAligned p) where
844 | transitive = append
848 | Reflexive a p => Reflexive a (Multiple p) where
849 | reflexive = MkMultiple { head = reflexive, front = ZeroEq, body = None Refl, back = ZeroEq, last = reflexive }
853 | Reflexive a p => Reflexive a (TypeAligned1 p) where
854 | reflexive = One reflexive