GenI is a chart generator. It has a notion of agenda/chart-based control to order operations and sub-tree sharing (basically for free by using Haskell), but what it lacks, crucially is a notion of equivalence-class based packing. Packing is extremely important because it's what allows you to control the combinatorial explosion of intermediary chart items as you explore the search space. In particular, in GenI, we're interested in exploring the whole space (enumerating all possible parses), so we're not particularly after any sort of pruning. Really, the chart is all about making sure we don't do a lot of stupid redundant work.
What you want your equivalence classes to do is partition your set of possible chart items in such a way that lets you compare the subsets with each other rather than the individual items within. So to illustrate example, imagine you're starting out with 8 items (in classes A, B, C) :
- A: 2 items
- B: 3 items
- C: 2 items
If you were just doing straight parsing without any sort of equivalence classes, you're going to be deriving 2x3x2=12 items. But if you use the equivalence classes, you only need to do 1x1x1=1. At the end of the day, you're still going to have 12 items when you expand the set, so what have you gained? Well, I'm still a bit fuzzy on that to be honest.
Part of my answer is that it saves you work when you have chart items that don't lead to any derivations. If you have say another 4 items that can combine with these 12, that gives something like 48 items to sift through (before you work out that you can only keep 12 of them). With equivalence-class packing at least, you avoid this sort of explosion.
I'm not sure if that's the whole story.
Anyhow...
There's one way I knew to get equivalence-class based packing for GenI, and that would be to implement a CKY/Earley parser for TAGs. I tried that during my 2nd year of the PhD, but the whole thing sort of fell apart because my coding sucked (I think now that I know about the Zipper, I can have a much better chance). Nevermind, it gave me a chance to refactor the hell out of the code. I still think it'd be good to get back to it... but what if there was a simpler way?
the plan
First, let's make some simplifying assumptions:- no substitution - we're in an adjuction only grammar (which is easy because GenI does 2-phase generation only)
- auxiliary trees all have the same root node category (we can relax this later on)
The problem I was struggling which trying to work out how packing would work is that it's not just good enough to partition your set of chart items. What you to do is to partition them in such a way that the result of combining two equivalence classes can be derived from the classes themselves and not the items within them. Coming up with any old scheme for putting your chart items into bins is the easy part. Now what happens when you plug two of those bins into each other? And if you do come up with such a scheme, is it going to chunk your inputs so that you get that factorisation thing going on, or are you just going to partition into a bunch of singleton sets?
And here's the scheme I just thought of:
Two items are in the same equivalence class if they have the same semantics, and the same number of nodes (of a given category X) which can receive adjunction
If you do adjunction with this scheme, all you have to do is take the union of the semantics (à la Martin Kay) and the sum of the numbers of the nodes (minus 1 or something like that). And if you want to deal with more than one category, just do it in phases. First focus on one category, derive everything you have. Then pick a new category and re-pack everything into a different chart.
I hope that this scheme is broad enough that it actually divides our chart into non-singleton sets.
I hope that this scheme is broad enough that it actually divides our chart into non-singleton sets.
Will it work? Will it work? Will it work?
I can't wait to find out.
Too bad I don't actually have time for GenI hacking.
