on master help sign in
Fix traversal of size change graphs

Fixes issue #134 - new regression test added

commit906862adb2aca16de856f43ffc9be08dc2393404 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSun 16 Dec 2012, 18:58 (14 years ago) parent8d090c0
6 files changed+70−25
lib/Prelude/Heap.idr+2 src/Idris/Coverage.hs+37−24 src/Idris/IBC.hs+1−1 test/reg006/expected+1 test/reg006/reg006.idr+27 test/reg006/run+2
lib/Prelude/Heap.idr+2
@@ -66,6 +66,7 @@ orderBySize left centre right =
6666 largest : Nat
6767 largest = maximum (size left) $ maximum (size centre) (size right)
6868
69+%assert_total -- relies on orderBySize doing the right thing
6970merge : Ord a => MaxiphobicHeap a -> MaxiphobicHeap a -> MaxiphobicHeap a
7071merge Empty right = right
7172merge left Empty = left
@@ -103,6 +104,7 @@ toList : Ord a => MaxiphobicHeap a -> List a
103104toList Empty = []
104105toList (Node s l e r) = toList' (Node s l e r) refl
105106 where
107+ %assert_total -- relies on deleteMinimum making heap smaller
106108 toList' : Ord a => (h : MaxiphobicHeap a) -> (isEmpty h = False) -> List a
107109 toList' heap p = findMinimum heap p :: (toList $ deleteMinimum heap p)
108110
src/Idris/Coverage.hs+37−24
@@ -535,13 +535,17 @@ mkMultiPaths ist path cg
535535-- If any route along the multipath leads to infinite descent, we're fine.
536536-- Try a route beginning with every argument.
537537-- If we reach a point we've been to before, but with a smaller value,
538−-- that means there is an infinitely descending path.
538+-- that means there is an infinitely descending path from that argument.
539539
540540checkMP :: IState -> Int -> MultiPath -> Totality
541541checkMP ist i mp = if i > 0
542542 then collapse (map (tryPath 0 [] mp) [0..i-1])
543543 else tryPath 0 [] mp 0
544544 where
545+ tryPath' d path mp arg
546+ = let res = tryPath d path mp arg in
547+ trace (show mp ++ "\n" ++ show arg ++ " " ++ show res) res
548+
545549 tryPath :: Int -> [(SCGEntry, Int)] -> MultiPath -> Int -> Totality
546550 tryPath desc path [] _ = Total []
547551-- tryPath desc path ((UN "believe_me", _) : _) arg
@@ -550,7 +554,7 @@ checkMP ist i mp = if i > 0
550554 tryPath desc path ((f, _) :es) arg
551555 | [TyDecl (DCon _ _) _] <- lookupDef Nothing f (tt_ctxt ist)
552556 = case lookupTotal f (tt_ctxt ist) of
553− [Total _] -> Total []
557+ [Total _] -> Unchecked -- okay so far
554558 [Partial _] -> Partial (Other [f])
555559 x -> error (show x)
556560 | [TyDecl (TCon _ _) _] <- lookupDef Nothing f (tt_ctxt ist)
@@ -561,39 +565,48 @@ checkMP ist i mp = if i > 0
561565 tryPath desc path (e@(f, nextargs) : es) arg
562566 | Just d <- lookup e path
563567 = if (desc - d) > 0
564− then Total []
568+ then -- trace ("Descent " ++ show (desc - d) ++ " "
569+ -- ++ show (path, e)) $
570+ Total []
565571 else Partial (Mutual (map (fst . fst) path ++ [f]))
566572 | [Unchecked] <- lookupTotal f (tt_ctxt ist) =
567573 let argspos = zip nextargs [0..] in
568− collapse' (Partial (Mutual (map (fst . fst) path ++ [f]))) $
569− do (arg, pos) <- argspos
570− case arg of
571− Nothing -> -- don't know, but it's okay if the
574+ collapse' Unchecked $
575+ do (a, pos) <- argspos
576+ case a of
577+ Nothing -> -- don't know, but if the
572578 -- rest definitely terminates without
573− -- any cycles with route so far
574− map (tryPath (-10000) ((e, desc):path) es)
575− [0..length nextargs - 1]
579+ -- any cycles with route so far,
580+ -- then we might yet be total
581+ case collapse (map (tryPath (-10000) ((e, desc):path) es)
582+ [0..length nextargs - 1]) of
583+ Total _ -> return Unchecked
584+ x -> return x
576585 Just (nextarg, sc) ->
577− case sc of
578− Same -> return $ tryPath desc ((e, desc):path)
579− es
580− nextarg
581− Smaller -> return $ tryPath (desc+1)
582− ((e, desc):path)
583− es
584− nextarg
585− _ -> trace ("Shouldn't happen " ++ show e) $
586− return (Partial Itself)
587− | [Total _] <- lookupTotal f (tt_ctxt ist) = Total []
586+ if nextarg == arg then
587+ case sc of
588+ Same -> return $ tryPath desc ((e, desc):path)
589+ es
590+ pos
591+ Smaller -> return $ tryPath (desc+1)
592+ ((e, desc):path)
593+ es
594+ pos
595+ _ -> trace ("Shouldn't happen " ++ show e) $
596+ return (Partial Itself)
597+ else return Unchecked
598+ | [Total _] <- lookupTotal f (tt_ctxt ist) = Unchecked
588599 | [Partial _] <- lookupTotal f (tt_ctxt ist) = Partial (Other [f])
589− | otherwise = Total []
600+ | otherwise = Unchecked
590601
591602noPartial (Partial p : xs) = Partial p
592603noPartial (_ : xs) = noPartial xs
593604noPartial [] = Total []
594605
595−collapse xs = collapse' (Partial Itself) xs
596−collapse' def (Total r : xs) = Total r
606+collapse xs = collapse' Unchecked xs
607+collapse' def (Total r : xs) = Total r
608+collapse' def (Unchecked : xs) = collapse' def xs
597609collapse' def (d : xs) = collapse' d xs
610+collapse' Unchecked [] = Total []
598611collapse' def [] = def
599612
src/Idris/IBC.hs+1−1
@@ -21,7 +21,7 @@ import System.Directory
2121import Paths_idris
2222
2323ibcVersion :: Word8
24−ibcVersion = 23
24+ibcVersion = 24
2525
2626data IBCFile = IBCFile { ver :: Word8,
2727 sourcefile :: FilePath,
test/reg006/expectednew file+1
@@ -0,0 +1 @@
1+reg006.idr:17:RBTree.lookup is possibly not total due to: RBTree.lookup_case
test/reg006/reg006.idrnew file+27
@@ -0,0 +1,27 @@
1+module RBTree
2+
3+data Colour = Red | Black
4+
5+data RBTree : Type -> Type -> Nat -> Colour -> Type where
6+ Leaf : RBTree k v O Black
7+ RedBranch : k -> v -> RBTree k v n Black -> RBTree k v n Black -> RBTree k v n Red
8+ BlackBranch : k -> v -> RBTree k v n x -> RBTree k v n y -> RBTree k v (S n) Black
9+
10+toBlack : RBTree k v n c -> (m ** (RBTree k v m Black, Either (m = n) (m = (S n))))
11+toBlack (RedBranch k v l r) = (_ ** (BlackBranch k v l r, Right refl))
12+toBlack Leaf = (_ ** (Leaf, Left refl))
13+toBlack (BlackBranch k v l r) = (_ ** (BlackBranch k v l r, Left refl))
14+
15+total
16+lookup : Ord k => k -> RBTree k v n Black -> Maybe v
17+lookup k Leaf = Nothing
18+lookup k (BlackBranch k0 v0 l r) =
19+ case compare k k0 of
20+ EQ => Just v0
21+ LT =>
22+ let (_ ** (t, _)) = toBlack l in
23+ lookup k t
24+ GT =>
25+ let (_ ** (t, _)) = toBlack r in
26+ lookup k t
27+
test/reg006/runnew file+2
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+idris $@ reg006.idr -o reg006