2 | import Core.Case.CaseTree
3 | import Core.Context.Log
6 | import Core.Normalise
8 | import public Core.UnifyState
13 | import Libraries.Data.List.SizeOf
15 | import Libraries.Data.VarSet
17 | import Libraries.Data.IntMap
18 | import Libraries.Data.NameMap
23 | data UnifyMode = InLHS
31 | record UnifyInfo where
32 | constructor MkUnifyInfo
38 | inTerm = MkUnifyInfo True InTerm
42 | inLHS = MkUnifyInfo True InLHS
46 | inMatch = MkUnifyInfo True InMatch
49 | inSearch : UnifyInfo
50 | inSearch = MkUnifyInfo True InSearch
52 | lower : UnifyInfo -> UnifyInfo
53 | lower = { atTop := False }
56 | InLHS == InLHS = True
57 | InTerm == InTerm = True
58 | InMatch == InMatch = True
59 | InSearch == InSearch = True
63 | x == y = atTop x == atTop y && umode x == umode y
65 | Show UnifyMode where
66 | show InLHS = "InLHS"
67 | show InTerm = "InTerm"
68 | show InMatch = "InMatch"
69 | show InSearch = "InSearch"
75 | data AddLazy = NoLazy | AddForce LazyReason | AddDelay LazyReason
79 | show NoLazy = "NoLazy"
80 | show (AddForce _) = "AddForce"
81 | show (AddDelay _) = "AddDelay"
84 | record UnifyResult where
85 | constructor MkUnifyResult
86 | constraints : List Int
88 | namesSolved : List Int
91 | union : UnifyResult -> UnifyResult -> UnifyResult
92 | union u1 u2 = MkUnifyResult (union (constraints u1) (constraints u2))
93 | (holesSolved u1 || holesSolved u2)
94 | (namesSolved u1 ++ namesSolved u2)
97 | unionAll : List UnifyResult -> UnifyResult
98 | unionAll [] = MkUnifyResult [] False [] NoLazy
100 | unionAll (c :: cs) = union c (unionAll cs)
102 | constrain : Int -> UnifyResult
103 | constrain c = MkUnifyResult [c] False [] NoLazy
105 | success : UnifyResult
106 | success = MkUnifyResult [] False [] NoLazy
108 | solvedHole : Int -> UnifyResult
109 | solvedHole n = MkUnifyResult [] True [n] NoLazy
112 | interface Unify tm where
114 | unifyD : {vars : Scope} ->
118 | FC -> Env Term vars ->
119 | tm vars -> tm vars ->
123 | unifyWithLazyD : {vars : _} ->
127 | FC -> Env Term vars ->
128 | tm vars -> tm vars ->
130 | unifyWithLazyD = unifyD
136 | unify : Unify tm =>
138 | {auto c : Ref Ctxt Defs} ->
139 | {auto u : Ref UST UState} ->
141 | FC -> Env Term vars ->
142 | tm vars -> tm vars ->
144 | unify {c} {u} = unifyD c u
147 | unifyWithLazy : Unify tm =>
149 | {auto c : Ref Ctxt Defs} ->
150 | {auto u : Ref UST UState} ->
152 | FC -> Env Term vars ->
153 | tm vars -> tm vars ->
155 | unifyWithLazy {c} {u} = unifyWithLazyD c u
159 | search : {vars : _} ->
160 | {auto c : Ref Ctxt Defs} ->
161 | {auto u : Ref UST UState} ->
163 | (defaults : Bool) -> (depth : Nat) ->
164 | (defining : Name) -> (topTy : Term vars) -> Env Term vars ->
167 | ufail : FC -> String -> Core a
168 | ufail loc msg = throw (GenericMsg loc msg)
170 | convertError : {vars : _} ->
171 | {auto c : Ref Ctxt Defs} ->
172 | FC -> Env Term vars -> NF vars -> NF vars -> Core a
173 | convertError loc env x y
174 | = do defs <- get Ctxt
175 | empty <- clearDefs defs
176 | throw (CantConvert loc (gamma defs)
177 | env !(quote empty env x)
178 | !(quote empty env y))
180 | convertErrorS : {vars : _} ->
181 | {auto c : Ref Ctxt Defs} ->
182 | Bool -> FC -> Env Term vars -> NF vars -> NF vars -> Core a
183 | convertErrorS s loc env x y
184 | = if s then convertError loc env y x
185 | else convertError loc env x y
189 | chaseMetas : {auto c : Ref Ctxt Defs} ->
190 | List Name -> NameMap () -> Core (List Name)
191 | chaseMetas [] all = pure (keys all)
192 | chaseMetas (n :: ns) all
193 | = case lookup n all of
194 | Just _ => chaseMetas ns all
195 | _ => do defs <- get Ctxt
196 | Just (PMDef _ _ (STerm _ soln) _ _) <-
197 | lookupDefExact n (gamma defs)
198 | | _ => chaseMetas ns (insert n () all)
199 | let sns = keys (getMetas soln)
200 | chaseMetas (sns ++ ns) (insert n () all)
204 | getMetaNames : {auto c : Ref Ctxt Defs} ->
205 | Term vars -> Core (List Name)
207 | = let metas = getMetas tm in
208 | chaseMetas (keys metas) empty
210 | postpone : {vars : _} ->
211 | {auto c : Ref Ctxt Defs} ->
212 | {auto u : Ref UST UState} ->
213 | FC -> UnifyInfo -> String ->
214 | Env Term vars -> NF vars -> NF vars -> Core UnifyResult
215 | postpone loc mode logstr env x y
216 | = do defs <- get Ctxt
217 | empty <- clearDefs defs
218 | logC "unify.postpone" 10 $
219 | do xq <- quote defs env x
220 | yq <- quote defs env y
221 | pure (logstr ++ ": " ++ show !(toFullNames xq) ++
222 | " =?= " ++ show !(toFullNames yq))
225 | checkDefined defs x
226 | checkDefined defs y
228 | c <- addConstraint (MkConstraint loc (atTop mode) env x y)
229 | log "unify.postpone" 10 $
230 | show c ++ " NEW CONSTRAINT " ++ show loc
231 | logNF "unify.postpone" 10 "X" env x
232 | logNF "unify.postpone" 10 "Y" env y
235 | checkDefined : Defs -> NF vars -> Core ()
236 | checkDefined defs (NApp _ (NRef _ n) _)
237 | = do Just _ <- lookupCtxtExact n (gamma defs)
238 | | _ => undefinedName loc n
240 | checkDefined _ _ = pure ()
242 | undefinedN : Name -> Core Bool
244 | = do defs <- get Ctxt
245 | pure $
case !(lookupDefExact n (gamma defs)) of
246 | Just (Hole {}) => True
247 | Just (BySearch {}) => True
248 | Just (Guess {}) => True
251 | postponeS : {vars : _} ->
252 | {auto c : Ref Ctxt Defs} ->
253 | {auto u : Ref UST UState} ->
254 | Bool -> FC -> UnifyInfo -> String -> Env Term vars ->
255 | NF vars -> NF vars ->
257 | postponeS s loc mode logstr env x y
258 | = if s then postpone loc (lower mode) logstr env y x
259 | else postpone loc mode logstr env x y
261 | unifyArgs : (Unify tm, Quote tm) =>
263 | {auto c : Ref Ctxt Defs} ->
264 | {auto u : Ref UST UState} ->
265 | UnifyInfo -> FC -> Env Term vars ->
266 | List (tm vars) -> List (tm vars) ->
268 | unifyArgs mode loc env [] [] = pure success
269 | unifyArgs mode loc env (cx :: cxs) (cy :: cys)
272 | cs <- unifyArgs mode loc env cxs cys
273 | res <- unify (lower mode) loc env cx cy
274 | pure (union res cs)
275 | unifyArgs mode loc env _ _ = ufail loc ""
283 | getVars : List (NF vars) -> Maybe (List (Var vars), VarSet vars)
284 | getVars = go [<] VarSet.empty where
286 | go : SnocList (Var vars) -> VarSet vars ->
287 | List (NF vars) -> Maybe (List (Var vars), VarSet vars)
288 | go acc got [] = Just (acc <>> [], got)
289 | go acc got (NErased fc (Dotted t) :: xs) = go acc got (t :: xs)
290 | go acc got (NApp fc (NLocal r idx p) [] :: xs)
291 | = let v := MkVar p in
292 | if v `VarSet.elem` got then Nothing
293 | else go (acc :< v) (VarSet.insert v got) xs
294 | go acc got (NAs _ _ _ p :: xs) = go acc got (p :: xs)
295 | go acc _ (_ :: xs) = Nothing
300 | updateVars : List (Var {a = Name} vars) -> Thin newvars vars -> List (Var newvars)
301 | updateVars vs th = mapMaybe (\ v => shrink v th) vs
318 | patternEnv : {auto c : Ref Ctxt Defs} ->
319 | {auto u : Ref UST UState} ->
321 | Env Term vars -> List (Closure vars) ->
322 | Core (Maybe (
newvars ** (List (Var newvars),
323 | Thin newvars vars))
)
324 | patternEnv {vars} env args
325 | = do defs <- get Ctxt
326 | empty <- clearDefs defs
327 | args' <- traverse (evalArg empty) args
329 | case getVars args' of
331 | Just (vslist, vsset) =>
332 | let (
newvars ** svs)
= fromVarSet _ vsset in
333 | Just (
newvars ** (updateVars vslist svs, svs))
335 | getVarsTm : List (Term vars) -> Maybe (List (Var vars), VarSet vars)
336 | getVarsTm = go [<] VarSet.empty where
338 | go : SnocList (Var vars) -> VarSet vars ->
339 | List (Term vars) -> Maybe (List (Var vars), VarSet vars)
340 | go acc got [] = Just (acc <>> [], got)
341 | go acc got (Local fc r idx p :: xs)
342 | = let v := MkVar p in
343 | if v `VarSet.elem` got then Nothing
344 | else go (acc :< v) (VarSet.insert v got) xs
345 | go acc _ (_ :: xs) = Nothing
348 | patternEnvTm : {auto c : Ref Ctxt Defs} ->
349 | {auto u : Ref UST UState} ->
351 | Env Term vars -> List (Term vars) ->
352 | Core (Maybe (
newvars ** (List (Var newvars),
353 | Thin newvars vars))
)
354 | patternEnvTm {vars} env args
355 | = do defs <- get Ctxt
356 | empty <- clearDefs defs
357 | pure $
case getVarsTm args of
359 | Just (vslist, vsset) =>
360 | let (
newvars ** svs)
= fromVarSet _ vsset in
361 | Just (
newvars ** (updateVars vslist svs, svs))
365 | occursCheck : {vars : _} ->
366 | {auto c : Ref Ctxt Defs} ->
367 | FC -> Env Term vars -> UnifyInfo ->
368 | Name -> Term vars -> Core (Maybe (Term vars))
369 | occursCheck fc env mode mname tm
370 | = do solmetas <- getMetaNames tm
371 | let False = mname `elem` solmetas
372 | | _ => do defs <- get Ctxt
373 | tmnf <- normalise defs env tm
374 | solmetas <- getMetaNames tmnf
375 | if mname `elem` solmetas
376 | then do failOnStrongRigid False
377 | (throw (CyclicMeta fc env mname tmnf))
380 | else pure $
Just tmnf
386 | failOnStrongRigid : Bool -> Core () -> Term vars -> Core ()
387 | failOnStrongRigid bad err (Meta _ n _ _)
388 | = if bad && n == mname
391 | failOnStrongRigid bad err tm
392 | = case getFnArgs tm of
394 | (Ref _ Func _, _) => pure ()
395 | (Ref _ _ _, args) => traverse_ (failOnStrongRigid True err) args
396 | (f, args) => traverse_ (failOnStrongRigid bad err) args
403 | data IVars : Scope -> Scoped where
404 | INil : IVars Scope.empty newvars
405 | ICons : Maybe (Var newvars) -> IVars vs newvars ->
406 | IVars (v :: vs) newvars
408 | Weaken (IVars vs) where
409 | weakenNs s INil = INil
410 | weakenNs s (ICons t ts) = ICons (weakenNs @{MaybeWeaken} s t) (weakenNs s ts)
412 | getIVars : IVars vs ns -> List (Maybe (Var ns))
414 | getIVars (ICons v vs) = v :: getIVars vs
420 | tryInstantiate : {auto c : Ref Ctxt Defs} ->
421 | {auto u : Ref UST UState} ->
422 | {vars, newvars : _} ->
423 | FC -> UnifyInfo -> Env Term vars ->
424 | (metavar : Name) -> (mref : Int) -> (numargs : Nat) ->
425 | (mdef : GlobalDef) ->
426 | List (Var newvars) ->
430 | tryInstantiate {newvars} loc mode env mname mref num mdef locs otm tm
431 | = do logTerm "unify.instantiate" 5 ("Instantiating in " ++ show newvars) tm
434 | case fullname mdef of
435 | PV pv pi => throw (PatternVariableUnifies loc (getLoc otm) env (PV pv pi) otm)
438 | ty <- normalisePis defs Env.empty $
type mdef
441 | logTerm "unify.instantiate" 5 ("Type: " ++ show mname) (type mdef)
442 | logTerm "unify.instantiate" 5 ("Type: " ++ show mname) ty
443 | log "unify.instantiate" 5 ("With locs: " ++ show locs)
444 | log "unify.instantiate" 5 ("From vars: " ++ show newvars)
448 | Just rhs <- mkDef locs INil tm ty
450 | log "unify.instantiate" 5 "Postponed"
453 | logTerm "unify.instantiate" 5 "Definition" rhs
454 | let simpleDef = MkPMDefInfo (SolvedHole num)
455 | (not (isUserName mname) && isSimple rhs)
457 | let newdef = { definition :=
458 | PMDef simpleDef Scope.empty (STerm 0 rhs) (STerm 0 rhs) []
460 | ignore $
addDef (Resolved mref) newdef
466 | = case definition mdef of
467 | Hole _ p => precisetype p
473 | noMeta : Term vs -> Nat -> Bool
474 | noMeta (App _ f a) (S k) = noMeta f k && noMeta a k
475 | noMeta (Bind _ _ b sc) (S k) = noMeta (binderType b) k && noMeta sc k
476 | noMeta (Meta {}) d = False
477 | noMeta (TDelayed _ _ t) d = noMeta t d
478 | noMeta (TDelay _ _ t a) d = noMeta t d && noMeta a d
479 | noMeta (TForce _ _ t) d = noMeta t d
480 | noMeta (As _ _ a p) d = noMeta a d && noMeta p d
481 | noMeta (Local {}) _ = True
482 | noMeta (Ref {}) _ = True
483 | noMeta (PrimVal {}) _ = True
484 | noMeta (TType {}) _ = True
487 | isSimple : Term vs -> Bool
488 | isSimple (Meta {}) = True
489 | isSimple (Bind _ _ (Lam {}) sc) = isSimple sc
490 | isSimple (App _ f a) = noMeta f 6 && noMeta a 3
491 | isSimple tm = noMeta tm 0
493 | updateIVar : forall vs, newvars . IVars vs newvars -> Var newvars ->
495 | updateIVar (ICons Nothing rest) new
496 | = later <$> updateIVar rest new
497 | updateIVar (ICons (Just old) rest) new
500 | else later <$> updateIVar rest new
501 | updateIVar _ _ = Nothing
503 | updateIVars : {vs, newvars : _} ->
504 | IVars vs newvars -> Term newvars -> Maybe (Term vs)
505 | updateIVars ivs (Local fc r idx p)
506 | = do MkVar p' <- updateIVar ivs (MkVar p)
507 | Just (Local fc r _ p')
508 | updateIVars ivs (Ref fc nt n) = pure $
Ref fc nt n
509 | updateIVars ivs (Meta fc n i args)
510 | = pure $
Meta fc n i !(traverse (updateIVars ivs) args)
511 | updateIVars {vs} ivs (Bind fc x b sc)
512 | = do b' <- updateIVarsB ivs b
513 | sc' <- updateIVars (ICons (Just first) (weaken ivs)) sc
514 | Just (Bind fc x b' sc')
516 | updateIVarsPi : {vs, newvars : _} ->
517 | IVars vs newvars -> PiInfo (Term newvars) -> Maybe (PiInfo (Term vs))
518 | updateIVarsPi ivs Explicit = Just Explicit
519 | updateIVarsPi ivs Implicit = Just Implicit
520 | updateIVarsPi ivs AutoImplicit = Just AutoImplicit
521 | updateIVarsPi ivs (DefImplicit t)
522 | = do t' <- updateIVars ivs t
523 | Just (DefImplicit t')
525 | updateIVarsB : {vs, newvars : _} ->
526 | IVars vs newvars -> Binder (Term newvars) -> Maybe (Binder (Term vs))
527 | updateIVarsB ivs (Lam fc c p t)
528 | = do p' <- updateIVarsPi ivs p
529 | Just (Lam fc c p' !(updateIVars ivs t))
530 | updateIVarsB ivs (Let fc c v t) = Just (Let fc c !(updateIVars ivs v) !(updateIVars ivs t))
533 | updateIVarsB ivs (Pi fc rig p t)
534 | = do p' <- updateIVarsPi ivs p
535 | Just (Pi fc rig p' !(updateIVars ivs t))
536 | updateIVarsB ivs (PVar fc c p t)
537 | = do p' <- updateIVarsPi ivs p
538 | Just (PVar fc c p' !(updateIVars ivs t))
539 | updateIVarsB ivs (PLet fc c v t) = Just (PLet fc c !(updateIVars ivs v) !(updateIVars ivs t))
540 | updateIVarsB ivs (PVTy fc c t) = Just (PVTy fc c !(updateIVars ivs t))
541 | updateIVars ivs (App fc f a)
542 | = Just (App fc !(updateIVars ivs f) !(updateIVars ivs a))
543 | updateIVars ivs (As fc u a p)
544 | = Just (As fc u !(updateIVars ivs a) !(updateIVars ivs p))
545 | updateIVars ivs (TDelayed fc r arg)
546 | = Just (TDelayed fc r !(updateIVars ivs arg))
547 | updateIVars ivs (TDelay fc r ty arg)
548 | = Just (TDelay fc r !(updateIVars ivs ty) !(updateIVars ivs arg))
549 | updateIVars ivs (TForce fc r arg)
550 | = Just (TForce fc r !(updateIVars ivs arg))
551 | updateIVars ivs (PrimVal fc c) = Just (PrimVal fc c)
552 | updateIVars ivs (Erased fc Impossible) = Just (Erased fc Impossible)
553 | updateIVars ivs (Erased fc Placeholder) = Just (Erased fc Placeholder)
554 | updateIVars ivs (Erased fc (Dotted t)) = Erased fc . Dotted <$> updateIVars ivs t
555 | updateIVars ivs (TType fc u) = Just (TType fc u)
557 | mkDef : {vs, newvars : _} ->
558 | List (Var newvars) ->
559 | IVars vs newvars -> Term newvars -> Term vs ->
560 | Core (Maybe (Term vs))
561 | mkDef (v :: vs) vars soln (Bind bfc x (Pi fc c info ty) sc)
562 | = do sc' <- mkDef vs (ICons (Just v) vars) soln sc
563 | pure $
(Bind bfc x (Lam fc c info (Erased bfc Placeholder)) <$> sc')
564 | mkDef vs vars soln (Bind bfc x b@(Let _ c val ty) sc)
565 | = do mbsc' <- mkDef vs (ICons Nothing vars) soln sc
566 | flip traverseOpt mbsc' $
\sc' =>
567 | case shrink sc' (Drop Refl) of
568 | Just scs => pure scs
569 | Nothing => pure $
Bind bfc x b sc'
570 | mkDef [] vars soln _
571 | = do let Just soln' = updateIVars vars soln
572 | | Nothing => ufail loc ("Can't make solution for " ++ show mname
573 | ++ " " ++ show (getIVars vars, soln))
575 | mkDef _ _ _ _ = pure Nothing
580 | updateSolution : {vars : _} ->
581 | {auto c : Ref Ctxt Defs} ->
582 | {auto u : Ref UST UState} ->
583 | Env Term vars -> Term vars -> Term vars -> Core Bool
584 | updateSolution env (Meta fc mname idx args) soln
585 | = do defs <- get Ctxt
586 | case !(patternEnvTm env args) of
587 | Nothing => pure False
588 | Just (
newvars ** (locs, submv))
=>
589 | case shrink soln submv of
590 | Nothing => pure False
592 | do Just hdef <- lookupCtxtExact (Resolved idx) (gamma defs)
593 | | Nothing => throw (InternalError "Can't happen: no definition")
594 | tryInstantiate fc inTerm env mname idx (length args) hdef (toList locs) soln stm
595 | updateSolution env metavar soln
599 | solveIfUndefined : {vars : _} ->
600 | {auto c : Ref Ctxt Defs} ->
601 | {auto u : Ref UST UState} ->
602 | Env Term vars -> Term vars -> Term vars -> Core Bool
603 | solveIfUndefined env metavar@(Meta fc mname idx args) soln
604 | = do defs <- get Ctxt
605 | Just (Hole {}) <- lookupDefExact (Resolved idx) (gamma defs)
607 | updateSolution env metavar soln
608 | solveIfUndefined env (Erased _ (Dotted metavar)) soln
609 | = solveIfUndefined env metavar soln
610 | solveIfUndefined env metavar soln
613 | isDefInvertible : {auto c : Ref Ctxt Defs} ->
614 | FC -> Int -> Core Bool
615 | isDefInvertible fc i
616 | = do defs <- get Ctxt
617 | Just gdef <- lookupCtxtExact (Resolved i) (gamma defs)
618 | | Nothing => throw (UndefinedName fc (Resolved i))
619 | pure (invertible gdef)
622 | unifyIfEq : {auto c : Ref Ctxt Defs} ->
623 | {auto u : Ref UST UState} ->
625 | (postpone : Bool) ->
626 | FC -> UnifyInfo -> Env Term vars -> NF vars -> NF vars ->
628 | unifyIfEq post loc mode env x y
629 | = do defs <- get Ctxt
630 | if !(convertInf defs env x y)
633 | then postpone loc mode ("Postponing unifyIfEq " ++
634 | show (atTop mode)) env x y
635 | else convertError loc env x y
637 | getArgTypes : {vars : _} ->
638 | {auto c : Ref Ctxt Defs} ->
639 | Defs -> (fnType : NF vars) -> List (Closure vars) ->
640 | Core (Maybe (List (NF vars)))
641 | getArgTypes defs (NBind _ n (Pi _ _ _ ty) sc) (a :: as)
642 | = do Just scTys <- getArgTypes defs !(sc defs a) as
643 | | Nothing => pure Nothing
644 | pure (Just (!(evalClosure defs ty) :: scTys))
645 | getArgTypes _ _ [] = pure (Just [])
646 | getArgTypes _ _ _ = pure Nothing
648 | headsConvert : {vars : _} ->
649 | {auto c : Ref Ctxt Defs} ->
650 | {auto u : Ref UST UState} ->
652 | FC -> Env Term vars ->
653 | Maybe (List (NF vars)) -> Maybe (List (NF vars)) ->
655 | headsConvert mode fc env (Just vs) (Just ns)
656 | = case (reverse vs, reverse ns) of
657 | (v :: _, n :: _) =>
658 | do logNF "unify.head" 10 "Unifying head" env v
659 | logNF "unify.head" 10 ".........with" env n
660 | res <- unify mode fc env v n
663 | pure (isNil (constraints res ))
665 | headsConvert mode fc env _ _
666 | = do log "unify.head" 10 "Nothing to convert"
669 | unifyInvertible : {auto c : Ref Ctxt Defs} ->
670 | {auto u : Ref UST UState} ->
672 | (swaporder : Bool) ->
673 | UnifyInfo -> FC -> Env Term vars ->
674 | (metaname : Name) -> (metaref : Int) ->
675 | (margs : List (Closure vars)) ->
676 | (margs' : List (Closure vars)) ->
677 | Maybe ClosedTerm ->
678 | (List (FC, Closure vars) -> NF vars) ->
679 | List (FC, Closure vars) ->
681 | unifyInvertible swap mode fc env mname mref margs margs' nty con args'
682 | = do defs <- get Ctxt
685 | Just vty <- lookupTyExact (Resolved mref) (gamma defs)
686 | | Nothing => ufail fc ("No such metavariable " ++ show mname)
687 | vargTys <- getArgTypes defs !(nf defs env (embed vty)) (margs ++ margs')
688 | nargTys <- maybe (pure Nothing)
689 | (\ty => getArgTypes defs !(nf defs env (embed ty)) $
map snd args')
693 | if !(headsConvert mode fc env vargTys nargTys)
697 | case (reverse margs', reverse args') of
698 | (h :: hargs, f :: fargs) =>
701 | do log "unify.invertible" 10 "Unifying invertible"
702 | ures <- unify mode fc env h (snd f)
703 | log "unify.invertible" 10 $
"Constraints " ++ show (constraints ures)
704 | uargs <- unify mode fc env
705 | (NApp fc (NMeta mname mref margs) (reverse $
map (EmptyFC,) hargs))
706 | (con (reverse fargs))
707 | pure (union ures uargs)
709 | do log "unify.invertible" 10 "Unifying invertible"
710 | ures <- unify mode fc env (snd f) h
711 | log "unify.invertible" 10 $
"Constraints " ++ show (constraints ures)
712 | uargs <- unify mode fc env
713 | (con (reverse fargs))
714 | (NApp fc (NMeta mname mref margs) (reverse $
map (EmptyFC,) hargs))
715 | pure (union ures uargs))
716 | (postponeS swap fc mode "Postponing hole application [1]" env
717 | (NApp fc (NMeta mname mref margs) $
map (EmptyFC,) margs')
719 | _ => postponeS swap fc mode "Postponing hole application [2]" env
720 | (NApp fc (NMeta mname mref margs) (map (EmptyFC,) margs'))
723 | postpone fc mode "Postponing hole application [3]" env
724 | (NApp fc (NMeta mname mref margs) (map (EmptyFC,) margs')) (con args')
729 | unifyHoleApp : {auto c : Ref Ctxt Defs} ->
730 | {auto u : Ref UST UState} ->
732 | (swaporder : Bool) ->
733 | UnifyInfo -> FC -> Env Term vars ->
734 | (metaname : Name) -> (metaref : Int) ->
735 | (margs : List (Closure vars)) ->
736 | (margs' : List (Closure vars)) ->
739 | unifyHoleApp swap mode loc env mname mref margs margs' (NTCon nfc n a args')
740 | = do defs <- get Ctxt
741 | mty <- lookupTyExact n (gamma defs)
742 | unifyInvertible swap (lower mode) loc env mname mref margs margs' mty (NTCon nfc n a) args'
743 | unifyHoleApp swap mode loc env mname mref margs margs' (NDCon nfc n t a args')
744 | = do defs <- get Ctxt
745 | mty <- lookupTyExact n (gamma defs)
746 | unifyInvertible swap (lower mode) loc env mname mref margs margs' mty (NDCon nfc n t a) args'
747 | unifyHoleApp swap mode loc env mname mref margs margs' (NApp nfc (NLocal r idx p) args')
748 | = unifyInvertible swap (lower mode) loc env mname mref margs margs' Nothing
749 | (NApp nfc (NLocal r idx p)) args'
750 | unifyHoleApp swap mode loc env mname mref margs margs' tm@(NApp nfc (NMeta n i margs2) args2')
751 | = do defs <- get Ctxt
752 | Just mdef <- lookupCtxtExact (Resolved i) (gamma defs)
753 | | Nothing => undefinedName nfc mname
754 | let inv = isPatName n || invertible mdef
756 | then unifyInvertible swap (lower mode) loc env mname mref margs margs' Nothing
757 | (NApp nfc (NMeta n i margs2)) args2'
758 | else postponeS swap loc mode "Postponing hole application" env
759 | (NApp loc (NMeta mname mref margs) $
map (EmptyFC,) margs') tm
761 | isPatName : Name -> Bool
762 | isPatName (PV {}) = True
763 | isPatName _ = False
765 | unifyHoleApp swap mode loc env mname mref margs margs' tm
766 | = postponeS swap loc mode "Postponing hole application" env
767 | (NApp loc (NMeta mname mref margs) $
map (EmptyFC,) margs') tm
769 | postponePatVar : {auto c : Ref Ctxt Defs} ->
770 | {auto u : Ref UST UState} ->
772 | (swaporder : Bool) ->
773 | UnifyInfo -> FC -> Env Term vars ->
774 | (metaname : Name) -> (metaref : Int) ->
775 | (margs : List (Closure vars)) ->
776 | (margs' : List (Closure vars)) ->
777 | (soln : NF vars) ->
779 | postponePatVar swap mode loc env mname mref margs margs' tm
780 | = do let x = NApp loc (NMeta mname mref margs) (map (EmptyFC,) margs')
782 | if !(convert defs env x tm)
784 | else postponeS swap loc mode "Not in pattern fragment" env
787 | solveHole : {auto c : Ref Ctxt Defs} ->
788 | {auto u : Ref UST UState} ->
789 | {newvars, vars : _} ->
790 | FC -> UnifyInfo -> Env Term vars ->
791 | (metaname : Name) -> (metaref : Int) ->
792 | (margs : List (Closure vars)) ->
793 | (margs' : List (Closure vars)) ->
794 | List (Var newvars) ->
795 | Thin newvars vars ->
796 | (solfull : Term vars) ->
797 | (soln : Term newvars) ->
798 | (solnf : NF vars) ->
799 | Core (Maybe UnifyResult)
800 | solveHole loc mode env mname mref margs margs' locs submv solfull stm solnf
801 | = do defs <- get Ctxt
803 | empty <- clearDefs defs
806 | if solutionHeadSame solnf || inNoSolve mref (noSolve ust)
807 | then pure $
Just success
813 | do Just hdef <- lookupCtxtExact (Resolved mref) (gamma defs)
814 | | Nothing => throw (InternalError ("Can't happen: Lost hole " ++ show mname))
815 | progress <- tryInstantiate loc mode env mname mref (length margs) hdef (toList locs) solfull stm
816 | pure $
toMaybe progress (solvedHole mref)
818 | inNoSolve : Int -> IntMap () -> Bool
820 | = case lookup i ns of
827 | solutionHeadSame : NF vars -> Bool
828 | solutionHeadSame (NApp _ (NMeta _ shead _) _) = shead == mref
829 | solutionHeadSame _ = False
831 | unifyHole : {auto c : Ref Ctxt Defs} ->
832 | {auto u : Ref UST UState} ->
834 | (swaporder : Bool) ->
835 | UnifyInfo -> FC -> Env Term vars ->
836 | FC -> (metaname : Name) -> (metaref : Int) ->
837 | (args : List (Closure vars)) ->
838 | (args' : List (Closure vars)) ->
839 | (soln : NF vars) ->
841 | unifyHole swap mode loc env fc mname mref margs margs' tmnf
842 | = do defs <- get Ctxt
843 | empty <- clearDefs defs
844 | let args = if isNil margs' then margs else margs ++ margs'
845 | logC "unify.hole" 10
846 | (do args' <- traverse (evalArg empty) args
847 | qargs <- traverse (quote empty env) args'
848 | qtm <- quote empty env tmnf
849 | pure $
"Unifying: " ++ show mname ++ " " ++ show qargs ++
850 | " with " ++ show qtm)
851 | case !(patternEnv env args) of
853 | do Just hdef <- lookupCtxtExact (Resolved mref) (gamma defs)
854 | | _ => postponePatVar swap mode loc env mname mref margs margs' tmnf
855 | let Hole _ _ = definition hdef
856 | | _ => postponePatVar swap mode loc env mname mref margs margs' tmnf
858 | then unifyHoleApp swap mode loc env mname mref margs margs' tmnf
859 | else postponePatVar swap mode loc env mname mref margs margs' tmnf
860 | Just (
newvars ** (locs, submv))
=>
861 | do Just hdef <- lookupCtxtExact (Resolved mref) (gamma defs)
862 | | _ => postponePatVar swap mode loc env mname mref margs margs' tmnf
863 | let Hole _ _ = definition hdef
864 | | _ => postponeS swap loc mode "Delayed hole" env
865 | (NApp loc (NMeta mname mref margs) $
map (EmptyFC,) margs')
867 | let qopts = MkQuoteOpts False False
868 | (Just defs.options.elabDirectives.nfThreshold)
869 | tm <- catch (quoteOpts qopts empty env tmnf)
870 | (\err => quote defs env tmnf)
871 | Just tm <- occursCheck loc env mode mname tm
872 | | _ => postponeS swap loc mode "Occurs check failed" env
873 | (NApp loc (NMeta mname mref margs) $
map (EmptyFC,) margs')
876 | let solveOrElsePostpone : Term newvars -> Core UnifyResult
877 | solveOrElsePostpone stm = do
878 | mbResult <- solveHole fc mode env mname mref
879 | margs margs' locs submv
881 | flip fromMaybe (pure <$> mbResult) $
882 | postponeS swap loc mode "Can't instantiate" env
883 | (NApp loc (NMeta mname mref margs) $
map (EmptyFC,) margs') tmnf
885 | case shrink tm submv of
886 | Just stm => solveOrElsePostpone stm
888 | do tm' <- quote defs env tmnf
889 | case shrink tm' submv of
890 | Nothing => postponeS swap loc mode "Can't shrink" env
891 | (NApp loc (NMeta mname mref margs) $
map (EmptyFC,) margs')
893 | Just stm => solveOrElsePostpone stm
896 | unifyApp : {auto c : Ref Ctxt Defs} ->
897 | {auto u : Ref UST UState} ->
899 | (swaporder : Bool) ->
901 | UnifyInfo -> FC -> Env Term vars -> FC ->
902 | NHead vars -> List (FC, Closure vars) -> NF vars ->
904 | unifyApp swap mode loc env fc (NMeta n i margs) args tm
905 | = unifyHole swap mode loc env fc n i margs (map snd args) tm
906 | unifyApp swap mode loc env fc hd args (NApp mfc (NMeta n i margs) margs')
907 | = unifyHole swap mode loc env mfc n i margs (map snd margs') (NApp fc hd args)
908 | unifyApp swap mode loc env fc hd args (NErased _ (Dotted t))
909 | = unifyApp swap mode loc env fc hd args t
912 | unifyApp swap mode loc env fc (NRef nt n) args tm
913 | = do log "unify.application" 10 $
"Name against app, unifyIfEq"
915 | then unifyIfEq True loc mode env (NApp fc (NRef nt n) args) tm
916 | else unifyIfEq True loc mode env tm (NApp fc (NRef nt n) args)
917 | unifyApp swap mode loc env xfc (NLocal rx x xp) [] (NApp yfc (NLocal ry y yp) [])
918 | = do gam <- get Ctxt
919 | if x == y then pure success
920 | else postponeS swap loc mode "Postponing var"
921 | env (NApp xfc (NLocal rx x xp) [])
922 | (NApp yfc (NLocal ry y yp) [])
924 | unifyApp swap mode loc env xfc (NLocal rx x xp) args y@(NBind {})
925 | = convertErrorS swap loc env (NApp xfc (NLocal rx x xp) args) y
926 | unifyApp swap mode loc env xfc (NLocal rx x xp) args y@(NDCon {})
927 | = convertErrorS swap loc env (NApp xfc (NLocal rx x xp) args) y
928 | unifyApp swap mode loc env xfc (NLocal rx x xp) args y@(NTCon {})
929 | = convertErrorS swap loc env (NApp xfc (NLocal rx x xp) args) y
930 | unifyApp swap mode loc env xfc (NLocal rx x xp) args y@(NPrimVal {})
931 | = convertErrorS swap loc env (NApp xfc (NLocal rx x xp) args) y
932 | unifyApp swap mode loc env xfc (NLocal rx x xp) args y@(NType {})
933 | = convertErrorS swap loc env (NApp xfc (NLocal rx x xp) args) y
936 | unifyApp False mode loc env fc hd args tm
937 | = do gam <- get Ctxt
938 | if !(convert gam env (NApp fc hd args) tm)
940 | else postponeS False loc mode "Postponing constraint"
941 | env (NApp fc hd args) tm
942 | unifyApp True mode loc env fc hd args tm
943 | = do gam <- get Ctxt
944 | if !(convert gam env tm (NApp fc hd args))
946 | else postponeS True loc mode "Postponing constraint"
947 | env (NApp fc hd args) tm
949 | unifyBothApps : {auto c : Ref Ctxt Defs} ->
950 | {auto u : Ref UST UState} ->
952 | UnifyInfo -> FC -> Env Term vars ->
953 | FC -> NHead vars -> List (FC, Closure vars) ->
954 | FC -> NHead vars -> List (FC, Closure vars) ->
956 | unifyBothApps mode loc env xfc (NLocal xr x xp) [] yfc (NLocal yr y yp) []
959 | else convertError loc env (NApp xfc (NLocal xr x xp) [])
960 | (NApp yfc (NLocal yr y yp) [])
963 | unifyBothApps mode@(MkUnifyInfo p InTerm) loc env xfc (NLocal xr x xp) xargs yfc (NLocal yr y yp) yargs
965 | then unifyArgs mode loc env (map snd xargs) (map snd yargs)
966 | else postpone loc mode "Postponing local app"
967 | env (NApp xfc (NLocal xr x xp) xargs)
968 | (NApp yfc (NLocal yr y yp) yargs)
969 | unifyBothApps mode loc env xfc (NLocal xr x xp) xargs yfc (NLocal yr y yp) yargs
970 | = do log "unify.application" 10 $
"Both local apps, unifyIfEq"
971 | unifyIfEq True loc mode env (NApp xfc (NLocal xr x xp) xargs)
972 | (NApp yfc (NLocal yr y yp) yargs)
974 | unifyBothApps mode loc env xfc (NMeta xn xi xargs) xargs' yfc (NMeta yn yi yargs) yargs'
975 | = do invx <- isDefInvertible loc xi
976 | if xi == yi && (invx || umode mode == InSearch)
979 | then unifyArgs mode loc env (xargs ++ map snd xargs')
980 | (yargs ++ map snd yargs')
981 | else do xlocs <- localsIn xargs
982 | ylocs <- localsIn yargs
986 | let xbigger = xlocs > ylocs
987 | || (xlocs == ylocs &&
988 | length xargs' <= length yargs')
989 | if (xbigger || umode mode == InMatch) && not (pv xn)
990 | then unifyApp False mode loc env xfc (NMeta xn xi xargs) xargs'
991 | (NApp yfc (NMeta yn yi yargs) yargs')
992 | else unifyApp True mode loc env yfc (NMeta yn yi yargs) yargs'
993 | (NApp xfc (NMeta xn xi xargs) xargs')
999 | localsIn : List (Closure vars) -> Core Nat
1003 | case !(evalClosure defs c) of
1004 | NApp _ (NLocal {}) _ => pure $
S !(localsIn cs)
1007 | unifyBothApps mode loc env xfc (NMeta xn xi xargs) xargs' yfc fy yargs'
1008 | = unifyApp False mode loc env xfc (NMeta xn xi xargs) xargs'
1010 | unifyBothApps mode loc env xfc fx xargs' yfc (NMeta yn yi yargs) yargs'
1011 | = if umode mode /= InMatch
1012 | then unifyApp True mode loc env xfc (NMeta yn yi yargs) yargs'
1014 | else unifyApp False mode loc env xfc fx xargs'
1015 | (NApp yfc (NMeta yn yi yargs) yargs')
1016 | unifyBothApps mode@(MkUnifyInfo p InSearch) loc env xfc fx@(NRef xt hdx) xargs yfc fy@(NRef yt hdy) yargs
1018 | then unifyArgs mode loc env (map snd xargs) (map snd yargs)
1019 | else unifyApp False mode loc env xfc fx xargs (NApp yfc fy yargs)
1020 | unifyBothApps mode@(MkUnifyInfo p InMatch) loc env xfc fx@(NRef xt hdx) xargs yfc fy@(NRef yt hdy) yargs
1022 | then do logC "unify.application" 5
1024 | xs <- traverse (quote defs env) (map snd xargs)
1025 | ys <- traverse (quote defs env) (map snd yargs)
1026 | pure ("Matching args " ++ show xs ++ " " ++ show ys))
1027 | unifyArgs mode loc env (map snd xargs) (map snd yargs)
1028 | else unifyApp False mode loc env xfc fx xargs (NApp yfc fy yargs)
1029 | unifyBothApps mode loc env xfc fx ax yfc fy ay
1030 | = unifyApp False mode loc env xfc fx ax (NApp yfc fy ay)
1032 | unifyPiInfo : {auto c : Ref Ctxt Defs} ->
1033 | {auto u : Ref UST UState} ->
1035 | UnifyInfo -> FC -> Env Term vars ->
1036 | PiInfo (Closure vars) -> PiInfo (Closure vars) ->
1037 | Core (Maybe UnifyResult)
1038 | unifyPiInfo mode loc env Explicit Explicit = pure $
Just success
1039 | unifyPiInfo mode loc env Implicit Implicit = pure $
Just success
1040 | unifyPiInfo mode loc env AutoImplicit AutoImplicit = pure $
Just success
1041 | unifyPiInfo mode loc env (DefImplicit x) (DefImplicit y) = Just <$> unify mode loc env x y
1042 | unifyPiInfo mode loc env _ _ = pure Nothing
1044 | unifyBothBinders: {auto c : Ref Ctxt Defs} ->
1045 | {auto u : Ref UST UState} ->
1047 | UnifyInfo -> FC -> Env Term vars ->
1048 | FC -> Name -> Binder (Closure vars) ->
1049 | (Defs -> Closure vars -> Core (NF vars)) ->
1050 | FC -> Name -> Binder (Closure vars) ->
1051 | (Defs -> Closure vars -> Core (NF vars)) ->
1053 | unifyBothBinders mode loc env xfc x (Pi fcx cx ix tx) scx yfc y (Pi fcy cy iy ty) scy
1055 | let err = convertError loc env
1056 | (NBind xfc x (Pi fcx cx ix tx) scx)
1057 | (NBind yfc y (Pi fcy cy iy ty) scy)
1060 | else do Just ci <- unifyPiInfo (lower mode) loc env ix iy
1062 | empty <- clearDefs defs
1063 | tx' <- quote empty env tx
1064 | logC "unify.binder" 10 $
1065 | (do ty' <- quote empty env ty
1066 | pure ("Unifying arg types " ++ show tx' ++ " and " ++ show ty'))
1067 | ct <- unify (lower mode) loc env tx ty
1069 | let env' : Env Term (x :: _)
1070 | = Pi fcy cy Explicit tx' :: env
1073 | do tscx <- scx defs (toClosure defaultOpts env (Ref loc Bound xn))
1074 | tscy <- scy defs (toClosure defaultOpts env (Ref loc Bound xn))
1075 | tmx <- quote empty env tscx
1076 | tmy <- quote empty env tscy
1077 | cs <- unify (lower mode) loc env'
1078 | (refsToLocals (Add x xn None) tmx)
1079 | (refsToLocals (Add x xn None) tmy)
1082 | do txtm <- quote empty env tx
1083 | tytm <- quote empty env ty
1084 | c <- newConstant loc erased env
1085 | (Bind xfc x (Lam fcy cy Explicit txtm) (Local xfc Nothing _ First))
1086 | (Bind xfc x (Pi fcy cy Explicit txtm)
1088 | tscx <- scx defs (toClosure defaultOpts env (Ref loc Bound xn))
1089 | tscy <- scy defs (toClosure defaultOpts env (App loc c (Ref loc Bound xn)))
1090 | tmx <- quote empty env tscx
1091 | tmy <- quote empty env tscy
1092 | cs' <- unify (lower mode) loc env'
1093 | (refsToLocals (Add x xn None) tmx)
1094 | (refsToLocals (Add x xn None) tmy)
1095 | pure (union ci (union ct cs'))
1096 | unifyBothBinders mode loc env xfc x (Lam fcx cx ix tx) scx yfc y (Lam fcy cy iy ty) scy
1098 | let err = convertError loc env
1099 | (NBind xfc x (Lam fcx cx ix tx) scx)
1100 | (NBind yfc y (Lam fcy cy iy ty) scy)
1103 | else do empty <- clearDefs defs
1104 | Just ci <- unifyPiInfo (lower mode) loc env ix iy
1106 | ct <- unify (lower mode) loc env tx ty
1108 | txtm <- quote empty env tx
1109 | let env' : Env Term (x :: _)
1110 | = Lam fcx cx Explicit txtm :: env
1112 | tscx <- scx defs (toClosure defaultOpts env (Ref loc Bound xn))
1113 | tscy <- scy defs (toClosure defaultOpts env (Ref loc Bound xn))
1114 | tmx <- quote empty env tscx
1115 | tmy <- quote empty env tscy
1116 | cs' <- unify (lower mode) loc env' (refsToLocals (Add x xn None) tmx)
1117 | (refsToLocals (Add x xn None) tmy)
1118 | pure (union ci (union ct cs'))
1120 | unifyBothBinders mode loc env xfc x bx scx yfc y by scy
1125 | dumpArg : {vars : _} ->
1126 | {auto c : Ref Ctxt Defs} ->
1127 | Env Term vars -> Closure vars -> Core ()
1128 | dumpArg env (MkClosure opts loc lenv tm)
1130 | empty <- clearDefs defs
1131 | logTerm "unify" 20 "Term: " tm
1132 | nf <- evalClosure empty (MkClosure opts loc lenv tm)
1133 | logNF "unify" 20 " " env nf
1136 | empty <- clearDefs defs
1137 | nf <- evalClosure empty cl
1138 | logNF "unify" 20 " " env nf
1141 | unifyNoEta : {auto c : Ref Ctxt Defs} ->
1142 | {auto u : Ref UST UState} ->
1144 | UnifyInfo -> FC -> Env Term vars ->
1147 | unifyNoEta mode loc env (NDCon xfc x tagx ax xs) (NDCon yfc y tagy ay ys)
1163 | unifyArgs mode loc env (map snd xs) (map snd ys)
1164 | else convertError loc env
1165 | (NDCon xfc x tagx ax xs)
1166 | (NDCon yfc y tagy ay ys)
1167 | unifyNoEta mode loc env (NTCon xfc x ax xs) (NTCon yfc y ay ys)
1168 | = do logC "unify" 20 $
do
1171 | pure $
"Comparing type constructors " ++ show x ++ " and " ++ show y
1173 | then do let xs = map snd xs
1177 | pure $
"Constructor " ++ show x
1178 | logC "unify" 20 $
map (const "") $
traverse_ (dumpArg env) xs
1179 | logC "unify" 20 $
map (const "") $
traverse_ (dumpArg env) ys
1180 | unifyArgs mode loc env xs ys
1188 | else convertError loc env
1191 | unifyNoEta mode loc env (NDelayed xfc _ x) (NDelayed yfc _ y)
1192 | = unify (lower mode) loc env x y
1193 | unifyNoEta mode loc env (NDelay xfc _ xty x) (NDelay yfc _ yty y)
1194 | = unifyArgs mode loc env [xty, x] [yty, y]
1195 | unifyNoEta mode loc env (NForce xfc _ x axs) (NForce yfc _ y ays)
1196 | = do cs <- unify (lower mode) loc env x y
1197 | cs' <- unifyArgs mode loc env (map snd axs) (map snd ays)
1199 | unifyNoEta mode loc env x@(NApp xfc fx@(NMeta {}) axs)
1200 | y@(NApp yfc fy@(NMeta {}) ays)
1202 | if !(convert defs env x y)
1204 | else unifyBothApps (lower mode) loc env xfc fx axs yfc fy ays
1205 | unifyNoEta mode loc env (NApp xfc fx axs) (NApp yfc fy ays)
1206 | = unifyBothApps (lower mode) loc env xfc fx axs yfc fy ays
1207 | unifyNoEta mode loc env x (NErased _ (Dotted y)) = unifyNoEta mode loc env x y
1208 | unifyNoEta mode loc env (NErased _ (Dotted x)) y = unifyNoEta mode loc env x y
1209 | unifyNoEta mode loc env (NApp xfc hd args) y
1210 | = unifyApp False (lower mode) loc env xfc hd args y
1211 | unifyNoEta mode loc env y (NApp yfc hd args)
1212 | = if umode mode /= InMatch
1213 | then unifyApp True mode loc env yfc hd args y
1214 | else do log "unify.noeta" 10 $
"Unify if Eq due to something with app"
1215 | unifyIfEq True loc mode env y (NApp yfc hd args)
1217 | unifyNoEta mode loc env x (NAs _ _ _ y) = unifyNoEta mode loc env x y
1218 | unifyNoEta mode loc env (NAs _ _ _ x) y = unifyNoEta mode loc env x y
1219 | unifyNoEta mode loc env x y
1221 | empty <- clearDefs defs
1222 | log "unify.noeta" 10 $
"Nothing else worked, unifyIfEq"
1223 | unifyIfEq (isDelay x || isDelay y) loc mode env x y
1228 | isDelay : NF vars -> Bool
1229 | isDelay (NDelayed {}) = True
1232 | isHoleApp : NF vars -> Bool
1233 | isHoleApp (NApp _ (NMeta {}) _) = True
1238 | unifyD _ _ mode loc env (NBind xfc x bx scx) (NBind yfc y by scy)
1239 | = unifyBothBinders mode loc env xfc x bx scx yfc y by scy
1240 | unifyD _ _ mode loc env tmx@(NBind xfc x (Lam fcx cx ix tx) scx) tmy
1242 | logNF "unify" 10 "EtaR" env tmx
1243 | logNF "unify" 10 "...with" env tmy
1245 | then if not !(convert defs env tmx tmy)
1246 | then unifyNoEta (lower mode) loc env tmx tmy
1248 | else do empty <- clearDefs defs
1249 | domty <- quote empty env tx
1251 | $
Bind xfc x (Lam fcx cx Explicit domty)
1252 | $
App xfc (weaken !(quote empty env tmy))
1253 | (Local xfc Nothing 0 First)
1254 | logNF "unify" 10 "Expand" env etay
1255 | unify (lower mode) loc env tmx etay
1256 | unifyD _ _ mode loc env tmx tmy@(NBind yfc y (Lam fcy cy iy ty) scy)
1258 | logNF "unify" 10 "EtaL" env tmx
1259 | logNF "unify" 10 "...with" env tmy
1261 | then if not !(convert defs env tmx tmy)
1262 | then unifyNoEta (lower mode) loc env tmx tmy
1264 | else do empty <- clearDefs defs
1265 | domty <- quote empty env ty
1267 | $
Bind yfc y (Lam fcy cy Explicit domty)
1268 | $
App yfc (weaken !(quote empty env tmx))
1269 | (Local yfc Nothing 0 First)
1270 | logNF "unify" 10 "Expand" env etax
1271 | unify (lower mode) loc env etax tmy
1272 | unifyD _ _ mode loc env tmx tmy = unifyNoEta mode loc env tmx tmy
1274 | unifyWithLazyD _ _ mode loc env (NDelayed _ _ tmx) (NDelayed _ _ tmy)
1275 | = unify (lower mode) loc env tmx tmy
1276 | unifyWithLazyD _ _ mode loc env x@(NDelayed _ r tmx) tmy
1277 | = if isHoleApp tmy && not (umode mode == InMatch)
1280 | then postpone loc mode "Postponing in lazy" env x tmy
1281 | else do vs <- unify (lower mode) loc env tmx tmy
1282 | pure ({ addLazy := AddForce r } vs)
1283 | unifyWithLazyD _ _ mode loc env tmx (NDelayed _ r tmy)
1284 | = do vs <- unify (lower mode) loc env tmx tmy
1285 | pure ({ addLazy := AddDelay r } vs)
1286 | unifyWithLazyD _ _ mode loc env tmx tmy
1287 | = unify mode loc env tmx tmy
1291 | unifyD _ _ mode loc env x y
1293 | empty <- clearDefs defs
1295 | then do log "unify.equal" 10 $
1296 | "Skipped unification (equal already): "
1297 | ++ show x ++ " and " ++ show y
1299 | else do xnf <- nf defs env x
1301 | unify mode loc env xnf ynf
1302 | unifyWithLazyD _ _ mode loc env x y
1304 | empty <- clearDefs defs
1306 | then do log "unify.equal" 10 $
1307 | "Skipped unification (equal already): "
1308 | ++ show x ++ " and " ++ show y
1310 | else do xnf <- nf defs env x
1312 | unifyWithLazy mode loc env xnf ynf
1316 | unifyD _ _ mode loc env x y
1318 | empty <- clearDefs defs
1319 | if !(convert empty env x y)
1322 | do xnf <- evalClosure defs x
1323 | ynf <- evalClosure defs y
1328 | (NApp _ (NMeta {}) _, NApp _ (NMeta {}) _)
1329 | => unify mode loc env xnf ynf
1330 | (NApp _ (NMeta _ i _) _, _) =>
1331 | do ynf' <- evalClosure empty y
1332 | xtm <- quote empty env xnf
1333 | ytm <- quote empty env ynf'
1334 | cs <- unify mode loc env !(nf empty env xtm)
1338 | _ => do ynf <- evalClosure defs y
1339 | unify mode loc env xnf ynf
1340 | (_, NApp _ (NMeta _ i _ ) _) =>
1341 | do xnf' <- evalClosure empty x
1342 | xtm <- quote empty env xnf'
1343 | ytm <- quote empty env ynf
1344 | cs <- unify mode loc env !(nf empty env ytm)
1348 | _ => unify mode loc env xnf ynf
1349 | _ => unify mode loc env xnf ynf
1352 | setInvertible : {auto c : Ref Ctxt Defs} ->
1356 | Just gdef <- lookupCtxtExact n (gamma defs)
1357 | | Nothing => undefinedName fc n
1358 | ignore $
addDef n ({ invertible := True } gdef)
1361 | data SolveMode = Normal
1367 | Normal == Normal = True
1368 | Defaults == Defaults = True
1369 | LastChance == LastChance = True
1373 | retry : {auto c : Ref Ctxt Defs} ->
1374 | {auto u : Ref UST UState} ->
1375 | UnifyInfo -> Int -> Core UnifyResult
1378 | case lookup c (constraints ust) of
1379 | Nothing => pure success
1380 | Just Resolved => pure success
1381 | Just (MkConstraint loc withLazy env xold yold)
1383 | x <- continueNF defs env xold
1384 | y <- continueNF defs env yold
1386 | (do logNF "unify.retry" 5 ("Retrying " ++ show c ++ " " ++ show (umode mode)) env x
1387 | logNF "unify.retry" 5 "....with" env y
1388 | log "unify.retry" 5 $
if withLazy
1391 | cs <- ifThenElse withLazy
1392 | (unifyWithLazy mode loc env x y)
1393 | (unify (lower mode) loc env x y)
1395 | [] => do log "unify.retry" 5 $
"Success " ++ show (addLazy cs)
1398 | _ => do log "unify.retry" 5 $
"Constraints " ++ show (addLazy cs)
1400 | (\err => do defs <- get Ctxt
1401 | empty <- clearDefs defs
1402 | throw (WhenUnifying loc (gamma defs) env !(quote empty env x) !(quote empty env y) err))
1404 | delayMeta : {vars : _} ->
1405 | LazyReason -> Nat -> Term vars -> Term vars -> Term vars
1406 | delayMeta r (S k) ty (Bind fc n b sc)
1407 | = Bind fc n b (delayMeta r k (weaken ty) sc)
1408 | delayMeta r envb ty tm = TDelay (getLoc tm) r ty tm
1410 | forceMeta : LazyReason -> Nat -> Term vars -> Term vars
1411 | forceMeta r (S k) (Bind fc n b sc)
1412 | = Bind fc n b (forceMeta r k sc)
1413 | forceMeta r envb tm = TForce (getLoc tm) r tm
1416 | recoverable : Error -> Bool
1417 | recoverable (UndefinedName {}) = False
1418 | recoverable (InType _ _ err) = recoverable err
1419 | recoverable (InCon _ err) = recoverable err
1420 | recoverable (InLHS _ _ err) = recoverable err
1421 | recoverable (InRHS _ _ err) = recoverable err
1422 | recoverable (WhenUnifying _ _ _ _ _ err) = recoverable err
1423 | recoverable (MaybeMisspelling err _) = recoverable err
1427 | retryGuess : {auto c : Ref Ctxt Defs} ->
1428 | {auto u : Ref UST UState} ->
1429 | UnifyInfo -> (smode : SolveMode) -> (hole : (Int, (FC, Name))) ->
1431 | retryGuess mode smode (hid, (loc, hname))
1433 | case !(lookupCtxtExact (Resolved hid) (gamma defs)) of
1437 | BySearch rig depth defining =>
1439 | (do tm <- search loc rig (smode == Defaults) depth defining
1441 | let gdef = { definition := PMDef defaultPI Scope.empty (STerm 0 tm) (STerm 0 tm) [] } def
1442 | logTermNF "unify.retry" 5 ("Solved " ++ show hname) Env.empty tm
1443 | ignore $
addDef (Resolved hid) gdef
1447 | DeterminingArg _ n i _ _ =>
1448 | do logTerm "unify.retry" 5
1449 | ("Failed (det " ++ show hname ++ " " ++ show n ++ ")")
1451 | setInvertible loc (Resolved i)
1454 | do logTermNF "unify.retry" 5
1455 | ("Search failed at " ++ show rig ++ " for " ++ show hname)
1458 | LastChance => throw err
1459 | _ => if recoverable err
1461 | else throw (CantSolveGoal loc (gamma defs)
1462 | Env.empty (type def) (Just err))
1463 | Guess tm envb [constr] =>
1464 | do let umode = case smode of
1467 | cs <- retry umode constr
1469 | [] => do tm' <- case addLazy cs of
1471 | AddForce r => pure $
forceMeta r envb tm
1473 | do ty <- getType Env.empty tm
1474 | logTerm "unify.retry" 5 "Retry Delay" tm
1475 | pure $
delayMeta r envb !(getTerm ty) tm
1476 | let gdef = { definition := PMDef (MkPMDefInfo NotHole True False)
1477 | Scope.empty (STerm 0 tm') (STerm 0 tm') [] } def
1478 | logTerm "unify.retry" 5 ("Resolved " ++ show hname) tm'
1479 | ignore $
addDef (Resolved hid) gdef
1482 | newcs => do tm' <- case addLazy cs of
1484 | AddForce r => pure $
forceMeta r envb tm
1486 | do ty <- getType Env.empty tm
1487 | logTerm "unify.retry" 5 "Retry Delay (constrained)" tm
1488 | pure $
delayMeta r envb !(getTerm ty) tm
1489 | let gdef = { definition := Guess tm' envb newcs } def
1490 | ignore $
addDef (Resolved hid) gdef
1492 | Guess tm envb constrs =>
1493 | do let umode = case smode of
1496 | cs' <- traverse (retry umode) constrs
1497 | let csAll = unionAll cs'
1498 | case constraints csAll of
1502 | [] => do let gdef = { definition := PMDef (MkPMDefInfo NotHole True False)
1503 | Scope.empty (STerm 0 tm) (STerm 0 tm) [] } def
1504 | logTerm "unify.retry" 5 ("Resolved " ++ show hname) tm
1505 | ignore $
addDef (Resolved hid) gdef
1507 | pure (holesSolved csAll)
1508 | newcs => do let gdef = { definition := Guess tm envb newcs } def
1509 | ignore $
addDef (Resolved hid) gdef
1514 | solveConstraints : {auto c : Ref Ctxt Defs} ->
1515 | {auto u : Ref UST UState} ->
1516 | UnifyInfo -> (smode : SolveMode) -> Core ()
1517 | solveConstraints umode smode
1519 | progress <- traverse (retryGuess umode smode) (toList (guesses ust))
1520 | when (any id progress) $
1521 | solveConstraints umode Normal
1524 | solveConstraintsAfter : {auto c : Ref Ctxt Defs} ->
1525 | {auto u : Ref UST UState} ->
1526 | Int -> UnifyInfo -> (smode : SolveMode) -> Core ()
1527 | solveConstraintsAfter start umode smode
1529 | progress <- traverse (retryGuess umode smode)
1530 | (filter afterStart (toList (guesses ust)))
1531 | when (any id progress) $
1532 | solveConstraintsAfter start umode Normal
1534 | afterStart : (Int, a) -> Bool
1535 | afterStart (x, _) = x >= start
1540 | giveUpConstraints : {auto c : Ref Ctxt Defs} ->
1541 | {auto u : Ref UST UState} ->
1545 | traverse_ constraintToHole (toList (guesses ust))
1547 | constraintToHole : (Int, (FC, Name)) -> Core ()
1548 | constraintToHole (hid, (_, _))
1550 | case !(lookupDefExact (Resolved hid) (gamma defs)) of
1552 | updateDef (Resolved hid) (const (Just (Hole 0 (holeInit False))))
1554 | updateDef (Resolved hid) (const (Just (Hole 0 (holeInit False))))
1560 | checkArgsSame : {auto u : Ref UST UState} ->
1561 | {auto c : Ref Ctxt Defs} ->
1563 | checkArgsSame [] = pure False
1564 | checkArgsSame (x :: xs)
1566 | Just (PMDef _ [] (STerm 0 def) _ _) <-
1567 | lookupDefExact (Resolved x) (gamma defs)
1568 | | _ => checkArgsSame xs
1574 | anySame : ClosedTerm -> List Int -> Core Bool
1575 | anySame tm [] = pure False
1578 | Just (PMDef _ [] (STerm 0 def) _ _) <-
1579 | lookupDefExact (Resolved t) (gamma defs)
1581 | if !(convert defs Env.empty tm def)
1586 | checkDots : {auto u : Ref UST UState} ->
1587 | {auto c : Ref Ctxt Defs} ->
1592 | traverse_ checkConstraint (reverse (dotConstraints ust))
1594 | update UST { dotConstraints := [] }
1596 | getHoleName : ClosedTerm -> Core (Maybe Name)
1599 | NApp _ (NMeta n' i args) _ <- nf defs Env.empty tm
1603 | checkConstraint : (Name, DotReason, Constraint) -> Core ()
1604 | checkConstraint (n, reason, MkConstraint fc wl env xold yold)
1606 | x <- continueNF defs env xold
1607 | y <- continueNF defs env yold
1608 | logNF "unify.constraint" 10 "Dot" env y
1609 | logNF "unify.constraint" 10 " =" env x
1617 | (i, _) <- getPosition n (gamma defs)
1618 | oldholen <- getHoleName (Meta fc n i [])
1625 | cs <- unify inMatch fc env x y
1634 | (\n => do Just ndef <- lookupDefExact n (gamma defs)
1635 | | Nothing => undefinedName fc n
1643 | argsSame <- checkArgsSame (namesSolved cs)
1644 | when (not (isNil (constraints cs))
1645 | || dotSolved || argsSame) $
1646 | throw (InternalError "Dot pattern match fail"))
1651 | Just dty <- lookupTyExact n (gamma defs)
1652 | | Nothing => undefinedName fc n
1653 | logTermNF "unify.constraint" 5 "Dot type" Env.empty dty
1656 | put UST ({ dotConstraints := [] } ust)
1657 | empty <- clearDefs defs
1658 | throw (BadDotPattern fc env reason
1661 | _ => do put UST ({ dotConstraints := [] } ust)
1663 | checkConstraint _ = pure ()