#1584: problem presenting with explicit pattern matching
-----------------------+----------------------------------------------------
  Reporter:  guest     |          Owner:       
      Type:  bug       |         Status:  new  
  Priority:  normal    |      Milestone:       
 Component:  Compiler  |        Version:  6.6.1
  Severity:  normal    |       Keywords:       
Difficulty:  Unknown   |             Os:  Linux
  Testcase:            |   Architecture:  x86  
-----------------------+----------------------------------------------------
Hi all,

 I believe I've found a bug in ghc 6.6.1.

 From Chapter 9. What to do when something goes wrong

   “I think GHC is producing incorrect code”:

   Unlikely :-)

 And yet I'm out of ideas on why my code is acting the way it
 does.  I've got a tiny program for the towers of hanoi.  In
 my step function moving one disk to the next peg I seem to
 be hitting a bug for explicit pattern matching.  I have a
 small example file (included below) to detail the issue.

 1.  What kind of machine am I running on?

 {{{
 $ uname -a
 Linux lanny-lnx 2.4.21-32.0.1.EL #1 Tue May 17 18:01:37 EDT 2005 i686 i686
 i386 GNU/Linux
 }}}

 I have also reproduced the bug (using ghc 6.6.1) on a Mac OS
 X system.  My linux box uses the rpm install from haskell.org/ghc
 but on the mac I built ghc from the ground up (via
 http://darwinports.com).

 2. What version of gcc am I using?

 {{{
 $ gcc -v
 Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
 Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
 --infodir=/usr/share/info --enable-shared --enable-threads=posix
 --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-
 redhat-linux
 Thread model: posix
 gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-52)
 }}}

 The mac is using the latest Xcode so it's got gcc 4.0.x

 3. Complete ghci -v run showing problem.

 {{{
 $ ghci -v hanoi_bug.hs
    ___         ___ _
   / _ \ /\  /\/ __(_)
  / /_\// /_/ / /  | |      GHC Interactive, version 6.6.1, for Haskell 98.
 / /_\\/ __  / /___| |      http://www.haskell.org/ghc/
 \____/\/ /_/\____/|_|      Type :? for help.

 Using package config file: /opt/ghc-6.6.1/lib/i386-unknown-
 linux/package.conf
 wired-in package base mapped to base-2.1.1
 wired-in package rts mapped to rts-1.0
 wired-in package haskell98 mapped to haskell98-1.0
 wired-in package template-haskell mapped to template-haskell-2.1
 Hsc static flags: -static
 Loading package base ... linking ... done.
 wired-in package base mapped to base-2.1.1
 wired-in package rts mapped to rts-1.0
 wired-in package haskell98 mapped to haskell98-1.0
 wired-in package template-haskell mapped to template-haskell-2.1
 *** Parser:
 *** Desugar:
 *** Simplify:
 *** CorePrep:
 *** ByteCodeGen:
 *** Parser:
 *** Desugar:
 *** Simplify:
 *** CorePrep:
 *** ByteCodeGen:
 wired-in package base mapped to base-2.1.1
 wired-in package rts mapped to rts-1.0
 wired-in package haskell98 mapped to haskell98-1.0
 wired-in package template-haskell mapped to template-haskell-2.1
 *** Chasing dependencies:
 Stable obj: []
 Stable BCO: []
 unload: retaining objs []
 unload: retaining bcos []
 Upsweep completely successful.
 *** Deleting temp files:
 Deleting:
 *** Chasing dependencies:
 Stable obj: []
 Stable BCO: []
 unload: retaining objs []
 unload: retaining bcos []
 compile: input file hanoi_bug.hs
 *** Checking old interface for main:Main:
 [1 of 1] Compiling Main             ( hanoi_bug.hs, interpreted )
 *** Parser:
 *** Renamer/typechecker:
 *** Desugar:
     Result size = 1076
 *** Simplify:
     Result size = 1523
     Result size = 1323
     Result size = 1323
 *** Tidy Core:
     Result size = 1323
 *** CorePrep:
     Result size = 1641
 *** ByteCodeGen:
 *** Deleting temp files:
 Deleting:
 Upsweep completely successful.
 *** Deleting temp files:
 Deleting:
 Ok, modules loaded: Main.
 *Main> main
 *** Parser:
 *** Desugar:
 *** Simplify:
 *** CorePrep:
 *** ByteCodeGen:
 [True,True,True,False,False,True]
 *Main> :q
 Leaving GHCi.
 *** Deleting temp files:
 Deleting:
 *** Deleting temp dirs:
 Deleting:
 }}}

 5. What program behavior is wrong?

 main is recording a list of properties which should all return True.

 The behavior is the same for compiled rather than interpreted code
 on both the linux and mac systems.

 6. Source code demonstrating the problem.

 {{{
 $ cat hanoi_bug.hs
 -- A Task is a tuple of
 --      n :: The number of disks to move
 --      i :: The initial peg
 --      a :: The auxillary peg
 --      f :: The final peg
 type Task = (Int, Int, Int, Int)

 data Tower a = Tower a a a
         deriving (Eq, Show)

 peg :: Int -> Tower [a] -> [a]
 peg 1 (Tower a b c) = a
 peg 2 (Tower a b c) = b
 peg 3 (Tower a b c) = c

 mkTower :: Task -> [a] -> [a] -> [a] -> Tower [a]
 mkTower (_,1,2,3) a b c = Tower a b c
 mkTower (_,1,3,2) a b c = Tower a c b
 mkTower (_,2,1,3) a b c = Tower b a c
 mkTower (_,2,3,1) a b c = Tower b c a   -- BUG!  returns (Tower c a b)
 mkTower (_,3,1,2) a b c = Tower c a b   -- BUG!  returns (Tower b c a)
 mkTower (_,3,2,1) a b c = Tower c b a

 step :: Task -> Tower [a] -> Tower [a]
 step task@(_,i,a,f) tower =
         let pi    = peg i tower
             pa    = peg a tower
             pf    = peg f tower
         in
                 mkTower task (tail pi) pa (head pi : pf)

 prop_test123 = step (1,1,2,3) (Tower [1] [3] [2]) == Tower []    [3]
 [1,2]
 prop_test132 = step (1,1,3,2) (Tower [1] [2] [3]) == Tower []    [1,2] [3]
 prop_test213 = step (1,2,1,3) (Tower [3] [1] [2]) == Tower [3]   []
 [1,2]
 prop_test231 = step (1,2,3,1) (Tower [2] [1] [3]) == Tower [1,2] []    [3]
 prop_test312 = step (1,3,1,2) (Tower [3] [2] [1]) == Tower [3]   [1,2] []
 prop_test321 = step (1,3,2,1) (Tower [2] [3] [1]) == Tower [1,2] [3]   []

 checkProps = [ prop_test123
              , prop_test132
              , prop_test213
              , prop_test231
              , prop_test312
              , prop_test321
              ]

 main :: IO ()
 main = print checkProps
 }}}

 7.  If you are a hero...

 Sorry.  Not yet.  At a guess the book-keeping for explicit pattern
 matches is getting mixed up.  Note that mkTower does provide the
 correct permutations, it's just that two of them are mixed up.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1584>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to