BUG FOUND

I found a compiler bug in 'ghc', it came up as follows: forgetting a 
definition, e.g. 'atMost', in a signature, but still keeping a default method 
for 'atMost' should produce something like

    TestADT.lhs:56: Value not in scope: `atMost'

But with the appended source ('TestADT.lhs') ghc gave the message

    panic! (the `impossible' happened):
            classOpTagByOccName PriorityQueue{-r3O,x-} atMost

    Please report it as a compiler bug to [EMAIL PROTECTED]

I used the command line 
              ghc -O - o testadt testADT.lhs -H16M

                                           -Joerg


Joerg Prante
[EMAIL PROTECTED]


-------TestADT.lhs-----------------------------------------------------


> data SeqView t a              =  Null
>                               |  Cons a (t a)

Priority Queue.

> class PriorityQueue q where

>     empty                     :: (Ord a) => q a
>     single                    :: (Ord a) => a -> q a
>     insert                    :: (Ord a) => a -> q a -> q a
>     meld                      :: (Ord a) => q a -> q a -> q a 

>     deleteMin                 :: (Ord a) => q a -> q a
>     replaceMin                :: (Ord a) => a -> q a -> q a

>     isEmpty                   :: (Ord a) => q a -> Bool
>     isSingle                  :: (Ord a) => q a -> Bool

>     fold                      :: (Ord a) => (a -> b -> b) -> b -> q a -> b
>     splitMin                  :: (Ord a) => q a -> SeqView q a
>     findMin                   :: (Ord a) => q a -> a  

     atMost                     :: (Ord a) => a -> q a -> [a]

>     size                      :: (Ord a) => q a -> Int

>     fromList                  :: (Ord a) => [a] -> q a
>     fromOrderedList           :: (Ord a) => [a] -> q a
>     toList                    :: (Ord a) => q a -> [a]
>     toOrderedList             :: (Ord a) => q a -> [a]


Defaultmethoden

>     single a                  =  insert a empty
>     insert a q                =  single a `meld` q
>     meld p q                  =  insertMany (toList p) q
>     deleteMin q               =  case splitMin q of
>         Null                  -> error "deleteMin: empty priority queue"
>         Cons _ q              -> q
>     replaceMin a q            =  deleteMin (insert a q)
>     isEmpty s                 =  case splitMin s of
>         Null                  -> True
>         _                     -> False
>     isSingle s                =  case splitMin s of
>         Null                  -> False
>         Cons _ s              -> isEmpty s
>     fold (*) e s              =  case splitMin s of
>         Null                  -> e
>         Cons a s              -> a * fold (*) e s
>     splitMin q
>         | isEmpty q           =  Null
>         | otherwise           =  Cons (findMin q) (deleteMin q)
>     findMin q                 =  case splitMin q of
>         Null                  -> error "findMin: empty priority queue"
>         Cons a _              -> a
>     atMost a q                =  takeWhile (<= a) (toOrderedList q)
>     size                      =  fold (\_ n -> n + 1) 0
>     fromList                  =  foldm meld empty . map single
>     toList                    =  fold (:) []
>     fromOrderedList           =  fromList
>     toOrderedList q           =  case splitMin q of
>         Null                  -> []
>         Cons a q              -> a : toOrderedList q

Abgeleitete Funktionen.

> insertMany                    :: (PriorityQueue q, Ord a) => [a] -> q a -> q a
> insertMany x q                =  foldr insert q x

> foldm                         :: (a -> a -> a) -> a -> [a] -> a
> foldm (*) e []                =  e
> foldm (*) e x                 =  fst (rec (length x) x)
>     where rec 1 (a:x)         =  (a, x)
>           rec n x             =  (a * b, z)
>               where m         =  n `div` 2
>                     (a, y)    =  rec (n - m) x 
>                     (b, z)    =  rec m       y

Binary Heaps.

> data BinTree a                =  Empty
>                               |  Bin (BinTree a) a (BinTree a)

> instance PriorityQueue BinTree where
>     empty                     =  Empty
>     single a                  =  Bin Empty a Empty
>     isEmpty Empty             = True
>     isEmpty _                 = False
>     insert b Empty            =  Bin Empty b Empty
>     insert b (Bin l a r)
>         | a <= b              =  Bin (insert b r) a l
>         | otherwise           =  Bin (insert a r) b l
>     meld Empty u              =  u
>     meld t@(Bin _ _ _) Empty  =  t
>     meld t@(Bin l a r) u@(Bin l' b r')
>        | a <= b               =  Bin (meld l r) a u
>        | otherwise            =  Bin t          b (meld l' r')
>     splitMin Empty            =  Null
>     splitMin (Bin l a r)      =  Cons a (meld l r)
>     fromList                  =  foldr insert empty

     toOrderedList Empty        = []
     toOrderedList (Bin l a r) = a : toOrderedList (meld l r)

> isBinTree Empty               = True
> isBinTree (Bin l a r)         = True
> isBinTree _           = False


Sortieren.

> pqSort q x            =  toOrderedList (insertMany x q)

> main                          =  do
>     let n = 10000
>     putStr "*** sorting\n"
>     out (pqSort q0 [1 .. n])
>     out (pqSort q0 [n, n-1 .. 1])
>     out (pqSort q0 (take n $ random2Ints 82437 24376))

> out                   :: (Num a) => [a] -> IO ()
> out x | sum x == 0    =  putStr "ok\n"
>       | otherwise     =  putStr "ok\n"

> q0                    :: (Ord a) => BinTree a
> q0                    =  empty

The random-number generator which is stolen from the `hbc'-library.

> random2Ints                   :: Int -> Int -> [Int]
> random2Ints s1 s2
>   | s1 < 1 || s1 > 2147483562 =  error "random2Ints: Bad first seed."
>   | s2 < 1 || s2 > 2147483398 =  error "random2Ints: Bad second seed."
>   | otherwise                 =  rands s1 s2

> rands                         :: Int -> Int -> [Int]
> rands s1 s2
>     | z < 1                   =  z + 2147483562 : rands s1'' s2''
>     | otherwise               =  z              : rands s1'' s2''
>     where k                   =  s1 `div` 53668
>           s1'                 =  40014 * (s1 - k * 53668) - k * 12211
>           s1'' | s1' < 0      =  s1' + 2147483563
>                | otherwise    =  s1'
>           k'                  =  s2 `div` 52774
>           s2'                 =  40692 * (s2 - k' * 52774) - k' * 3791
>           s2'' | s2' < 0      =  s2' + 2147483399
>                | otherwise    =  s2'
>           z                   =  s1'' - s2''

Reply via email to