2 | import Control.Relation
7 | data IsSuffixOf : (xs, ys : List a) -> Type where
8 | SuffixRefl : xs `IsSuffixOf` xs
9 | ConsSuffix : xs `IsSuffixOf` ys -> xs `IsSuffixOf` (y :: ys)
12 | Reflexive (List a) IsSuffixOf where
13 | reflexive = SuffixRefl
16 | Transitive (List a) IsSuffixOf where
17 | transitive prf1 SuffixRefl = prf1
18 | transitive prf1 (ConsSuffix prf2) = ConsSuffix (transitive prf1 prf2)
21 | Preorder (List a) IsSuffixOf where
30 | appendIsSuffix : (xs, ys : List a) -> ys `IsSuffixOf` xs ++ ys
31 | appendIsSuffix [] ys = SuffixRefl
32 | appendIsSuffix (x :: xs) ys = ConsSuffix (appendIsSuffix xs ys)
35 | suffixLengthLTE : (xs, ys : List a) -> xs `IsSuffixOf` ys -> length xs `LTE` length ys
36 | suffixLengthLTE xs xs SuffixRefl = reflexive
37 | suffixLengthLTE xs (y :: ys) (ConsSuffix x) = lteSuccRight (suffixLengthLTE xs ys x)
45 | record DiffList a where
46 | constructor MkDiffList
47 | append : List a -> List a
48 | 0 isSuffix : (rest : List a) -> rest `IsSuffixOf` append rest
52 | Nil = MkDiffList id (\_ => reflexive)
55 | (::) : a -> DiffList a -> DiffList a
56 | x :: xs = MkDiffList
57 | (\ys => x :: xs.append ys)
58 | (\rest => ConsSuffix (xs.isSuffix rest))
60 | public export %inline
61 | toList : DiffList a -> List a
62 | toList xs = xs.append []
65 | diffAppendIsSuffix :
66 | (xs, ys : DiffList a) ->
68 | rest `IsSuffixOf` xs.append (ys.append rest)
70 | public export %inline
71 | Semigroup (DiffList a) where
72 | xs <+> ys = MkDiffList
73 | (\zs => xs.append (ys.append zs))
75 | let ysPrf = ys.isSuffix _
76 | xsPrf = xs.isSuffix _
77 | in transitive ysPrf xsPrf)
79 | public export %inline
80 | Monoid (DiffList a) where
83 | public export %inline
84 | singleton : a -> DiffList a
85 | singleton x = MkDiffList (\xs => x :: xs) (\rest => ConsSuffix SuffixRefl)
87 | public export %inline
88 | fromList : List a -> DiffList a
89 | fromList xs = MkDiffList (\ys => xs ++ ys) (\rest => appendIsSuffix xs rest)
121 | DiffListEq : (xs, ys : DiffList a) -> Type
122 | DiffListEq xs ys = toList xs === toList ys
127 | (.==) : (xs, ys : DiffList a) -> Type
131 | semigroupAssoc : (xs, ys, zs : DiffList a) -> ((xs <+> ys) <+> zs) .== (xs <+> (ys <+> zs))
132 | semigroupAssoc xs ys zs = Refl
135 | toListFromListId : (xs : List a) -> DiffList.toList (DiffList.fromList xs) === xs
136 | toListFromListId xs = appendNilRightNeutral xs
139 | semigroupNilRightNeutral : (xs : DiffList a) -> (xs <+> Nil) .== xs
140 | semigroupNilRightNeutral xs = Refl
143 | semigroupNilLeftNeutral : (xs : DiffList a) -> (Nil <+> xs) .== xs
144 | semigroupNilLeftNeutral xs = Refl