0 | module Language.Reflection.Expr
2 | import public Control.Applicative.Const
4 | import public Data.Bits
5 | import public Data.Cozippable
6 | import public Data.Fin.Set
7 | import public Data.Fin.ToFin
8 | import public Data.List.Ex
9 | import public Data.List.Quantifiers
10 | import public Data.SortedSet
11 | import public Data.These
12 | import public Data.Vect.Dependent
14 | import public Language.Reflection
15 | import public Language.Reflection.Syntax
16 | import Language.Reflection.Syntax.Ops
18 | import public Syntax.IHateParens.List
27 | data IsNamedArg : Arg -> Type where
28 | ItIsNamed : IsNamedArg $
MkArg cnt pii (Just n) ty
31 | isNamedArg : (arg : Arg) -> Dec $
IsNamedArg arg
32 | isNamedArg (MkArg count piInfo (Just x) type) = Yes ItIsNamed
33 | isNamedArg (MkArg count piInfo Nothing type) = No $
\case ItIsNamed
impossible
40 | stname : Maybe Name -> Name
41 | stname = fromMaybe $
UN Underscore
44 | argName : (a : Arg) -> (0 _ : IsNamedArg a) => Name
45 | argName (MkArg _ _ Nothing _) impossible
46 | argName (MkArg _ _ (Just x) _) = x
49 | argName' : Arg -> Name
50 | argName' = stname . (.name)
53 | cleanupNamedHoles : TTImp -> TTImp
54 | cleanupNamedHoles = mapTTImp $
\case
55 | IHole {} => implicitFalse
60 | cleanupArg : Arg -> Arg
61 | cleanupArg = { type $= cleanupNamedHoles, piInfo $= map cleanupNamedHoles }
64 | argNames : (l : List Arg) -> (0 _ : All IsNamedArg l) => List Name
66 | argNames (x :: xs) @{_ :: _} = Expr.argName x :: argNames xs
73 | normaliseAs' : Elaboration m =>
74 | (0 expected : Type) ->
75 | (preProcess : TTImp -> TTImp) ->
76 | {0 resulting : _} -> (0 postProcess : (x : expected) -> resulting x) ->
78 | normaliseAs' expected pre post expr = do
79 | let expr = cleanupNamedHoles expr
80 | expr' <- quote $
post !(check {expected} $
pre expr)
81 | let (args, _) = unPi expr
82 | let (args', ty) = unPi expr'
83 | let args'' = comergeWith (\pre => {name := pre.name}) args args'
84 | pure $
piAll ty args''
86 | public export %inline
87 | normaliseAs : Elaboration m => (0 expected : Type) -> TTImp -> m TTImp
88 | normaliseAs ty = normaliseAs' ty id id
91 | public export %inline
92 | normalise : Elaboration m => TTImp -> m TTImp
93 | normalise = normaliseAs' (
ty ** ty)
(\expr => `((
_ **
~expr)
)) snd
96 | public export %inline
97 | normaliseAsType : Elaboration m => TTImp -> m TTImp
98 | normaliseAsType = normaliseAs Type
107 | | NamedApp Name TTImp
112 | appArg : Arg -> TTImp -> AnyApp
113 | appArg (MkArg {piInfo=ExplicitArg, _}) expr = PosApp expr
114 | appArg (MkArg {piInfo=ImplicitArg, name, _}) expr = NamedApp (stname name) expr
115 | appArg (MkArg {piInfo=DefImplicit _, name, _}) expr = NamedApp (stname name) expr
116 | appArg (MkArg {piInfo=AutoImplicit, _}) expr = AutoApp expr
119 | getExpr : AnyApp -> TTImp
120 | getExpr $
PosApp e = e
121 | getExpr $
NamedApp _ e = e
122 | getExpr $
AutoApp e = e
123 | getExpr $
WithApp e = e
127 | mapExpr : (TTImp -> TTImp) -> AnyApp -> AnyApp
128 | mapExpr f $
PosApp e = PosApp $
f e
129 | mapExpr f $
NamedApp n e = NamedApp n $
f e
130 | mapExpr f $
AutoApp e = AutoApp $
f e
131 | mapExpr f $
WithApp e = WithApp $
f e
134 | unAppAny : TTImp -> (TTImp, List AnyApp)
135 | unAppAny = runTR [] where
136 | runTR : List AnyApp -> TTImp -> (TTImp, List AnyApp)
137 | runTR curr $
IApp _ lhs rhs = runTR (PosApp rhs :: curr) lhs
138 | runTR curr $
INamedApp _ lhs n rhs = runTR (NamedApp n rhs :: curr) lhs
139 | runTR curr $
IAutoApp _ lhs rhs = runTR (AutoApp rhs :: curr) lhs
140 | runTR curr $
IWithApp _ lhs rhs = runTR (WithApp rhs :: curr) lhs
141 | runTR curr lhs = (lhs, curr)
144 | reAppAny1 : TTImp -> AnyApp -> TTImp
145 | reAppAny1 l $
PosApp e = app l e
146 | reAppAny1 l $
NamedApp n e = namedApp l n e
147 | reAppAny1 l $
AutoApp e = autoApp l e
148 | reAppAny1 l $
WithApp e = IWithApp EmptyFC l e
150 | public export %inline
151 | reAppAny : Foldable f => TTImp -> f AnyApp -> TTImp
152 | reAppAny = foldl reAppAny1
160 | liftList : Foldable f => f TTImp -> TTImp
161 | liftList = foldr (\l, r => `(~l ::
~r)) `([]
)
165 | liftList' : Foldable f => f TTImp -> TTImp
166 | liftList' = foldr (\l, r => `(Prelude.(::)
~l ~r)) `(Prelude.Nil
)
172 | applySyn : TTImp -> TTImp -> TTImp
173 | applySyn (ILam _ _ _ Nothing _ lamExpr) _ = lamExpr
174 | applySyn (ILam _ _ _ (Just n) _ lamExpr) rhs = mapTTImp (\case orig@(IVar _ n') => if n == n' then rhs else orig;
e => e) lamExpr
175 | applySyn lhs rhs = lhs `app` rhs
180 | unDPair : TTImp -> (List Arg, TTImp)
181 | unDPair (IApp _ (IApp _ (IVar _ `{Builtin.DPair.DPair
}) typ) (ILam _ cnt piInfo mbname _ lamTy)) =
182 | mapFst (MkArg cnt piInfo mbname typ ::) $
unDPair lamTy
183 | unDPair expr = ([], expr)
186 | unDPairUnAlt : TTImp -> Maybe (List Arg, TTImp)
187 | unDPairUnAlt (IAlternative _ _ alts) = case filter (not . null . Builtin.fst) $
unDPair <$> alts of
190 | unDPairUnAlt x = Just $
unDPair x
193 | buildDPair : (rhs : TTImp) -> List (Name, TTImp) -> TTImp
194 | buildDPair = foldr $
\(name, type), res =>
195 | var `{Builtin.DPair.DPair
} .$ type .$ lam (MkArg MW ExplicitArg (Just name) type) res
205 | unNS : Name -> (List String, Name)
206 | unNS (NS (MkNS revNSs) nm) = mapFst (reverse revNSs ++) $
unNS nm
207 | unNS (DN _ nm) = unNS nm
215 | allNameSuffixes : Name -> List Name
216 | allNameSuffixes nm = do
217 | let (nss, n) = unNS nm
218 | tails nss <&> \case
220 | ns => NS (MkNS $
reverse ns) n
223 | isNamespaced : Name -> Bool
224 | isNamespaced = not . null . fst . unNS
227 | isImplicit : PiInfo c -> Bool
228 | isImplicit ImplicitArg = True
229 | isImplicit (DefImplicit x) = True
230 | isImplicit AutoImplicit = True
231 | isImplicit ExplicitArg = False
238 | isSameTypeAs : Name -> Name -> Elab Bool
239 | isSameTypeAs n m = let eq = (==) `on` fst in [| lookupName n `eq` lookupName m |]
242 | nameConformsTo : (cand, origin : Name) -> Bool
243 | nameConformsTo cand origin = do
244 | let (cns, cn) = simplify cand
245 | let (ons, on) = simplify origin
246 | cn == on && (cns `isPrefixOf` ons)
248 | simplify : Name -> (List String, Name)
249 | simplify (NS (MkNS ns) nm) = mapFst (++ ns) $
simplify nm
250 | simplify (DN _ nm) = simplify nm
251 | simplify x = ([], x)
253 | 0 nct_corr_eq : nameConformsTo `{A.B.c
} `{A.B.c
} = True;
nct_corr_eq = Refl
254 | 0 nct_corr_le : nameConformsTo `{B.c
} `{A.B.c
} = True;
nct_corr_le = Refl
255 | 0 nct_corr_ge : nameConformsTo `{A.B.c
} `{B.c
} = False;
nct_corr_ge = Refl
259 | allVarNames' : TTImp -> SortedSet Name
260 | allVarNames' = runConst . mapATTImp' f where
261 | f : TTImp -> Const (SortedSet Name) TTImp -> Const (SortedSet Name) TTImp
262 | f (IVar _ n) = const $
MkConst $
singleton n
267 | allVarNames : TTImp -> List Name
268 | allVarNames = Prelude.toList . allVarNames'
271 | isVar : TTImp -> Bool
272 | isVar $
IVar {} = True
276 | 0 ArgDeps : Nat -> Type
277 | ArgDeps n = DVect n $
FinSet . Fin.finToNat
280 | argDeps : (args : List Arg) -> ArgDeps args.length
282 | let nameToIndices = SortedMap.fromList $
mapI args $
\i, arg => (argName' arg, Fin.Set.singleton i)
283 | let args = Vect.fromList args <&> \arg => allVarNames arg.type <&> fromMaybe empty . lookup' nameToIndices
284 | flip upmapI args $
\i, deps => flip concatMap deps $
\candidates =>
285 | maybe empty singleton $
last' $
mapMaybe tryToFit $
Fin.Set.toList candidates
288 | dependees : (args : List Arg) -> FinSet args.length
289 | dependees args = do
290 | let nameToIndex = SortedMap.fromList $
mapI args $
\i, arg => (argName' arg, i)
291 | let varsInTypes = concatMap (\arg => allVarNames' arg.type) args
292 | fromList $
mapMaybe (lookup' nameToIndex) $
Prelude.toList varsInTypes
294 | namespace UpToRenaming
298 | compWithSubst : (subst : List $
These Name Name) => (from, to : Maybe Name) -> TTImp -> TTImp -> Bool
299 | compWithSubst (Just n) (Just n') e e' = n == n' && (e == e') @{UpToSubst} || (e == e') @{UpToSubst @{Both n n' :: subst}}
300 | compWithSubst (Just n) Nothing e e' = (e == e') @{UpToSubst @{This n :: subst}}
301 | compWithSubst Nothing (Just n') e e' = (e == e') @{UpToSubst @{That n' :: subst}}
302 | compWithSubst Nothing Nothing e e' = (e == e') @{UpToSubst}
304 | [UpToSubst] (subst : List $
These Name Name) => Eq TTImp where
305 | IVar _ v == IVar _ v' = maybe (v == v') (== Both v v') $
flip find subst $
\ior => fromThis ior == Just v || fromThat ior == Just v'
306 | IPi _ c i n a r == IPi _ c' i' n' a' r' =
307 | c == c' && (assert_total $
i == i') && a == a' && (assert_total $
compWithSubst n n' r r')
308 | ILam _ c i n a r == ILam _ c' i' n' a' r' =
309 | c == c' && (assert_total $
i == i') && a == a' && (assert_total $
compWithSubst n n' r r')
310 | ILet _ _ c n ty val s == ILet _ _ c' n' ty' val' s' =
311 | c == c' && ty == ty' && val == val' && (assert_total $
compWithSubst (Just n) (Just n') s s')
313 | ICase _ os t ty cs == ICase _ os' t' ty' cs' =
314 | t == t' && (assert_total $
os == os') && ty == ty' && (assert_total $
cs == cs')
315 | ILocal _ ds e == ILocal _ ds' e' =
316 | (assert_total $
ds == ds') && e == e'
317 | IUpdate _ fs t == IUpdate _ fs' t' =
318 | (assert_total $
fs == fs') && t == t'
320 | IApp _ f x == IApp _ f' x' = f == f' && x == x'
321 | INamedApp _ f n x == INamedApp _ f' n' x' =
322 | f == f' && n == n' && x == x'
323 | IAutoApp _ f x == IAutoApp _ f' x' = f == f' && x == x'
324 | IWithApp _ f x == IWithApp _ f' x' = f == f' && x == x'
326 | ISearch _ n == ISearch _ n' = n == n'
327 | IAlternative _ t as == IAlternative _ t' as' =
328 | (assert_total $
t == t') && (assert_total $
as == as')
329 | IRewrite _ p q == IRewrite _ p' q' =
332 | IBindHere _ m t == IBindHere _ m' t' =
334 | IBindVar _ s == IBindVar _ s' = s == s'
335 | IAs _ _ u n t == IAs _ _ u' n' t' =
336 | u == u' && n == n' && t == t'
337 | IMustUnify _ r t == IMustUnify _ r' t' =
340 | IDelayed _ r t == IDelayed _ r' t' = r == r' && t == t'
341 | IDelay _ t == IDelay _ t' = t == t'
342 | IForce _ t == IForce _ t' = t == t'
344 | IQuote _ tm == IQuote _ tm' = tm == tm'
345 | IQuoteName _ n == IQuoteName _ n' = n == n'
346 | IQuoteDecl _ ds == IQuoteDecl _ ds' = assert_total $
ds == ds'
347 | IUnquote _ tm == IUnquote _ tm' = tm == tm'
349 | IPrimVal _ c == IPrimVal _ c' = c == c'
350 | IType _ == IType _ = True
351 | IHole _ s == IHole _ s' = True
353 | Implicit _ b == Implicit _ b' = b == b'
354 | IWithUnambigNames _ ns t == IWithUnambigNames _ ns' t' =
355 | map snd ns == map snd ns' && t == t'
360 | [UpToRenaming] Eq TTImp where
361 | x == y = (x == y) @{UpToSubst @{empty}}