0 | module Core.Name.Scoped
2 | import public Core.Name
4 | import Libraries.Data.List.SizeOf
6 | import public Libraries.Data.List.Thin
15 | Scopeable : (a: Type) -> Type
27 | Scope = Scopeable Name
42 | addInner : Scopeable a -> Scopeable a -> Scopeable a
43 | addInner vars inner = inner ++ vars
47 | bind : Scopeable a -> a -> Scopeable a
48 | bind vars n = n :: vars
52 | single : a -> Scopeable a
58 | Scoped = Scope -> Type
64 | scopeEq : (xs, ys : Scope) -> Maybe (xs = ys)
65 | scopeEq [] [] = Just Refl
66 | scopeEq (x :: xs) (y :: ys)
67 | = do Refl <- nameEq x y
68 | Refl <- scopeEq xs ys
70 | scopeEq _ _ = Nothing
76 | mkFresh : Scope -> Name -> Name
79 | then assert_total $
mkFresh vs (next n)
87 | data CompatibleVars : (xs, ys : List a) -> Type where
88 | Pre : CompatibleVars xs xs
89 | Ext : CompatibleVars xs ys -> CompatibleVars (n :: xs) (m :: ys)
92 | invertExt : CompatibleVars (n :: xs) (m :: ys) -> CompatibleVars xs ys
94 | invertExt (Ext p) = p
97 | extendCompats : (args : List a) ->
98 | CompatibleVars xs ys ->
99 | CompatibleVars (args ++ xs) (args ++ ys)
100 | extendCompats args Pre = Pre
101 | extendCompats args prf = go args prf where
103 | go : (args : List a) ->
104 | CompatibleVars xs ys ->
105 | CompatibleVars (args ++ xs) (args ++ ys)
107 | go (x :: xs) prf = Ext (go xs prf)
110 | decCompatibleVars : (xs, ys : List a) -> Dec (CompatibleVars xs ys)
111 | decCompatibleVars [] [] = Yes Pre
112 | decCompatibleVars [] (x :: xs) = No (\case p impossible)
113 | decCompatibleVars (x :: xs) [] = No (\case p impossible)
114 | decCompatibleVars (x :: xs) (y :: ys) = case decCompatibleVars xs ys of
115 | Yes prf => Yes (Ext prf)
116 | No nprf => No (nprf . invertExt)
119 | areCompatibleVars : (xs, ys : List a) ->
120 | Maybe (CompatibleVars xs ys)
121 | areCompatibleVars [] [] = pure Pre
122 | areCompatibleVars (x :: xs) (y :: ys)
123 | = do compat <- areCompatibleVars xs ys
125 | areCompatibleVars _ _ = Nothing
131 | 0 Weakenable : Scoped -> Type
132 | Weakenable tm = {0 vars, ns : Scope} ->
133 | SizeOf ns -> tm vars -> tm (ns ++ vars)
136 | 0 Strengthenable : Scoped -> Type
137 | Strengthenable tm = {0 vars, ns : Scope} ->
138 | SizeOf ns -> tm (ns ++ vars) -> Maybe (tm vars)
141 | 0 GenWeakenable : Scoped -> Type
142 | GenWeakenable tm = {0 outer, ns, local : Scope} ->
143 | SizeOf local -> SizeOf ns -> tm (local ++ outer) -> tm (local ++ (ns ++ outer))
146 | 0 Thinnable : Scoped -> Type
147 | Thinnable tm = {0 xs, ys : Scope} -> tm xs -> Thin xs ys -> tm ys
150 | 0 Shrinkable : Scoped -> Type
151 | Shrinkable tm = {0 xs, ys : Scope} -> tm xs -> Thin ys xs -> Maybe (tm ys)
154 | 0 Embeddable : Scoped -> Type
155 | Embeddable tm = {0 outer, vars : Scope} -> tm vars -> tm (vars ++ outer)
161 | interface Weaken (0 tm : Scoped) where
162 | constructor MkWeaken
164 | weaken : tm vars -> tm (nm :: vars)
165 | weakenNs : Weakenable tm
167 | weaken = weakenNs (suc zero)
171 | interface GenWeaken (0 tm : Scoped) where
172 | constructor MkGenWeaken
173 | genWeakenNs : GenWeakenable tm
176 | genWeaken : GenWeaken tm =>
177 | SizeOf local -> tm (local ++ outer) -> tm (local ++ n :: outer)
178 | genWeaken l = genWeakenNs l (suc zero)
181 | interface Strengthen (0 tm : Scoped) where
182 | constructor MkStrengthen
184 | strengthenNs : Strengthenable tm
187 | strengthen : Strengthen tm => tm (nm :: vars) -> Maybe (tm vars)
188 | strengthen = strengthenNs (suc zero)
191 | interface FreelyEmbeddable (0 tm : Scoped) where
192 | constructor MkFreelyEmbeddable
194 | embed : Embeddable tm
198 | FunctorFreelyEmbeddable : Functor f => FreelyEmbeddable tm => FreelyEmbeddable (f . tm)
199 | FunctorFreelyEmbeddable = MkFreelyEmbeddable believe_me
202 | ListFreelyEmbeddable : FreelyEmbeddable tm => FreelyEmbeddable (List . tm)
203 | ListFreelyEmbeddable = FunctorFreelyEmbeddable
206 | MaybeFreelyEmbeddable : FreelyEmbeddable tm => FreelyEmbeddable (Maybe . tm)
207 | MaybeFreelyEmbeddable = FunctorFreelyEmbeddable
210 | GenWeakenWeakens : GenWeaken tm => Weaken tm
211 | GenWeakenWeakens = MkWeaken (genWeakenNs zero (suc zero)) (genWeakenNs zero)
214 | FunctorGenWeaken : Functor f => GenWeaken tm => GenWeaken (f . tm)
215 | FunctorGenWeaken = MkGenWeaken (\ l, s => map (genWeakenNs l s))
218 | FunctorWeaken : Functor f => Weaken tm => Weaken (f . tm)
219 | FunctorWeaken = MkWeaken (go (suc zero)) go where
221 | go : Weakenable (f . tm)
222 | go s = map (weakenNs s)
225 | ListWeaken : Weaken tm => Weaken (List . tm)
226 | ListWeaken = FunctorWeaken
229 | MaybeWeaken : Weaken tm => Weaken (Maybe . tm)
230 | MaybeWeaken = FunctorWeaken
233 | interface Weaken tm => IsScoped (0 tm : Scoped) where
235 | compatNs : CompatibleVars xs ys -> tm xs -> tm ys
237 | thin : Thinnable tm
238 | shrink : Shrinkable tm
241 | compat : IsScoped tm => tm (m :: xs) -> tm (n :: xs)
242 | compat = compatNs (Ext Pre)