incremental chart construction

This commit is contained in:
Krasimir Angelov
2026-08-04 10:39:42 +02:00
parent ec7354ca1c
commit cccce4d064
8 changed files with 328 additions and 145 deletions
+1
View File
@@ -262,6 +262,7 @@ struct PGF_INTERNAL_DECL PgfSymbolCCat {
ref<PgfConcrLincat> lincat; ref<PgfConcrLincat> lincat;
interval_t value; interval_t value;
interval_t lin_idx; interval_t lin_idx;
prob_t viterbi_prob;
PgfMetaId fid; PgfMetaId fid;
}; };
+2 -2
View File
@@ -12,11 +12,11 @@ class PGF_INTERNAL_DECL interval_map {
size_t sz; size_t sz;
size_t start, end, max; size_t start, end, max;
V value;
Node *left; Node *left;
Node *right; Node *right;
V value;
Node(size_t start, size_t end) Node(size_t start, size_t end)
{ {
this->sz = 1; this->sz = 1;
+271 -121
View File
@@ -1,6 +1,7 @@
#include "data.h" #include "data.h"
#include "printer.h" #include "printer.h"
#include "parser.h" #include "parser.h"
#include <math.h>
//#define DEBUG_PARSER //#define DEBUG_PARSER
//#define DEBUG_EXPRS //#define DEBUG_EXPRS
@@ -9,7 +10,6 @@ PgfAbstractParser::PgfAbstractParser(ref<PgfConcr> concr)
{ {
this->concr = concr; this->concr = concr;
this->first_state = NULL;
this->current_state = NULL; this->current_state = NULL;
this->initial_fid = concr->last_fid; this->initial_fid = concr->last_fid;
this->last_fid = concr->last_fid; this->last_fid = concr->last_fid;
@@ -54,7 +54,7 @@ PgfAbstractParser::Cont::~Cont()
PgfAbstractParser::~PgfAbstractParser() PgfAbstractParser::~PgfAbstractParser()
{ {
State *state = first_state; State *state = current_state;
while (state != NULL) { while (state != NULL) {
for (auto it1 : state->completed) { for (auto it1 : state->completed) {
/* for (auto it2 : it1) { /* for (auto it2 : it1) {
@@ -76,22 +76,22 @@ PgfAbstractParser::~PgfAbstractParser()
} }
} }
void PgfAbstractParser::process(Item *item, const PgfTextSpot &spot, bool bind) void PgfAbstractParser::process(Item *item, State *state)
{ {
#ifdef DEBUG_PARSER #ifdef DEBUG_PARSER
print_item(item,spot); print_item(item,state);
#endif #endif
if (item->dot < item->syms.size()) { if (item->dot < item->syms.size()) {
symbol(item,spot,bind,item->syms[item->dot]); symbol(item,state,item->syms[item->dot]);
} else if (item->pre_alt > 0) { } else if (item->pre_alt > 0) {
item->dot = item->pre_dot+1; item->dot = item->pre_dot+1;
item->pre_alt = 0; item->pre_alt = 0;
item->pre_dot = 0; item->pre_dot = 0;
item->syms = item->rule->syms.as_vector(); item->syms = item->rule->syms.as_vector();
process(item,spot,bind); process(item,state);
} else { } else {
complete(item,spot,bind); complete(item,state);
} }
} }
@@ -99,14 +99,12 @@ PGF_INTERNAL_DECL
int text_symbol_cmp(PgfTextSpot *spot, const uint8_t *end, int text_symbol_cmp(PgfTextSpot *spot, const uint8_t *end,
PgfSymbol sym, bool case_sensitive); PgfSymbol sym, bool case_sensitive);
void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym) void PgfAbstractParser::symbol(Item *item, State *state, PgfSymbol sym)
{ {
switch (ref<PgfSymbol>::get_tag(sym)) { switch (ref<PgfSymbol>::get_tag(sym)) {
case PgfSymbolCat::tag: { case PgfSymbolCat::tag: {
auto symcat = ref<PgfSymbolCat>::untagged(sym); auto symcat = ref<PgfSymbolCat>::untagged(sym);
State *state = new_state(spot);
CCat *ccat = item->args[symcat->d]; CCat *ccat = item->args[symcat->d];
if (ccat == NULL) { if (ccat == NULL) {
ref<PgfConcrLincat> lincat = 0; ref<PgfConcrLincat> lincat = 0;
@@ -125,6 +123,7 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
} }
if (lincat != 0) { if (lincat != 0) {
size_t n_suspended1 = state->conts1.size();
Cont *&cont = state->conts1[lincat]; Cont *&cont = state->conts1[lincat];
if (cont == NULL) { if (cont == NULL) {
cont = new Cont; cont = new Cont;
@@ -138,7 +137,7 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
auto &suspended = cont->suspended[value_i][lin_idx_i]; auto &suspended = cont->suspended[value_i][lin_idx_i];
suspended.push_back(item); suspended.push_back(item);
suspend(cont,item,suspended.size()); suspend(cont,item,n_suspended1,suspended.size());
} }
} else { } else {
Cont *&cont = state->conts2[ccat]; Cont *&cont = state->conts2[ccat];
@@ -154,10 +153,24 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
interval_t value_i = item->interval(item->rule->args[symcat->d]); interval_t value_i = item->interval(item->rule->args[symcat->d]);
interval_t lin_idx_i = item->interval(ref<PgfLParam>::from_ptr(&symcat->r)); interval_t lin_idx_i = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
bool subsumed = false;
for (auto it1 : cont->suspended.overlaps(value_i)) {
if (it1.first.first <= value_i.first && it1.first.second >= value_i.second) {
for (auto it2 : it1.second.overlaps(lin_idx_i)) {
if (it2.first.first <= lin_idx_i.first && it2.first.second >= lin_idx_i.second) {
subsumed = true;
goto found;
}
}
}
}
found:;
auto &suspended = cont->suspended[value_i][lin_idx_i]; auto &suspended = cont->suspended[value_i][lin_idx_i];
suspended.push_back(item); suspended.push_back(item);
if (suspended.size() == 1) { if (!subsumed && suspended.size() == 1) {
if (ccat->fid <= initial_fid) { if (ccat->fid <= initial_fid) {
size_t n_items = 0; size_t n_items = 0;
vector<ref<PgfItem>> items = vector<ref<PgfItem>> items =
@@ -165,11 +178,11 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
for (size_t i = 0; i < n_items; i++) { for (size_t i = 0; i < n_items; i++) {
ref<PgfItem> pitem = items[i]; ref<PgfItem> pitem = items[i];
td_epsilon(state,cont,pitem,item,item->rule->args[symcat->d],ref<PgfLParam>::from_ptr(&symcat->r)); td_epsilon(state,cont,pitem,item,symcat);
} }
} else { } else {
for (Production *prod : ccat->prods) { for (Production *prod : ccat->prods) {
td_predict(state,cont,prod,item,item->rule->args[symcat->d],ref<PgfLParam>::from_ptr(&symcat->r)); td_predict(state,cont,prod,item,symcat);
} }
} }
} else { } else {
@@ -194,7 +207,7 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
break; break;
} }
case PgfSymbolKS::tag: { case PgfSymbolKS::tag: {
symbol_token(item, spot, bind, sym); symbol_token(item, state, sym);
break; break;
} }
case PgfSymbolKP::tag: { case PgfSymbolKP::tag: {
@@ -206,7 +219,9 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
new_item->dot = 0; new_item->dot = 0;
new_item->syms = symkp->default_form; new_item->syms = symkp->default_form;
new_item->rule = item->rule; new_item->rule = item->rule;
process(new_item, spot, bind); new_item->inside_prob = item->inside_prob;
new_item->outside_prob = item->outside_prob;
process(new_item, state);
for (size_t i = 0; i < symkp->alts.size(); i++) { for (size_t i = 0; i < symkp->alts.size(); i++) {
Item *new_item = new(item) Item; Item *new_item = new(item) Item;
@@ -215,22 +230,18 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
new_item->dot = 0; new_item->dot = 0;
new_item->syms = symkp->alts[i].form; new_item->syms = symkp->alts[i].form;
new_item->rule = item->rule; new_item->rule = item->rule;
process(new_item, spot, bind); new_item->inside_prob = item->inside_prob;
new_item->outside_prob = item->outside_prob;
process(new_item, state);
} }
delete item; delete item;
break; break;
} }
case PgfSymbolBIND::tag: { case PgfSymbolBIND::tag:
symbol_bind(item, spot, sym);
break;
}
case PgfSymbolSOFTBIND::tag: case PgfSymbolSOFTBIND::tag:
case PgfSymbolSOFTSPACE::tag: { case PgfSymbolSOFTSPACE::tag: {
item->dot++; symbol_bind(item, state, sym);
process(new (item) Item, spot, true);
process(new (item) Item, spot, false);
delete item;
break; break;
} }
case PgfSymbolNE::tag: case PgfSymbolNE::tag:
@@ -239,15 +250,13 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
case PgfSymbolCAPIT::tag: case PgfSymbolCAPIT::tag:
case PgfSymbolALLCAPIT::tag: case PgfSymbolALLCAPIT::tag:
item->dot++; item->dot++;
process(item, spot, bind); process(item, state);
break; break;
} }
} }
void PgfAbstractParser::complete(Item *item, const PgfTextSpot &spot, bool bind) void PgfAbstractParser::complete(Item *item, State *state)
{ {
State *state = new_state(spot);
switch (ref<object>::get_tag(item->rule->container)) { switch (ref<object>::get_tag(item->rule->container)) {
case PgfConcrLin::tag: { case PgfConcrLin::tag: {
auto lin = ref<PgfConcrLin>::untagged(item->rule->container); auto lin = ref<PgfConcrLin>::untagged(item->rule->container);
@@ -263,6 +272,7 @@ void PgfAbstractParser::complete(Item *item, const PgfTextSpot &spot, bool bind)
ccat->lin_idx = lin_idx; ccat->lin_idx = lin_idx;
ccat->value = res; ccat->value = res;
ccat->covered = false; ccat->covered = false;
ccat->viterbi_prob = item->inside_prob;
#ifdef DEBUG_PARSER #ifdef DEBUG_PARSER
{ {
@@ -327,7 +337,7 @@ void PgfAbstractParser::complete(Item *item, const PgfTextSpot &spot, bool bind)
for (auto it2 : it1.second) { for (auto it2 : it1.second) {
Item *item = it2.second[0]; Item *item = it2.second[0];
auto symcat = ref<PgfSymbolCat>::untagged(item->syms[item->dot]); auto symcat = ref<PgfSymbolCat>::untagged(item->syms[item->dot]);
td_predict(next,cont,prod,item,item->rule->args[symcat->d],ref<PgfLParam>::from_ptr(&symcat->r)); td_predict(next,cont,prod,item,symcat);
} }
} }
} }
@@ -492,11 +502,15 @@ void PgfAbstractParser::combine(State *state, Item *item, CCat *ccat)
} }
item->dot++; item->dot++;
if (item->args[sym_cat->d] != NULL) {
item->inside_prob -= item->args[sym_cat->d]->viterbi_prob;
}
item->args[sym_cat->d] = ccat; item->args[sym_cat->d] = ccat;
process(item, state->start, false); item->inside_prob += ccat->viterbi_prob;
state->push_item(item);
} }
void PgfAbstractParser::td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem, Item *xitem, ref<PgfLParam> value, ref<PgfLParam> lin_idx) void PgfAbstractParser::td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem, Item *xitem, ref<PgfSymbolCat> symcat)
{ {
switch (ref<object>::get_tag(pitem->rule->container)) { switch (ref<object>::get_tag(pitem->rule->container)) {
case PgfConcrLin::tag: { case PgfConcrLin::tag: {
@@ -510,12 +524,14 @@ void PgfAbstractParser::td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem,
item->pre_dot = 0; item->pre_dot = 0;
item->syms = rule->syms.as_vector(); item->syms = rule->syms.as_vector();
item->rule = rule; item->rule = rule;
item->inside_prob = lin->absfun->prob;
item->outside_prob = xitem->outside_prob+xitem->inside_prob-xitem->args[symcat->d]->viterbi_prob;
if (!item->instantiate(item->rule->res, xitem->rule, &xitem->vars[0], value)) { if (!item->instantiate(item->rule->res, xitem->rule, &xitem->vars[0], xitem->rule->args[symcat->d])) {
delete item; delete item;
continue; continue;
} }
if (!item->instantiate(item->rule->lin_idx, xitem->rule, &xitem->vars[0], lin_idx)) { if (!item->instantiate(item->rule->lin_idx, xitem->rule, &xitem->vars[0], ref<PgfLParam>::from_ptr(&symcat->r))) {
delete item; delete item;
continue; continue;
} }
@@ -533,8 +549,10 @@ void PgfAbstractParser::td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem,
arg_ccat->lin_idx = arg->lin_idx; arg_ccat->lin_idx = arg->lin_idx;
arg_ccat->value = arg->value; arg_ccat->value = arg->value;
arg_ccat->covered = true; arg_ccat->covered = true;
arg_ccat->viterbi_prob = arg->viterbi_prob;
} }
item->args[i] = arg_ccat; item->args[i] = arg_ccat;
item->inside_prob += arg_ccat->viterbi_prob;
} }
if (!item->instantiate(item->rule->args[i], pitem->rule, &pitem->vars[0], pitem->rule->args[i])) { if (!item->instantiate(item->rule->args[i], pitem->rule, &pitem->vars[0], pitem->rule->args[i])) {
@@ -543,7 +561,7 @@ void PgfAbstractParser::td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem,
} }
} }
process(item, state->start, false); state->push_item(item);
next:; next:;
} }
} }
@@ -552,7 +570,7 @@ next:;
} }
} }
void PgfAbstractParser::td_predict(State *state, Cont *cont, Production *prod, Item *xitem, ref<PgfLParam> value, ref<PgfLParam> lin_idx) void PgfAbstractParser::td_predict(State *state, Cont *cont, Production *prod, Item *xitem, ref<PgfSymbolCat> symcat)
{ {
switch (ref<object>::get_tag(prod->rule->container)) { switch (ref<object>::get_tag(prod->rule->container)) {
case PgfConcrLin::tag: { case PgfConcrLin::tag: {
@@ -566,13 +584,15 @@ void PgfAbstractParser::td_predict(State *state, Cont *cont, Production *prod, I
item->pre_dot = 0; item->pre_dot = 0;
item->syms = rule->syms.as_vector(); item->syms = rule->syms.as_vector();
item->rule = rule; item->rule = rule;
item->inside_prob = lin->absfun->prob;
item->outside_prob = xitem->outside_prob+xitem->inside_prob-xitem->args[symcat->d]->viterbi_prob;
if (!item->instantiate(item->rule->res, xitem->rule, &xitem->vars[0], value)) { if (!item->instantiate(item->rule->res, xitem->rule, &xitem->vars[0], xitem->rule->args[symcat->d])) {
delete item; delete item;
continue; continue;
} }
if (!item->instantiate(item->rule->lin_idx, xitem->rule, &xitem->vars[0], lin_idx)) { if (!item->instantiate(item->rule->lin_idx, xitem->rule, &xitem->vars[0], ref<PgfLParam>::from_ptr(&symcat->r))) {
delete item; delete item;
continue; continue;
} }
@@ -583,9 +603,12 @@ void PgfAbstractParser::td_predict(State *state, Cont *cont, Production *prod, I
goto next; goto next;
} }
item->args[i] = prod->args[i]; item->args[i] = prod->args[i];
if (item->args[i] != NULL) {
item->inside_prob += item->args[i]->viterbi_prob;
}
} }
process(item, state->start, false); state->push_item(item);
next:; next:;
} }
} }
@@ -634,11 +657,11 @@ void print_symbols(PgfPrinter &printer, PgfConcrRule *rule, vector<PgfSymbol> sy
printer.puts(" . "); printer.puts(" . ");
} }
void PgfAbstractParser::print_item(Item *item, const PgfTextSpot &spot) void PgfAbstractParser::print_item(Item *item, State *state)
{ {
PgfPrinter printer(NULL,0,NULL); PgfPrinter printer(NULL,0,NULL);
printer.nprintf(32, "[%zd-%zd; ", item->cont ? item->cont->state->end.pos : 0, spot.pos); printer.nprintf(32, "[%zd-%zd; ", item->cont ? item->cont->state->end.pos : 0, state->start.pos);
if (item->vars.size() > 0) { if (item->vars.size() > 0) {
printer.lvar_ranges(item->rule->ranges, &item->vars[0]); printer.lvar_ranges(item->rule->ranges, &item->vars[0]);
@@ -703,7 +726,7 @@ void PgfAbstractParser::print_item(Item *item, const PgfTextSpot &spot)
printer.lparam(item->rule->lin_idx); printer.lparam(item->rule->lin_idx);
printer.puts(" : "); printer.puts(" : ");
print_symbols(printer, item->rule, item->syms, item->pre_alt, item->pre_dot, item->dot); print_symbols(printer, item->rule, item->syms, item->pre_alt, item->pre_dot, item->dot);
printer.puts("]"); printer.nprintf(40,"; %f+%f=%f]", item->inside_prob, item->outside_prob, item->inside_prob+item->outside_prob);
PgfText *text = printer.get_text(); PgfText *text = printer.get_text();
fprintf(stderr, "%s\n", text->text); fprintf(stderr, "%s\n", text->text);
@@ -780,14 +803,16 @@ PgfParser::PgfParser(ref<PgfConcr> concr, PgfText *sentence, bool case_sensitive
{ {
this->m = m; this->m = m;
this->u = u; this->u = u;
this->sentence = sentence; this->sentence = textdup(sentence);
this->end = (uint8_t *) (sentence->text+sentence->size); this->end = (uint8_t *) (this->sentence->text+this->sentence->size);
this->case_sensitive = case_sensitive; this->case_sensitive = case_sensitive;
} }
PgfParser::~PgfParser() PgfParser::~PgfParser()
{ {
State *state = first_state; free(sentence);
State *state = current_state;
while (state != NULL) { while (state != NULL) {
for (auto it1 : state->completed) { for (auto it1 : state->completed) {
for (auto it2 : it1.second) { for (auto it2 : it1.second) {
@@ -832,13 +857,7 @@ void PgfParser::bu_predict(PgfPhrasetable phrasetable,
return; return;
PgfTextSpot current = state->end; PgfTextSpot current = state->end;
int cmp; int cmp = text_symbol_cmp(&current,end,phrasetable->sym,case_sensitive);
if (state->needs_bind) {
uint8_t tag = ref<PgfSymbol>::get_tag(phrasetable->sym);
cmp = ((int) PgfSymbolBIND::tag) - ((int) tag);
} else {
cmp = text_symbol_cmp(&current,end,phrasetable->sym,case_sensitive);
}
if (cmp < 0) { if (cmp < 0) {
bu_predict(phrasetable->left,state,min,max); bu_predict(phrasetable->left,state,min,max);
} else if (cmp > 0) { } else if (cmp > 0) {
@@ -856,16 +875,14 @@ void PgfParser::bu_predict(PgfPhrasetable phrasetable,
bu_predict(phrasetable->left,state,min,len); bu_predict(phrasetable->left,state,min,len);
if (len > 0) { if (len > 0) {
if (*current.ptr != ' ' && *current.ptr != 0) State *next_state = new_state(current);
return;
for (size_t i = 0; i < phrasetable->n_items; i++) { for (size_t i = 0; i < phrasetable->n_items; i++) {
std::map<ref<PgfConcrLincat>, bool> visited; std::map<ref<PgfConcrLincat>, bool> visited;
//if (!td_reachable(state, phrasetable->items[i], visited)) //if (!td_reachable(state, phrasetable->items[i], visited))
// continue; // continue;
Item *item = bu_item(state, phrasetable->items[i]); Item *item = bu_item(state, phrasetable->items[i]);
item->dot++; item->dot++;
process(item, current, false); next_state->push_item(item);
} }
} }
@@ -874,6 +891,42 @@ void PgfParser::bu_predict(PgfPhrasetable phrasetable,
} }
} }
void PgfParser::bu_predict(PgfPhrasetable phrasetable,
State *state)
{
if (phrasetable == 0)
return;
PgfTextSpot current = state->end;
int cmp;
uint8_t tag = ref<PgfSymbol>::get_tag(phrasetable->sym);
cmp = ((int) PgfSymbolBIND::tag) - ((int) tag);
if (cmp < 0) {
bu_predict(phrasetable->left,state);
} else if (cmp > 0) {
bu_predict(phrasetable->right,state);
} else {
State *next_state = state->next;
if (next_state == NULL || state->end.pos != next_state->start.pos) {
next_state = new State;
next_state->start = state->end;
next_state->end = state->end;
next_state->next = state->next;
next_state->needs_bind = false;
state->next = next_state;
}
for (size_t i = 0; i < phrasetable->n_items; i++) {
std::map<ref<PgfConcrLincat>, bool> visited;
//if (!td_reachable(state, phrasetable->items[i], visited))
// continue;
Item *item = bu_item(state, phrasetable->items[i]);
item->dot++;
next_state->push_item(item);
}
}
}
void PgfParser::bu_predict(State *state, CCat *ccat) void PgfParser::bu_predict(State *state, CCat *ccat)
{ {
size_t n_items = 0; size_t n_items = 0;
@@ -944,6 +997,8 @@ PgfAbstractParser::Item *PgfParser::bu_item(State *state, ref<PgfItem> pitem)
item->dot = pitem->dot; item->dot = pitem->dot;
item->syms = pitem->rule->syms.as_vector(); item->syms = pitem->rule->syms.as_vector();
item->rule = pitem->rule; item->rule = pitem->rule;
item->inside_prob = lin->absfun->prob;
item->outside_prob = 0;
break; break;
} }
case PgfConcrLincat::tag: { case PgfConcrLincat::tag: {
@@ -964,6 +1019,8 @@ PgfAbstractParser::Item *PgfParser::bu_item(State *state, ref<PgfItem> pitem)
item->dot = pitem->dot; item->dot = pitem->dot;
item->syms = pitem->rule->syms.as_vector(); item->syms = pitem->rule->syms.as_vector();
item->rule = pitem->rule; item->rule = pitem->rule;
item->inside_prob = 0;
item->outside_prob = 0;
break; break;
} }
} }
@@ -994,8 +1051,10 @@ PgfAbstractParser::Item *PgfParser::bu_item(State *state, ref<PgfItem> pitem)
arg_ccat->lin_idx = arg->lin_idx; arg_ccat->lin_idx = arg->lin_idx;
arg_ccat->value = arg->value; arg_ccat->value = arg->value;
arg_ccat->covered = true; arg_ccat->covered = true;
arg_ccat->viterbi_prob = arg->viterbi_prob;
} }
item->args[i] = arg_ccat; item->args[i] = arg_ccat;
item->inside_prob += arg_ccat->viterbi_prob;
} }
} }
@@ -1014,6 +1073,7 @@ void PgfParser::make_chunks(State *state, std::vector<CCat*> &chunks, prob_t pro
estate->n_args = chunks.size(); estate->n_args = chunks.size();
for (size_t i = 0; i < estate->n_args; i++) { for (size_t i = 0; i < estate->n_args; i++) {
estate->args[i] = chunks[estate->n_args-i-1]; estate->args[i] = chunks[estate->n_args-i-1];
estate->prob += estate->args[i]->viterbi_prob;
} }
queue.push_back(estate); queue.push_back(estate);
std::push_heap(queue.begin(), queue.end(), estate_comp); std::push_heap(queue.begin(), queue.end(), estate_comp);
@@ -1041,8 +1101,6 @@ void PgfParser::prepare(ref<PgfConcrLincat> start)
PgfTextSpot start_spot = {0, (uint8_t *) sentence->text}; PgfTextSpot start_spot = {0, (uint8_t *) sentence->text};
State *state = new_state(start_spot); State *state = new_state(start_spot);
state->needs_bind = false;
current_state = state;
for (size_t i = start->n_lindefs; i < start->rules.size(); i++) { for (size_t i = start->n_lindefs; i < start->rules.size(); i++) {
ref<PgfConcrRule> rule = start->rules[i]; ref<PgfConcrRule> rule = start->rules[i];
@@ -1053,18 +1111,9 @@ void PgfParser::prepare(ref<PgfConcrLincat> start)
item->pre_dot = 0; item->pre_dot = 0;
item->syms = rule->syms.as_vector(); item->syms = rule->syms.as_vector();
item->rule = rule; item->rule = rule;
process(item, start_spot, false); item->inside_prob = 0;
} item->outside_prob = 0;
state->push_item(item);
while (current_state != NULL) {
bu_predict(concr->phrasetable, current_state, 1, sentence->size);
state = current_state;
current_state = current_state->next;
}
if (queue.size() == 0) {
std::vector<CCat*> chunks;
make_chunks(state, chunks, 0);
} }
} }
@@ -1072,6 +1121,57 @@ PgfExpr PgfParser::fetch(PgfDB *db, prob_t *prob)
{ {
DB_scope scope(db, READER_SCOPE); DB_scope scope(db, READER_SCOPE);
bool first_fetch = (initial_fid == last_fid);
for (;;) {
State *state = current_state;
prob_t min_prob = INFINITY;
State *min_state = NULL;
if (queue.size() > 0) {
min_prob = queue.front()->prob;
}
while (state != NULL) {
if (state->queue.size() > 0) {
Item *item = state->queue.front();
prob_t prob = item->outside_prob + item->inside_prob;
if (min_prob > prob) {
min_prob = prob;
min_state = state;
}
}
state = state->next;
}
if (min_state == NULL)
break;
State *prev = current_state;
current_state = NULL;
while (current_state != min_state) {
State *next = prev->next;
prev->next = current_state;
current_state = prev;
prev = next;
}
Item *item = current_state->pop_item();
process(item,current_state);
while (current_state != NULL) {
State *next = current_state->next;
current_state->next = prev;
prev = current_state;
current_state = next;
}
current_state = prev;
}
if (first_fetch && queue.size() == 0) {
std::vector<CCat*> chunks;
make_chunks(current_state, chunks, 0);
}
while (queue.size() > 0) { while (queue.size() > 0) {
ExprState *estate = queue.front(); ExprState *estate = queue.front();
std::pop_heap(queue.begin(), queue.end(), estate_comp); std::pop_heap(queue.begin(), queue.end(), estate_comp);
@@ -1122,7 +1222,7 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
ExprState *new_estate = new(pitem->args.size()) ExprState; ExprState *new_estate = new(pitem->args.size()) ExprState;
new_estate->expr = u->efun(&lin->name); new_estate->expr = u->efun(&lin->name);
new_estate->prob = estate->prob+lin->absfun->prob; new_estate->prob = estate->prob-ccat->viterbi_prob+lin->absfun->prob;
new_estate->hash = 0; new_estate->hash = 0;
new_estate->res = ccat; new_estate->res = ccat;
new_estate->index = 0; new_estate->index = 0;
@@ -1143,8 +1243,10 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
arg_ccat->lin_idx = arg->lin_idx; arg_ccat->lin_idx = arg->lin_idx;
arg_ccat->value = arg->value; arg_ccat->value = arg->value;
arg_ccat->covered = true; arg_ccat->covered = true;
arg_ccat->viterbi_prob = arg->viterbi_prob;
} }
new_estate->args[i] = arg_ccat; new_estate->args[i] = arg_ccat;
new_estate->prob += arg_ccat->viterbi_prob;
} }
} }
queue.push_back(new_estate); queue.push_back(new_estate);
@@ -1156,7 +1258,7 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
ExprState *new_estate = new(prod->args.size()) ExprState; ExprState *new_estate = new(prod->args.size()) ExprState;
new_estate->expr = u->efun(&lin->name); new_estate->expr = u->efun(&lin->name);
new_estate->prob = estate->prob+lin->absfun->prob; new_estate->prob = estate->prob-ccat->viterbi_prob+lin->absfun->prob;
new_estate->hash = 0; new_estate->hash = 0;
new_estate->res = ccat; new_estate->res = ccat;
new_estate->index = 0; new_estate->index = 0;
@@ -1166,6 +1268,9 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
} }
for (size_t i = 0; i < new_estate->n_args; i++) { for (size_t i = 0; i < new_estate->n_args; i++) {
new_estate->args[i] = prod->args[i]; new_estate->args[i] = prod->args[i];
if (prod->args[i] != NULL) {
new_estate->prob += prod->args[i]->viterbi_prob;
}
} }
queue.push_back(new_estate); queue.push_back(new_estate);
std::push_heap(queue.begin(), queue.end(), estate_comp); std::push_heap(queue.begin(), queue.end(), estate_comp);
@@ -1175,7 +1280,7 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
for (ExprProb ep : ccat->exprs) { for (ExprProb ep : ccat->exprs) {
ExprState *app_state = new(estate->n_args) ExprState; ExprState *app_state = new(estate->n_args) ExprState;
app_state->expr = estate->expr ? u->eapp(estate->expr, ep.expr) : ep.expr; app_state->expr = estate->expr ? u->eapp(estate->expr, ep.expr) : ep.expr;
app_state->prob = estate->prob+ep.prob; app_state->prob = estate->prob-ccat->viterbi_prob+ep.prob;
app_state->hash = estate->hash * 31 + ep.hash; app_state->hash = estate->hash * 31 + ep.hash;
app_state->res = estate->res; app_state->res = estate->res;
app_state->index = estate->index+1; app_state->index = estate->index+1;
@@ -1194,7 +1299,7 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
return estate->expr; return estate->expr;
} }
prob_t prob = estate->prob - estate->res->pending[0]->prob; prob_t prob = estate->prob - (estate->res->pending[0]->prob-estate->res->viterbi_prob);
for (size_t i = estate->res->exprs.size(); i > 0; i--) { for (size_t i = estate->res->exprs.size(); i > 0; i--) {
ExprProb &ep = estate->res->exprs[i-1]; ExprProb &ep = estate->res->exprs[i-1];
if (ep.prob != prob) if (ep.prob != prob)
@@ -1207,7 +1312,7 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
for (ExprState *parent : estate->res->pending) { for (ExprState *parent : estate->res->pending) {
ExprState *app_state = new(parent->n_args) ExprState; ExprState *app_state = new(parent->n_args) ExprState;
app_state->expr = parent->expr ? u->eapp(parent->expr, estate->expr) : estate->expr; app_state->expr = parent->expr ? u->eapp(parent->expr, estate->expr) : estate->expr;
app_state->prob = parent->prob+prob; app_state->prob = parent->prob-estate->res->viterbi_prob+prob;
app_state->hash = parent->hash * 31 + estate->hash; app_state->hash = parent->hash * 31 + estate->hash;
app_state->res = parent->res; app_state->res = parent->res;
app_state->index = parent->index+1; app_state->index = parent->index+1;
@@ -1224,7 +1329,7 @@ PgfExpr PgfParser::process_expr(ExprState *estate, prob_t *prob)
PgfAbstractParser::State *PgfParser::new_state(const PgfTextSpot &start) PgfAbstractParser::State *PgfParser::new_state(const PgfTextSpot &start)
{ {
State **prev = &first_state; State **prev = &current_state;
State *state = current_state; State *state = current_state;
while (state != NULL && state->start.ptr <= start.ptr) { while (state != NULL && state->start.ptr <= start.ptr) {
if (state->start.ptr == start.ptr) if (state->start.ptr == start.ptr)
@@ -1248,42 +1353,48 @@ PgfAbstractParser::State *PgfParser::new_state(const PgfTextSpot &start)
state->end.ptr = ptr; state->end.ptr = ptr;
} }
state->needs_bind = (state->start.pos == state->end.pos); state->needs_bind = (state->start.pos > 0 && state->start.pos == state->end.pos);
return state; return state;
} }
void PgfParser::symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym) void PgfParser::symbol_token(Item *item, State *state, PgfSymbol sym)
{ {
PgfTextSpot next = spot; PgfTextSpot next = state->end;
const uint8_t *start = next.ptr;
for (;;) {
const uint8_t *ptr = next.ptr;
uint32_t ucs = pgf_utf8_decode(&ptr);
if (!pgf_utf8_is_space(ucs))
break;
next.ptr = ptr;
next.pos++;
}
if (bind != (spot.ptr == next.ptr))
return;
if (text_symbol_cmp(&next,end,sym,case_sensitive) != 0) if (text_symbol_cmp(&next,end,sym,case_sensitive) != 0)
return; return;
State *next_state = new_state(next);
item->dot++; item->dot++;
process(item, next, false); process(item, next_state);
} }
void PgfParser::symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym) void PgfParser::symbol_bind(Item *item, State *state, PgfSymbol sym)
{ {
item->dot++; if (state->needs_bind) {
process(item, spot, true); State *next_state = state->next;
if (next_state == NULL || state->end.pos != next_state->start.pos) {
next_state = new State;
next_state->start = state->end;
next_state->end = state->end;
next_state->next = state->next;
next_state->needs_bind = false;
state->next = next_state;
}
item->dot++;
next_state->push_item(item);
} else {
if (ref<PgfSymbol>::get_tag(sym) == PgfSymbolBIND::tag) {
delete item;
} else {
item->dot++;
process(item, state);
}
}
} }
void PgfParser::suspend(Cont *cont,Item *item,size_t n_suspended) void PgfParser::suspend(Cont *cont,Item *item,size_t n_suspended1,size_t n_suspended)
{ {
if (n_suspended == 1) { if (n_suspended == 1) {
std::function<void(ref<PgfSymbolCCat>,size_t,vector<ref<PgfItem>>)> f = std::function<void(ref<PgfSymbolCCat>,size_t,vector<ref<PgfItem>>)> f =
@@ -1312,26 +1423,40 @@ void PgfParser::suspend(Cont *cont,Item *item,size_t n_suspended)
arg_ccat->lin_idx = symcf->lin_idx; arg_ccat->lin_idx = symcf->lin_idx;
arg_ccat->value = symcf->value; arg_ccat->value = symcf->value;
arg_ccat->covered = true; arg_ccat->covered = true;
arg_ccat->viterbi_prob = symcf->viterbi_prob;
} }
cont->state->completed[cont][symcf->value][symcf->lin_idx] = arg_ccat; cont->state->completed[cont][symcf->value][symcf->lin_idx] = arg_ccat;
new_item->dot++; new_item->dot++;
new_item->args[sym_cat->d] = arg_ccat; new_item->args[sym_cat->d] = arg_ccat;
new_item->inside_prob += arg_ccat->viterbi_prob;
process(new_item, cont->state->start, false); cont->state->push_item(new_item);
}; };
phrasetable_iter(concr->phrasetable,cont->lincat,f); phrasetable_iter(concr->phrasetable,cont->lincat,f);
} else { }
auto it1 = cont->state->completed.find(cont);
if (it1 != cont->state->completed.end()) { State *state = cont->state;
while (state != NULL) {
auto it1 = state->completed.find(cont);
if (it1 != state->completed.end()) {
for (auto it2 : it1->second) { for (auto it2 : it1->second) {
for (auto it3 : it2.second) { for (auto it3 : it2.second) {
Item *new_item = new (item) Item; Item *new_item = new (item) Item;
combine(cont->state, new_item, it3.second); combine(state, new_item, it3.second);
} }
} }
} }
state = state->next;
}
if (n_suspended1 == 0) {
if (cont->state->needs_bind) {
bu_predict(concr->phrasetable, cont->state);
} else {
bu_predict(concr->phrasetable, cont->state, 1, sentence->size);
}
} }
} }
@@ -1347,6 +1472,7 @@ void PgfParser::final_item(State *state, CCat *ccat, Item *item, interval_t valu
estate->n_args = item->args.size(); estate->n_args = item->args.size();
for (size_t i = 0; i < estate->n_args; i++) { for (size_t i = 0; i < estate->n_args; i++) {
estate->args[i] = item->args[i]; estate->args[i] = item->args[i];
estate->prob += estate->args[i]->viterbi_prob;
} }
queue.push_back(estate); queue.push_back(estate);
std::push_heap(queue.begin(), queue.end(), estate_comp); std::push_heap(queue.begin(), queue.end(), estate_comp);
@@ -1390,7 +1516,15 @@ void PgfParser::print_expr_state(PgfMarshaller *m, ExprState *estate)
PgfPrinter printer(NULL,0,m); PgfPrinter printer(NULL,0,m);
printer.nprintf(64,"[%f] ",estate->prob); printer.nprintf(64,"[%f] ",estate->prob);
print_expr_state_left(&printer, m, estate); print_expr_state_left(&printer, m, estate);
printer.puts(" ."); printer.puts(" . ");
if (estate->index < estate->n_args) {
if (estate->args[estate->index] != NULL)
printer.emeta(estate->args[estate->index]->fid);
else
printer.puts("?");
}
print_expr_state_right(&printer, estate); print_expr_state_right(&printer, estate);
PgfText *text = printer.get_text(); PgfText *text = printer.get_text();
@@ -1402,12 +1536,11 @@ void PgfParser::print_expr_state(PgfMarshaller *m, ExprState *estate)
PgfParseTableMaker::PgfParseTableMaker(ref<PgfConcr> concr) PgfParseTableMaker::PgfParseTableMaker(ref<PgfConcr> concr)
: PgfAbstractParser(concr) : PgfAbstractParser(concr)
{ {
first_state = new State; current_state = new State;
first_state->start.pos = 0; current_state->start.pos = 0;
first_state->start.ptr = NULL; current_state->start.ptr = NULL;
first_state->end = first_state->start; current_state->end = current_state->start;
first_state->next = NULL; current_state->next = NULL;
current_state = first_state;
} }
ref<PgfItem> PgfParseTableMaker::clone_item(Item *item) ref<PgfItem> PgfParseTableMaker::clone_item(Item *item)
@@ -1421,7 +1554,7 @@ ref<PgfItem> PgfParseTableMaker::clone_item(Item *item)
pitem->dot = item->dot; pitem->dot = item->dot;
pitem->rule = item->rule; pitem->rule = item->rule;
memcpy(&pitem->vars[0],&item->vars[0],sizeof(size_t) * item->vars.size()); memcpy(&pitem->vars[0],&item->vars[0],sizeof(size_t) * item->vars.size());
for (size_t i = 0; i < item->args.size(); i++) { for (size_t i = 0; i < item->args.size(); i++) {
ref<PgfSymbolCCat> symcf = 0; ref<PgfSymbolCCat> symcf = 0;
if (item->args[i] != NULL) { if (item->args[i] != NULL) {
@@ -1430,6 +1563,7 @@ ref<PgfItem> PgfParseTableMaker::clone_item(Item *item)
symcf->value = item->args[i]->value; symcf->value = item->args[i]->value;
symcf->lin_idx = item->args[i]->lin_idx; symcf->lin_idx = item->args[i]->lin_idx;
symcf->fid = item->args[i]->fid; symcf->fid = item->args[i]->fid;
symcf->viterbi_prob = item->args[i]->viterbi_prob;
} }
pitem->args[i] = symcf; pitem->args[i] = symcf;
} }
@@ -1439,10 +1573,10 @@ ref<PgfItem> PgfParseTableMaker::clone_item(Item *item)
PgfAbstractParser::State *PgfParseTableMaker::new_state(const PgfTextSpot &start) PgfAbstractParser::State *PgfParseTableMaker::new_state(const PgfTextSpot &start)
{ {
return this->first_state; return current_state;
} }
void PgfParseTableMaker::symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym) void PgfParseTableMaker::symbol_token(Item *item, State *state, PgfSymbol sym)
{ {
auto pitem = clone_item(item); auto pitem = clone_item(item);
auto phrasetable = phrasetable_insert(concr->phrasetable,sym,pitem); auto phrasetable = phrasetable_insert(concr->phrasetable,sym,pitem);
@@ -1450,15 +1584,21 @@ void PgfParseTableMaker::symbol_token(Item *item, const PgfTextSpot &spot, bool
delete item; delete item;
} }
void PgfParseTableMaker::symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym) void PgfParseTableMaker::symbol_bind(Item *item, State *state, PgfSymbol sym)
{ {
auto pitem = clone_item(item); auto pitem = clone_item(item);
auto phrasetable = phrasetable_insert(concr->phrasetable,sym,pitem); auto phrasetable = phrasetable_insert(concr->phrasetable,ref<PgfSymbolBIND>(0).tagged(),pitem);
concr->phrasetable = phrasetable; concr->phrasetable = phrasetable;
delete item;
if (ref<PgfSymbol>::get_tag(sym) == PgfSymbolBIND::tag) {
delete item;
} else {
item->dot++;
process(item,state);
}
} }
void PgfParseTableMaker::suspend(Cont *cont,Item *item,size_t n_suspended) void PgfParseTableMaker::suspend(Cont *cont,Item *item,size_t n_suspended1,size_t n_suspended)
{ {
// collect the cats first, since calling combine in // collect the cats first, since calling combine in
// the loop will change the search index // the loop will change the search index
@@ -1488,7 +1628,7 @@ void PgfParseTableMaker::final_item(State *state, CCat *ccat, Item *item, interv
PgfPhrasetable phrasetable = concr->phrasetable; PgfPhrasetable phrasetable = concr->phrasetable;
phrasetable = phrasetable_insert(phrasetable, phrasetable = phrasetable_insert(phrasetable,
item->cont->lincat, value, lin_idx, ccat->fid, item->cont->lincat, value, lin_idx, ccat->fid, ccat->viterbi_prob,
pitem); pitem);
concr->phrasetable = phrasetable; concr->phrasetable = phrasetable;
} }
@@ -1503,12 +1643,12 @@ void PgfParseTableMaker::insert_rule(ref<PgfConcrRule> rule)
case PgfConcrLin::tag: { case PgfConcrLin::tag: {
auto lin = ref<PgfConcrLin>::untagged(rule->container); auto lin = ref<PgfConcrLin>::untagged(rule->container);
Cont *&cont = first_state->conts1[lin->lincat]; Cont *&cont = current_state->conts1[lin->lincat];
if (cont == NULL) { if (cont == NULL) {
cont = new Cont; cont = new Cont;
cont->ccat = NULL; cont->ccat = NULL;
cont->lincat = lin->lincat; cont->lincat = lin->lincat;
cont->state = first_state; cont->state = current_state;
} }
Item *item = new(rule) Item; Item *item = new(rule) Item;
@@ -1518,7 +1658,17 @@ void PgfParseTableMaker::insert_rule(ref<PgfConcrRule> rule)
item->pre_dot = 0; item->pre_dot = 0;
item->syms = rule->syms.as_vector(); item->syms = rule->syms.as_vector();
item->rule = rule; item->rule = rule;
return process(item, first_state->end, false); item->inside_prob = lin->absfun->prob;
item->outside_prob = 0;
current_state->push_item(item);
} }
} }
} }
void PgfParseTableMaker::prepare()
{
while (current_state->has_items()) {
Item *item = current_state->pop_item();
process(item,current_state);
}
}
+46 -18
View File
@@ -89,6 +89,7 @@ protected:
State *state; State *state;
interval_t value; interval_t value;
interval_t lin_idx; interval_t lin_idx;
prob_t viterbi_prob;
bool covered; bool covered;
std::vector<Production*> prods; std::vector<Production*> prods;
std::vector<ExprState*> pending; std::vector<ExprState*> pending;
@@ -103,8 +104,25 @@ protected:
std::map<ref<PgfConcrLincat>,Cont*> conts1; std::map<ref<PgfConcrLincat>,Cont*> conts1;
std::map<CCat*,Cont*> conts2; std::map<CCat*,Cont*> conts2;
std::map<Cont*,interval_map<interval_map<CCat*>>> completed; std::map<Cont*,interval_map<interval_map<CCat*>>> completed;
std::vector<Item*> queue;
State *next; State *next;
bool has_items() {
return queue.size() > 0;
}
void push_item(Item *item) {
queue.push_back(item);
std::push_heap(queue.begin(), queue.end(), item_comp);
}
Item *pop_item() {
Item *item = queue.front();
std::pop_heap(queue.begin(), queue.end(), item_comp);
queue.pop_back();
return item;
}
}; };
struct Cont { struct Cont {
@@ -123,6 +141,8 @@ protected:
uint16_t dot; uint16_t dot;
vector<PgfSymbol> syms; vector<PgfSymbol> syms;
ref<PgfConcrRule> rule; ref<PgfConcrRule> rule;
prob_t inside_prob;
prob_t outside_prob;
struct { struct {
size_t &operator[](int i) const { size_t &operator[](int i) const {
@@ -177,6 +197,12 @@ protected:
PgfConcrRule *rule, size_t *values, ref<PgfLParam> lparam2); PgfConcrRule *rule, size_t *values, ref<PgfLParam> lparam2);
}; };
static struct ItemComparator : std::less<Item*> {
bool operator()(Item *item1, Item *item2) {
return item1->inside_prob+item1->outside_prob > item2->inside_prob+item2->outside_prob;
}
} item_comp;
struct ExprState { struct ExprState {
PgfExpr expr; PgfExpr expr;
prob_t prob; prob_t prob;
@@ -204,29 +230,29 @@ protected:
} }
}; };
State *first_state, *current_state; State *current_state;
std::map<ref<PgfConcrLincat>,interval_map<interval_map<CCat*>>> epsilons; std::map<ref<PgfConcrLincat>,interval_map<interval_map<CCat*>>> epsilons;
PgfMetaId initial_fid, last_fid; PgfMetaId initial_fid, last_fid;
void process(Item *item, const PgfTextSpot &spot, bool bind); void process(Item *item, State *state);
void symbol(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym); void symbol(Item *item, State *state, PgfSymbol sym);
void complete(Item *item, const PgfTextSpot &spot, bool bind); void complete(Item *item, State *state);
virtual State *new_state(const PgfTextSpot &start)=0; virtual State *new_state(const PgfTextSpot &start)=0;
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym)=0; virtual void symbol_token(Item *item, State *state, PgfSymbol sym)=0;
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym)=0; virtual void symbol_bind(Item *item, State *state, PgfSymbol sym)=0;
virtual void suspend(Cont *cont, Item *item, size_t n_suspended)=0; virtual void suspend(Cont *cont, Item *item, size_t n_suspended1, size_t n_suspended)=0;
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx)=0; virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx)=0;
virtual void bu_predict(State *state, CCat *ccat)=0; virtual void bu_predict(State *state, CCat *ccat)=0;
void td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem, Item *xitem, ref<PgfLParam> value, ref<PgfLParam> lin_idx); void td_epsilon(State *state, Cont *cont, ref<PgfItem> pitem, Item *xitem, ref<PgfSymbolCat> symcat);
void td_predict(State *state, Cont *cont, Production *prod, Item *xitem, ref<PgfLParam> value, ref<PgfLParam> lin_idx); void td_predict(State *state, Cont *cont, Production *prod, Item *xitem, ref<PgfSymbolCat> symcat);
void combine(State *state, Item *item, CCat *ccat); void combine(State *state, Item *item, CCat *ccat);
void get_info(CCat *ccat, ref<PgfConcrRule> *rule, size_t **pvalues); void get_info(CCat *ccat, ref<PgfConcrRule> *rule, size_t **pvalues);
static static
void print_item(Item *item, const PgfTextSpot &spot); void print_item(Item *item, State *state);
static static
void print_prod(CCat *ccat, Production *prod); void print_prod(CCat *ccat, Production *prod);
@@ -245,12 +271,13 @@ class PGF_INTERNAL_DECL PgfParser : private PgfAbstractParser, public PgfExprEnu
bool case_sensitive; bool case_sensitive;
virtual State *new_state(const PgfTextSpot &start); virtual State *new_state(const PgfTextSpot &start);
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym); virtual void symbol_token(Item *item, State *state, PgfSymbol sym);
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym); virtual void symbol_bind(Item *item, State *state, PgfSymbol sym);
virtual void suspend(Cont *cont,Item *item,size_t n_suspended); virtual void suspend(Cont *cont,Item *item,size_t n_suspended1,size_t n_suspended);
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx); virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
virtual void bu_predict(State *state, CCat *ccat); virtual void bu_predict(State *state, CCat *ccat);
void bu_predict(PgfPhrasetable phrasetable, State *state);
void bu_predict(PgfPhrasetable phrasetable, State *state, ptrdiff_t min, ptrdiff_t max); void bu_predict(PgfPhrasetable phrasetable, State *state, ptrdiff_t min, ptrdiff_t max);
void make_chunks(State *state, std::vector<CCat*> &chunks, prob_t prob); void make_chunks(State *state, std::vector<CCat*> &chunks, prob_t prob);
PgfExpr process_expr(ExprState *estate, prob_t *prob); PgfExpr process_expr(ExprState *estate, prob_t *prob);
@@ -265,7 +292,7 @@ class PGF_INTERNAL_DECL PgfParser : private PgfAbstractParser, public PgfExprEnu
static static
void print_expr_state(PgfMarshaller *m, ExprState *estate); void print_expr_state(PgfMarshaller *m, ExprState *estate);
struct ExprStateComparator : std::less<ExprState*> { static struct ExprStateComparator : std::less<ExprState*> {
bool operator()(ExprState *estate1, ExprState *estate2) { bool operator()(ExprState *estate1, ExprState *estate2) {
return estate1->prob > estate2->prob; return estate1->prob > estate2->prob;
} }
@@ -286,9 +313,9 @@ class PGF_INTERNAL_DECL PgfParseTableMaker : private PgfAbstractParser
{ {
private: private:
virtual State *new_state(const PgfTextSpot &start); virtual State *new_state(const PgfTextSpot &start);
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym); virtual void symbol_token(Item *item, State *state, PgfSymbol sym);
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym); virtual void symbol_bind(Item *item, State *state, PgfSymbol sym);
virtual void suspend(Cont *cont, Item *item, size_t n_suspended); virtual void suspend(Cont *cont, Item *item, size_t n_suspended1, size_t n_suspended);
virtual void final_item(State *state, CCat *ccat,Item *item,interval_t value,interval_t lin_idx); virtual void final_item(State *state, CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
virtual void bu_predict(State *state, CCat *ccat); virtual void bu_predict(State *state, CCat *ccat);
@@ -298,6 +325,7 @@ private:
public: public:
PgfParseTableMaker(ref<PgfConcr> concr); PgfParseTableMaker(ref<PgfConcr> concr);
void insert_rule(ref<PgfConcrRule> rule); void insert_rule(ref<PgfConcrRule> rule);
void prepare();
PgfMetaId get_last_fid() { return last_fid; }; PgfMetaId get_last_fid() { return last_fid; };
}; };
+1
View File
@@ -1726,6 +1726,7 @@ void pgf_free_parse_table(PgfDB *db,
ref<PgfPGF> pgf = db->revision2pgf(revision); ref<PgfPGF> pgf = db->revision2pgf(revision);
ref<PgfConcr> concr = db->revision2concr(cnc_revision); ref<PgfConcr> concr = db->revision2concr(cnc_revision);
table_maker->prepare();
concr->last_fid = table_maker->get_last_fid(); concr->last_fid = table_maker->get_last_fid();
delete table_maker; delete table_maker;
} }
+4 -3
View File
@@ -1001,7 +1001,7 @@ PgfPhrasetable phrasetable_insert(PgfPhrasetable table,
PgfPhrasetable phrasetable_insert(PgfPhrasetable table, PgfPhrasetable phrasetable_insert(PgfPhrasetable table,
ref<PgfConcrLincat> lincat, ref<PgfConcrLincat> lincat,
interval_t value, interval_t lin_idx, interval_t value, interval_t lin_idx,
PgfMetaId fid, PgfMetaId fid, prob_t viterbi_prob,
ref<PgfItem> item) ref<PgfItem> item)
{ {
if (table == 0) { if (table == 0) {
@@ -1010,6 +1010,7 @@ PgfPhrasetable phrasetable_insert(PgfPhrasetable table,
symcf->value = value; symcf->value = value;
symcf->lin_idx = lin_idx; symcf->lin_idx = lin_idx;
symcf->fid = fid; symcf->fid = fid;
symcf->viterbi_prob = viterbi_prob;
PgfPhrasetable new_table = PgfPhrasetableNode::new_node(symcf.tagged(),1); PgfPhrasetable new_table = PgfPhrasetableNode::new_node(symcf.tagged(),1);
new_table->n_items = 1; new_table->n_items = 1;
new_table->items[0] = item; new_table->items[0] = item;
@@ -1019,12 +1020,12 @@ PgfPhrasetable phrasetable_insert(PgfPhrasetable table,
int cmp = symbol_cmp(lincat,value,lin_idx,table->sym); int cmp = symbol_cmp(lincat,value,lin_idx,table->sym);
if (cmp < 0) { if (cmp < 0) {
PgfPhrasetable left = phrasetable_insert(table->left, PgfPhrasetable left = phrasetable_insert(table->left,
lincat, value, lin_idx, fid, item); lincat, value, lin_idx, fid, viterbi_prob, item);
table = PgfPhrasetableNode::upd_node(table,left,table->right); table = PgfPhrasetableNode::upd_node(table,left,table->right);
return PgfPhrasetableNode::balanceL(table); return PgfPhrasetableNode::balanceL(table);
} else if (cmp > 0) { } else if (cmp > 0) {
PgfPhrasetable right = phrasetable_insert(table->right, PgfPhrasetable right = phrasetable_insert(table->right,
lincat, value, lin_idx, fid, item); lincat, value, lin_idx, fid, viterbi_prob, item);
table = PgfPhrasetableNode::upd_node(table, table->left, right); table = PgfPhrasetableNode::upd_node(table, table->left, right);
return PgfPhrasetableNode::balanceR(table); return PgfPhrasetableNode::balanceR(table);
} else { } else {
+1 -1
View File
@@ -91,7 +91,7 @@ PgfPhrasetable phrasetable_insert(PgfPhrasetable table,
PgfPhrasetable phrasetable_insert(PgfPhrasetable table, PgfPhrasetable phrasetable_insert(PgfPhrasetable table,
ref<PgfConcrLincat> lincat, ref<PgfConcrLincat> lincat,
interval_t value, interval_t lin_idx, interval_t value, interval_t lin_idx,
PgfMetaId fid, PgfMetaId fid, prob_t viterbi_prob,
ref<PgfItem> item); ref<PgfItem> item);
PGF_INTERNAL_DECL PGF_INTERNAL_DECL
+2
View File
@@ -712,6 +712,8 @@ ref<PgfConcr> PgfReader::read_concrete()
auto lins = read_namespace<PgfConcrLin>(&PgfReader::read_lin); auto lins = read_namespace<PgfConcrLin>(&PgfReader::read_lin);
concrete->lins = lins; concrete->lins = lins;
tm.prepare();
concrete->last_fid = tm.get_last_fid(); concrete->last_fid = tm.get_last_fid();
this->table_maker = NULL; this->table_maker = NULL;