0 | module TTImp.Impossible
6 | import TTImp.TTImp.Functor
7 | import TTImp.Elab.App
10 | import Idris.Resugar
22 | match : {auto c : Ref Ctxt Defs} ->
23 | ClosedNF -> (Name, Int, ClosedTerm) -> Core Bool
24 | match nty (n, i, rty)
25 | = do defs <- get Ctxt
26 | rtynf <- nf defs Env.empty rty
29 | sameRet : ClosedNF -> ClosedNF -> Core Bool
30 | sameRet _ (NApp {}) = pure True
31 | sameRet _ (NErased {}) = pure True
32 | sameRet (NApp {}) _ = pure True
33 | sameRet (NErased {}) _ = pure True
34 | sameRet (NTCon _ n _ _) (NTCon _ n' _ _) = pure (n == n')
35 | sameRet (NPrimVal _ c) (NPrimVal _ c') = pure (c == c')
36 | sameRet (NType {}) (NType {}) = pure True
37 | sameRet nf (NBind fc _ (Pi {}) sc)
38 | = do defs <- get Ctxt
39 | sc' <- sc defs (toClosure defaultOpts Env.empty (Erased fc Placeholder))
41 | sameRet _ _ = pure False
43 | dropNoMatch : {auto c : Ref Ctxt Defs} ->
44 | Maybe ClosedNF -> List (Name, Int, GlobalDef) ->
45 | Core (List (Name, Int, GlobalDef))
46 | dropNoMatch Nothing ts = pure ts
47 | dropNoMatch (Just nty) ts
49 | filterM (match nty . map (map type)) ts
51 | nextVar : {auto q : Ref QVar Int} ->
52 | FC -> Core ClosedTerm
56 | pure (Ref fc Bound (MN "imp" i))
58 | badClause : {auto c : Ref Ctxt Defs} ->
60 | List (WithFC RawImp) ->
61 | List (WithFC RawImp) ->
62 | List (Name, WithFC RawImp) ->
64 | badClause fn exps autos named
65 | = throw (GenericMsg (getLoc fn)
66 | ("Badly formed impossible clause "
67 | ++ show (!(toFullNames fn),
70 | mapSnd (.val) <$> named)))
73 | processArgs : {auto c : Ref Ctxt Defs} ->
74 | {auto s : Ref Syn SyntaxInfo} ->
75 | {auto q : Ref QVar Int} ->
77 | ClosedTerm -> ClosedNF ->
78 | (expargs : List (WithFC RawImp)) ->
79 | (autoargs : List (WithFC RawImp)) ->
80 | (namedargs : List (Name, WithFC RawImp)) ->
83 | processArgs con fn (NBind _ x (Pi _ _ Explicit ty) sc) (e :: exps) autos named
84 | = do e' <- mkTerm e.val (Just ty)
86 | processArgs con (App e.fc fn e')
87 | !(sc defs (toClosure defaultOpts Env.empty e'))
89 | processArgs con fn (NBind _ x (Pi _ _ Explicit ty) sc) [] autos named
90 | = do defs <- get Ctxt
91 | case findNamed x named of
92 | Just ((_, e), named') =>
93 | do e' <- mkTerm e.val (Just ty)
94 | processArgs con (App e.fc fn e')
95 | !(sc defs (toClosure defaultOpts Env.empty e'))
99 | | True => throw $
GenericMsg (getLoc fn) $
100 | "Cannot match on a partially applied constructor: "
101 | ++ show !(toFullNames fn)
102 | let True = null autos && null named
103 | | False => badClause fn [] autos named
105 | processArgs con fn (NBind _ x (Pi _ _ Implicit ty) sc) exps autos named
106 | = do defs <- get Ctxt
107 | case findNamed x named of
108 | Nothing => do let fc = getLoc fn
110 | processArgs con (App fc fn e')
111 | !(sc defs (toClosure defaultOpts Env.empty e'))
113 | Just ((_, e), named') =>
114 | do e' <- mkTerm e.val (Just ty)
115 | processArgs con (App e.fc fn e')
116 | !(sc defs (toClosure defaultOpts Env.empty e'))
118 | processArgs con fn (NBind _ x (Pi _ _ AutoImplicit ty) sc) exps autos named
119 | = do defs <- get Ctxt
122 | do e' <- mkTerm e.val (Just ty)
123 | processArgs con (App e.fc fn e')
124 | !(sc defs (toClosure defaultOpts Env.empty e'))
127 | case findNamed x named of
129 | do let fc = getLoc fn
131 | processArgs con (App fc fn e')
132 | !(sc defs (toClosure defaultOpts Env.empty e'))
134 | Just ((_, e), named') =>
135 | do e' <- mkTerm e.val (Just ty)
136 | processArgs con (App e.fc fn e')
137 | !(sc defs (toClosure defaultOpts Env.empty e'))
139 | processArgs _ fn _ [] [] [] = pure fn
140 | processArgs _ fn _ (x :: _) autos named
141 | = throw $
GenericMsg x.fc "Too many arguments"
142 | processArgs _ fn _ exps autos named
143 | = badClause fn exps autos named
145 | buildApp : {auto c : Ref Ctxt Defs} ->
146 | {auto s : Ref Syn SyntaxInfo} ->
147 | {auto q : Ref QVar Int} ->
148 | FC -> Name -> Maybe ClosedClosure ->
149 | (expargs : List (WithFC RawImp)) ->
150 | (autoargs : List (WithFC RawImp)) ->
151 | (namedargs : List (Name, WithFC RawImp)) ->
153 | buildApp fc n mty exps autos named
154 | = do defs <- get Ctxt
155 | prims <- getPrimitiveNames
156 | when (n `elem` prims) $
157 | throw (GenericMsg fc "Can't deal with \{show n} in impossible clauses yet")
159 | gdefs <- lookupNameBy id n (gamma defs)
160 | mty' <- traverseOpt (evalClosure defs) mty
161 | [(n', i, gdef)] <- dropNoMatch mty' gdefs
162 | | [] => if length gdefs == 0
163 | then undefinedName fc n
164 | else throw $
GenericMsg fc "\{show n} does not match expected type"
165 | | ts => throw $
AmbiguousName fc (map fst ts)
166 | tynf <- nf defs Env.empty (type gdef)
173 | let nameType = getDefNameType gdef
174 | processArgs (isJust $
isCon nameType)
175 | (Ref fc nameType (Resolved i))
176 | tynf exps autos named
178 | mkTerm : {auto c : Ref Ctxt Defs} ->
179 | {auto s : Ref Syn SyntaxInfo} ->
180 | {auto q : Ref QVar Int} ->
181 | RawImp -> Maybe ClosedClosure ->
183 | mkTerm tm mty = go tm [] [] []
186 | (expargs : List (WithFC RawImp)) ->
187 | (autoargs : List (WithFC RawImp)) ->
188 | (namedargs : List (Name, WithFC RawImp)) ->
190 | go (IVar fc n) exps autos named
191 | = buildApp fc n mty exps autos named
192 | go (IAs fc fc' u n pat) exps autos named
193 | = go pat exps autos named
194 | go (IApp fc fn arg) exps autos named
195 | = go fn (MkFCVal fc arg :: exps) autos named
196 | go (IWithApp fc fn arg) exps autos named
197 | = go fn (MkFCVal fc arg :: exps) autos named
198 | go (IAutoApp fc fn arg) exps autos named
199 | = go fn exps (MkFCVal fc arg :: autos) named
200 | go (INamedApp fc fn nm arg) exps autos named
201 | = go fn exps autos ((nm, MkFCVal fc arg) :: named)
202 | go (IMustUnify fc r tm) exps autos named
203 | = Erased fc . Dotted <$> go tm exps autos named
204 | go (IPrimVal fc c) _ _ _
205 | = do let tm = PrimVal fc c
206 | True <- isValidPrimType
207 | | _ => throw $
GenericMsg fc "\{show tm} does not match expected type"
210 | isValidPrimType : Core Bool
212 | = do defs <- get Ctxt
213 | Just ty <- traverseOpt (evalClosure defs) mty
215 | case (primType c, ty) of
216 | (Nothing, NType {}) => pure True
217 | (Just t1, NPrimVal _ (PrT t2)) => pure (t1 == t2)
219 | go (IType fc) _ _ _
220 | = do defs <- get Ctxt
221 | Just (NType {}) <- traverseOpt (evalClosure defs) mty
222 | | _ => throw $
GenericMsg fc "Type does not match expected type"
223 | pure (TType fc $
MN "top" 0)
227 | go (IAlternative _ (UniqueDefault tm) _) exps autos named
228 | = go tm exps autos named
229 | go (Implicit fc _) _ _ _ = nextVar fc
230 | go (IBindVar fc _) _ _ _ = nextVar fc
232 | = do tm' <- pterm (map defaultKindedName tm)
233 | throw $
GenericMsg (getFC tm) "Unsupported term in impossible clause: \{show tm'}"
239 | getImpossibleTerm : {vars : _} ->
240 | {auto c : Ref Ctxt Defs} ->
241 | {auto s : Ref Syn SyntaxInfo} ->
242 | Env Term vars -> NestedNames vars -> RawImp -> Core ClosedTerm
243 | getImpossibleTerm env nest tm
244 | = do q <- newRef QVar (the Int 0)
245 | mkTerm (applyEnv tm) Nothing
247 | addEnv : {vars : _} ->
248 | FC -> Env Term vars -> List RawImp
250 | addEnv fc (b :: env) =
253 | else Implicit fc False :: addEnv fc env
255 | expandNest : RawImp -> RawImp
256 | expandNest (IVar fc n)
257 | = case lookup n (names nest) of
258 | Just (Just n', _, _) => IVar fc n'
264 | applyEnv : RawImp -> RawImp
265 | applyEnv (IApp fc fn arg) = IApp fc (applyEnv fn) arg
266 | applyEnv (IWithApp fc fn arg) = IWithApp fc (applyEnv fn) arg
267 | applyEnv (IAutoApp fc fn arg) = IAutoApp fc (applyEnv fn) arg
268 | applyEnv (INamedApp fc fn n arg)
269 | = INamedApp fc (applyEnv fn) n arg
270 | applyEnv tm = apply (expandNest tm) (addEnv (getFC tm) env)