0 | module Data.List.Suffix
2 | import Control.Relation
3 | import public Data.Bool.Rewrite
11 | data Suffix : (strict : Bool) -> (xs,ys : List a) -> Type where
13 | Same : Suffix False xs xs
17 | Uncons : Suffix b (h :: t) cs -> Suffix b2 t cs
19 | %builtin Natural Suffix
22 | Uninhabited (Suffix b (h :: t) []) where
23 | uninhabited Same
impossible
24 | uninhabited (Uncons x) = uninhabited x
27 | Uninhabited (Suffix True xs []) where
28 | uninhabited (Uncons x) = uninhabited x
31 | public export %inline
32 | uncons : Suffix b (h::t) cs -> Suffix True t cs
44 | toNat : Suffix b xs ys -> Nat
46 | toNat (Uncons x) = S $
toNat x
48 | public export %inline
49 | Cast (Suffix b xs ys) Nat where cast = toNat
52 | swapOr : {0 x,y : _} -> Suffix (x || y) xs ys -> Suffix (y || x) xs ys
53 | swapOr = swapOr (\k => Suffix k xs ys)
55 | public export %inline
56 | orSame : {0 x : _} -> Suffix (x || x) xs ys -> Suffix x xs ys
57 | orSame = orSame (\k => Suffix k xs ys)
59 | public export %inline
60 | orTrue : {0 x : _} -> Suffix (x || True) xs ys -> Suffix True xs ys
61 | orTrue = orTrue (\k => Suffix k xs ys)
63 | public export %inline
64 | orFalse : {0 x : _} -> Suffix (x || False) xs ys -> Suffix x xs ys
65 | orFalse = orFalse (\k => Suffix k xs ys)
67 | public export %inline
68 | swapAnd : {0 x,y : _} -> Suffix (x && y) xs ys -> Suffix (y && x) xs ys
69 | swapAnd = swapAnd (\k => Suffix k xs ys)
71 | public export %inline
72 | andSame : {0 x : _} -> Suffix (x && x) xs ys -> Suffix x xs ys
73 | andSame = andSame (\k => Suffix k xs ys)
75 | public export %inline
76 | andTrue : {0 x : _} -> Suffix (x && True) xs ys -> Suffix x xs ys
77 | andTrue = andTrue (\k => Suffix k xs ys)
79 | public export %inline
80 | andFalse : {0 x : _} -> Suffix (x && False) xs ys -> Suffix False xs ys
81 | andFalse = andFalse (\k => Suffix k xs ys)
87 | weaken : Suffix b xs ys -> Suffix False xs ys
89 | weaken (Uncons x) = Uncons x
95 | weakens : Suffix True xs ys -> Suffix b xs ys
96 | weakens (Uncons x) = Uncons x
97 | weakens Same
impossible
100 | unconsBoth : Suffix b (y :: ys) (x :: xs) -> Suffix False ys xs
101 | unconsBoth Same = Same
102 | unconsBoth (Uncons z) = Uncons $
unconsBoth z
105 | unconsRight : Suffix True ys (x :: xs) -> Suffix False ys xs
106 | unconsRight (Uncons x) = unconsBoth x
109 | and1 : Suffix b1 xs ys -> Suffix (b1 && b2) xs ys
111 | and1 (Uncons x) = Uncons x
114 | and2 : Suffix b2 xs ys -> Suffix (b1 && b2) xs ys
115 | and2 s = swapAnd (and1 s)
125 | trans : Suffix b1 xs ys -> Suffix b2 ys cs -> Suffix (b1 || b2) xs cs
127 | trans (Uncons x) t = Uncons $
trans x t
130 | transp : Suffix b1 xs ys -> Suffix b2 ys cs -> Suffix (b1 || b2) xs cs
131 | transp x y = believe_me (toNat x + toNat y)
133 | %transform "suffixTransPlus"
Suffix.trans = Suffix.transp
136 | public export %inline
137 | Reflexive (List a) (Suffix False) where
141 | public export %inline
142 | Transitive (List a) (Suffix False) where
146 | public export %inline
147 | Transitive (List a) (Suffix True) where
155 | data SuffixAcc : (ts : List t) -> Type where
159 | -> ({0 ys : List t} -> {auto p : Suffix True ys ts} -> SuffixAcc ys)
165 | -> ({0 ys : List t} -> (p : Suffix True ys ts) -> SuffixAcc ys)
167 | sa f = SA $
f %search
169 | acc' : (ts : List t) -> Suffix False qs ts -> SuffixAcc qs
170 | acc' [] Same = sa $
\v => absurd v
171 | acc' [] (Uncons x) = absurd x
172 | acc' (x :: xs) tt = sa $
\v => acc' xs (unconsRight $
trans v tt)
175 | suffixAcc : {ts : List t} -> SuffixAcc ts
176 | suffixAcc = acc' ts Same
184 | data Link : (xs,ys : List a) -> Type where
185 | F : {0 ys : _} -> (0 xs : _) -> {auto 0 p : Suffix False xs ys} -> Link xs ys
186 | T : {0 ys : _} -> (0 xs : _) -> {auto 0 p : Suffix True xs ys} -> Link xs ys
189 | any : {b : _} -> Suffix b xs ys -> Link xs ys
190 | any {b = True} _ = T xs
191 | any {b = False} _ = F xs
195 | data Chain : (xs,ys : List a) -> Type where
196 | Nil : {0 xs : List a} -> Chain xs xs
198 | {0 xs,ys,zs : List a}
199 | -> (0 link : Link xs ys)
200 | -> (0 ch : Chain ys zs)
204 | data IsStrict : Chain xs ys -> Type where
205 | Here : IsStrict (T xs @{p} :: ys)
206 | There : IsStrict c -> IsStrict (l :: c)
209 | 0 weak : Chain xs ys -> Suffix False xs ys
211 | weak (F _ @{p} :: ch) = trans p $
weak ch
212 | weak (T _ @{p} :: ch) = weaken $
trans p (weak ch)
215 | 0 strict : (c : Chain xs ys) -> {auto p : IsStrict c} -> Suffix True xs ys
216 | strict (T _ @{q} :: c) @{Here} = trans q $
weak c
217 | strict (T _ @{q} :: c) @{There _} = trans q $
weak c
218 | strict (F _ @{q} :: c) @{There _} = trans q $
strict c
225 | takePrefix : (ys : List t) -> Suffix b xs ys -> List t
226 | takePrefix ys Same = []
227 | takePrefix (y::ys) (Uncons p) = y :: takePrefix ys (unconsBoth p)
228 | takePrefix [] (Uncons p) = absurd p
230 | public export %inline
231 | packPrefix : {cs : List Char} -> Suffix b xs cs -> String
232 | packPrefix = pack . takePrefix cs