Today hasn't been terrifically productive PhD wise: helped debug some shell scripts, took care of some details for this holiday trip we had been planning for a while, attended a team meeting, chitted here and chatted there.
This morning I made the printing out of trees that do not have an idx label a little more systematic: I did it in such a way that you could display the idx-less trees for an entire test suite, and using a little XSLT on the metagrammar XML, display the trace information associated with those items.
The afternoon was mostly spent trying to figure out how to use octave and gnuplot. I'm starting to wonder if I should just not simplify gtester down to just use Gnuplot, because at least, that I can understand.
The early evening I was killing a bunch of minor bugs in GenI so that Claire could work more productively (things like not being able to call ViewTAG). I noticed one user-interface thing that I'll need to improve: I have "polarity detection" checked and untoggable to indicate that it is now mandatory, but this misleads the user into thinking that polarities are on, which they are not. It's just detection of the polarity values that is should polarities be enabled. One small fix is just to call it "auto-detection" so that the word "polarity" doesn't trip the user up. The other thing I'll need to do is to make its checked/unchecked status depend on polarities being checked/unchecked.
There is one SelectTAG issue I'll need to talk to Yannick about when he gets back. I don't think SelectTAG accepts input with an atomic disjunction. It can *output* them just fine, but passing disjunctions to it seems to be problematic.
Tonight was spent working on other user interface stuff. There was something that had been bugging me about my code for a long time, in that I was using my Show implementations for graphical stuff, which is not a very good idea because sometimes you need to display graphical stuff differently than on the console. Atomic disjunction, for instance, I would normally represent as a "|", but graphviz chokes on that so I output "!" instead. Problem is that if you feed "!" into almost any other tool than graphviz, it'll go, "huh?" So I cleaned all of this up, and have separate graphvizShow functions for my basic data, like GNode and AvPair. It means more code, but cleaner, better factored and more modular code.
Friday, 31 March 2006
Thursday, 30 March 2006
working with Claire
Been working with Claire today: trying to figure out how we're attacking the INLG. Seems that we're going after the polarities stuff as that's what really makes our contribution unique. So at first we started thinking about whether or not we could integrate semantic indices into the polarity counting as opposed to just categories. Claire made a comparison between the polarities stuff and QuickCheck, thinking maybe we could look for some automated mechanism for figuring out what would be good feature structures to build the polarity automata out of. This gave me a very simple, stupid idea for automatically detecting what features we could even use for polarity automata, the stupid idea being that we could just look for those which appear on all substitution and non-auxiliary root nodes (the auxes cancel themselves out) and for which all values are instantiated.
But implementing that brought us to the question of WHERE the attributes have to be defined. It turns out that I've been doing it kinda wrong the whole time, only it didn't matter because we were using categories. Today I learned from Claire how feature percolation works, you basically form a ladder up the tree, using coindexation of the top feature of the lower node with the bottom feature of the upper node. The point being that the indices would be set not on the top of the root node, but on its bottom. This might be counterintuitive at first because you perform unification on the TOP node only (actually we do both, but we should really stop doing that and fix the grammar to not require that behaviour instead)... but really, swear to $deity it's the right thing to do, because what matters is not the local unification behaviour, but the global information of where the nodes end up... roughly. Ya just gotta be able to count them, all that matters.
At first we thought we'd found a mechanism for making better use of auxiliary trees in the polarity automata. Instead of them canceling themselves out, we could actually have a seperate count for the top and bottom of the root node, because, for index percolation, their values wouldn't neccesarily be the same. This then evolved into another idea where we would count polarities in layers, where we'd have different kinds of polarities for each operation, substitution and adjunction for maximum flexibility (not everything has to be instantiated everywhere). But after a long afternoon of discussion, we decided that this was really not going to work, and that even if we managed to get this working, it probably wouldn't even help much. Back to the drawing board: how to we include semantic indices into the polarity automata stuff?
There wasn't very much coding involved today, pretty just Thinking Real Hard and talking alot. But it was fun. I learned a bit more about TAG and can a bit more confident in knowing how things should work. Sort of monopolising Claire's time for the next couple of days. Hope I'm making the most of it :-/
GenI needs automated regression tests. I keep coming up with test cases, then not implementing them. I'm going to have to sit down and import the mechanism that darcs uses for regression testing one of these days.
But implementing that brought us to the question of WHERE the attributes have to be defined. It turns out that I've been doing it kinda wrong the whole time, only it didn't matter because we were using categories. Today I learned from Claire how feature percolation works, you basically form a ladder up the tree, using coindexation of the top feature of the lower node with the bottom feature of the upper node. The point being that the indices would be set not on the top of the root node, but on its bottom. This might be counterintuitive at first because you perform unification on the TOP node only (actually we do both, but we should really stop doing that and fix the grammar to not require that behaviour instead)... but really, swear to $deity it's the right thing to do, because what matters is not the local unification behaviour, but the global information of where the nodes end up... roughly. Ya just gotta be able to count them, all that matters.
At first we thought we'd found a mechanism for making better use of auxiliary trees in the polarity automata. Instead of them canceling themselves out, we could actually have a seperate count for the top and bottom of the root node, because, for index percolation, their values wouldn't neccesarily be the same. This then evolved into another idea where we would count polarities in layers, where we'd have different kinds of polarities for each operation, substitution and adjunction for maximum flexibility (not everything has to be instantiated everywhere). But after a long afternoon of discussion, we decided that this was really not going to work, and that even if we managed to get this working, it probably wouldn't even help much. Back to the drawing board: how to we include semantic indices into the polarity automata stuff?
There wasn't very much coding involved today, pretty just Thinking Real Hard and talking alot. But it was fun. I learned a bit more about TAG and can a bit more confident in knowing how things should work. Sort of monopolising Claire's time for the next couple of days. Hope I'm making the most of it :-/
Did someone say coding?
Well ok, there was a little coding: made a small patch to display the trees that don't have an idx feature that would be usable for polarities. Also cleaned a bunch of stuff up in literate GenI: I ended up removing about 60 pages from the literate documentation after deciding that those modules were best read as pure source code, not in PDF form. That leaves me with 124 pages of GenI.the bug
Shit, forgot to mention the bug I think I found in GenI. If I recall correctly, we have this auxiliary agenda mechanism where we set aside all auxiliary trees which no longer have open substitution nodes. But I don't think that's the right behaviour because you might have the situation where your auxiliary tree is supposed to be substituted into some other tree to form a bigger auxiliary tree that would then be adjoined somewhere else. I don't think that gives you quite the same word order as, say, substituting some node into the tree and then adjoining into that. I'm not even sure this is possible, using the auxiliary trees to plug a substitution site, but if is, this means that GenI is probably doing it wrong, because if you set them aside the minute you build complete auxiliary trees, and later on in the chart/agenda control thingy you create a new node with a substitution site, you're not going to be creating the tree you want, because the aux tree you need to build the mega-aux tree would already have been set aside. Those suckers need to stay in your chart until the bitter end... well, at least until the substitution/adjunction phase flipover. I need to draw pictures and make a test case.GenI needs automated regression tests. I keep coming up with test cases, then not implementing them. I'm going to have to sit down and import the mechanism that darcs uses for regression testing one of these days.
Wednesday, 29 March 2006
mostly HaXmL and MMAX
That's the end of the MMAX stuff for a while then. Today went better. Implemented my robust scheme for dealing with the MMAX validation plus version control issue.
Found a very annoying darcs bug in the process. Sigh... well, being able to darcs mv to get the files rearranged was worth it. But this is another one of the cases where using not-yet-mature software bites you in ass. Anyway, I guess this gives me a new project for my hobby hacking time. I think I know how to fix the bug, and will attempt to tackle it this weekend or something.
XML, how do I hate thee.
Spent the rest of day hacking on the actual Haskell code to do the conversion. I kept introducing all sorts of stupid bugs into my code, logical errors like
instead of
Note that the above could stand to be refactored a bit. Some of the errors I made could probably have been signaled by the compiler, but I just never thought to turn warnings off. Stupid eric.. always compile with warnings on. Anyway, me and Hélène had to spend some time working out exactly what the right rules for this: one simple decision we made actually gave us a small bug fix: you should never delete the pointer for an object which is NOT coreferential (because you might have antecedants which are bridging, for example); and you should never delete the pointer of anything which points to two objects (because it's one of those funny corefence-to-split-antecendant issues).
Anyway, the big struggle here is that I can't figure out how to use Octave and Gnuplot. I'm working with a couple of tutorials, and I'm sure it's really easy, but, yes... I'm just slow that way. If anybody wants to show me how to use this, I'd be grateful.
Found a very annoying darcs bug in the process. Sigh... well, being able to darcs mv to get the files rearranged was worth it. But this is another one of the cases where using not-yet-mature software bites you in ass. Anyway, I guess this gives me a new project for my hobby hacking time. I think I know how to fix the bug, and will attempt to tackle it this weekend or something.
coreferential pointers to sets
Spent the large majority of my day working on converting coreferential pointer relations into sets. This job was extra-annoying. For one thing, since you're using revision control, you become aware of a lot of spurious "changes" like spaces getting inserted before attribute names or what not. Naturally enough, you want to avoid making these changes if you can have it. When you make a patch (or a revision -- this has nothing to do with the difference between darcs and CVS) you want to avoid introducing these false "differences" into your repository. So I spent a good hour wrapping things up with sed regular expressions to make the output XML look like the original as possible. This way the only changes were actual changes and not just stupid syntactic stuff.XML, how do I hate thee.
Spent the rest of day hacking on the actual Haskell code to do the conversion. I kept introducing all sorts of stupid bugs into my code, logical errors like
mergeIntersecting [] = []
mergeIntersecting (s:ss) =
let (yes,no) = List.partition (intersects s) ss
next = mergeIntersecting no
in if null yes then next else (Set.unions yes) : next
instead of
mergeIntersecting [] = []
mergeIntersecting (s:ss) =
let (yes,no) = List.partition (intersects s) ss
next = mergeIntersecting no
in if null yes then s:next else (Set.unions yes) : next
Note that the above could stand to be refactored a bit. Some of the errors I made could probably have been signaled by the compiler, but I just never thought to turn warnings off. Stupid eric.. always compile with warnings on. Anyway, me and Hélène had to spend some time working out exactly what the right rules for this: one simple decision we made actually gave us a small bug fix: you should never delete the pointer for an object which is NOT coreferential (because you might have antecedants which are bridging, for example); and you should never delete the pointer of anything which points to two objects (because it's one of those funny corefence-to-split-antecendant issues).
INLG is 19 April
What a relief. I thought it was 9 April. So maybe I can, like, not freak out now. TAG+8 is 7 April. I wanted to talk about GenI, do the whole, "hey guys we now have a working surface realiser for TAG and large grammars now, wanna play?" routine, but I don't think I can manage it. Besides, already doing a paper with Yannick where we mention GenI as part of a TAG toolbox. There is also FINTAL which has been extended to 3 April, but I'm not going to be ready for that.gtester
Working on getting simple plots into the gtester, and otherwise improving the output for it. I have one useful column, maybe, just showing how much time lexical selection itself -- calling SelectTAG -- takes. Useful for differentiating between that and surface realisation proper. I've learned two new things about Python today:- looks like everything is by-reference. So if you say a=1 and then b=a and then b++, a also changes value. I like things with implicit pointers, I do, but arrrgh, mutability! Why oh why do things have to change value under my feet? Sniiiff... ;-) Just more whining from a functional programmer having trouble switching back to the imperative mindset. Maybe I should rewrite gtester in Haskell. (kidding! kidding!)
- Those mysterious underscores I was always wondering about, like in methods like __foo are used for name mangling (collision avoidance), because in Python, I guess, everything within one module is global to the module. Yippee. Anyway __foo gets translated into myclass__foo or something like that
Anyway, the big struggle here is that I can't figure out how to use Octave and Gnuplot. I'm working with a couple of tutorials, and I'm sure it's really easy, but, yes... I'm just slow that way. If anybody wants to show me how to use this, I'd be grateful.
ugh
Well, today sucked.
Had to figure out how to deal with a situation where MMAX and darcs (or any other version control system) were just not playing nice together. The problem is that MMAX has this handy 'validation' feature, which also has the side effect of completely rearranging your markables file... which completely sucks if
And the reason why this sucks is that the minute you say "validate", you've completely rearranged the contents of your co-annotator's MMAX levels. When you try to darcs pull or cvs checkout their changes, you get conflicts to deal with, and if you are not a techie, if you are just a linguist trying to get your annotation done you are not a happy camper.
Sigh... well that's what I get for suggesting version control. The old way would be just to keep sending each other email with the latest versions of each other's files, but (1) that is so a source for confusion (2) the process doesn't lend itself to things like getting outside intervention from a coder (me) to run scripts on stuff because the coder gets confused too and could potentially make a mess of things.
So that was one morning eaten up. I had even gotten to the office bright and early too, around 9h40. Ended up spending the morning explaining why, no we could not all just work on the same file over an NFS share (or something similar), because all hell could break loose, depending on when you edit what file; trying to defend the fact that we are choosing version control; explaining that no, this has nothing to do with patch-based vs. version-based revision control.
And the funny thing is after all that fuss including maybe an aborted attempt to wrap the whole process up into some kind of script or Makefile (not a good idea in this case), the solution was really simple: don't use MMAX validation.
Well, ok, I ended up coming up with an even better solution at the end of the day when everybody left. The basic idea is that each annotator gets her own directory, with her own mmax files (duh) so that MMAX validation does not affect any of the other annotator's work. There would still be a multi-level version of the mmax file so that you can query across levels and do all sorts of fancy crap. The funny thing is that if I had thought of this solution in the first place, I wouldn't even have mentioned darcs or anything else, because clobbering things could have been done in a simpler manner, since everything was more modular.
Gah.
Had to figure out how to deal with a situation where MMAX and darcs (or any other version control system) were just not playing nice together. The problem is that MMAX has this handy 'validation' feature, which also has the side effect of completely rearranging your markables file... which completely sucks if
- you're using CVS/Subversion/darcs
- you are doing multi-level annotation with one annotator per level
And the reason why this sucks is that the minute you say "validate", you've completely rearranged the contents of your co-annotator's MMAX levels. When you try to darcs pull or cvs checkout their changes, you get conflicts to deal with, and if you are not a techie, if you are just a linguist trying to get your annotation done you are not a happy camper.
Sigh... well that's what I get for suggesting version control. The old way would be just to keep sending each other email with the latest versions of each other's files, but (1) that is so a source for confusion (2) the process doesn't lend itself to things like getting outside intervention from a coder (me) to run scripts on stuff because the coder gets confused too and could potentially make a mess of things.
So that was one morning eaten up. I had even gotten to the office bright and early too, around 9h40. Ended up spending the morning explaining why, no we could not all just work on the same file over an NFS share (or something similar), because all hell could break loose, depending on when you edit what file; trying to defend the fact that we are choosing version control; explaining that no, this has nothing to do with patch-based vs. version-based revision control.
And the funny thing is after all that fuss including maybe an aborted attempt to wrap the whole process up into some kind of script or Makefile (not a good idea in this case), the solution was really simple: don't use MMAX validation.
Well, ok, I ended up coming up with an even better solution at the end of the day when everybody left. The basic idea is that each annotator gets her own directory, with her own mmax files (duh) so that MMAX validation does not affect any of the other annotator's work. There would still be a multi-level version of the mmax file so that you can query across levels and do all sorts of fancy crap. The funny thing is that if I had thought of this solution in the first place, I wouldn't even have mentioned darcs or anything else, because clobbering things could have been done in a simpler manner, since everything was more modular.
Gah.
HaXmL
The rest of the night, I worked on writing a small program to convert all coreferential pointer relationships into set membership. It's actually an absurdly simple task, and I was making life difficult for myself as usual. The end solution -- well, it's not done yet -- is to make two passes, one HaXmL parsing just to determine who points to what and calculate the member sets out of that, a second pass to modify the contents, à la XSLT (only using Haskell), updating all the set memberships accordingly. To collect the sets, what I basically did was put all pointer relationships into a two-member set (pointer and pointee), and then merge all sets with a non-empty intersection. Before that, I was working on this way complicated solution where I was trying to preserve the ids of known sets in order to minimise the changes or something stupid like that. XML is such a pain in the ass.Monday, 27 March 2006
mmaxql
Still helping Claire and Hélène on the MMAX stuff. Made a quick transformation for them, using this bit of XLST, wasn't very painful, especially now that I'm using PXSL syntax to keep things concise.
Me and Hélène used an empirical informatics approach to learn how to use MMAXQL, quite a nice little query language, would be nice if it was a little more expressive, but it seems they can do some good stuff with what MMAX2 already offers. The ability to edit markables returned by the query language is killer.
Also got H. set up with a local account and access to the local darcs/trac server. One thought is that there are a lot of projects which don't neccesarily need trac pages. Maybe I should make a light version of the admin script to create darcs-only setups.
There is one task I'm working on now which is a little bit beyond my XSLT abilities (which aren't very profound for that matter): I need to merge certain items that were MMAX pointers into MMAX member sets, which isn't very easy because you have to create new sets, make sure they are unique and all that jazz. So I think I'm going to do this in Haskell instead, write a little HaXmL program.
Oh and Claire and I had a quick generation chat this afternoon. I had pointed out that the semantics for function words like "le" could be finer grained, "le_clitic" and "le_determiner" for example. This was my fault. I had earlier insisted on a semantics with a tight coupling to the vocabulary such that where you would say "courir" in French, our semantics for it would be something like
Claire also had a useful observation about the test suite building process, that a lot of the test cases were identical were it not for morphology. Since the majority of her time is spent hacking the test suite and the grammar, it would be useful to really cut that stuff down and then build up on it with more generation specific stuff. Works for me. I offered to modify the sematiser script so that we only return test cases with unique lemmatised output.
Me and Hélène used an empirical informatics approach to learn how to use MMAXQL, quite a nice little query language, would be nice if it was a little more expressive, but it seems they can do some good stuff with what MMAX2 already offers. The ability to edit markables returned by the query language is killer.
Also got H. set up with a local account and access to the local darcs/trac server. One thought is that there are a lot of projects which don't neccesarily need trac pages. Maybe I should make a light version of the admin script to create darcs-only setups.
There is one task I'm working on now which is a little bit beyond my XSLT abilities (which aren't very profound for that matter): I need to merge certain items that were MMAX pointers into MMAX member sets, which isn't very easy because you have to create new sets, make sure they are unique and all that jazz. So I think I'm going to do this in Haskell instead, write a little HaXmL program.
Oh and Claire and I had a quick generation chat this afternoon. I had pointed out that the semantics for function words like "le" could be finer grained, "le_clitic" and "le_determiner" for example. This was my fault. I had earlier insisted on a semantics with a tight coupling to the vocabulary such that where you would say "courir" in French, our semantics for it would be something like
courir(c) agent(c, x). The idea was that we keep things simple and don't try to handle things like synonymy or paraphrasing just yet. If we can make the damned thing work, then we can think about going after a looser coupling between the semantics and the lexicon. What I was mostly worried about is synonymy - lumping several lexical entries into the same semantics. The idea of assigning different semantics to what would ostensibly be the same lemma never bothered me, but I should have made that point clear early on. No big deal.Claire also had a useful observation about the test suite building process, that a lot of the test cases were identical were it not for morphology. Since the majority of her time is spent hacking the test suite and the grammar, it would be useful to really cut that stuff down and then build up on it with more generation specific stuff. Works for me. I offered to modify the sematiser script so that we only return test cases with unique lemmatised output.
Saturday, 25 March 2006
Hélène is here until Wednesday to do some annotation work. Seems her and Claire are working over the weekend as well to maximise annotation time. They had a question for me and so I offered to come down to the office and talk with them in face to face.
Had a discussion on how we should structure the annotation schema. Eventually after drawing lots of diagrams and working out how things would relate, we decided on a single level scheme, but treating each annotator plus the gold standard as a separate MMAX markable level.
Spent a bit of time fighting with colours, trying to make visible a line, visible but not blocking the text underneath it, visible, but contrasting with both the red lines, the black text, the blue markables and the white background; it being a thin line, light colours (except red) would not do, because you would see que dalle, nothing. My final decision was to keep the line blue, but make it curvy so that it was longer and you could see it better, and make the markables green so that you could see the line. Keeping the markables blue and making the line green would not have worked as well, because it's hard to make the green line out against black text. Details are everything. Life of a Mac user. I'm crap at making usable interface, but I do understand somewhere that getting the details right is essential.
Also tried anticipate the future by separating out Claire and Hélène's annotations into separate levels, but then I got the impression that this would be a user interface nightmare or something, don't remember what, but something made me skittish about the whole thing, so I went conservative and just kept things the same way, reasoning that when it came time to kappa the whole thing, I would also write some scripts to merge their corpora together. Turns out that this is what they were expecting me to do, literally separate out their levels, so they were surprised that I hadn't done it, and I was slightly taken aback that the experiment I did just to be anticipatory was actually the desired behaviour. Fine, fine. Good thing there is darcs unrevert to undo my undo.
Managed to convince Claire that we should use darcs to keep track of hers and Hélène's annotations. I hope this is the right thing to do. What I figure is that this is the kind of stuff that evolves -- consider all the reannotations they seem to keep doing -- and that version control is something they need, and since they don't have the luxury of a common server, nor of open source corpora (the original text is not open), darcs's decentralisation is ideal for the job. Hélène would just have to darcs record her changes, zip up her repository, mail them to me/Claire, and we would do the darcs pull. It's kinda ugly. The alternative would be do write up a shell script to do some kind of recursive copy, clobbering the old versions or something, but it seems cleaner to do it with darcs. I'm not abusing the darcs hammer, am I?
Had a discussion on how we should structure the annotation schema. Eventually after drawing lots of diagrams and working out how things would relate, we decided on a single level scheme, but treating each annotator plus the gold standard as a separate MMAX markable level.
Spent a bit of time fighting with colours, trying to make visible a line, visible but not blocking the text underneath it, visible, but contrasting with both the red lines, the black text, the blue markables and the white background; it being a thin line, light colours (except red) would not do, because you would see que dalle, nothing. My final decision was to keep the line blue, but make it curvy so that it was longer and you could see it better, and make the markables green so that you could see the line. Keeping the markables blue and making the line green would not have worked as well, because it's hard to make the green line out against black text. Details are everything. Life of a Mac user. I'm crap at making usable interface, but I do understand somewhere that getting the details right is essential.
Also tried anticipate the future by separating out Claire and Hélène's annotations into separate levels, but then I got the impression that this would be a user interface nightmare or something, don't remember what, but something made me skittish about the whole thing, so I went conservative and just kept things the same way, reasoning that when it came time to kappa the whole thing, I would also write some scripts to merge their corpora together. Turns out that this is what they were expecting me to do, literally separate out their levels, so they were surprised that I hadn't done it, and I was slightly taken aback that the experiment I did just to be anticipatory was actually the desired behaviour. Fine, fine. Good thing there is darcs unrevert to undo my undo.
Managed to convince Claire that we should use darcs to keep track of hers and Hélène's annotations. I hope this is the right thing to do. What I figure is that this is the kind of stuff that evolves -- consider all the reannotations they seem to keep doing -- and that version control is something they need, and since they don't have the luxury of a common server, nor of open source corpora (the original text is not open), darcs's decentralisation is ideal for the job. Hélène would just have to darcs record her changes, zip up her repository, mail them to me/Claire, and we would do the darcs pull. It's kinda ugly. The alternative would be do write up a shell script to do some kind of recursive copy, clobbering the old versions or something, but it seems cleaner to do it with darcs. I'm not abusing the darcs hammer, am I?
lexical selection
Oh yeah, I forgot to mention the semi-useful thought I had on the way home last night: I think the metagrammar/anchoring system's behaviour is such that we've pretty much got selection of semantics (defined exclusively in the grammar) for free. This is a useful side effect of being able to define semantics in the metagrammar classes and use the anchoring mechanism to fill them out or something. Nothing to do with metagrammars per se, mind you, just that it's useful to be able to hard-code a semantics into the tree schema and use unification on the predicates to plug a value in. The flip side of this is that (as we saw yesterday), you have to do filtering to make sure the metagrammar does not introduce too much semantics, but that's just a tiny line of Haskell, no big deal.MRS in generation
I just randomly recalled something that John Carroll told me after his talk -- something he had been meaning to mention during, but forgot about. He doesn't actually do anything with the handle constraints. He equates stuff. Uh wait, I'm not sure I know what that means. Does that mean he equates stuff that isn't defined by a constraint? Any open variables, he simply equates? If I understand correctly anyway, at some point he's just generating from a bag of EPs. Well... the GenI semantics is essentially a bag of EPs right? We're basically just MRS sans top handle and handle constraints, right? So does that mean that we are more or less generating from MRS like everyone and their step-cousin thrice removed?Friday, 24 March 2006
lexical selection
Ugh.. never again. I have a recurring freeciv addiction, every binge being a blot in my sleep schedule and a terrible terrible memory, crawling to bed at 7am a shivering huddled mess feeling utterly sick. Not my idea of fun. Yet somehow every once in a while I get that strange urge and give in completely to the impulse. It is not fun, not interesting, but sometimes you just... I don't know... Anyway. Game over. Back to reality for a time.
Got to work at 16h today, in time for Guillaume's FR FrameNet talk.
Spent an hour after that making a fancy Omnigraffle diagram for Patrick (Hint: command-click allows you to add bezier handles in the pen tool. It's useful to draw the diagram out using straight lines and then throw the curves in when you have the general shape worked out).
I figured out what was wrong with the lexical selection process: Claire's version of the grammar has classes which introduce literals into the candidate semantics, literals that were not in the lexicon. The quick fix is to add another filter on top of the lexical selection process to throw out any items who introduce relations. In fact, Carroll 1999 (An Efficient Chart Generator) also mentions that grammar rules which introduce relations are not allowed if the relations are in the input sem, so I'm pretty comfortable adding this one-liner in. Will have to check with Claire, of course, and will have to see what to do when we actually want to select on the basis of these relations, but for the moment, this filter solves the problem :
On a slightly unrelated note: I have always thought of lexical selection as retrieving the set of lexical items which subsume the input semantics. That is, you want items whose semantics is equivalent to or more general than the input. What this basically amounts to is that your lexical semantics should be a subset of the input semantics, assuming you can unify all the constants into the right place. One difference between me and Claire is that Claire always says "subsumes part of the input semantics" whereas I say "subsumes the input semantics" because if you subsume part of the input semantics, you neccesarily subsume the input semantics, right?
Ok subsume-part implies subsume, but not necessarily the other way around. But who cares? You could say that subsume part of the input semantics if you wanted to be cautious, I guess, because for example, you might want to subsume only foo and bar, but not bletch. But this only makes sense if you've got some mechanism for splitting the input semantics into parts such that you would want to select items that subsume only those parts and not the other. Not a big deal, but this reminded me a bit about subsumption and all that lovely business.
Oh, so what happens now that we've fixed the two-determiner bug in the grammar? Things go a whole lot faster! Things that used to take 20 seconds in Simple get generated in 6. The same things used to take over 1000 seconds in Earley, and now they take 50 seconds. Especially when that one way is actually constrained. The lesson? Badly constrained ddjunction is EEEEEEEVVIL. Well, I can't run away from adjunction forever. One of these days, somebody is going to come up with an adjective or an adverb and ooh boy are things going to suck.
There is a bad news side to this though: none of our clitics work anymore! We can no longer say stuff like "l'ingéniur le lui apprend". Oops. Regression. Hopefully Claire will fix this up real quick with her linguistics-fu (without re-introducing the bug).
Got to work at 16h today, in time for Guillaume's FR FrameNet talk.
Spent an hour after that making a fancy Omnigraffle diagram for Patrick (Hint: command-click allows you to add bezier handles in the pen tool. It's useful to draw the diagram out using straight lines and then throw the curves in when you have the general shape worked out).
I figured out what was wrong with the lexical selection process: Claire's version of the grammar has classes which introduce literals into the candidate semantics, literals that were not in the lexicon. The quick fix is to add another filter on top of the lexical selection process to throw out any items who introduce relations. In fact, Carroll 1999 (An Efficient Chart Generator) also mentions that grammar rules which introduce relations are not allowed if the relations are in the input sem, so I'm pretty comfortable adding this one-liner in. Will have to check with Claire, of course, and will have to see what to do when we actually want to select on the basis of these relations, but for the moment, this filter solves the problem :
filter (\t -> all (`elem` tsem) $ tsemantics t)
On a slightly unrelated note: I have always thought of lexical selection as retrieving the set of lexical items which subsume the input semantics. That is, you want items whose semantics is equivalent to or more general than the input. What this basically amounts to is that your lexical semantics should be a subset of the input semantics, assuming you can unify all the constants into the right place. One difference between me and Claire is that Claire always says "subsumes part of the input semantics" whereas I say "subsumes the input semantics" because if you subsume part of the input semantics, you neccesarily subsume the input semantics, right?
input semantics: foo(a) bar(b) baz(c) bletch(d)
part of input semantics: foo(a) bar(b) baz(c)
subsumes the input semantics: foo(?X) bar(?X)
Ok subsume-part implies subsume, but not necessarily the other way around. But who cares? You could say that subsume part of the input semantics if you wanted to be cautious, I guess, because for example, you might want to subsume only foo and bar, but not bletch. But this only makes sense if you've got some mechanism for splitting the input semantics into parts such that you would want to select items that subsume only those parts and not the other. Not a big deal, but this reminded me a bit about subsumption and all that lovely business.
Oh, so what happens now that we've fixed the two-determiner bug in the grammar? Things go a whole lot faster! Things that used to take 20 seconds in Simple get generated in 6. The same things used to take over 1000 seconds in Earley, and now they take 50 seconds. Especially when that one way is actually constrained. The lesson? Badly constrained ddjunction is EEEEEEEVVIL. Well, I can't run away from adjunction forever. One of these days, somebody is going to come up with an adjective or an adverb and ooh boy are things going to suck.
There is a bad news side to this though: none of our clitics work anymore! We can no longer say stuff like "l'ingéniur le lui apprend". Oops. Regression. Hopefully Claire will fix this up real quick with her linguistics-fu (without re-introducing the bug).
Thursday, 23 March 2006
Well, that was a nice visit.
Got here at normal-people time, around 9h40; gave John C. a demonstration of GenI and rambled on about all sorts of random issues. I checked my understanding of index accesibility filtering and quickcheck with him. He seems to think that's about right, so that's a good sign, eh? I'd be really interested to get it implemented for GenI and see how much it helps.
John pointed out that my CKYish algorithm is more like an Earley one and Claire agreed, but I'm not so sure. I think that Simple is quite Earleyish, and that CKY+ordered substitution is Earleyish (what I used to call CKY2), but may cky sans the ordered substitution? Anyway, Claire makes about complete and incomplete items and that if you're working with CKY you are neccesarily building from complete items only - which is what I think I'm doing, but maybe I don't know what I'm saying. Doesn't matter. Anyway, if I understand correctly, it took me 5 months to implement a CKY style algorithm, but it took me about a couple of hours to implement an Earley one on top of that.
Claire and Jesse were there, so I also managed to show her a small bug that I had discovered two nights ago in the grammar: we were getting two determiners and they were made such that they could adjoin pratically anywhere. Claire managed to track it down and fix it this afternoon after John's talk, so that was good.
The talk was nice. I was surprised by how much I liked the selective unpacking approach. Very easy to understand and done in a pretty elegant, efficient manner. Also found out that the skolemisation thing is no big deal, it just treating those MRS variables as constants, basically what we do implicitly in GenI. Asked a stupid performance question. Turns out I just wasn't listening enough, or reading the chart right, because J was presenting data in terms of performance of one generator wrt to the other, where I thought it was a table of raw seconds he was showing. Silly me.
That's about it. I just found out that I've been using an old version of the grammar with gtester... the new one gives me a case that I had never foreseen: lexical items which introduce relations. Ugh. I think these used to work, but now that I've switched to my bitvector representation of the semantics, I'll have to slightly rethink matters. That's an issue for tomorrow though...
Got here at normal-people time, around 9h40; gave John C. a demonstration of GenI and rambled on about all sorts of random issues. I checked my understanding of index accesibility filtering and quickcheck with him. He seems to think that's about right, so that's a good sign, eh? I'd be really interested to get it implemented for GenI and see how much it helps.
John pointed out that my CKYish algorithm is more like an Earley one and Claire agreed, but I'm not so sure. I think that Simple is quite Earleyish, and that CKY+ordered substitution is Earleyish (what I used to call CKY2), but may cky sans the ordered substitution? Anyway, Claire makes about complete and incomplete items and that if you're working with CKY you are neccesarily building from complete items only - which is what I think I'm doing, but maybe I don't know what I'm saying. Doesn't matter. Anyway, if I understand correctly, it took me 5 months to implement a CKY style algorithm, but it took me about a couple of hours to implement an Earley one on top of that.
Claire and Jesse were there, so I also managed to show her a small bug that I had discovered two nights ago in the grammar: we were getting two determiners and they were made such that they could adjoin pratically anywhere. Claire managed to track it down and fix it this afternoon after John's talk, so that was good.
The talk was nice. I was surprised by how much I liked the selective unpacking approach. Very easy to understand and done in a pretty elegant, efficient manner. Also found out that the skolemisation thing is no big deal, it just treating those MRS variables as constants, basically what we do implicitly in GenI. Asked a stupid performance question. Turns out I just wasn't listening enough, or reading the chart right, because J was presenting data in terms of performance of one generator wrt to the other, where I thought it was a table of raw seconds he was showing. Silly me.
That's about it. I just found out that I've been using an old version of the grammar with gtester... the new one gives me a case that I had never foreseen: lexical items which introduce relations. Ugh. I think these used to work, but now that I've switched to my bitvector representation of the semantics, I'll have to slightly rethink matters. That's an issue for tomorrow though...
Wednesday, 22 March 2006
I've been in pretty bad mood overall these past couple weeks (local minima and maxima of course).
Today in the tram, I finally got around to taking a look at Parser Engineering and Performance Profiling. Pretty cool stuff. To be honest, my eyes kinda glazed over when they explained hyper-active parsing. But it has a pretty cool name at least. This is what I get trying to read things at the last minute in the tram. Anyway, there is one general theme in making parsers and generators go faster: Fail early. Well... what else can you do? Everything can be thought of as some variant on this, but what I really had in mind is not so much a formal pruning of the search space but jiggling around the order of the operations that we have to do anyway such that we find out as early as possible that the effort would be wasted anyway. Oh lordy, I'm not saying anything useful. Well, look, it's what this head driven parsing thing is all about right? You start with the most specific stuff because that's where you know things are going to fail. If you started with something that is only a variable, that is coindexed with some other node far off, well that's going to succeed, but later on you're going to get your failure, just with a whole bunch of completely useless intermediary items being created in the meantime. Fail early and you avoid producing a lot of useless crap.
Right, so what's with the bad mood. Only today, only looking in article did I find out about incr_tsbd. Now this is like gtester, only a whole lot more complete, and it was made for testing the LKB (and PAGE) parsers. Hey, it's great that this stuff exists, works better than what I have, and has been around longer. I'm happy about that. What bugs me is that feeling that I've really not been doing my job and that I still don't have a bleeping clue what my job is. Why is it only now that I find out about this? Could I have avoid a bunch of boring gtester hacking if I had known about incr_tsbd?
Ah well, so today, I skimmed through the user manual, read the TSNLP paper. Spent some more time looking at the Parser Performance paper. Threw together a quick GenI demo for John Carroll. Oh yeah, Yannick's been working on the TAG+8 paper, but I haven't really done very much. Tried to smooth some stuff out and squish down to two pages, but then lunch came around and all sorts of other random activity came about. Yep. Been a wheel spinny kind of week. I'd rather be coding :-). That's the problem, see. I'm not a computer scientist; I'm just a programmer with a fancy degree.
Nothing wrong with that of course. It's just that by signing up for this PhD program, I've got pretentions to computer scientistness which I obviously cannot fulfill. But hey. constant sense of insecurity is apparantly what all PhD students go through, isn't it? Heh... isn't this supposed to be my professional blog? No feelings, just dry news?
Today in the tram, I finally got around to taking a look at Parser Engineering and Performance Profiling. Pretty cool stuff. To be honest, my eyes kinda glazed over when they explained hyper-active parsing. But it has a pretty cool name at least. This is what I get trying to read things at the last minute in the tram. Anyway, there is one general theme in making parsers and generators go faster: Fail early. Well... what else can you do? Everything can be thought of as some variant on this, but what I really had in mind is not so much a formal pruning of the search space but jiggling around the order of the operations that we have to do anyway such that we find out as early as possible that the effort would be wasted anyway. Oh lordy, I'm not saying anything useful. Well, look, it's what this head driven parsing thing is all about right? You start with the most specific stuff because that's where you know things are going to fail. If you started with something that is only a variable, that is coindexed with some other node far off, well that's going to succeed, but later on you're going to get your failure, just with a whole bunch of completely useless intermediary items being created in the meantime. Fail early and you avoid producing a lot of useless crap.
Right, so what's with the bad mood. Only today, only looking in article did I find out about incr_tsbd. Now this is like gtester, only a whole lot more complete, and it was made for testing the LKB (and PAGE) parsers. Hey, it's great that this stuff exists, works better than what I have, and has been around longer. I'm happy about that. What bugs me is that feeling that I've really not been doing my job and that I still don't have a bleeping clue what my job is. Why is it only now that I find out about this? Could I have avoid a bunch of boring gtester hacking if I had known about incr_tsbd?
Ah well, so today, I skimmed through the user manual, read the TSNLP paper. Spent some more time looking at the Parser Performance paper. Threw together a quick GenI demo for John Carroll. Oh yeah, Yannick's been working on the TAG+8 paper, but I haven't really done very much. Tried to smooth some stuff out and squish down to two pages, but then lunch came around and all sorts of other random activity came about. Yep. Been a wheel spinny kind of week. I'd rather be coding :-). That's the problem, see. I'm not a computer scientist; I'm just a programmer with a fancy degree.
Nothing wrong with that of course. It's just that by signing up for this PhD program, I've got pretentions to computer scientistness which I obviously cannot fulfill. But hey. constant sense of insecurity is apparantly what all PhD students go through, isn't it? Heh... isn't this supposed to be my professional blog? No feelings, just dry news?
Monday, 20 March 2006
Index accesibility filtering
Ok, I think I'm starting to "get" how index accesibility filtering works, although I get the impression that for this to be more useful than delayed adjunction, you need to have packing enabled. I'm gonna bet that the effect of index accesibility filtering is similar to that of chunking the logical form (White 2002 [?] - OpenCCG stuff). The idea is that rather than delaying modifier insertion (adjunction for us TAGgeurs), you delay substitution but implicitly, through this index accesibility thing. The main point of this mechanism is NOT to do any substitution if the thing ain't got all its modifiers yet. Any items that try to do this get DISCARDED.
Consider the input semantics
I'm sort of translating things to TAG terms on the fly. The idea here is that semantic indices are accesible so long as they are in the root node of the chart item or there is an open substitution node that has that index. If you perform substitution, what happens is that you are potentially making indices unavailable -- those which were on the subst node of the substitutee and on the root node of the substituter. If at any point an index becomes inaccesible and that index is part of the yet-to-be-realised semantics, we can nip the item at its progeny off in the bud by tossing it in the trash. We NEVER try to adjoin "the" into "cat runs" (because "cat runs" would just be chucked out), instead we wait until we have "the cat" and then we try to plug that into "runs".
This is basically the exact opposite of delayed adjunction. But it has the same kind of effect: it nips items off in the bud. The things it nips off are potentially good. They could potentially become results, but it's ok because we know that we can get the same exact result by doing things in another order.
Oof. Things get a lot clearer when you sleep on them. This stuff I figured out on the tram on the way to work. I had always sort of seen how it worked, but never really understood WHY it worked so well, why it could be better than delayed modification. I still feel like you've got slightly more chart items and comparisons to do using this method, but at least I can see that we're in the same ballpark.
Consider the input semantics
def(a) cat(a) runs(r,a) and a toy grammar which consists of an auxiliary tree for def(a), and a couple of simple initial trees for cat(a) and run run(r,a). Here's what the top of the agenda is going to look like during a run through the algorithm, with index and semantic availability on the side. Items that need to be discarded will be struck out:
item | missing sem | accesible | inaccesible | result
cat | def(a), runs(r,a) | a | |
cat runs | def(a) | r | a | TOSS
the cat | runs(r,a) | a | |
the cat runs | | r | a |
I'm sort of translating things to TAG terms on the fly. The idea here is that semantic indices are accesible so long as they are in the root node of the chart item or there is an open substitution node that has that index. If you perform substitution, what happens is that you are potentially making indices unavailable -- those which were on the subst node of the substitutee and on the root node of the substituter. If at any point an index becomes inaccesible and that index is part of the yet-to-be-realised semantics, we can nip the item at its progeny off in the bud by tossing it in the trash. We NEVER try to adjoin "the" into "cat runs" (because "cat runs" would just be chucked out), instead we wait until we have "the cat" and then we try to plug that into "runs".
This is basically the exact opposite of delayed adjunction. But it has the same kind of effect: it nips items off in the bud. The things it nips off are potentially good. They could potentially become results, but it's ok because we know that we can get the same exact result by doing things in another order.
Oof. Things get a lot clearer when you sleep on them. This stuff I figured out on the tram on the way to work. I had always sort of seen how it worked, but never really understood WHY it worked so well, why it could be better than delayed modification. I still feel like you've got slightly more chart items and comparisons to do using this method, but at least I can see that we're in the same ballpark.
GenI
Now that I've semi-understood this mechanism, I'm going to need to implement this in GenI for both Simple and CKY. Oh, speaking of which, another thing I figured out in the tram. This thing I figured out was actually the prelude to me figuring out index accesibility filtering. I've puzzling over why the CKY GenI would produce so many more chart items than Simple even without any adjunction. We seem to be walking the trees either way and generating chart items on the fly right? Well, one very simple fact is that with delayed adjunction, we're discarding a lot mess of syntactically incomplete intermediate structures before passing into the adjunction phases. This is important not so much for items themselves, but for all the tree walking they avoid. It's all about nipping things in the bud. Even if you don't have any adjunction, the two phase approach is useful, because it tells you how much tree walking you do not need to do. Incidentally, a small, potentially useless optimisation would be to detect that there are no auxiliary trees and not bother with any tree walking. A simple test I could perform for this is to disable the discard of items between the substitution and adjunction phases. Then we ought to get roughly comparable numbers of chart items.Yay sleep!
So that's two useful ideas right before I've ever properly started my work day. Just got here and had lunch, and am taking the opportunity to jot all this down before I forget it. I guess that's an important lesson, eh? Work is important if you want to produce anything, but sometimes rest is even more so. It's the kind of thing EVERYBODY knows, or thinks they know, but it's also something we need to be reminded of. I got my best work for this week done in my sleep and on the tram... not in the office. Well ok, then again, that's not entirely true. The time you spend at work is important because you need to use it dump things into your head so that you can process them at night in your sleep. If I hadn't spent time struggling over the JC article by day, I wouldn't have gotten any of these results by night.preparing for John Carroll
John Carroll's coming to visit us on Thursday, so I'm trying to prepare by (re)reading everything (recent) by him et al on surface realisation:
Right, so I've started on that first one, and noticed some useful stuff:
Carroll also mentions Skolemisation. Seems to be a technical detail, but I realised the reason I wasn't comfortable with all that is that (1) although I have seen MRS more or less have an idea how it all works, I don't know it as well as the dumb format we use in GenI (2) I don't know what skolemisation is. Have seen it before, but keep forgetting. The explanation from Patrick's book, and from Dmitry is that the idea is that you can convert any logical formula with existential quantifiers into one without (using constants); and semantically they'd be the same thing. If you're under a universal, you can't just pick any constant, you have to grab a new one for each instance of the bound thingy - so your skolem constant has to be a function. All of this pops you into a slightly bigger language (one containing the functions), so you can't deskolemise or anything. So why is this useful? What's this got to do with MRS? Will have to re-read that bit.
Why do you want a flat semantics? Cuz it helps us get around the Logical Form Equivalence problem (which is undecidable). I need to be re-reading Schieber 1993 to get comfortable with this. I've seen this a kajillion times, but I still can't talk about this like I know what I'm saying. For me the idea is that flat semantic representations are just simpler to manipulate. You only have to worry about doing union to combine stuff. Much easier to put pieces together. Much easier to think about stuff like chart generation. Ok, so shaky territory there.
Thing that makes flat semantics easier is that it bumps you up one level of ambiguity. In a non-flat representation:
aren't the same thing. Similarly, given something like "the end of the road", you could either have
which aren't going to be the same thing. Is it the end that we're talking about, or the road? Flat representations are nice because they smoosh down all these non-sense scope problems into a single ambiguous form with an implicit conjunction over all these guys:
Great! Life is simple! Ding dong, the scope is dead! Except... except that... that sucks! Because now, imagine you wanted to say something like "Every white hores is old". Ok, very good, let's use our new scope-free representation:
You see a problem? This representation is ambiguous. It could easily mean something completely different, like "Every old horse is white". Oops.
So what does MRS buy us? It lets us keep things nice, flat and easy to manipulate but adds a notion of scope back into the game. And this notion of scope, we get out of the use of handles. Every literal is assigned some handle, like so
Note that what keeps things flat and still ambiguous enough to be useful is that we can give multiple literals the same exact handle, for example,
So handles are one thing that MRS adds. By the way, the stuff we use for GenI has handles too, so we should be able to do scopy things just fine. The other things that MRS adds are underspecification -- you can use a variable handle instead of a constant
That's what we don't have in the format that GenI uses: we can't generate from underspecified forms -- though that might not be very hard to fix; just do subsumption instead of equality check on the semantics -- and we don't have a notion of top handle.
- High Efficiency Realization for a Wide-Coverage Unification Grammar - 2005
- Parser Engineering and Performance Profiling - 2000
- A Bag of Useful Techniques for Efficient and Robust Parsing - 1999
- An Efficient Chart Generator for (Semi-)Lexicalist Grammars - 1999
Right, so I've started on that first one, and noticed some useful stuff:
- Apparantly, the quickcheck mechanism works with the same exact paths for parsing and realisation
- Packing only helps if you use FS subsumption instead of equality. In fact, if you use equality, your performance actually degrades. This (maybe) confirms the experience I had with CKY, but it's not sure. I would need to make a CKY variant with equivalence classes off and see if its better or not. It's sort of a "no-duh" thing. I mean, Bertrand's already talked about this during my DEA syntax course, so I should have known about this. I guess I'll have to implement this in GenI as well. Whole point is to increase amount of packing that we do; make it worth something. But I'll also have to throw in a secondary unification step to make sure we don't overgenerate
- Still not sure how index accesibility filtering works. I think my main questions would be how the collect-semantic-vars thing works exactly. Don't you have any uninstantiated variables?
- Packing and filtering together are more useful than each one alone. There's a synergetic (ugh) thing going on here
Carroll also mentions Skolemisation. Seems to be a technical detail, but I realised the reason I wasn't comfortable with all that is that (1) although I have seen MRS more or less have an idea how it all works, I don't know it as well as the dumb format we use in GenI (2) I don't know what skolemisation is. Have seen it before, but keep forgetting. The explanation from Patrick's book, and from Dmitry is that the idea is that you can convert any logical formula with existential quantifiers into one without (using constants); and semantically they'd be the same thing. If you're under a universal, you can't just pick any constant, you have to grab a new one for each instance of the bound thingy - so your skolem constant has to be a function. All of this pops you into a slightly bigger language (one containing the functions), so you can't deskolemise or anything. So why is this useful? What's this got to do with MRS? Will have to re-read that bit.
MRS
Trying to get to the bottom of this MRS thing. By re-re-re-reading Minimal Recursion Semantics - An Introduction. So here's the idea. I think. Maybe.Why do you want a flat semantics? Cuz it helps us get around the Logical Form Equivalence problem (which is undecidable). I need to be re-reading Schieber 1993 to get comfortable with this. I've seen this a kajillion times, but I still can't talk about this like I know what I'm saying. For me the idea is that flat semantic representations are just simpler to manipulate. You only have to worry about doing union to combine stuff. Much easier to put pieces together. Much easier to think about stuff like chart generation. Ok, so shaky territory there.
Thing that makes flat semantics easier is that it bumps you up one level of ambiguity. In a non-flat representation:
white(x) ^ (English(x) ^ horse(x)
(white(x) ^ English(x)) ^ horse(x)
aren't the same thing. Similarly, given something like "the end of the road", you could either have
the(x, road(x) ^ the(y, end(x,y))
the(y, the(x, road(x) ^ end(x,y))
which aren't going to be the same thing. Is it the end that we're talking about, or the road? Flat representations are nice because they smoosh down all these non-sense scope problems into a single ambiguous form with an implicit conjunction over all these guys:
white(x), English(x), horse(x)
the(y), the(x), road(x), end(x,y)
Great! Life is simple! Ding dong, the scope is dead! Except... except that... that sucks! Because now, imagine you wanted to say something like "Every white hores is old". Ok, very good, let's use our new scope-free representation:
every(x), horse(x), old(x), white(x)
You see a problem? This representation is ambiguous. It could easily mean something completely different, like "Every old horse is white". Oops.
So what does MRS buy us? It lets us keep things nice, flat and easy to manipulate but adds a notion of scope back into the game. And this notion of scope, we get out of the use of handles. Every literal is assigned some handle, like so
h1:horse(x). The assigned handle is what we call a label, and these labels are useful because we can point to them by using handles as arguments (h1:horse(x), h2:old(x), h0:every(x,h1,h2)) and look at that, we got our scope back just by jiggling the handles around a bit:
h1:horse(x), h1:white(x), h2:old(x), h0:every(x,h1,h2)
h1:horse(x), h1:old(x), h2:white(x), h0:every(x,h1,h2)
Note that what keeps things flat and still ambiguous enough to be useful is that we can give multiple literals the same exact handle, for example,
h1:horse(x), h1:old(x) and that bit we consider to be on the same level. Handles let us choose keep things flat as much as possible, and only occasionally when we really have to do, impose some kind of scopal structure over things.So handles are one thing that MRS adds. By the way, the stuff we use for GenI has handles too, so we should be able to do scopy things just fine. The other things that MRS adds are underspecification -- you can use a variable handle instead of a constant
h0:every(x,h1,?HX) to let you explictly represent scope amibiguities -- and handle constraints, which is the flip side of the underspecification and let you close the ambiguity off: ?HX <- h1. One minor detail I don't get about MRS though is what exactly the top handles are for. Nothing outscopes the top handle. Will have to re-re-re-read the end part of the paper to find out (again).That's what we don't have in the format that GenI uses: we can't generate from underspecified forms -- though that might not be very hard to fix; just do subsumption instead of equality check on the semantics -- and we don't have a notion of top handle.
Etc
Really have a hard time reading. Hard to sit still for 5 minutes, hard to get into that so called state of flow. Just want to get up and move around or something. Anyway, I guess now I can go back and figure out what this index accesibility filter is doing and why JC is talking about Skolem constants over there. Sigh... I wish I actually knew what the heck I was talking about for a change.Friday, 17 March 2006
TAG+8
Today has been slow and procrastinatory. For example, I think I spent half an hour responding to some guy that liked my monads tutorial (merci!) responding to his worries that "gee, Haskell... not simple, is it?", and spent another chunk of time creating my musuem of encoding problems (had been meaning to do that for a while). Why? Because it's time to get working on that TAG+8 article. Ugh. Took me a whole day to produce half a page of text, and not very good text at that, either. Guess I'll call it a day, though. Progress is progress.
I'll need to note this for when time comes to write my thesis... if it takes me one day to squeeze out a half page of text... well... uh-oh.
I'll need to note this for when time comes to write my thesis... if it takes me one day to squeeze out a half page of text... well... uh-oh.
Haskell workshop
I've been thinking about submitting something to the upcoming Haskell workshop Or maybe it was Yannick who's been prodding me, I'm not sure. But I was relieved to find that the submission deadline is 2 June, not somewhere in April. So maybe by then I actually will have something to say. Like maybe I can get the arrows stuff working or something.Thursday, 16 March 2006
still mmax'ing
Well, that's progress. I have finally created my script for automatically converting our MMAX1 data to the MMAX2 format. I'm sure there's lots of little bugs lying around in the conversion, but at least MMAX is running with the converted data. Sent my progress so far to Claire and Hélène and documented my comings and goings on the wiki, seeing as to how there may be decisions to be made, things to change, instructions to write, etc.
Using PXSL has made the stylesheet writing process a lot more bearable, cuts out a huge amount of useless verbosity.
Let's see... what else have I accomplished today...
Huh.
Not bleeping much.
Oh yeah, yesterday, I decided to upgrade my version of darcs via darwinports. The unfortunate consequence of that is that dp promptly decided to upgrade my ghc as well. One of these dependency things, I guess. Anyway, that took a day of compilation, which didn't bother me much, because I could just get on with my business and use my old ghc whilst compiling the new one. But what did suck is that I lost all my packages. Would be great if the haskell packaging stuff came together one day so that I could upgrade stuff, manage dependencies and have all that goodness. DP could then hook directly into this system, along with CPAN and CTAN. One interface to control everything. No worries.
Anyway, I tried to recompile wxhaskell, but I got a linker error. Ugh! Found a fix on the wxhaskell mailing list though, so I was happy. I also came up with an alternate correction, one which consists of simplifying the makefile somewhat. This has the advantage that it works directly with the darwinports version of wxWidgets. But the disadvantage is that the BouncingBalls example does not work with it. Not that I care; GenI doesn't use any of that fancy stuff. But this is probably not so good for other users.
Using PXSL has made the stylesheet writing process a lot more bearable, cuts out a huge amount of useless verbosity.
Let's see... what else have I accomplished today...
Huh.
Not bleeping much.
prz..prz...prz...
Oh yeah, the day started with a bit of silliness. Claire had forgotten some information for her trip in Poland with a good chunk of the team. There was a point where I wanted to read some Polish names to her, and I was like, ok, I'm not going to pronounce that. So there I was on Jesse's answering service, spelling out the whole list with its Zs, Ws and many many syllables. Polish pronounciation really isn't that hard if you look up a rule table, but at first glance... oooh boy. Anyway, everybody got a good laugh out of that, so at least I was good for something.wxhaskell
Oh yeah, yesterday, I decided to upgrade my version of darcs via darwinports. The unfortunate consequence of that is that dp promptly decided to upgrade my ghc as well. One of these dependency things, I guess. Anyway, that took a day of compilation, which didn't bother me much, because I could just get on with my business and use my old ghc whilst compiling the new one. But what did suck is that I lost all my packages. Would be great if the haskell packaging stuff came together one day so that I could upgrade stuff, manage dependencies and have all that goodness. DP could then hook directly into this system, along with CPAN and CTAN. One interface to control everything. No worries.
Anyway, I tried to recompile wxhaskell, but I got a linker error. Ugh! Found a fix on the wxhaskell mailing list though, so I was happy. I also came up with an alternate correction, one which consists of simplifying the makefile somewhat. This has the advantage that it works directly with the darwinports version of wxWidgets. But the disadvantage is that the BouncingBalls example does not work with it. Not that I care; GenI doesn't use any of that fancy stuff. But this is probably not so good for other users.
- $(CXX) -r -keep_private_externs -nostdlib -o $(WXC-OUTDIR)/master.o $^ $(WXC-LIBS)
- $(CXX) -dynamiclib -install_name $(SHARED-PREFIX)$(notdir $@) -undefined suppress -flat_namespace -o $@ $(WXC-OUTDIR)/master.o $(filter-out %.a,$(WXC
-LIBS))
- $(RM) -f $(WXC-OUTDIR)/master.o
+ $(CXX) -dynamiclib -install_name $(SHARED-PREFIX)$(notdir $@) -undefined suppress -flat_namespace -o $@ $^ $(filter-out %.a,$(WXC-LIBS))
Wednesday, 15 March 2006
mmax encore encore (yay pxsl!)
Here is my stylesheet for converting the old MMAX annotation data from the new multi-layer schemefile. It's using Tom Moertel's Parsimonious XML Shorthand Language, which takes a lot of the pain out of writing XSLT. Just a slight syntactic twiddle and I feel like I'm programming again. A simple simple task, and at last I can do it without drowning myself in syntax. Just a matter of syntax. How superficial am I?
I think PXSL could do wonders for soothing my irrational hatred for all things XML.
stylesheet\
-version=1.0\
-xmlns:xsl=http://www.w3.org/1999/XSL/Transform
template markables
markables
apply-templates
template markable
markable
attribute coreference
choose
when @type='co-reference'
<<yes>>
otherwise
<<no>>
copy-of @*
I think PXSL could do wonders for soothing my irrational hatred for all things XML.
more mmax stuff
Starting to get the hang of this MMAX thing, now that the fight-with-NullPointerExceptions part of the game is over. It helps to print out all the doc and actually read them in order - like, starting with the Quickstart. One-click annotation is pretty cool. Go Christoph! I also like the lines that show elements in the same markable set. In my opinion, a thin straight red line is the best compromise between visibility of the line, and readability of the text, at least for our data. Right, so what's left to do:- automate the production of the .mmax files; make a script which generates these (easy), and which hardlinks the common paths stuff
- figure out if there is a way to NOT select the paragraph and headline markables, but still display them, i.e. put a blank line between each paragraph and italicise the headline
- figure out what we're doing with pointers as opposed to the sets
- check the new annotation scheme with Claire - do we want branching attributes?
Tuesday, 14 March 2006
more mmax2
Still working on getting MMAX2 to run. Making some progress. Sort of gave up on paragraphs and headlines being unselectable until Christoph responds to my mail... there is some NullPointerException when I try to set the tag
Banging my head against a desk how slow going and intellectually unstimulating this is. Always something to complain about ;-)
Oh, yeah, and I installed Ubuntu on one of the team's spare machines, for Hélène's visit. Pretty pleased with it. It's not a Mac, but its usability is rather not bad.
sentence in my .mmax file. Got the defnp markables to display as blue, at last. Took some fighting with the stylesheet -- did I mention how much I hate XSLT? -- and the customisation, grumbling about more NullPointerExceptions (this time, because i didn't set the DTD). Don't know how I managed to do it. Started by setting the customisation file to something I already had. Then cp'd the file to a new value, and then changed the contents of the new file. Trying to write the thing by hand didn't seem to work, even though from the looks of things, what I had written was exactly the same as what I had copied. Whatever. Also made an MMAX2 version of our schemefile, which means that MMAX2 can now read Helene and Claire's previous annotations. Next things I need to do are- check with Claire how exactly they want annotation to work
- figure out how the heck you work with markable pointers -- it seems to be in the quickstart, but I can't see anything like (1) right click here (2) click there
- write stylesheets or software to convert their data over to MMAX2
Banging my head against a desk how slow going and intellectually unstimulating this is. Always something to complain about ;-)
Oh, yeah, and I installed Ubuntu on one of the team's spare machines, for Hélène's visit. Pretty pleased with it. It's not a Mac, but its usability is rather not bad.
Monday, 13 March 2006
mmax to mmax2
Looks like I won't be doing too much PhD stuff this week. Instead it will be more sort of inter-team solidarity: Hélène and Claire are doing some more annotation work, and they're going to want to do this using the new MMAX2 software, because they need to get some functionality out of it. My job is to get their data converted over. Ugh. XML stuff.
Been working on this all afternoon, trying to make sense of MMAX2. Finally hit on the right approach. Did a cp -R on the Korean treebank sample, and slowly moved things around one by one until they looked more and more like Claire and Hélène's work. I'm a bit worried that there's going to be a lot of converting to do, depending on how different MMAX2 and MMAX1 are. Questions I'm going to need to email Christoph about tomorrow, well, after checking his samples and the documentation again
Otherwise, things are going to suck. I might have to write some XSLT stylesheets... horror! I loathe XSLT. Maybe I'll go learn how to use the Haskell XML toolbox instead. It shouldn't take too much time, and it'll give me a chance to work with arrows. Only constraint is that this has to be done before next week, when Hélène arrives.
Been working on this all afternoon, trying to make sense of MMAX2. Finally hit on the right approach. Did a cp -R on the Korean treebank sample, and slowly moved things around one by one until they looked more and more like Claire and Hélène's work. I'm a bit worried that there's going to be a lot of converting to do, depending on how different MMAX2 and MMAX1 are. Questions I'm going to need to email Christoph about tomorrow, well, after checking his samples and the documentation again
- Does MMAX2 still support read-only annotations - for example, I want to say that sentence 3 corresponds to words 39 to 56, but I don't want these to be markables, because I don't want to clutter up the user interface
- Dose MMAX2 still support nested annotations? I want to say that paragraph 3 is composed of sentences 3 to 7
Otherwise, things are going to suck. I might have to write some XSLT stylesheets... horror! I loathe XSLT. Maybe I'll go learn how to use the Haskell XML toolbox instead. It shouldn't take too much time, and it'll give me a chance to work with arrows. Only constraint is that this has to be done before next week, when Hélène arrives.
Saturday, 11 March 2006
clarification
I think an important clarification needs to be made about yesterday's dejectedness. It's not CKY's poor performance that bothers me, performance schmerformance after all, but the feeling that all 5 past months I have not been doing what I was supposed to be doing.
Sigh. Bad PhD student, no biscuit for you! When Claire mentioned Kristina's work, and Günter Neumann, I wasn't able to respond in an intelligent way, because I didn't know it well enough. I wasn't totally ignorant about it. I had read stuff about Indigen (the big tech report) and I had read the Phd thesis, but apparantly did not get out of them what I should have gotten. From Kristina's stuff, I basically saw GenI, which makes sense given our scientific family tree. From GN's, I saw this really neat idea of doing parsing and generation together, and using parsing results to guide your generator -- should I go generate this intermediary structure? No, no, on second thought, let's not go there. It is a silly parse. (By silly, I meant ambiguous). But as Claire urged me to go work on tabulation stuff, I don't know why I didn't occur to me that I should have been taking a VERY CLOSE look at how these two people represent their chart items. In my discussions with Bertrand, we were talking about how vague everyone seemed to be regarding their chart generators, and HELLO?, here are two people being very much so NOT vague and I completely overlooked them. I say I and not we, because Bertrand didn't know about these papers -- how could he? -- but I definitely should have because it is my job to know about these papers. At least, anyway, I thought I knew about them, but apparantly not.
Gah...
Well, look the past five months haven't been totally wasted. What have we got here:
But still, the inefficiency of it all. It's quite clear to me that I'm still not Doing Research... This is my topic. I should know the literature better than Claire, not the other way around.
Sigh. Bad PhD student, no biscuit for you! When Claire mentioned Kristina's work, and Günter Neumann, I wasn't able to respond in an intelligent way, because I didn't know it well enough. I wasn't totally ignorant about it. I had read stuff about Indigen (the big tech report) and I had read the Phd thesis, but apparantly did not get out of them what I should have gotten. From Kristina's stuff, I basically saw GenI, which makes sense given our scientific family tree. From GN's, I saw this really neat idea of doing parsing and generation together, and using parsing results to guide your generator -- should I go generate this intermediary structure? No, no, on second thought, let's not go there. It is a silly parse. (By silly, I meant ambiguous). But as Claire urged me to go work on tabulation stuff, I don't know why I didn't occur to me that I should have been taking a VERY CLOSE look at how these two people represent their chart items. In my discussions with Bertrand, we were talking about how vague everyone seemed to be regarding their chart generators, and HELLO?, here are two people being very much so NOT vague and I completely overlooked them. I say I and not we, because Bertrand didn't know about these papers -- how could he? -- but I definitely should have because it is my job to know about these papers. At least, anyway, I thought I knew about them, but apparantly not.
Gah...
Well, look the past five months haven't been totally wasted. What have we got here:
- Made GenI a whole lot more modular wrt building stuff - now it is easier to go experiment with lots of wacky surface realisation algorithms for TAG just by running off and making your own Builder. You can thank Tatjana Scheffler for that in a way; her Master's thesis talks about seperating algorithm from the other stuff so that you can plug a new algorithm in. I don't think I would have had as much success modularising GenI were I not working on something as different as CKY
- Implemented CKY - which is useful because it gave me much clearer ideas on how packing should work, and what you can do to reconstruct results
- Improved gtester enough that we are soon going to have a very nice test harness on our hands, one which will let us poke at GenI and find out what improves or worsens our performance (thank you, Carlos for hylotester)
- Seriously cleaned up GenI's approach to counting things, statistics tracking, with the use of monad transformers. Thank-you, Carlos. Learned about monad transformers!
- Got interested in arrows, but this might not bear fruit, we'll have to see
But still, the inefficiency of it all. It's quite clear to me that I'm still not Doing Research... This is my topic. I should know the literature better than Claire, not the other way around.
Friday, 10 March 2006
huh, what's going on?
Plodding along. Introduced a new 'null' builder so that I can collect data about the testcases without interfering with the lazy goodness of the rest of my code. Am working on plotting stuff out with octave. Boring as heck. Gave Claire a briefing on what I've been up to. I dunno... I'm feeling back in one my PhD down spots. Ooooh, don't look like i'm going anywhere with this. Claire suggested that I (re)read Kristina's paper on the chart generator she does. Somehow she manages to do packing in a delayed-adjunction friendly way. It seems possible. Will have to make a variant of Simple builder to use split chart items the same way CKY does, but eh... different. After working on CKY for so long, I've pretty much got the tools I need... List monad, etc. Argh, going in circles, not being up to speed on current research, everything going slowly. Life sucks.
Thursday, 9 March 2006
very short day, but an Idea!
I promised myself last night that I would go to bed by 2am at least. Ended up staying till 3h45, not being productive on hobbies either, just being a zombie. Anyway, did a bit of hobby writing, had lunch and made my way rather late to the lab, almost in time for Michael Strube's talk on multi party dialogue summarisation.
Brain was a little fried after the talk -- I never was very good at paying attention in class, or to talks -- so I spent some time improving my wikibooks module on Haskell indentation, which I know, I know, really isn't work.
Also spent a good chunk of the afternoon having a nice chat with Michael about life, research in general, the MMAX software that we plan to use and our respective recent work.
Not being very productive, but, I had an Idea today, so that makes up for it. The problem was of trying to find a useful way to extract performance data out of the test suite, that is, to answer the question, "what makes GenI hurt"? I think I have a simple 2D criterium for ranking test cases by difficulty: just count the number of substitution and foot nodes in the lexical selection. I can then graph against these two axes, plus some comparison criteria, like number of chart items, or the time that it takes. I think that I don't have time to play with CKY until after the next bout of article deadlines, so I'll probably just test the polarities system. We've talked about polarities at length already, but we've never actually wrung them through a full fledged test suite and a big grammar. Big grammar yes, test suite no.
Brain was a little fried after the talk -- I never was very good at paying attention in class, or to talks -- so I spent some time improving my wikibooks module on Haskell indentation, which I know, I know, really isn't work.
Also spent a good chunk of the afternoon having a nice chat with Michael about life, research in general, the MMAX software that we plan to use and our respective recent work.
Not being very productive, but, I had an Idea today, so that makes up for it. The problem was of trying to find a useful way to extract performance data out of the test suite, that is, to answer the question, "what makes GenI hurt"? I think I have a simple 2D criterium for ranking test cases by difficulty: just count the number of substitution and foot nodes in the lexical selection. I can then graph against these two axes, plus some comparison criteria, like number of chart items, or the time that it takes. I think that I don't have time to play with CKY until after the next bout of article deadlines, so I'll probably just test the polarities system. We've talked about polarities at length already, but we've never actually wrung them through a full fledged test suite and a big grammar. Big grammar yes, test suite no.
Wednesday, 8 March 2006
grumble grumble grumble
On the tram last night, I thought I had a clever idea, one which consisted of discarding items on which we have not completed adjunction. The thinking was that simple builder does something similar when it gets rid of items it can't perform any adjunction on, and that we wouldn't need these items anymore since we would already have called adjunction or non-adjunction on them. Turns out that this was a stupid idea. You need to keep these guys in the chart because you don't know when you're going to produce some new auxiliary tree that needs to be adjoined into them. Sigh. Still trying to figure out why on earth we get more chart items in cky than we would with the simple builder. It's not like we're doing adjunction anyway. The only reason I was fiddling around with these rules was as a way of getting rid of intermediary items that are no longer useful.
Anyway, I tried to console myself with a little useful coding. I decided to simplify my inference rules:
The reason I did this is because I could not figure out what possible use I would have for a succesful result which returns an empty list. One thing that made me smile was that since I had written the kids to parent rule in a monadic fashion, switching the code over was very easy. Just change one type definition, and get rid of a couple of helper functions, and let the bind operator do all the walking. Well ok, it was almost that easy. I also had to change one of my helper functions, simplify the hell out of it, actually:
Later on, I'll upgrade the inference rules to use the list transformer, so that we can embed statistical information in them, like counting the number of substitutions performed by CKY.
Anyway, it's still pretty infuriating. I don't really care of CKY is slower than Simple... ok, well I just spent 5 months working on it, so I do care a little bit... but what bugs me most of all is that I can't figure out why CKY generates so many more chart items than Simple does. We're both walking the tree, aren't we? Is it really just the business of delayed adjunction that is doing the trick? Do I want to think about a delayed adjunction mechanism for CKY? Or am I better off trying to figure out how John Carroll's filter works (not the quick check one, but the dynamic available-variables thingy) and implementing that instead. I dunno. I can't keep dabbling around like this. Need to sit down and think about why things behave they way they do.
Anyway, I think I'm going to go home early and take a nap. Reset my clock. Went to bed at 5h again last night. Play hooky on Chinese class, like I've been doing for the past 3 weeks.
Anyway, I tried to console myself with a little useful coding. I decided to simplify my inference rules:
{- before -} type InferenceRule a = a -> [a] -> Maybe [a]
{- after -} type InferenceRule a = a -> [a] -> [a]
The reason I did this is because I could not figure out what possible use I would have for a succesful result which returns an empty list. One thing that made me smile was that since I had written the kids to parent rule in a monadic fashion, switching the code over was very easy. Just change one type definition, and get rid of a couple of helper functions, and let the bind operator do all the walking. Well ok, it was almost that easy. I also had to change one of my helper functions, simplify the hell out of it, actually:
combinations :: [[a]] -> [[a]]
combinations [] = [[]]
combinations (hs:t) = liftM2 (:) hs (combinations t)
Later on, I'll upgrade the inference rules to use the list transformer, so that we can embed statistical information in them, like counting the number of substitutions performed by CKY.
Anyway, it's still pretty infuriating. I don't really care of CKY is slower than Simple... ok, well I just spent 5 months working on it, so I do care a little bit... but what bugs me most of all is that I can't figure out why CKY generates so many more chart items than Simple does. We're both walking the tree, aren't we? Is it really just the business of delayed adjunction that is doing the trick? Do I want to think about a delayed adjunction mechanism for CKY? Or am I better off trying to figure out how John Carroll's filter works (not the quick check one, but the dynamic available-variables thingy) and implementing that instead. I dunno. I can't keep dabbling around like this. Need to sit down and think about why things behave they way they do.
Anyway, I think I'm going to go home early and take a nap. Reset my clock. Went to bed at 5h again last night. Play hooky on Chinese class, like I've been doing for the past 3 weeks.
Tuesday, 7 March 2006
nextLeafRule
Well, that wasn't too hard. I went ahead and added my new inference rule as an optional feature in the cky builder. I guess then we're not really doing CKY anymore... are we? It has this Earley-ish top-down-ish feature now where we don't explore nodes on the right until we're done exploring nodes on the left. But wait, no, that has nothing to do with top-down. What the heck am I talking about? Nevermind. Code now. Think later.
Here's what the new inference rule looks like:
I also had to change a few other things - disallow merging until the item was complete (this causes more ambiguity, but nothing that couldn't be fixed with a little automaton merging, I'll bet) so that we don't have to think as hard about what happens with the payload when items merge; do a little folding so that we don't deploy all the leaf items on the agenda (they're all packed into each other's payload, like a singly linked list).
Edit 22h: No, no, no, stupid! You can't implement this as an inference rule because it's going to keep firing over and over again. Here is the right way to do it (I think): you release the payload if the agenda item succesfully interacts with some rules or if it is already complete as it is. You do not ever propagate the payload... geez, eric, have to babysit you through every single detail:
end edit
I'm testing it against my seven randomly chosen sentences as we speak. Before I leave for home, I'll launch a test on the full C_Complementation suite.
Kinda worried about the conference deadlines coming up. I still don't have anything to write, really. Not sitting down and thinking hard enough about what would be reasonable stuff to discuss, what kind of testing methodology things we want to say or what I could say about the geni tests that would be useful. I'm just dabbling around in an uncontroled manner trying to make my CKY work. That's all.
I'm not sure it's even fair for me to be including CKY in these papers. I'm using a completely unproven technique, this thing with variable collection, that I semi came up with slash copied off John Carroll without making sure that the two ideas are related or just sound similar... It's the kind of unproven technique that will give you all the right results on your test suite, but bite you in the ass some seven years down the road with a corner case you hadn't thought of yet. Need to find a way to prove/disprove that my variable collections thing is equivalent to doing a big evil unification run. Sigh, but then I have to formalise the problem, find a way to talk about what I'm trying to prove. Maybe I should hack CKY to do the big evil unification run so that it's safe. Don't know what's the best choice here:
Argh. Too much thinking. I've been keeping all the wrong hours for this. Went to bed at 5h last night, just got absorbed in some hobby hacking. So unhealthy.
Here's what the new inference rule looks like:
nextLeafRule item _ | ciComplete item = listAsMaybe $ ciPayload item
nextLeafRule _ _ = Nothing
I also had to change a few other things - disallow merging until the item was complete (this causes more ambiguity, but nothing that couldn't be fixed with a little automaton merging, I'll bet) so that we don't have to think as hard about what happens with the payload when items merge; do a little folding so that we don't deploy all the leaf items on the agenda (they're all packed into each other's payload, like a singly linked list).
Edit 22h: No, no, no, stupid! You can't implement this as an inference rule because it's going to keep firing over and over again. Here is the right way to do it (I think): you release the payload if the agenda item succesfully interacts with some rules or if it is already complete as it is. You do not ever propagate the payload... geez, eric, have to babysit you through every single detail:
releasePayload = not (null results) || ciComplete agendaItem
payload = if releasePayload && (orderedsubs $ genconfig st)
then ciPayload agendaItem else []
end edit
I'm testing it against my seven randomly chosen sentences as we speak. Before I leave for home, I'll launch a test on the full C_Complementation suite.
ugh...papers
Kinda worried about the conference deadlines coming up. I still don't have anything to write, really. Not sitting down and thinking hard enough about what would be reasonable stuff to discuss, what kind of testing methodology things we want to say or what I could say about the geni tests that would be useful. I'm just dabbling around in an uncontroled manner trying to make my CKY work. That's all.
I'm not sure it's even fair for me to be including CKY in these papers. I'm using a completely unproven technique, this thing with variable collection, that I semi came up with slash copied off John Carroll without making sure that the two ideas are related or just sound similar... It's the kind of unproven technique that will give you all the right results on your test suite, but bite you in the ass some seven years down the road with a corner case you hadn't thought of yet. Need to find a way to prove/disprove that my variable collections thing is equivalent to doing a big evil unification run. Sigh, but then I have to formalise the problem, find a way to talk about what I'm trying to prove. Maybe I should hack CKY to do the big evil unification run so that it's safe. Don't know what's the best choice here:
- don't mention CKY; it's old tech anyway
- do the big evil unification
- prove correctness of variable collection trick
Argh. Too much thinking. I've been keeping all the wrong hours for this. Went to bed at 5h last night, just got absorbed in some hobby hacking. So unhealthy.
Monday, 6 March 2006
slow cky
The ability to load your lexical selection from a file is really really handy. I used it to narrow down the lexical selection into a single main tree and a couple of clitics, and from there realised that my kids to parent rule was not firing. Turns out that I had previously made an overzealous bugfix to squash some over-generation. I said that the semantics of the kid nodes should not be overlapping -- we don't want to substitute the same node into two different sides of a tree, for example. Naturally enough, that meant that the kids to parent rule could never fire. Doh. So today, I scaled it back a bit, by saying that the intersection of their semantics should be equal to their original semantics to begin with. As a result, it seems that cky is passing the TSNLP test suite stuff, at least, the six randomly chosen sentences is my play file.
Only problem is that it's really frickin slow. How's that for an optimisation? With the old code, it takes 31 ms to generate "l'ingénieur nous le présente", whereas with the new, intelligent code, it takes 800 ms. Fantastic. I think I have an idea why, though. The new code generates a whole mess load of chart items, but there really isn't any reason that it should generate that much more than the new code. Exploding a tree and walking through it should give you more or less the same number of items. But one thing that causes the old algorithm to work better is ordered substitution - we don't try substituting into the right node if the left node hasn't be plugged yet. We could do something like this for the new algorithm as well. To avoid wasting time with chart items that can never become a result, we could also impose an order in which to perform substitution. The way we could do is to to create something like a RightSister inference rule which only fires when the current node is complete (adjunction, substitution, etc), and which produces the chart item corresponding a node's right sister. And there you've got your ordered substitution. Would like to experiment with that. Maybe there's no time, though. TAG+8 deadline coming up, along with INLG, and I still don't have any results to publish.
Other than that, helped a friend out with some diagrams for a paper. I really really like Omnigraffle, but I feel kinda guilty not sitting down and learning how to express diagrams in directly in latex in a declarative manner. Neat trick though: you want to integrate some fancy latex font into a diagram? Use the latex equation editor and then drag'n'drop! Only... it doesn't quite print out right since it's a pdf. Guess I'll have to use imagemagick to convert the thing into a png or something. Yeck.
Only problem is that it's really frickin slow. How's that for an optimisation? With the old code, it takes 31 ms to generate "l'ingénieur nous le présente", whereas with the new, intelligent code, it takes 800 ms. Fantastic. I think I have an idea why, though. The new code generates a whole mess load of chart items, but there really isn't any reason that it should generate that much more than the new code. Exploding a tree and walking through it should give you more or less the same number of items. But one thing that causes the old algorithm to work better is ordered substitution - we don't try substituting into the right node if the left node hasn't be plugged yet. We could do something like this for the new algorithm as well. To avoid wasting time with chart items that can never become a result, we could also impose an order in which to perform substitution. The way we could do is to to create something like a RightSister inference rule which only fires when the current node is complete (adjunction, substitution, etc), and which produces the chart item corresponding a node's right sister. And there you've got your ordered substitution. Would like to experiment with that. Maybe there's no time, though. TAG+8 deadline coming up, along with INLG, and I still don't have any results to publish.
Other than that, helped a friend out with some diagrams for a paper. I really really like Omnigraffle, but I feel kinda guilty not sitting down and learning how to express diagrams in directly in latex in a declarative manner. Neat trick though: you want to integrate some fancy latex font into a diagram? Use the latex equation editor and then drag'n'drop! Only... it doesn't quite print out right since it's a pdf. Guess I'll have to use imagemagick to convert the thing into a png or something. Yeck.
Friday, 3 March 2006
Loading and saving
So yesterday, I was talking about making lexical selection debugger fancy so that you could select a bunch of trees and delete them. But then I realised that this would be pretty annoying to use. Instead, I spent today working a much simpler feature to dump the lexical selection to a file and then load it back, all using my GeniHand format. This wasn't immediately easy though, because my dump code was slightly bit rotten, and wasn't meant to dump actual TagElems. So I did some heavy refactoring and made it all nice and clean, making use of... you guessed it... typeclasses!
I'm not too thrilled about the name either, but you see where I'm going with this.
Anyway, the people who came up with typeclasses deserve my gratitude. Haskell typeclasses have helped me wash away a lot of the ugliness in my code. Doing all this has had an extra benefit -- I've now also managed to get rid of one of my ugly parsing hacks for interacting with XMG. Now that we have a way of reading actual TagElems instead of macros, we simply make the XMG stuff ride on top of that.
So, here's a screenshot of the new lexical selection dialogue:

The idea is that you can click on "Save to file", dump the contents into GenI's text format, use your favourite text editor to remove the trees that you find irrelevant, and then use the Load button to change the lexical selection. When you're ready to generate, you click on "Continue", and that sends you to the next generation phase. I don't actually know if it works yet, but I'll deal with that next week
class GeniHandShow a where
toGeniHand :: a -> String
I'm not too thrilled about the name either, but you see where I'm going with this.
Anyway, the people who came up with typeclasses deserve my gratitude. Haskell typeclasses have helped me wash away a lot of the ugliness in my code. Doing all this has had an extra benefit -- I've now also managed to get rid of one of my ugly parsing hacks for interacting with XMG. Now that we have a way of reading actual TagElems instead of macros, we simply make the XMG stuff ride on top of that.
So, here's a screenshot of the new lexical selection dialogue:

The idea is that you can click on "Save to file", dump the contents into GenI's text format, use your favourite text editor to remove the trees that you find irrelevant, and then use the Load button to change the lexical selection. When you're ready to generate, you click on "Continue", and that sends you to the next generation phase. I don't actually know if it works yet, but I'll deal with that next week
Thursday, 2 March 2006
gtester, GenI
Spent most of my afternoon on really really boring programming work, hacking up the gtester to output data in a more readable, compact format. The basic idea is to put each version of GenI side by side in the tables so that you can easily see, for example, if simple GenI generates something that cky GenI does not. Previously, it would display a new table for each GenI, which is not very useful.
Now I'm trying to figure out CKY does not want to generate for the C_Complementation test suite. Not too sure. I'm digging into the graphical debugger to find out though. I'm going to make the lexical selection viewer a little fancier by adding a button which lets you remove trees from the selection before continuing with the rest of the generation task. This should help you to avoid stepping through a whole bunch of crap when you're really just interested in a small set of phenomena. Maybe there's a better way to do this though.. on second thought... maybe I could just have a configuration option that says "only allow the following trees to be selected" and then do the filtering automatically? Hmm...
Now I'm trying to figure out CKY does not want to generate for the C_Complementation test suite. Not too sure. I'm digging into the graphical debugger to find out though. I'm going to make the lexical selection viewer a little fancier by adding a button which lets you remove trees from the selection before continuing with the rest of the generation task. This should help you to avoid stepping through a whole bunch of crap when you're really just interested in a small set of phenomena. Maybe there's a better way to do this though.. on second thought... maybe I could just have a configuration option that says "only allow the following trees to be selected" and then do the filtering automatically? Hmm...
Wednesday, 1 March 2006
gtester / trac-darcs
Been working on refining the gtester. Turns out that the responses directory is pretty useful, so I was glad to have the darcs rollback command to be able to cancel out one of my patches.
Hmm, what else?
Sébastien needs some help with a Muskens article from way back when. Thing is that the article was writen in some ancient WYSWIG editor, not in LaTeX, which makes difficult for Seb and his braille-board. So me, Yannick and Dmitry are helping him out by cleaning up the initial attempt to convert from $wordProcessor to tex via RTF. Since we were recruiting Dmitry for the job, I thought it would be useful to take advantage of our fancy new trac server.
But... I didn't want to create any new projects on the server until I had upgraded to the nice new darcs plugin (so that we could use a vanilla trac instead of the hacked version). The upgrade wasn't so bad. Was scratching my head for some time, but it was mostly because I was being stupid. Wrote up my results as a subpage of the TracOnDarcs howto. One big problem remaining, though, the new plugin really does not like GenI's repository. I get an error message like Command failed: No node at u'grammars/benoit/index' in revision 494. Only hints I have are that grammars/benoit was something I had removed a long time ago. Sort of a problematic patch, if I recall correctly. Other detail is that 494 is the very latest patch that I've got.
Argh.
Anyway, I've also updated my adminDT scripts to automate the new darcs-trac installations. Still need to do some fancy stuff like adding in default text, but I'll get around to that later.
Hmm, what else?
Sébastien needs some help with a Muskens article from way back when. Thing is that the article was writen in some ancient WYSWIG editor, not in LaTeX, which makes difficult for Seb and his braille-board. So me, Yannick and Dmitry are helping him out by cleaning up the initial attempt to convert from $wordProcessor to tex via RTF. Since we were recruiting Dmitry for the job, I thought it would be useful to take advantage of our fancy new trac server.
But... I didn't want to create any new projects on the server until I had upgraded to the nice new darcs plugin (so that we could use a vanilla trac instead of the hacked version). The upgrade wasn't so bad. Was scratching my head for some time, but it was mostly because I was being stupid. Wrote up my results as a subpage of the TracOnDarcs howto. One big problem remaining, though, the new plugin really does not like GenI's repository. I get an error message like Command failed: No node at u'grammars/benoit/index' in revision 494. Only hints I have are that grammars/benoit was something I had removed a long time ago. Sort of a problematic patch, if I recall correctly. Other detail is that 494 is the very latest patch that I've got.
Argh.
Anyway, I've also updated my adminDT scripts to automate the new darcs-trac installations. Still need to do some fancy stuff like adding in default text, but I'll get around to that later.
Subscribe to:
Posts (Atom)
