on master help sign in
Coverage checker fix

The patterns generated for the 'impossible' cases were not done correctly in the case of ambiguous zero argument constructors, where it generated a 'match anything' pattern. This is bad news for things which use [] because that just became 'match anything'! Also fixed a couple of definitions which relied on this bug, and added a comment or two.

commitfb6a0ed1ad5e3acc3795d7ab674977bdb419129a authorEdwin Brady <eb@cs.st-andrews.ac.uk> dateWed 2 Apr 2014, 00:04 (13 years ago) parent86f68b5
5 files changed+27−11
libs/base/Data/HVect.idr+1 libs/prelude/Prelude/Vect.idr+2 src/Idris/AbsSyntax.hs+4−3 src/Idris/Coverage.hs+19−7 test/error004/FunErrTest.idr+1−1
libs/base/Data/HVect.idr+1
@@ -19,6 +19,7 @@ using (k : Nat, ts : Vect k Type)
1919 deleteAt : {us : Vect (S l) Type} -> (i : Fin (S l)) -> HVect us -> HVect (deleteAt i us)
2020 deleteAt fZ (x::xs) = xs
2121 deleteAt {l = S m} (fS j) (x::xs) = x :: deleteAt j xs
22+ deleteAt {l = Z} (fS j) (x::xs) = absurd j
2223 deleteAt _ [] impossible
2324
2425 replaceAt : (i : Fin k) -> t -> HVect ts -> HVect (replaceAt i t ts)
libs/prelude/Prelude/Vect.idr+2
@@ -7,6 +7,7 @@ import Prelude.List
77import Prelude.Classes
88import Prelude.Nat
99import Prelude.Bool
10+import Prelude.Uninhabited
1011
1112%access public
1213%default total
@@ -71,6 +72,7 @@ index fZ [] impossible
7172deleteAt : Fin (S n) -> Vect (S n) a -> Vect n a
7273deleteAt fZ (x::xs) = xs
7374deleteAt {n = S m} (fS k) (x::xs) = x :: deleteAt k xs
75+deleteAt {n = Z} (fS k) (x::xs) = absurd k
7476deleteAt _ [] impossible
7577
7678||| Replace an element at a particlar index with another
src/Idris/AbsSyntax.hs+4−3
@@ -1533,8 +1533,6 @@ matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
15331533 = do mf <- match' f f'
15341534 ms <- zipWithM matchArg args args'
15351535 return (mf ++ concat ms)
1536−-- match (PRef _ n) (PRef _ n') | n == n' = return []
1537−-- | otherwise = Nothing
15381536 match (PRef f n) (PApp _ x []) = match (PRef f n) x
15391537 match (PPatvar f n) xr = match (PRef f n) xr
15401538 match xr (PPatvar f n) = match xr (PRef f n)
@@ -1544,7 +1542,10 @@ matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
15441542 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
15451543 || tm == Placeholder)
15461544 = return [(n, tm)]
1547− | n == n' = return []
1545+ -- if one namespace is missing, drop the other
1546+ | n == n' || n == dropNS n' || dropNS n == n' = return []
1547+ where dropNS (NS n _) = n
1548+ dropNS n = n
15481549 match (PRef _ n) tm
15491550 | not names && (not (isConName n (tt_ctxt i) ||
15501551 isFnName n (tt_ctxt i)) || tm == Placeholder)
src/Idris/Coverage.hs+19−7
@@ -18,10 +18,14 @@ import Debug.Trace
1818
1919import Control.Monad.State.Strict
2020
21+-- Generate a pattern from an 'impossible' LHS. (Need this to eliminate the
22+-- pattern clauses which have been provided explicitly from new clause
23+-- generation.)
24+
2125mkPatTm :: PTerm -> Idris Term
2226mkPatTm t = do i <- getIState
2327 let timp = addImpl' True [] [] i t
24− evalStateT (toTT timp) 0
28+ evalStateT (toTT (mapPT deNS timp)) 0
2529 where
2630 toTT (PRef _ n) = do i <- lift getIState
2731 case lookupDef n (tt_ctxt i) of
@@ -30,10 +34,16 @@ mkPatTm t = do i <- getIState
3034 toTT (PApp _ t args) = do t' <- toTT t
3135 args' <- mapM (toTT . getTm) args
3236 return $ mkApp t' args'
37+ -- For alternatives, pick the first and drop the namespaces. It doesn't
38+ -- really matter which is taken since matching will ignore the namespace.
39+ toTT (PAlternative _ (a : as)) = toTT a
3340 toTT _ = do v <- get
3441 put (v + 1)
3542 return (P Bound (sMN v "imp") Erased)
3643
44+ deNS (PRef f (NS n _)) = PRef f n
45+ deNS t = t
46+
3747-- Given a list of LHSs, generate a extra clauses which cover the remaining
3848-- cases. The ones which haven't been provided are marked 'absurd' so that the
3949-- checker will make sure they can't happen.
@@ -50,10 +60,10 @@ genClauses fc n xs given
5060 logLvl 5 $ "COVERAGE of " ++ show n
5161 logLvl 5 $ show (map length argss) ++ "\n" ++ show (map length all_args)
5262 logLvl 10 $ show argss ++ "\n" ++ show all_args
53− logLvl 10 $ "Original: \n" ++
63+ logLvl 1 $ "Original: \n" ++
5464 showSep "\n" (map (\t -> showTm i (delab' i t True True)) xs)
5565 -- add an infinite supply of explicit arguments to update the possible
56− -- cases for (the return type may be variadic, or function type, sp
66+ -- cases for (the return type may be variadic, or function type, so
5767 -- there may be more case splitting that the idris_implicits record
5868 -- suggests)
5969 let parg = case lookupCtxt n (idris_implicits i) of
@@ -61,10 +71,10 @@ genClauses fc n xs given
6171 _ -> repeat (pexp Placeholder)
6272 let tryclauses = mkClauses parg all_args
6373 logLvl 2 $ show (length tryclauses) ++ " initially to check"
64− logLvl 5 $ showSep "\n" (map (showTm i) tryclauses)
74+ logLvl 1 $ showSep "\n" (map (showTm i) tryclauses)
6575 let new = filter (noMatch i) (nub tryclauses)
6676 logLvl 1 $ show (length new) ++ " clauses to check for impossibility"
67− logLvl 5 $ "New clauses: \n" ++ showSep "\n" (map (showTm i) new)
77+ logLvl 3 $ "New clauses: \n" ++ showSep "\n" (map (showTm i) new)
6878-- ++ " from:\n" ++ showSep "\n" (map (showImp True) tryclauses)
6979 return new
7080-- return (map (\t -> PClause n t [] PImpossible []) new)
@@ -75,9 +85,11 @@ genClauses fc n xs given
7585 lhsApp (PClause _ _ l _ _ _) = l
7686 lhsApp (PWith _ _ l _ _ _) = l
7787
88+ -- Return whether the given clause matches none of the input clauses
89+ -- (xs)
7890 noMatch i tm = all (\x -> case matchClause i (delab' i x True True) tm of
79− Right _ -> False
80− Left miss -> True) xs
91+ Right ms -> False
92+ Left miss -> True) xs
8193
8294
8395 mkClauses :: [PArg] -> [[PTerm]] -> [PTerm]
test/error004/FunErrTest.idr+1−1
@@ -6,7 +6,6 @@ import Language.Reflection.Utils
66
77%language ErrorReflection
88
9−
109total
1110cadr : (xs : List a)
1211 -> {auto cons1 : isCons xs = True}
@@ -14,6 +13,7 @@ cadr : (xs : List a)
1413 -> a
1514cadr (x :: (y :: _)) {cons1=refl} {cons2=refl} = y
1615cadr (x :: []) {cons1=refl} {cons2=refl} impossible
16+cadr [] {cons1=refl} {cons2=refl} impossible
1717
1818extractList : TT -> Maybe TT
1919extractList (App (App reflCon (App isCons lst)) _) = Just lst