Idris2/libs/contrib/Data/Path.idr
2021-03-25 16:01:32 +00:00

48 lines
1.6 KiB
Idris

module Data.Path
%default total
||| Paths in a typed graph as a sequence of edges with source and target nodes matching up domino-style.
||| AKA reflexive-transitive closure.
public export
data Path : (t -> t -> Type) -> t -> t -> Type where
Nil : Path g i i
(::) : {0 i, j, k : t} ->
g i j -> Path g j k -> Path g i k
export
joinPath : Path g i j -> Path g j k -> Path g i k
joinPath [] jk = jk
joinPath (e::ij) jk = e :: joinPath ij jk
export
snocPath : Path g i j -> g j k -> Path g i k
snocPath [] f = [f]
snocPath (e::ij) f = e :: snocPath ij f
export
lengthPath : Path g i j -> Nat
lengthPath [] = Z
lengthPath (_::p) = S $ lengthPath p
export
mapPath : {0 gt : t -> t -> Type} -> {0 gu : u -> u -> Type} -> {0 f : t -> u}
-> ({0 i, j : t} -> gt i j -> gu (f i) (f j))
-> {0 i, j : t} -> Path gt i j -> Path gu (f i) (f j)
mapPath gf [] = []
mapPath gf (e::p) = gf e :: mapPath gf p
export
foldPath : {0 gt : t -> t -> Type} -> {0 gu : u -> u -> Type} -> {0 f : t -> u}
-> ({0 i, j, k : t} -> gt i j -> gu (f j) (f k) -> gu (f i) (f k))
-> {0 i, j, k : t} -> Path gt i j -> gu (f j) (f k) -> gu (f i) (f k)
foldPath gf [] jk = jk
foldPath gf (e::ij) jk = gf e (foldPath {gu} gf ij jk)
export
foldlPath : {0 gt : t -> t -> Type} -> {0 gu : u -> u -> Type} -> {0 f : t -> u}
-> ({0 i, j, k : t} -> gu (f i) (f j) -> gt j k -> gu (f i) (f k))
-> {0 i, j, k : t} -> gu (f i) (f j) -> Path gt j k -> gu (f i) (f k)
foldlPath gf ij [] = ij
foldlPath gf ij (e::jk) = foldlPath {gu} gf (gf ij e) jk