Hi,

profiling the attached program (a Haskell solution to an exercise from
the Prolog competition at JICSLP'98/Manchester by  Heribert Sch�tz)
yields an invalid profile.hp:

---------------------------------------------------------------------
panne@marutea:~ > /usr/bin/hugs -d10000 compress.hs
[Hugs banner deleted]
Main> main
x(c(aab)3ccadad)2y

hp2ps: profile.hp, line 29: integer must follow identifier
---------------------------------------------------------------------

Line 29 in profile.hp is:

  Undefined member:  member: hen 1

This looks very strange, because the only string "Undefined member:"
is contained in Hugs' typechecker.

Setup:
uname -a:
   Linux marutea 2.2.10 #3 Wed Sep 29 10:15:31 CEST 1999 i686 unknown

configure options:
   --prefix=/usr --with-readline --with-preprocessor --enable-profiling 
--enable-stack-dumps

Cheers,
   Sven
-- 
Sven Panne                                        Tel.: +49/89/2178-2235
LMU, Institut fuer Informatik                     FAX : +49/89/2178-2211
LFE Programmier- und Modellierungssprachen              Oettingenstr. 67
mailto:[EMAIL PROTECTED]            D-80538 Muenchen
http://www.informatik.uni-muenchen.de/~Sven.Panne
import Array

data ComprTree = Ch Char
               | Sq ComprTree ComprTree
               | Rp ComprTree Int
  deriving (Show, Read)

-- Invariants:
-- - Rp has a numeric argument of at least 2 and at least 3 if its
--   subtree is a single Char.
-- - Rp is not directly nested.
-- - Sq is right-associative.
-- Optimal compressions obeying these (and more) invariants exist always.

ctToString ct = cts ct ""
  where
  cts (Ch c)    = showChar c
  cts (Sq t t') = cts t . cts t'
  cts (Rp t n)  = (case t of
                   Ch c -> showChar c
                   _    -> showChar '(' . cts t . showChar ')')
                . shows n

expand ct = exp ct ""
  where
  exp (Ch c)    = showChar c
  exp (Sq t t') = exp t . exp t'
  exp (Rp t n)  = expRp n t

  expRp 0 t = id
  expRp n t = exp t . expRp (n-1) t

compress "" = ""
compress s  = ctToString $ head $ compressions s

-- compressions is undefined for the empty string
compressions s  = [ t
                  | n <- [0..lengthS]
                  , (t, p) <- enumerateCTs True True n 0
                  , atEnd p
                  ]
  where
  lengthS = length s

  atEnd p = p == lengthS

  arrayS = array (0, lengthS-1) (zip [0..] s)

  -- `enumerateCTs sq rp n p' enumerates the ComprTrees t with the following
  -- properties:
  -- - t obeys the invariants.
  -- - t has a string representation of length n.
  -- - t expands to a substring of s starting at position p.
  -- The ComprTrees are paired with the end position of this string.
  -- sq and rp say whether the top-level constructor may be `Sq' or `Rp', resp.
  --
  -- enumerateCTs is tabulated
  enumerateCTs' _  _  0 _      = []
  enumerateCTs' _  _  1 p      = [ (Ch (arrayS!p), p+1)
                                 | p < lengthS
                                 ]
  enumerateCTs' sq rp n p      = [ (Sq t t', p)
                                 | sq
                                 , p < lengthS
                                 , nLeft <- [1..n-1]
                                 , let nRight = n - nLeft
                                 , (t , p) <- enumerateCTs False True nLeft  p
                                 , p < lengthS
                                 , (t', p) <- enumerateCTs True  True nRight p
                                 ]
                                 ++
                                 if iOuter
                                 then
                                   [ (Rp t i, p)
                                   | rp
                                   , p < lengthS
                                   ----------------------------------------------
                                   , i <- [2..lengthS-p]
                                   , nParen <- [0, 2]
                                   , let nSub = n - nParen - length (show i)
                                   , nParen == (if nSub == 1 then 0 else 2)
                                   , nSub > 0
                                   , not (nSub == 1 && i == 2)
                                   , (t , p) <- enumerateCTs True  False nSub p
                                   ----------------------------------------------
                                   , p <- checkString (expand (Rp t (i-1))) p
                                   ]
                                 else
                                   [ (Rp t i, p)
                                   | rp
                                   , p < lengthS
                                   ----------------------------------------------
                                   , nSub <- [1..n-1]
                                   , let nSubParen = nSub +
                                                     (if nSub == 1 then 0 else 2)
                                   , n > nSubParen
                                   , let p' = p
                                   , (t , p) <- enumerateCTs True  False nSub p
                                   , i <- [if nSub == 1 then 3 else 2
                                           ..
                                           (lengthS-p') `div` (p-p')]
                                   , n == nSubParen + length (show i)
                                   ----------------------------------------------
                                   , p <- checkString (expand (Rp t (i-1))) p
                                   ]
  enumerateCTs sq rp n p = tab ! (sq, rp, n, p)

  tab = array ((False, False, 0, 0),(True, True, lengthS, lengthS))
              [ ((sq, rp, n, p), enumerateCTs' sq rp n p)
              | sq <- [False .. True]
              , rp <- [False .. True]
              , n  <- [0..lengthS]
              , p  <- [0..lengthS]
              ]

  -- `checkstring xs p' checks whether s contains the substring xs at
  -- position p. If so, a singleton list containing the end position of
  -- the substring is returned. Otherwise the empty list is returned.
  checkString ""     p = [p]
  checkString (x:xs) p = [ p
                         | p < lengthS
                         , x == arrayS!p
                         , p <- checkString xs (p+1)
                         ]

-- iOuter chooses between two equivalent expressions enumerating Rp trees.
-- When true, the number of repetitions is chosen in an outer loop
-- and the repeated part is chosen in an inner loop.  When false, the
-- loops are nested the other way round. (The latter seems to be slightly
-- more efficient.)
iOuter = False -- True


----------------------------------------------------------------------

testString = "xcaabaabaabccadadcaabaabaabccadady"
-- testString = "aaaaaabaabaabaab"

xxx = [ (ctToString c, expand c == testString)
      | c <- compressions testString
      ]

-- main = do mapM_ print xxx
main = do putStrLn (compress testString)

Reply via email to