summaryrefslogtreecommitdiff
path: root/src/Data/Setoid/List.idr
blob: 76a79cd78411920df8e8cd7e6e07f545b5756a03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
||| Setoid of lists over a setoid and associated definitions
module Data.Setoid.List

import Data.List
import Data.Setoid.Definition

%default total

namespace Relation
  public export
  data (.ListEquality) : (a : Setoid) -> Rel (List $ U a) where
    Nil : a.ListEquality [] []
    (::) : (hdEq : a.equivalence.relation x y) -> (tlEq : a.ListEquality xs ys) ->
          a.ListEquality (x :: xs) (y :: ys)

public export
(.ListEqualityReflexive) : (a : Setoid) -> (xs : List $ U a) -> a.ListEquality xs xs
a.ListEqualityReflexive [] = []
a.ListEqualityReflexive (x :: xs) = a.equivalence.reflexive x :: a.ListEqualityReflexive xs

public export
(.ListEqualitySymmetric) : (a : Setoid) -> (xs,ys : List $ U a) -> (prf : a.ListEquality xs ys) ->
  a.ListEquality ys xs
a.ListEqualitySymmetric [] [] [] = []
a.ListEqualitySymmetric (x :: xs) (y :: ys) (hdEq :: tlEq)
  = a.equivalence.symmetric x y hdEq :: a.ListEqualitySymmetric xs ys tlEq

public export
(.ListEqualityTransitive) : (a : Setoid) -> (xs,ys,zs : List $ U a) ->
  (prf1 : a.ListEquality xs ys) -> (prf2 : a.ListEquality ys zs) ->
  a.ListEquality xs zs
a.ListEqualityTransitive [] [] [] [] [] = []
a.ListEqualityTransitive (x :: xs) (y :: ys) (z :: zs) (hdEq1 :: tlEq1) (hdEq2 :: tlEq2)
  = a.equivalence.transitive x  y  z  hdEq1 hdEq2 ::
    a.ListEqualityTransitive xs ys zs tlEq1 tlEq2

public export
ListSetoid : (a : Setoid) -> Setoid
ListSetoid a = MkSetoid (List $ U a)
  $ MkEquivalence
  { relation   = a.ListEquality
  , reflexive  = a.ListEqualityReflexive
  , symmetric  = a.ListEqualitySymmetric
  , transitive = a.ListEqualityTransitive
  }

public export
ListMapFunctionHomomorphism : (f : a ~> b) ->
  SetoidHomomorphism (ListSetoid a) (ListSetoid b) (map f.H)
ListMapFunctionHomomorphism f [] [] [] = []
ListMapFunctionHomomorphism f (x :: xs) (y :: ys) (hdEq :: tlEq) =
  f.homomorphic x y hdEq :: ListMapFunctionHomomorphism f xs ys tlEq

public export
ListMapHomomorphism : (f : a ~> b) -> (ListSetoid a ~> ListSetoid b)
ListMapHomomorphism f = MkSetoidHomomorphism (map f.H) (ListMapFunctionHomomorphism f)

public export
ListMapIsHomomorphism : SetoidHomomorphism (a ~~> b) (ListSetoid a ~~> ListSetoid b)
  ListMapHomomorphism
ListMapIsHomomorphism f g f_eq_g [] = []
ListMapIsHomomorphism f g f_eq_g (x :: xs) = f_eq_g x :: ListMapIsHomomorphism f g f_eq_g xs

public export
ListMap : {0 a, b : Setoid} -> (a ~~> b) ~> (ListSetoid a ~~> ListSetoid b)
ListMap = MkSetoidHomomorphism
  { H           = ListMapHomomorphism
  , homomorphic = ListMapIsHomomorphism
  }

public export
reverseHomomorphic : {a : Setoid} -> (x, y : List (U a)) ->
  (a.ListEquality x y) -> a.ListEquality (reverse x) (reverse y)
reverseHomomorphic x y prf = roh [] [] x y (a.ListEqualityReflexive _) prf
  where roh  : (ws, xs, ys, zs : List (U a)) -> a.ListEquality ws xs -> a.ListEquality ys zs ->
               a.ListEquality (reverseOnto ws ys) (reverseOnto xs zs)
        roh ws xs   []      []    wx     []       = wx
        roh ws xs (y::ys) (z::zs) wx (yzh :: yzt) = roh (y::ws) (z::xs) ys zs (yzh :: wx) yzt

public export
appendCongruence : {a : Setoid} -> (x1, x2, y1, y2 : List (U a)) ->
  a.ListEquality x1 y1 -> a.ListEquality x2 y2 -> a.ListEquality (x1 ++ x2) (y1 ++ y2)
appendCongruence   []    x2   []    y2    []    p = p
appendCongruence (x::xs) x2 (y::ys) y2 (ph::pt) p = ph :: appendCongruence _ _ _ _ pt p