## 12.3 Putting it into Prolog

As we have seen, we only have to adapt steps 1 (the initialization of chart and agenda) and 2d (how new hypotheses are predicted) of the general algorithm to arrive either at a bottom-up or at a top-down parser.

That means that we can also reuse most of the code that we implemented in the last chapter for the bottom-up algorithm. In fact, we only have to change the predicates `initialize_chart_bottomup/2` and `initialize_agenda_bottomup/1` that take care of the initialization and the predicates `make_new_arcs_bottomup/2` and `predict_new_arcs_bottomup/2` that implement step 2d. Let's first look at the initialization predicates.

For top-down processing, we initially write not only the words and their position into the chart but also passive arcs giving us the categories of the words. `initialize_chart_topdown/2` recurses through the input list, writes the approriate `scan` entries to the chart and then uses `doall` (see Chapter 10) to retrieve all categories for each word from the lexicon. For each of these categories it asserts a passive arc to the chart.

`%%% initialize_chart_topdown(+sentence, +start node) initialize_chart_topdown([], _).initialize_chart_topdown([Word|Input], From) :-        To is From + 1,        assert(scan(From, To, Word)),        doall(             (lex(Word,Cat), assert(arc(From,To,Cat,[Word],[]))             )        ),        initialize_chart_topdown(Input, To).`

In the initial agenda we want to have all possible hypotheses of how a sentence can be built. We therefore use findall to find all rules that have `s` on the left hand side of the arrow and add and active arc from position 0 to position 0.

`%%% initialize_agenda_topdown(-agenda) initialize_agenda_topdown(Agenda) :-        findall(arc(0, 0, s, [], RHS), s ---> RHS, Agenda).`

Now, let's look at how new arcs are created. As in the bottom-up case, we apply step 2c to all arcs. Different than in the bottom-up case, we will apply step 2d only to active arcs. `make_new_arcs_topdown/2` makes sure that `apply_fundamental_rule/2` and `predict_new_arcs_topdown/2` are applied appropriately depending on whether an active or a passive arc is coming in.

`%%% make_new_arcs_topdown(+arc, -list of arcs)   %%% 'arc' is active -> steps 2c and 2d apply.make_new_arcs_topdown(Arc, NewArcs) :-        apply_fundamental_rule(Arc, NewArcs1),        predict_new_arcs_topdown(Arc, NewArcs2),        append(NewArcs1,NewArcs2,NewArcs). %%% 'arc' is passive -> only step 2c applies.make_new_arcs_topdown(Arc, NewArcs) :-        apply_fundamental_rule(Arc, NewArcs).`

The fundamental rule is always the same, no matter whether we are parsing bottom-up or top-down. But `predict_new_arcs_topdown/2` changes. The arcs that are coming in are active. `ToFindCat` is the category that they need next. `predict_new_arcs_topdown/2` looks for all rules that have this category on the left hand side and creates new active edges for them. These active edges span positions `J` to `J`, i.e., they don't cover anything of the string, yet, and start in the position where the active edge ends.

`%%% predict_new_arcs_topdown(+arc, -list of arcs) predict_new_arcs_topdown(arc(_, J, _, _, [ToFindCat|_]), NewArcs) :-        findall(arc(J, J, ToFindCat, [], RHS),                ToFindCat ---> RHS,                NewArcs            ).`

You can find the whole code in active_chart_topdown.pl.

Patrick Blackburn and Kristina Striegnitz
Version 1.2.4 (20020829)