Monday, 31 March 2008

non, non to recherche (reg 8h)

But no stress or angst, either. Just practice your craft. Final push to make everything live. It's amazing how many little last minute changes you always have to make. Have increased the level of automation in the test script... now using TagSoup to parse the results and compare them against the expected-results header.

Friday, 28 March 2008

zero recherche (reg 9h)

Day of hacking. Rewrote large chunks of the submission script (as I slowly become less incompetent in Perl).

Developed a semi-automated test harness for the submission form (using Haskell's Network.HTTP). No, nothing so fancy as generating random inputs via quickcheck. In doing so, I have learned a little bit more about how HTTP, MIME and CGI fit together. So many layers in the onion. Did not realise until today how absurdly simple and non-threatening CGI is: just some conventions for environment variables you'll get stuff in, and what to expect on stdin and stdout. This is why you can write CGI programs in really any language without fancy libraries. (Oh, you could use fancy libraries to make your life easier -- I am thankful for CGI.pm -- but you're actually not so stuck without them).

So now I can generate multipart/form-data by hand and send a file upload over to the server, and sort of inspect the results. The test harness was a big help. Found lots of bugs and regressions (from my clean up efforts). Automation is your friend. Really need to learn to stop resisting and start automating the heck out of things. It's not that you rely on them... rather, it's a matter of finding lots of bugs out quickly, and then looking for more stuff by hand.

Oh yeah, another thing I learned about whilst putting together the automated test harness: implicit parameter in Haskell. John Hughes had written a paper showing how they may be useful for global variables. I didn't do anything as fancy as what his paper had. I do like the results. Here's a function that accepts two implicit parameters

runSubmission :: (?counts :: IORef CountMap, ?uri :: URI)
=> String -- ^ team
-> Mode
-> Track
-> ExpectedResult
-> FilePath
-> IO ()
runSubmission teamId mode track expected filename =
do (submit, dl) <- Map.findWithDefault (0,0) (teamId, track)
`fmap` readIORef ?counts
-- several lines of code later...
eresp <- simpleHTTP (request ?uri form)
-- ...


And here's that function being used with a value being generated for the params

runTests :: (?uri :: URI) => IO ()
runTests =
do cref <- newIORef (Map.empty)
let ?counts = cref
runSubmission "Foo" Submit TunaAttribute Sorry "/tmp/debug.txt"
runSubmission "Foo" Submit TunaAttribute Sorry "/tmp/debug.pdf"
runSubmission "Bar" Submit TunaAttribute Sorry "/tmp/debug.txt"


This lets me pass the ?counts down (and the ?uri, also as an implicit param to the calling function). What's nice is that I don't have to pass any extra parameters down or make up any crazy monad transformers.

Thursday, 27 March 2008

text planning (reg 5h)

This week has been strangely... well behaved. Been going to bed early, coming in to work before 9, that kind of deal. See what a little 4-day weekend self-reset can do? On the other hand, the week has also been rather dull (both in terms of bored Eric and stupid Eric). I guess today was the least boring of them all because I got to do some reading. Was a good break from the chop wood work.

Fleshed out the reading list a bit.

Read a couple of interesting articles on text planning, Experiments using stochastic search for text planning. (mellish+1998eus) and From local to global coherence: A bottom-up approach to text planning (marcu1997flg). All this stuff feels new to me, it's a big world out there, what happens before surface realisation. I'm still kinda confused about what all these NLG subtasks are.

I do like the Marcu formulation of text planning: given U, a set of semantic units, and R a set of relations over those units, express ALL of the semantic units in a way that satisfies most of the constraints expressed by R [I might have gotten this wrong].

The Mellish article is cute because it uses a genetic algorithm (hey!). Not sure if it's really practical, but yes, I could see GAs being handy for finding nice sequences. It was just nice to spend some time thinking about crossover and mutation again. Heh. Maybe I should break out the Haskell GA library and have some fun with it (yeah, right).

verify annotations

Did some work for REG this afternoon. Helped verify some annotations (wrote up a little Haskell script). At first, I tried to use HaXmL and DtdToHaskell, but the resulting scripts gives me a stack overflow (even on trivial files). Hmm... might have an infinite loop or something. But I don't see how. All I did was fReadXml. Maybe it's a bug in the library? Anyway, after that bit of stupidity, I decided to preprocess the XML with a little XSLT (pxsl makes XSLT so... tolerable!) and then use the Haskell for simple line-based operations.

Here's the pxsl:
xsl:stylesheet \
-version=1.0 \
-xmlns:xsl=http://www.w3.org/1999/XSL/Transform

output -method=text

template TRIAL
for-each DOMAIN/ENTITY[@TYPE="target"]
call-template -name=printAttrs
text <<----
>>
for-each ATTRIBUTE-SET
call-template -name=printAttrs

template -name=printAttrs
for-each ATTRIBUTE
value-of @NAME
text << >>
value-of @VALUE
text <<
>>


and the Haskell. Can you tell what they do?
import Control.Arrow (second)
import Control.Monad (mapM_, forM_, when)
import System.Environment (getArgs)

main :: IO ()
main = getArgs >>= mapM_ checkFile

checkFile :: FilePath -> IO ()
checkFile f =
do (target, desc) <- getParts `fmap` readFile f
when (null desc) $ putStrLn noAttr
mapM_ (putStrLn . wrongAttr)
[ d | d <- desc, not $ d `elem` target ]
where
err x e = x ++ ": " ++ e
noAttr = err f "No attributes in the attribute set"
wrongAttr d = err f . err d $ "Incorrect attribute!"

getParts :: String -> ([String],[String])
getParts = second (drop 1) . break (== "----") . lines


Ain't rocket science. But this is a good example of the kind of non-research legwork that I at least know I can do. Wrote it in Haskell because it was just a little throwaway script.

submission

Also for REG, I spent some time making the submission script fancier (argh! had dumbly misunderstood what AB was saying about tracks). I don't like this submissions script. This is the kind of task that's hard not because it's particularly interesting, but just because there are so many combinations of variables that you the programmer have to consider (as in, you have to invent a behaviour for each combination, write some canned text, etc).

Wednesday, 26 March 2008

reading list (reg 4h)

Another day of just plodding along. Spent the morning debugging the submission script and trying to write some automated testing for it. Problem is that I don't really know a good way to test these fancy multipart CGI forms for file upload. I'm starting to think that maybe I should learn how to use the HTTP module and interact with the webserver. Meh.

reading list

Compiling an annotated reading list. Found something we might want to note for later, the Stochastic text generation article by Oberlander.

Tuesday, 25 March 2008

script hacking (reg 7h)

I think I've spent the whole day just working on the submission script. I dunno if it should have taken that long, but it did. This is the most complicated one yet (or maybe it's about the same as the prelim registration one), although I guess the only really new thing about this script is that I have to handle people's uploaded files.

I'm now armed with the habit of using FSA to describe the basic interactions involved.

I confess that I found this pretty boring. Not supposed to do that, I guess, chop wood, carry water, do everything to the best of your ability. And it's certainly less difficult and angst-inducing than research. Choose your poison.

Get the feeling that I've forgotten how to program. The thing feels a little grungy.

Otherwise doing ok. Meant to go to work this weekend, but got locked out. So instead of working from home (well, I did sorta start putting a reading list together), I just sort of rested and got myself back into some life stuff like gardening, cooking, going to bed early. More ready to tackle the day.

Thursday, 20 March 2008

huh... normalish day

Thought about the data to cr stuff a bit. Helped ILG with some proofreading. Seemed like a sort of normal day.

Wednesday, 19 March 2008

late but doing stuff

Bit of insomnia. Got here in time for lunch. Annotated some doughnuts. Tried to read a bit more Wong and Mooney (Synchronous CFG stuff).

Reading is hard.

Monday, 17 March 2008

meh

Another unproductive day.

Read the synchronous grammars tutorial by David Chiang.

Some random non-work hacking.

A lot of general, not-working activities.

And no, I'm not trying to prove a point (I'll explain later)

Friday, 14 March 2008

Holy crap, I actually DID WORK today! (Exclamation mark! Exclamation mark!)

Was in the middle of reading Hovy 1993 Automated Discourse Generation Using Discourse Structure Relations (which I feel really stupid for not finding until now), when all of a sudden it occurred to me that ya know, what would be really an obvious thing to try is to put together a simple D-LTAG grammar with GenI. The idea here is that we're going to ignore the realisation of sentences (just pretend they are "words"). Anyway, that took me through a little hacking detour in GenI, not to implement anything new, but to fix bugs that I found, for example, in the GUI when I was trying to debug my little 3-tree D-LTAG.

Here is the input we feed the generator:

last_night
semantics:[
e1:had_evening()
e2:had_meal()
e3:ate_salmon()
e4:ate_cheese()
e5:won_dancing()
r6:elaboration(e2 r7)
r7:narration(e3 e4)
r8:narration(r6 e5)
r0:elaboration(e1 r8)
]


Here's what the results I get from my grammar/lexicon (they're really small, and of course I'll send them to you). Note that I introduced ambiguity for the realisation of the narration and elaboration relations (either "S1 . S2" or "S1 . Conn S2"). I also hard-coded some parentheses in the trees, so that I could visually inspect what my grammar was really doing:
evening , in that ( meal , in that ( fish . cheese ) . dancing )
evening , in that ( meal , in that ( fish . cheese ) . then, dancing )
evening , in that ( meal , in that ( fish . then, cheese ) . dancing )
evening , in that ( meal , in that ( fish . then, cheese ) . then, dancing )
evening , in that ( meal : ( fish . cheese ) . dancing )
evening , in that ( meal : ( fish . cheese ) . then, dancing )
evening , in that ( meal : ( fish . then, cheese ) . dancing )
evening , in that ( meal : ( fish . then, cheese ) . then, dancing )
evening : ( meal , in that ( fish . cheese ) . dancing )
evening : ( meal , in that ( fish . cheese ) . then, dancing )
evening : ( meal , in that ( fish . then, cheese ) . dancing )
evening : ( meal , in that ( fish . then, cheese ) . then, dancing )
evening : ( meal : ( fish . cheese ) . dancing )
evening : ( meal : ( fish . cheese ) . then, dancing )
evening : ( meal : ( fish . then, cheese ) . dancing )
evening : ( meal : ( fish . then, cheese ) . then, dancing )

If you replace the lexicon with one where you use full sentences, then you get a results like this one:
John had a great evening last night , in that ( he had a great meal , in that ( he ate salmon . he devoured lots of cheese ) . he won a dancing competition )


This kinda looks right, but I'm not too happy with the semantics. Particularly, I fiddled around with the indices until the input discourse was no longer a graph, but a tree. What I really want, rather is something like this:
fakedesired?

e1:had_evening()
e2:had_meal()
e3:ate_salmon()
e4:ate_cheese()
e5:won_dancing()
r6:elaboration(e2 r7)
r7:narration(e3 e4)
r8:narration(r6 e5)
r0:elaboration(e1 r8)

e1:had_evening()
e2:had_meal()
e3:ate_salmon()
e4:ate_cheese()
e5:won_dancing()
r6:elaboration(e2 r7)
r7:narration(e3 e4)
r6:narration(e2 e5)
r0:elaboration(e1 r6)

Will need to think about this some more... No, waitasecond... that actually does what I want?!
evening : ( meal : ( fish . cheese ) . dancing )


Dude!

(too little, too late? INLG deadline is coming up, and I still have nothing to say except beuhbeuhbeuh? Gnarr)

Thursday, 13 March 2008

still stuck in late-late-late cycle

cycle

Last night was weird. Just didn't feel like going to bed. Ended up sleeping at like 03:00 (after a very long day too). Stayed home, more laziness, open source stuff, generally being a bum. Got here around 14:00 to begin anew this cycle of working late, starting slow, feeling guilty and working late.

lesson in humility

will write about this one later

more directed reading

But maybe starting to make some breakthroughs. That feeling of not having done my homework is quite justified, but now I have a better idea what I should have been looking at which I haven't yet. Completely ignored the whole body of literature on how RST is used for generation (why?), and now after struggling through my tech report, I have a clearer picture of what problems I'm trying to solve. All of a sudden, the body of RST/NLG literature makes more sense. Ahh:
Scott and Souza (1990) have posed the problem of how a rhetorical structure (in which propositions are linked by rhetorical relations, but not yet arranged in a linear order) can be realized by a text structure (in which propositions are ordered and linked up by appropriate discourse connectives. -- bouayadagha+2000cts (abstract)

That's pretty much exactly what my hypothetical discourse-processing device is supposed to do, only that until now, I didn't have a clear picture to what extent this was something other researchers have been trying to solve. Well, duh, people have been doing NLG long enough that somebody's bound to have thought about this... but I guess what I meant is that I didn't have a very good idea how to ask the questions I didn't even know I had.

Another mistake

Things which are helping out a lot:
  1. This comprehensive overview of NLG tasks (pdf slides)
  2. Bouayad-Agha et al, 2000, Can text structure be incompatible with rhetorical structure?


Sounds like I really need to read this scott+1990gtm. Too bad it's not available online anywhere.

Wednesday, 12 March 2008

aaaaaaaaaarrrr (reg 2)

I've been getting into this idiotic habit of staying really late at work and... not doing anything. [oh doing lots of stuff, just not work]

Except maybe in my last half hour, or something.

I'm not really happy with what I've proposed in my tech report version 0. I feel like I haven't done a good enough job seeing what it is other people have done.

Monday, 10 March 2008

not much progress (reg 2h30)

Eh. Not very productive today, although not horribly undisciplined either. Spent a couple of hours doing REG stuff. Spent a little bit of time learning how to use the xyling package for drawing trees (not too sure I like it). Plodding along on my little technical report trying to clarify some more ideas in my head. Discussed things with ILG a bit, which was somewhat useful as a way of doing sounding-board.

Friday, 7 March 2008

not horrible, not here

Had a doctor's appointment this morning, so got in around 11h. Worked on the journal paper from home. I'm a bit worried that I never really pull my weight in these things, but hey, I'm happy to make diagrams if diagrams are needed.

Chatted a bit in the afternoon with AX (X because I don't know his surname), PhD student (if I recall correctly), resident Linux guru, Gnome hacker. I got a little too chatty, which is fine, except that I think I was keeping him a little bit. Anyway, it was very nice to just exchange nerd DNA for a little bit. See, real life nerds aren't all Jolt-cola-chugging parents' basement dwellers. Some of them [will] have kids, play rugby, and are politically aware, and not just about your usual hacktivist fare.

Did more journal paper stuff.

Spent maybe an hour or a little bit more working on my tech report, getting my ideas a little bit more solid. But still haven't solved the basic problems :-/

BTW, I might consider applying for an EPSRC postdoctoral fellowship. They're sending out a call in summer, I think. It's meant for researchers who just finished their PhDs and want a nice chunk of time to go do some research (something like that). They last for 3 years. I'll bet they're horribly horribly competitive, and I basically won't get one. But, why not? [I'll tell you why not. I HATE applying for crap. I've been applying for crap since 1997, first get into Uni, then into the study abroad program, then into France job, then into the DEA, then the PhD, (actually, the last two were pretty easy all things considered, no motivation letters), and the monitorat, and the postdoc, and the qualifications]. Yeah, yeah, so have you. Yeah, yeah, I have nothing more to whinge about than you do. If I could only break free of this cycle of endless applications for crap...

Thursday, 6 March 2008

work! (reg 1h30)

Can you believe it? I actually worked today! I don't know what got into me. Well, actually I think I know what. I was looking at an old technical report (in my distress) and noticed something that set a few gears in motion. Unfortunately, nothing much, and this may lead nowhere. But I've basically spent today writing up a technical report, although I don't actually have a concrete idea to back it up.

Got here around 10h or so. Had a visit from the VRU, who explained to me roughly how research funding works. Nothing I plan to put to use in the short term, but ya never know. At least if people ask me to do stuff, I can have a much more precise idea why (other than, it's related to me continuing to have a job...)

Wednesday, 5 March 2008

not a productive week

I think I've done half a day's work between yesterday and today. Worked from home in the morning yesterday because I wanted to get some stuff done on the laptop (Omnigraffle stuff). But then I just sorta stayed home and did nothing useful (was it wxhaskell hacking I worked on?) Basic inertia. Today, came in at a reasonable time, but I still wanted to push some wxhaskell stuff out the door (I'm trying to get a release candidate out the door). Hack hack hack. Afternoon was similarly wasted, a bit of chit chat, a bit of staring out into space not able to set my mind on something, and a bit more hacking. Finally got started around 20:30 to think about this prodigy stuff. Generally discouraged.

Monday, 3 March 2008

looking at trees

Wow... it took me all day to do this? Made some trees for the journal paper (old work, not work work). Occurred to me that our indices were wrong, so spent some time fixing those. But it couldn't have taken that long?

Also a bit of putzing around in the form of trying to convert some tex-generated trees via pstoedit into a format that Inkscape could handle. Only problem was that pstoedit 3.44 had a bug where it would just hang. Took me sometime to figure out how to rebuild 3.45 from the Debian source package, following the kind instructions from the Ubuntu bugtracker. Only thing I would add to that is that you have to add the GPG keys for the package maintainer:
gpg --keyserver hkp://subkeys.pgp.net --recv-keys 3799E787
gpg --export --armor 3799E787 | sudo apt-key add -
(the key-id you figure out by looking at dpkg-source complaining that it can't find the public key. top line has the id)

Was trying to do two things: make part of the image in LaTeX (I'm such an idiot; completely forgotten that I had already done this for the viva) and redo the putting-together of everything in Inkscape. No real reason, just wanted to be independent from Mac (OmniGraffle) and my laptop. But after learning how to use the Bezier curves tool, after failing to import my converted svg (pstoedit foo.eps foo.svg works fine, but it can't find the CMM17 font for the math symbols), after learning how to align individual nodes in a bezier curve diagram... all that pushing and popping onto the mental stack... and it occurs to me "hey, I have exactly the image I'm trying to build all ready to go! (the viva)" So tonight I'm going to go home, fire up OmniGraffle (after all) and export the image to eps.

Oh well. I did learn some new skills:
  1. Building Debian source packages (basically dpkg-source -x and fakeroot)
  2. Aligning individual nodes on hand drawn Bezier curve shapes in Inkscape
  3. Converting from eps to a vector graphics format via pstoedit
  4. Using the charmap tool to locate Unicode characters like DOWNWARDS ARROW


not so guilty after all

... oh wait! It did NOT take me all day to do this. I spent the early afternoon talking with ILG, who is now up to speed about the problems I was having last month (and still am). I think she agrees it's a problem (as does AB), so I'm doubly reassured.