Tensor closure
export infixr 1 ⇒
data IsNothing : Maybe a -> Type where
N : IsNothing Nothing
Uninhabited (IsNothing (Just x)) where
uninhabited _ impossible
(⇒) : Container -> Container -> Container
(⇒) a b = (m : Maybe • a =%> b) !> Σ (i : a.request) | Σ (j : b.response(m.fwd i)) | IsNothing (m.bwd i j)
getRight : a + b -> Maybe b
getRight (<+ x) = Nothing
getRight (+> x) = Just x
left : (p : a + b) -> (contra : IsNothing (getRight p)) => a
left (<+ x) = x
left (+> x) = absurd contra
curryFwd : a * b =%> c -> a =%> (b ⇒ c)
curryFwd m = (\xa => curry m.fwd xa <! (\yb, ya => getRight (m.bwd (xa && yb) ya))) <!
(\xa, pp => left (m.bwd (xa && pp.π1) pp.π2.π1) @{pp.π2.π2})
distribM : (f : Type -> Type) -> Functor f => f • (a * b) =%> (f • a) * (f • b)
distribM f = id <! (\x => distribF)
%unbound_implicits off
backward : {0 a, b, c : Container} ->
(m : Maybe • (a * b) =%> c) ->
(xa : a .request) ->
(b ⇒ c).response (curry m.fwd xa <! (\yb, ya => (m.bwd (xa && yb) ya) >>= getRight))->
Maybe (a .response xa)
backward (fw <! bw) xa (p1 ## p2 ## p3) with (bw (xa && p1) p2)
backward (fw <! bw) xa (p1 ## p2 ## p3) | Nothing = Nothing
backward (fw <! bw) xa (p1 ## p2 ## p3) | (Just (<+ x)) = Just x
backward (fw <! bw) xa (p1 ## p2 ## p3) | (Just (+> x)) = absurd p3
%unbound_implicits on
curryF : Maybe • (a * b) =%> c ->
Maybe • a =%> b ⇒ c
curryF m = (\xa => curry m.fwd xa <! (\yb, ya => (m.bwd (xa && yb) ya) >>= getRight)) <!
backward m
curry : ((a * b) ⇒ c) =%> (a ⇒ (b ⇒ c))
curry = curryF <! curryBwd
where
curryBwd :
(m : ((a * b) ⇒ c).request) ->
let
asd : Maybe • a =%> b ⇒ c
asd = curryF m
in (a ⇒ b ⇒ c) .response asd ->
((a * b) ⇒ c) .response m
curryBwd (fw <! bw) (p1 ## (p2 ## p3 ## p4) ## p5) with (bw (p1 && p2) p3) proof p
_ | Nothing = (p1 && p2) ## p3 ## (rewrite p in N)
_ | Just (+> x) = (p1 && p2) ## p3 ## absurd p4
_ | Just (<+ x) = (p1 && p2) ## p3 ## absurd p5