1 | module TypeAligned.Trio
3 | import Control.Relation
4 | import Data.Linear.Notation
6 | import TypeAligned.Duo
10 | %prefix_record_projections off
14 | record Trio (p : Rel a) (w, z : a) where
23 | fst3, head : (three : Trio p w z) -> p w three.x
29 | snd3 : (three : Trio p w z) -> p three.x three.y
34 | thrd, last : (three : Trio p w z) -> p three.y z
40 | tail : (three : Trio p w z) -> Duo p three.x z
41 | tail three = MkDuo { fst = three.snd3, snd = three.thrd }
45 | init : (three : Trio p w z) -> Duo p w three.y
46 | init three = MkDuo { fst = three.fst3, snd = three.snd3 }
48 | parameters {0 p : a -> a -> Type}
52 | ({0 x, y : a} -> p x y -@ p x y -@ Bool) ->
53 | (1 l, r : Trio p w z) -> (0 eqX : l.x = r.x) -> (0 eqY : l.y = r.y) -> Bool
54 | eqMeetOnce eqP (MkTrio fstl sndl thrl) (MkTrio fstr sndr thrr) eqX eqY =
55 | eqP fstl (rewrite eqX in fstr) -&& eqP sndl (rewrite eqX in rewrite eqY in sndr) -&& eqP thrl (rewrite eqY in thrr)
60 | ({0 x, y : a} -> p x y -> p x y -> Bool) -> (l, r : Trio p w z) -> (0 eqX : l.x = r.x) -> (0 eqY : l.y = r.y) -> Bool
61 | eqMeet eqP l r eqX eqY =
62 | eqP l.fst3 (rewrite eqX in r.fst3)
63 | && eqP l.snd3 (rewrite eqX in rewrite eqY in r.snd3)
64 | && eqP l.thrd (rewrite eqY in r.thrd)
68 | {0 p : Rel a} -> ({0 x, y : a} -> Show (p x y)) => Show (Trio p x y) where
69 | show three = "(" ++ show three.fst3 ++ ", " ++ show three.snd3 ++ ", " ++ show three.thrd ++ ")"
71 | parameters {0 p : Rel a}
72 | parameters {0 f : a -> b} {0 q : Rel b}
73 | parameters (pq : {0 x, y : a} -> p x y -@ q (f x) (f y))
76 | mapReduceOnce : ({0 x, y, z : b} -> q x y -@ q y z -@ q x z) -> Trio p x y -@ q (f x) (f y)
77 | mapReduceOnce trans (MkTrio fst3 snd3 thrd) = trans (trans (pq fst3) (pq snd3)) (pq thrd)
81 | mapOnce : Trio p x y -@ Trio q (f x) (f y)
82 | mapOnce (MkTrio fst3 snd3 thrd) = MkTrio { fst3 = pq fst3, snd3 = pq snd3, thrd = pq thrd }
84 | parameters (pq : {0 x, y : a} -> p x y -> q (f x) (f y))
87 | mapReduce : ({0 x, y, z : b} -> q x y -> q y z -> q x z) -> Trio p x y -> q (f x) (f y)
88 | mapReduce trans xy = trans (trans (pq xy.fst3) (pq xy.snd3)) (pq xy.thrd)
92 | map : Trio p x y -> Trio q (f x) (f y)
93 | map xy = MkTrio { fst3 = pq xy.fst3, snd3 = pq xy.snd3, thrd = pq xy.thrd }
97 | reduceOnce : ({0 x, y, z : a} -> p x y -@ p y z -@ p x z) -> Trio p x y -@ p x y
98 | reduceOnce trans (MkTrio fst3 snd3 thrd) = trans (trans fst3 snd3) thrd
102 | reduce : ({0 x, y, z : a} -> p x y -> p y z -> p x z) -> Trio p x y -> p x y
103 | reduce trans xy = trans (trans xy.fst3 xy.snd3) xy.thrd