coli-saar / alto

Alto, the Algebraic Language Toolkit
Other
16 stars 2 forks source link

Top-down vs Bottom-up tree automata #53

Open jgroschwitz opened 4 years ago

jgroschwitz commented 4 years ago

TreeAutomaton requires the classes that implement it to implement both bottom-up and top-down queries (the functions getRulesBottomUp and getRulesTopDown). But for some lazy automata, only one of these queries can be implemented efficiently (or sometimes one does not want to have to implement both). At the same time, several functions in the TreeAutomaton class assume that a specific one of the two functions is implemented (issue #12 states that TreeAutomaton#accepts only works with bottom-up queries, and, iirc, TreeAutomaton#viterbi and TreeAutomaton#countRules need top-down queries).

My current workaround to this problem is that, when one of the queries is not implemented, I make the automaton explicit and answer the query from there. The problem is that there is no default implementation that makes this happen automatically in the TreeAutomaton class and one needs to reimplement it/remember it every time, causing extra work and extra bugs. There seems to be an attempt at a default implementation with the RuleStore class, but it may be buggy (c.f. issue #52 ) and is not fully automatic yet.

I suggest something like a default implementation of each of the two queries where, if it is not overridden, the default implementation uses the other query to make the automaton explicit and then answers the query. (This may need some mechanism to make sure that at least one of the queries is implemented).

akoehn commented 4 years ago

We (Jonas, Alexander, I) talked about this and came to the conclusion that a "magic" extension would lead to behavior that is too hard to predict.

Instead of having default implementations that make the automaton explicit, we opted to investigate whether a type hierarchy would be more beneficial:

This way, all methods only needing the TopDown (or BottomUp) aspect to work could relax their arguments to the corresponding class/interface. Legacy results where we know that only one direction is supported could be re-casted to prevent runtime errors. New code could return either TopDown or BottomUp tree transdurcers which would then need to be extended explicitly.

We obviously have the problem of diamond inheritance. Modern Java can work around this to some extend via default implementations in interface. However, no variables can be declared in interfaces, rendering our idea of pushing down the implementations down as far as possible void.

We can still have three interfaces declaring the subset of functions applicable for Base, BottomUp, and TopDown transducers, but all code would need to stay in TreeTransducer. Code could then cast objects down the the features they actually implement.