very strange behavior (crashes!) with Dynamics

Hal Daume t-hald at microsoft.com
Thu Aug 14 18:46:09 EDT 2003


This hasn't yet been posted, but I've actually whittled it down quite a
bit.

All we need is to import the Util.DynamicMap and do:

> dm1 = addToDM emptyDM (Range 1 2)
> showDM :: DShow -> DynamicMap -> ShowS
> showDM sd = foldDM (\d b -> case sd d of { Nothing -> b ; Just s -> s
. b }) id

and do the show definition for Coref and then we get:

Compiling ReadCorefData    (
c:/home/t-hald/projects/PennUtil/ReadCorefData.hs, interpreted )
Ok, modules loaded: ReadCorefData, PennUtil.Util, Util.DynamicMap,
NLP.PennParser, NLP.FiniteMap, NLP.String, NLP.Util, Common.
*ReadCorefData> showDM corefDShow dm1 ""
Loading package haskell98 ... linking ... done.
""
*ReadCorefData> :!touch ReadCorefData.hs
*ReadCorefData> :r
Compiling ReadCorefData    (
c:/home/t-hald/projects/PennUtil/ReadCorefData.hs, interpreted )
Ok, modules loaded: ReadCorefData, PennUtil.Util, Util.DynamicMap,
NLP.PennParser, NLP.FiniteMap, NLP.String, NLP.Util, Common.
*ReadCorefData> showDM corefDShow dm1 ""
"Coref=Coref 1 2 
Process ghci exited abnormally with code 5


interestingly it seems to be trying to read this as the range (since the
two ints are the same as the initial ones)...

 --
 Hal Daume III                                   | hdaume at isi.edu
 "Arrest this man, he talks in maths."           | www.isi.edu/~hdaume


> -----Original Message-----
> From: Hal Daume 
> Sent: Thursday, August 14, 2003 12:37 PM
> To: 'glasgow-haskell-bugs at haskell.org'
> Subject: very strange behavior (crashes!) with Dynamics
> 
> 
> First, I apologize for the length of this message.  
> Unfortunately, I cannot whittle this down to a smaller example.
> 
> I'm dealing with parse trees, whose datatype looks like:
> 
> > data AnnTree a
> >     = Term    { treeTag :: PackedString, treeText :: 
> PackedString   , treeAnn :: a }
> >     | NonTerm { treeTag :: PackedString, treeChildren :: 
> [AnnTree a], treeAnn :: a }
> >     deriving (Eq, Ord)
> 
> In particular, I parameterize these over a DynamicMap 
> datatype, which looks like:
> 
> > import Data.Dynamic
> > type DynamicMap = FiniteMap String Dynamic  -- cuz TypeRep 
> \not \in Ord :(
> 
> This supports, for instance:
> 
> > stypeOf x = show (typeOf x)
> > ttypeOf (x :: T a) = stypeOf (undefined :: a)
> > 
> > emptyDM :: DynamicMap
> > emptyDM = emptyFM
> > 
> > addToDM :: Typeable a => DynamicMap -> a -> DynamicMap
> > addToDM dm a = addToFM dm (stypeOf a) (toDyn a)
> > 
> > lookupDM :: Typeable a => DynamicMap -> Maybe a
> > lookupDM dm :: Maybe a =
> >     case lookupFM dm (stypeOf (undefined :: a)) of
> >       Nothing -> Nothing
> >       Just x  -> fromDynamic x
> 
> as well as a few other of the standard FM functions that I need.
> 
> I have a type synonym:
> 
> > type DTree = AnnTree DynamicMap
> 
> so that I can add whatever types of annotations I want to the tree.
> 
> I also provide methods of showing the trees with various 
> annotations shown, based on a DShow type:
> 
> > type DShow = Dynamic -> Maybe ShowS
> > dshowLabel :: Typeable a => (a -> ShowS) -> DShow
> > dshowLabel x d = 
> >   case fromDynamic d of
> >     Nothing -> Nothing
> >     Just v  -> Just (shows (typeOf v) . showChar '=' . x v)
> > 
> > showDTreeWith :: DShow -> DTree -> ShowS
> > showDTreeWith shws t =
> >   showChar '(' . 
> >     showString (unpackPS (treeTag t)) .
> >     showChar ' ' . showAnn (treeAnn t) .
> >     (if isTerm t 
> >        then showString (unpackPS (treeText t))
> >        else showChildren (treeChildren t)) .
> >     showChar ')'
> >   where
> >     showChildren []   = showString "<<EMPTY>>"
> >     showChildren [ch] = showDTreeWith shws ch
> >     showChildren (ch:chl) = showDTreeWith shws ch . 
> showChar ' ' . showChildren chl
> >     showAnn a = showList (foldDM showAnn' [] a)
> >     showAnn' dyn acc = 
> >       case shws dyn of
> >         Nothing -> acc
> >         Just ss -> showChar '{' . ss . showChar '}' : acc
> >     showList [] = id
> >     showList [x] = showChar '{' . x . showChar '}' . showChar ' '
> >     showList (x:xs) = showChar '{' . x . showList' xs . 
> showChar '}' . showChar ' '
> >     showList' [] = id
> >     showList' (x:xs) = showChar ';' . x . showList' xs
> 
> Basically, what this does is it is given a DShow (which can 
> be combined, of course, using non-shown functions), and 
> prints the tree with the dynamic annotations shown in braces. 
>  The dshowLabel function takes a shows function and creates a 
> DShow function based on it.
> 
> For instance, I have a coreference data type, which looks like:
> 
> > data Coref = Coref Int Int Bool (Maybe String) 
> >     -- Id, ref, in-min; eventually we cannonicalize these
> >     -- and we can assume id= ref, type
> >          deriving (Eq, Ord, Show)
> 
> We make this an instance of Typeable so we can put it in dynamic maps:
> 
> > corefTypeCon = mkTyCon "Coref" ; corefTypeRep = mkAppTy 
> corefTypeCon []
> > instance Typeable Coref where typeOf _ = corefTypeRep
> > {-# NOINLINE corefTypeCon #-}
> > {-# NOINLINE corefTypeRep #-}
> 
> Now, we have another annotation type, Range, which specifies 
> what subset of the sentence a given node covers.
> 
> > data Range = Single Int
> >            | Range  Int Int
> > 
> > instance Show Range where
> >   showsPrec _ (Single i) = shows i
> >   showsPrec _ (Range i j) = shows i . showChar '^' . shows j
> > 
> > rangeTypeCon = mkTyCon "Range" ; rangeTypeRep = mkAppTy 
> rangeTypeCon []
> > instance Typeable Range where typeOf _ = rangeTypeRep
> > {-# NOINLINE rangeTypeCon #-}
> > {-# NOINLINE rangeTypeRep #-}
> 
> And we can take a DTree and add ranges with:
> 
> > numberTree :: Int -> DTree -> (Int, DTree)
> > numberTree n t@(Term _ _ _) = (n+1, addAnn t (Single n))
> > numberTree n t@(NonTerm _ chl _) =
> >     let (n',chl') = mapAccumL numberTree n chl
> >     in  (n', addAnn (t { treeChildren = chl' }) (mkRange n (n'-1)))
> 
> The associate DShow function is:
> 
> > rangeDShow :: DShow
> > rangeDShow = dshowLabel (shows :: Range -> ShowS)
> 
> Now, we parse a tree, convert it into a dtree and number it:
> 
> We do:
> 
> > (_:Right (_,tree):_) = parseFile "wsj93_005.0011.par" 
> (unsafePerformIO $ readFile "wsj93_005.0011.par")
> 
> now, tree is of type AnnTree ().  We can convert this to a 
> DTree with nothing in it by applying the mkDTree function:
> 
> > mkDTree :: Tree -> DTree
> > mkDTree (Term tag txt _) = Term tag txt emptyDM
> > mkDTree (NonTerm tag chl _) = NonTerm tag (map mkDTree chl) emptyDM
> 
> And the number it, by doing:
> 
> > pTree :: DTree
> > pTree = snd $ numberTree 1 $ mkDTree tree
> 
> we can test showing this by:
> 
> *ReadCorefData> showDTreeWith rangeDShow pTree ""
> "(TOP {{Range=1^32}} (S {{Range=1^32}} (NP-A {{Range=1^11}} 
> (NPB {{Range=1^4}} (NE {{Range=1^3}} (NNP {{Range=1}} 
> Michael) (NNP {{Range=2}} D.) (NNP {{Range=3}} Casey)) (COMMA 
> {{Range=4}} ,)) (NP {{Range=5^11}} (NPB {{Range=5^11}} (DT 
> {{Range=5}} a) (JJ {{Range=6}} top) (NE {{Range=7}} (NNP 
> {{Range=7}} Johnson)) (CC {{Range=8}} &) (NE {{Range=9}} (NNP 
> {{Range=9}} Johnson)) (NN {{Range=10}} manager) (COMMA 
> {{Range=11}} ,)))) (VP {{Range=12^32}} (VBD {{Range=12}} 
> moved) (PP {{Range=13^23}} (TO {{Range=13}} to) (NP-A 
> {{Range=14^23}} (NPB {{Range=14^17}} (NE {{Range=14^16}} (NNP 
> {{Range=14}} Genetic) (NNP {{Range=15}} Therapy) (NNP 
> {{Range=16}} Inc.)) (COMMA {{Range=17}} ,)) (NP 
> {{Range=18^23}} (NPB {{Range=18^21}} (DT {{Range=18}} a) (JJ 
> {{Range=19}} small) (NN {{Range=20}} biotechnology) (NN 
> {{Range=21}} concern)) (ADVP {{Range=22^23}} (RB {{Range=22}} 
> here) (COMMA {{Range=23}} ,))))) (SG {{Range=24^32}} (VP 
> {{Range=24^32}} (TO {{Range=24}} to) (VP-A {{Range=25^32}} 
> (VB {{Range=25}} become) (NP-A_AND {{Range=26^32}} (NP 
> {{Range=26^27}} (NPB {{Range=26^27}} (PRP$ {{Range=26}} its) 
> (NN {{Range=27}} president))) (CC {{Range=28}} and) (NP 
> {{Range=29^32}} (NPB {{Range=29^32}} (NN {{Range=29}} chief) 
> (VBG {{Range=30}} operating) (NN {{Range=31}} officer) 
> (PERIOD {{Range=32}} .))))))))))"
> 
> you can take my word that this is correct :).
> 
> We can show it without the annotations by:
> 
> *ReadCorefData> showDTreeWith dshow0 pTree ""
> "(TOP (S (NP-A (NPB (NE (NNP Michael) (NNP D.) (NNP Casey)) 
> (COMMA ,)) (NP (NPB (DT a) (JJ top) (NE (NNP Johnson)) (CC &) 
> (NE (NNP Johnson)) (NN manager) (COMMA ,)))) (VP (VBD moved) 
> (PP (TO to) (NP-A (NPB (NE (NNP Genetic) (NNP Therapy) (NNP 
> Inc.)) (COMMA ,)) (NP (NPB (DT a) (JJ small) (NN 
> biotechnology) (NN concern)) (ADVP (RB here) (COMMA ,))))) 
> (SG (VP (TO to) (VP-A (VB become) (NP-A_AND (NP (NPB (PRP$ 
> its) (NN president))) (CC and) (NP (NPB (NN chief) (VBG 
> operating) (NN officer) (PERIOD .))))))))))"
> 
> now, note that we have *NOT* ever added any annotations 
> having to do with corefs to it.
> 
> however, we can still segfault ghci by doing:
> 
> *ReadCorefData> showDTreeWith corefDShow pTree ""
> "(TOP {{Coref=Coref 1 32 
> Process ghci exited abnormally with code 5
> 
> where it gets the 1 32 is beyond me :).
> 
> now, for some more fun, I can reload this module into ghci, 
> and run it and it works fine:
> 
>    ___         ___ _
>   / _ \ /\  /\/ __(_)
>  / /_\// /_/ / /  | |      GHC Interactive, version 6.0, for 
> Haskell 98.
> / /_\\/ __  / /___| |      http://www.haskell.org/ghc/
> \____/\/ /_/\____/|_|      Type :? for help.
> 
> Loading package base ... linking ... done.
> Loading package lang ... linking ... done.
> :   Can't find module `'
>     (use -v to see a list of the files searched for)
> Prelude> :load c:/home/t-hald/projects/PennUtil/ReadCorefData.hs
> Skipping  Common           ( /home/t-hald/projects/Common.hs, 
> /home/t-hald/projects/Common.o )
> Compiling NLP.Util         ( 
> /home/t-hald/projects/NLP/Util.hs, interpreted )
> Skipping  NLP.String       ( 
> /home/t-hald/projects/NLP/String.lhs, 
> /home/t-hald/projects/NLP/String.o )
> Skipping  NLP.FiniteMap    ( 
> /home/t-hald/projects/NLP/FiniteMap.hs, 
> /home/t-hald/projects/NLP/FiniteMap.o )
> Compiling NLP.PennParser   ( 
> /home/t-hald/projects/NLP/PennParser.hs, interpreted )
> Compiling Util.DynamicMap  ( 
> /home/t-hald/projects/Util/DynamicMap.hs, interpreted )
> Compiling PennUtil.Util    ( 
> /home/t-hald/projects/PennUtil/Util.hs, interpreted )
> Compiling ReadCorefData    ( 
> c:/home/t-hald/projects/PennUtil/ReadCorefData.hs, interpreted )
> Ok, modules loaded: ReadCorefData, PennUtil.Util, 
> Util.DynamicMap, NLP.PennParser, NLP.FiniteMap, NLP.String, 
> NLP.Util, Common.
> *ReadCorefData> showDTreeWith corefDShow pTree ""
> Loading package haskell98 ... linking ... done.
> "(TOP (S (NP-A (NPB (NE (NNP Michael) (NNP D.) (NNP Casey)) 
> (COMMA ,)) (NP (NPB (DT a) (JJ top) (NE (NNP Johnson)) (CC &) 
> (NE (NNP Johnson)) (NN manager) (COMMA ,)))) (VP (VBD moved) 
> (PP (TO to) (NP-A (NPB (NE (NNP Genetic) (NNP Therapy) (NNP 
> Inc.)) (COMMA ,)) (NP (NPB (DT a) (JJ small) (NN 
> biotechnology) (NN concern)) (ADVP (RB here) (COMMA ,))))) 
> (SG (VP (TO to) (VP-A (VB become) (NP-A_AND (NP (NPB (PRP$ 
> its) (NN president))) (CC and) (NP (NPB (NN chief) (VBG 
> operating) (NN officer) (PERIOD .))))))))))"
> *ReadCorefData> 
> 
> just as it shouldn't print any coref data (as it doesn't know 
> any!), it doesn't.
> 
> now, i insert a blank line somewhere in the source, save it, 
> and reload (just to force ghci to actually reload it), and:
> 
> *ReadCorefData> :r
> Compiling ReadCorefData    ( 
> c:/home/t-hald/projects/PennUtil/ReadCorefData.hs, interpreted )
> Ok, modules loaded: ReadCorefData, PennUtil.Util, 
> Util.DynamicMap, NLP.PennParser, NLP.FiniteMap, NLP.String, 
> NLP.Util, Common.
> *ReadCorefData> showDTreeWith corefDShow pTree ""
> "(TOP {{Coref=Coref 1 32 
> Process ghci exited abnormally with code 5
> 
> 
> I can do this every time :).
> 
> I should mention that NLP.FiniteMap was created by stealing 
> the code from Data.FiniteMap and adding a few functions I 
> felt were missing.
> 
> I've attached all the relevant source code.  The 
> PennUtil/ReadCorefData.hs is the module we're trying to run.  
> You should untar it into a new directory if you want to 
> experiment with it.
> 
> Any help would really be incredibly appreciated.
> 
> Thanks!
> 
>  - Hal
> 
> --
>  Hal Daume III                                   | hdaume at isi.edu
>  "Arrest this man, he talks in maths."           | www.isi.edu/~hdaume
> 



More information about the Glasgow-haskell-bugs mailing list