2 | module TypeAligned.Duo
4 | import Control.Relation
5 | import Data.Linear.Notation
10 | %prefix_record_projections off
14 | record Duo (p : Rel a) (x, z : a) where
22 | fst : (two : Duo p x z) -> p x two.y
27 | snd : (two : Duo p x z) -> p two.y z
30 | parameters {0 p : Rel a}
34 | ({0 x, y : a} -> p x y -@ p x y -@ Bool) ->
35 | (1 l, r : Duo p x z) -> (0 eqIndex : l.y = r.y) -> Bool
36 | eqMeetOnce eqP (MkDuo fstl sndl) (MkDuo fstr sndr) eqIndex =
37 | eqP fstl (rewrite eqIndex in fstr) -&& eqP sndl (rewrite eqIndex in sndr)
41 | eqMeet : ({0 x, y : a} -> p x y -> p x y -> Bool) -> (l, r : Duo p x z) -> (0 eqIndex : l.y = r.y) -> Bool
42 | eqMeet eqP l r eqIndex =
43 | eqP l.fst (rewrite eqIndex in r.fst) && eqP l.snd (rewrite eqIndex in r.snd)
47 | {0 p : Rel a} -> ({0 x, y : a} -> Show (p x y)) => Show (Duo p x y) where
48 | show two = "(" ++ show two.fst ++ ", " ++ show two.snd ++ ")"
50 | parameters {0 p : Rel a}
51 | parameters {0 f : a -> b} {0 q : Rel b}
52 | parameters (pq : {0 x, y : a} -> p x y -@ q (f x) (f y))
55 | mapReduceOnce : ({0 x, y, z : b} -> q x y -@ q y z -@ q x z) -> Duo p x y -@ q (f x) (f y)
56 | mapReduceOnce trans (MkDuo fst snd) = trans (pq fst) (pq snd)
60 | mapOnce : Duo p x y -@ Duo q (f x) (f y)
61 | mapOnce (MkDuo fst snd) = MkDuo { fst = pq fst, snd = pq snd }
63 | parameters (pq : {0 x, y : a} -> p x y -> q (f x) (f y))
66 | mapReduce : ({0 x, y, z : b} -> q x y -> q y z -> q x z) -> Duo p x y -> q (f x) (f y)
67 | mapReduce trans two = trans (pq two.fst) (pq two.snd)
71 | map : Duo p x y -> Duo q (f x) (f y)
72 | map xy = MkDuo { fst = pq xy.fst, snd = pq xy.snd }
76 | reduceOnce : ({0 x, y, z : a} -> p x y -@ p y z -@ p x z) -> Duo p x y -@ p x y
77 | reduceOnce trans (MkDuo fst snd) = trans fst snd
81 | reduce : ({0 x, y, z : a} -> p x y -> p y z -> p x z) -> Duo p x y -> p x y
82 | reduce trans xy = trans xy.fst xy.snd