on master help sign in
Unify more things!

If two solutions arrive at more or less the same time (e.g. part of the same application) but are not identical, we need to unify them before propagating solutions.

commit41f921fd687a61dc3fb392e2d79fb6f5287893d0 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateThu 29 May 2014, 14:46 (12 years ago) parent5c4ee75
3 files changed+32−10
src/Idris/Core/Elaborate.hs+4−2 src/Idris/Core/ProofState.hs+25−7 src/Idris/ElabTerm.hs+3−1
src/Idris/Core/Elaborate.hs+4−2
@@ -681,11 +681,13 @@ try' :: Elab' aux a -> Elab' aux a -> Bool -> Elab' aux a
681681try' t1 t2 proofSearch
682682 = do s <- get
683683 ps <- get_probs
684+ ulog <- getUnifyLog
684685 case prunStateT 999999 False ps t1 s of
685686 OK ((v, _, _), s') -> do put s'
686687 return $! v
687− Error e1 -> if recoverableErr e1 then
688− do case runStateT t2 s of
688+ Error e1 -> traceWhen ulog ("try failed " ++ show e1) $
689+ if recoverableErr e1 then
690+ do case runStateT t2 s of
689691 OK (v, s') -> do put s'; return $! v
690692 Error e2 -> if score e1 >= score e2
691693 then lift (tfail e1)
src/Idris/Core/ProofState.hs+25−7
@@ -180,6 +180,19 @@ match_unify' ctxt env topx topy =
180180-- -- ++ show (pterm ps)
181181-- ++ "\n----------") $
182182
183+mergeSolutions :: Env -> [(Name, TT Name)] -> StateT TState TC [(Name, TT Name)]
184+mergeSolutions env ns = merge [] ns
185+ where
186+ merge acc [] = return (reverse acc)
187+ merge acc ((n, t) : ns)
188+ | Just t' <- lookup n ns
189+ = do ps <- get
190+ let probs = problems ps
191+ put (ps { problems = probs ++ [(t,t',env,Msg "New problem",
192+ [], Unify)] })
193+ merge acc ns
194+ | otherwise = merge ((n, t): acc) ns
195+
183196unify' :: Context -> Env -> TT Name -> TT Name ->
184197 StateT TState TC [(Name, TT Name)]
185198unify' ctxt env topx topy =
@@ -206,17 +219,22 @@ unify' ctxt env topx topy =
206219 ++ "\nCurrent problems:\n" ++ qshow (problems ps)
207220-- ++ show (pterm ps)
208221 ++ "\n----------") $
209− do ps <- get
210− let (h, ns) = unified ps
211− let (ns', probs') = updateProblems (context ps) (u ++ ns)
222+ do let (h, ns) = unified ps
223+ -- if a metavar has multiple solutions, make a new unification
224+ -- problem for each.
225+ uns <- mergeSolutions env (u ++ ns)
226+ ps <- get
227+ let (ns', probs') = updateProblems (context ps) uns
212228 (fails ++ problems ps)
213229 (injective ps)
214230 (holes ps)
215231 let (notu', probs_notu) = mergeNotunified env (notu ++ notunified ps)
216− put (ps { problems = probs' ++ probs_notu,
217− unified = (h, ns'),
218− injective = updateInj u (injective ps),
219− notunified = notu' })
232+ traceWhen (unifylog ps)
233+ ("Now solved: " ++ show ns') $
234+ put (ps { problems = probs' ++ probs_notu,
235+ unified = (h, ns'),
236+ injective = updateInj u (injective ps),
237+ notunified = notu' })
220238 return u
221239 where updateInj ((n, a) : us) inj
222240 | (P _ n' _, _) <- unApply a,
src/Idris/ElabTerm.hs+3−1
@@ -66,9 +66,11 @@ build ist info pattern opts fn tm
6666 ctxt <- get_context
6767 probs <- get_probs
6868 u <- getUnifyLog
69+ hs <- get_holes
6970
7071 when (not pattern) $
71− traceWhen u ("Remaining problems:\n" ++ show probs) $
72+ traceWhen u ("Remaining holes:\n" ++ show hs ++ "\n" ++
73+ "Remaining problems:\n" ++ show probs) $
7274 do unify_all; matchProblems True; unifyProblems
7375
7476 probs <- get_probs