on master help sign in
Remember constants when checking recoverability

A primitive constant against a function application may turn out to be unifiable if the function gets to reduce. Fixes #3792

commit3fba96b60f8e5ede25d7e52a99d2bbcfb2c1b9c0 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateThu 4 May 2017, 13:08 (9 years ago) parentaa0abbc
4 files changed+45−12
src/Idris/Coverage.hs+29−12 test/regression002/Canonicity.idr+13 test/regression002/expected+2 test/regression002/run+1
src/Idris/Coverage.hs+29−12
@@ -410,31 +410,43 @@ recoverableCoverage _ _ = False
410410-- with
411411checkRec :: Term -> Term -> State [(Name, Term)] Bool
412412checkRec (P Bound x _) tm
413− | (P yt _ _, _) <- unApply tm,
414− conType yt = do nmap <- get
415− case lookup x nmap of
416− Nothing -> do put ((x, tm) : nmap)
417− return True
418− Just y' -> checkRec tm y'
413+ | isCon tm = do nmap <- get
414+ case lookup x nmap of
415+ Nothing -> do put ((x, tm) : nmap)
416+ return True
417+ Just y' -> checkRec tm y'
419418 where
419+ isCon tm
420+ | (P yt _ _, _) <- unApply tm,
421+ conType yt = True
422+ isCon (Constant _) = True
423+ isCon _ = False
424+
420425 conType (DCon _ _ _) = True
421426 conType (TCon _ _) = True
422427 conType _ = False
423428
424429checkRec tm (P Bound y _)
425− | (P xt _ _, _) <- unApply tm,
426− conType xt = do nmap <- get
427− case lookup y nmap of
428− Nothing -> do put ((y, tm) : nmap)
429− return True
430− Just x' -> checkRec tm x'
430+ | isCon tm = do nmap <- get
431+ case lookup y nmap of
432+ Nothing -> do put ((y, tm) : nmap)
433+ return True
434+ Just x' -> checkRec tm x'
431435 where
436+ isCon tm
437+ | (P yt _ _, _) <- unApply tm,
438+ conType yt = True
439+ isCon (Constant _) = True
440+ isCon _ = False
441+
432442 conType (DCon _ _ _) = True
433443 conType (TCon _ _) = True
434444 conType _ = False
435445
436446checkRec (App _ f a) p@(P _ _ _) = checkRec f p
447+checkRec (App _ f a) p@(Constant _) = checkRec f p
437448checkRec p@(P _ _ _) (App _ f a) = checkRec p f
449+checkRec p@(Constant _) (App _ f a) = checkRec p f
438450checkRec fa@(App _ _ _) fa'@(App _ _ _)
439451 | (f, as) <- unApply fa,
440452 (f', as') <- unApply fa'
@@ -454,6 +466,7 @@ checkRec fa@(App _ _ _) fa'@(App _ _ _)
454466 return (aok && asok)
455467 conType (P (DCon _ _ _) _ _) = True
456468 conType (P (TCon _ _) _ _) = True
469+ conType (Constant _) = True
457470 conType _ = False
458471
459472checkRec (P xt x _) (P yt y _)
@@ -469,4 +482,8 @@ checkRec (P xt x _) (P yt y _)
469482 | Bound <- x = True
470483 | Bound <- y = True
471484 | otherwise = False -- name is different, unrecoverable
485+-- A function reference against a constant might be recoverable if we get to
486+-- reduce the function
487+checkRec (P Ref _ _) (Constant _) = return True
488+checkRec (Constant _) (P Ref _ _) = return True
472489checkRec _ _ = return False
test/regression002/Canonicity.idrnew file+13
@@ -0,0 +1,13 @@
1+module Canonicity
2+%default total
3+
4+data ZeroSumList : Integer -> Type where
5+ Cons : (m : Integer) -> ZeroSumList n -> ZeroSumList (m + n)
6+ Nil : ZeroSumList 0
7+
8+f : ZeroSumList 0 -> Nat
9+f Nil = 0
10+
11+NaN : Nat
12+NaN = f (Cons 0 Nil)
13+
test/regression002/expected+2
@@ -145,3 +145,5 @@ When checking argument value to function Prelude.Basics.the:
145145 -0.0
146146 and
147147 0.0
148+Canonicity.idr:9:1:Canonicity.f is not total as there are missing cases
149+Canonicity.idr:12:1:Canonicity.NaN is possibly not total due to: Canonicity.f
test/regression002/run+1
@@ -32,6 +32,7 @@ ${IDRIS:-idris} $@ --nobanner --nocolour --quiet --port none <<!
3232:load reg076.idr
3333:load reg077.idr
3434:load DoubleEquality.idr
35+:load Canonicity.idr
3536!
3637
3738rm -f *.ibc