@@ -6,7 +6,7 @@
66
77module Idris.Core.ProofState(ProofState(..), newProof, envAtFocus, goalAtFocus,
88 Tactic(..), Goal(..), processTactic, nowElaboratingPS, doneElaboratingAppPS,
9− doneElaboratingArgPS, dropGiven, keepGiven) where
9+ doneElaboratingArgPS, dropGiven, keepGiven, getProvenance) where
1010
1111import Idris.Core.Typecheck
1212import Idris.Core.Evaluate
@@ -154,9 +154,11 @@ holeName i = sMN i "hole"
154154qshow :: Fails -> String
155155qshow fs = show (map (\ (x, y, hs, _, _, _, t) -> (t, x, y, hs)) fs)
156156
157−match_unify' :: Context -> Env -> TT Name -> TT Name ->
157+match_unify' :: Context -> Env ->
158+ (TT Name, Maybe Provenance) ->
159+ (TT Name, Maybe Provenance) ->
158160 StateT TState TC [(Name, TT Name)]
159−match_unify' ctxt env topx topy =
161+match_unify' ctxt env (topx, xfrom) (topy, yfrom) =
160162 do ps <- get
161163 let while = while_elaborating ps
162164 let dont = dontunify ps
@@ -168,7 +170,7 @@ match_unify' ctxt env topx topy =
168170 ++ "\n"
169171 ++ "\n" ++ show (getProofTerm (pterm ps)) ++ "\n\n"
170172 ) $
171− case match_unify ctxt env topx topy inj (holes ps) while of
173+ case match_unify ctxt env (topx, xfrom) (topy, yfrom) inj (holes ps) while of
172174 OK u -> traceWhen (unifylog ps)
173175 ("Matched " ++ show u) $
174176 do let (h, ns) = unified ps
@@ -196,14 +198,16 @@ mergeSolutions env ns = merge [] ns
196198 = do ps <- get
197199 let probs = problems ps
198200 put (ps { problems = probs ++ [(t,t',True,env,
199− CantUnify True t t' (Msg "") (errEnv env) 0,
201+ CantUnify True (t, Nothing) (t', Nothing) (Msg "") (errEnv env) 0,
200202 [], Unify)] })
201203 merge acc ns
202204 | otherwise = merge ((n, t): acc) ns
203205
204−unify' :: Context -> Env -> TT Name -> TT Name ->
206+unify' :: Context -> Env ->
207+ (TT Name, Maybe Provenance) ->
208+ (TT Name, Maybe Provenance) ->
205209 StateT TState TC [(Name, TT Name)]
206−unify' ctxt env topx topy =
210+unify' ctxt env (topx, xfrom) (topy, yfrom) =
207211 do ps <- get
208212 let while = while_elaborating ps
209213 let dont = dontunify ps
@@ -216,7 +220,7 @@ unify' ctxt env topx topy =
216220 "\nHoles: " ++ show (holes ps)
217221 ++ "\nInjective: " ++ show (injective ps)
218222 ++ "\n") $
219− lift $ unify ctxt env topx topy inj (holes ps)
223+ lift $ unify ctxt env (topx, xfrom) (topy, yfrom) inj (holes ps)
220224 (map fst (notunified ps)) while
221225 let notu = filter (\ (n, t) -> case t of
222226-- P _ _ _ -> False
@@ -456,7 +460,7 @@ regret ctxt env (Bind x (Hole t) _)
456460unifyGoal :: Raw -> RunTactic
457461unifyGoal tm ctxt env h@(Bind x b sc) =
458462 do (tmv, _) <- lift $ check ctxt env tm
459− ns' <- unify' ctxt env (binderTy b) tmv
463+ ns' <- unify' ctxt env (binderTy b, Nothing) (tmv, Nothing)
460464 return h
461465
462466exact :: Raw -> RunTactic
@@ -473,12 +477,20 @@ fill guess ctxt env (Bind x (Hole ty) sc) =
473477 do (val, valty) <- lift $ check ctxt env guess
474478-- let valtyn = normalise ctxt env valty
475479-- let tyn = normalise ctxt env ty
476− ns <- unify' ctxt env valty ty
480+ ns <- unify' ctxt env (valty, Just $ SourceTerm val)
481+ (ty, Just (chkPurpose val ty))
477482 ps <- get
478483 let (uh, uns) = unified ps
479484-- put (ps { unified = (uh, uns ++ ns) })
480485-- addLog (show (uh, uns ++ ns))
481486 return $ Bind x (Guess ty val) sc
487+ where
488+ -- some expected types show up commonly in errors and indicate a
489+ -- specific problem.
490+ -- argTy -> retTy suggests a function applied to too many arguments
491+ chkPurpose val (Bind _ (Pi _ (P _ (MN _ _) _) _) (P _ (MN _ _) _))
492+ = TooManyArgs val
493+ chkPurpose _ _ = ExpectedType
482494fill _ _ _ _ = fail "Can't fill here."
483495
484496-- As fill, but attempts to solve other goals by matching
@@ -488,7 +500,8 @@ match_fill guess ctxt env (Bind x (Hole ty) sc) =
488500 do (val, valty) <- lift $ check ctxt env guess
489501-- let valtyn = normalise ctxt env valty
490502-- let tyn = normalise ctxt env ty
491− ns <- match_unify' ctxt env valty ty
503+ ns <- match_unify' ctxt env (valty, Just $ SourceTerm val)
504+ (ty, Just ExpectedType)
492505 ps <- get
493506 let (uh, uns) = unified ps
494507-- put (ps { unified = (uh, uns ++ ns) })
@@ -506,7 +519,8 @@ complete_fill :: RunTactic
506519complete_fill ctxt env (Bind x (Guess ty val) sc) =
507520 do let guess = forget val
508521 (val', valty) <- lift $ check ctxt env guess
509− ns <- unify' ctxt env valty ty
522+ ns <- unify' ctxt env (valty, Just $ SourceTerm val')
523+ (ty, Just ExpectedType)
510524 ps <- get
511525 let (uh, uns) = unified ps
512526-- put (ps { unified = (uh, uns ++ ns) })
@@ -524,7 +538,8 @@ solve ctxt env (Bind x (Guess ty val) sc)
524538 dropdots <-
525539 case lookup x (notunified ps) of
526540 Just tm -> -- trace ("NEED MATCH: " ++ show (x, tm, val) ++ "\nIN " ++ show (pterm ps)) $
527− do match_unify' ctxt env tm val
541+ do match_unify' ctxt env (tm, Just InferredVal)
542+ (val, Just GivenVal)
528543 return [x]
529544 _ -> return []
530545 action (\ps -> ps { holes = traceWhen (unifylog ps) ("Dropping hole " ++ show x) $
@@ -567,7 +582,7 @@ introTy ty mn ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
567582-- ns <- lift $ unify ctxt env tyv t'
568583 case t' of
569584 Bind y (Pi _ s _) t -> let t' = subst y (P Bound n s) t in
570− do ns <- unify' ctxt env s tyv
585+ do ns <- unify' ctxt env (s, Nothing) (tyv, Nothing)
571586 ps <- get
572587 let (uh, uns) = unified ps
573588-- put (ps { unified = (uh, uns ++ ns) })
@@ -593,8 +608,8 @@ intro n ctxt env _ = fail "Can't introduce here."
593608forall :: Name -> Maybe ImplicitInfo -> Raw -> RunTactic
594609forall n impl ty ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
595610 do (tyv, tyt) <- lift $ check ctxt env ty
596− unify' ctxt env tyt (TType (UVar 0))
597− unify' ctxt env t (TType (UVar 0))
611+ unify' ctxt env (tyt, Nothing) (TType (UVar 0), Nothing)
612+ unify' ctxt env (t, Nothing) (TType (UVar 0), Nothing)
598613 return $ Bind n (Pi impl tyv (TType (UVar 0))) (Bind x (Hole t) (P Bound x t))
599614forall n impl ty ctxt env _ = fail "Can't pi bind here"
600615
@@ -817,13 +832,17 @@ updateEnv ns [] = []
817832updateEnv ns ((n, b) : env)
818833 = (n, fmap (updateSolvedTerm ns) b) : updateEnv ns env
819834
835+updateProv ns (SourceTerm t) = SourceTerm $ updateSolvedTerm ns t
836+updateProv ns p = p
837+
820838updateError [] err = err
821839updateError ns (At f e) = At f (updateError ns e)
822840updateError ns (Elaborating s n e) = Elaborating s n (updateError ns e)
823841updateError ns (ElaboratingArg f a env e)
824842 = ElaboratingArg f a env (updateError ns e)
825−updateError ns (CantUnify b l r e xs sc)
826− = CantUnify b (updateSolvedTerm ns l) (updateSolvedTerm ns r) (updateError ns e) xs sc
843+updateError ns (CantUnify b (l,lp) (r,rp) e xs sc)
844+ = CantUnify b (updateSolvedTerm ns l, fmap (updateProv ns) lp)
845+ (updateSolvedTerm ns r, fmap (updateProv ns) rp) (updateError ns e) xs sc
827846updateError ns e = e
828847
829848solveInProblems x val [] = []
@@ -837,7 +856,7 @@ mergeNotunified env holes ns = mnu ns [] [] where
837856 mnu ((n, t):ns) ns_acc ps_acc
838857 | Just t' <- lookup n ns, t /= t'
839858 = mnu ns ((n,t') : ns_acc)
840− ((t,t',True, env,CantUnify True t t' (Msg "") [] 0, [],Match) : ps_acc)
859+ ((t,t',True, env,CantUnify True (t, Nothing) (t', Nothing) (Msg "") [] 0, [],Match) : ps_acc)
841860 | otherwise = mnu ns ((n,t) : ns_acc) ps_acc
842861
843862updateNotunified [] nu = nu
@@ -846,6 +865,10 @@ updateNotunified ns nu = up nu where
846865 up ((n, t) : nus) = let t' = updateSolvedTerm ns t in
847866 ((n, t') : up nus)
848867
868+getProvenance :: Err -> (Maybe Provenance, Maybe Provenance)
869+getProvenance (CantUnify _ (_, lp) (_, rp) _ _ _) = (lp, rp)
870+getProvenance _ = (Nothing, Nothing)
871+
849872updateProblems :: ProofState -> [(Name, TT Name)] -> Fails
850873 -> ([(Name, TT Name)], Fails)
851874-- updateProblems ctxt [] ps inj holes = ([], ps)
@@ -860,11 +883,12 @@ updateProblems ps updates probs = up updates probs where
860883 up ns (prob@(x, y, ready, env, err, while, um) : ps) =
861884 let (x', newx) = updateSolvedTerm' ns x
862885 (y', newy) = updateSolvedTerm' ns y
886+ (lp, rp) = getProvenance err
863887 err' = updateError ns err
864888 env' = updateEnv ns env in
865889 if newx || newy || ready ||
866890 any (\n -> n `elem` inj) (refsIn x ++ refsIn y) then
867− case unify ctxt env' x' y' inj hs usupp while of
891+ case unify ctxt env' (x', lp) (y', rp) inj hs usupp while of
868892 OK (v, []) -> traceWhen ulog ("DID " ++ show (x',y',ready,v)) $
869893 up (ns ++ v) ps
870894 e -> -- trace ("FAILED " ++ show (x',y',ready,e)) $
@@ -887,9 +911,10 @@ matchProblems all ps updates probs = up updates probs where
887911 | all || um == Match =
888912 let x' = updateSolvedTerm ns x
889913 y' = updateSolvedTerm ns y
914+ (lp, rp) = getProvenance err
890915 err' = updateError ns err
891916 env' = updateEnv ns env in
892− case match_unify ctxt env' x' y' inj hs while of
917+ case match_unify ctxt env' (x', lp) (y', rp) inj hs while of
893918 OK v -> -- trace ("Added " ++ show v ++ " from " ++ show (x', y')) $
894919 up (ns ++ v) ps
895920 _ -> let (ns', ps') = up ns ps in