use overlapping intervals to detect unifiable terms

This commit is contained in:
Krasimir Angelov
2026-05-11 15:41:02 +02:00
parent 8340386033
commit c37e7b5a7a
3 changed files with 182 additions and 73 deletions
+115 -8
View File
@@ -41,13 +41,13 @@ class PGF_INTERNAL_DECL interval_map {
}
int cmp;
if (node->start < start)
if (start < node->start)
cmp = -1;
else if (node->start > start)
else if (start > node->start)
cmp = 1;
else if (node->end < end)
else if (end < node->end)
cmp = -1;
else if (node->end > end)
else if (end > node->end)
cmp = 1;
else
cmp = 0;
@@ -74,13 +74,13 @@ class PGF_INTERNAL_DECL interval_map {
}
int cmp;
if (node->start < start)
if (start < node->start)
cmp = -1;
else if (node->start > start)
else if (start > node->start)
cmp = 1;
else if (node->end < end)
else if (end < node->end)
cmp = -1;
else if (node->end > end)
else if (end > node->end)
cmp = 1;
else
cmp = 0;
@@ -383,6 +383,113 @@ public:
iterator end() const {
return iterator();
}
class Overlaps {
Node *root;
interval_t i;
public:
class iterator {
struct Parent {
Node *node;
Parent *next;
};
Parent *spine;
size_t start, end;
public:
iterator() {
spine = NULL;
}
iterator(Node *node, size_t start, size_t end) {
this->start = start;
this->end = end;
spine = NULL;
for (;;) {
Parent *parent;
while (node != NULL && start <= node->max) {
parent = new Parent;
parent->node = node;
parent->next = spine;
spine = parent;
node = node->left;
}
if (spine == NULL || (start <= spine->node->end && end >= spine->node->start))
return;
parent = spine->next;
node = spine->node->right;
delete spine;
spine = parent;
}
}
bool operator ==(const iterator other) const {
return this->spine == other.spine;
}
bool operator !=(const iterator other) const {
return this->spine != other.spine;
}
std::pair<interval_t,V&> operator *() const {
return std::pair<interval_t,V&>
(interval_t(spine->node->start,spine->node->end)
,spine->node->value
);
}
void operator ++() {
for (;;) {
Parent *parent = spine->next;
Node *node = spine->node->right;
delete spine;
spine = parent;
while (node != NULL && start <= node->max) {
parent = new Parent;
parent->node = node;
parent->next = spine;
spine = parent;
node = node->left;
}
if (spine == NULL || (start <= spine->node->end && end >= spine->node->start))
return;
}
}
~iterator() {
while (spine != NULL) {
Parent *parent = spine->next;
delete spine;
spine = parent;
}
}
};
Overlaps(Node *root, interval_t i) {
this->root = root;
this->i = i;
}
iterator begin() const {
return iterator(root,i.first,i.second);
}
iterator end() const {
return iterator();
}
};
Overlaps overlaps(interval_t interval)
{
return Overlaps(this->root, interval);
}
};
#endif
+61 -59
View File
@@ -43,8 +43,12 @@ PgfAbstractParser::CCat::~CCat()
PgfAbstractParser::Cont::~Cont()
{
for (Item *item : suspended) {
delete item;
for (auto it1 : suspended) {
for (auto it2 : it1.second) {
for (Item *item : it2.second) {
delete item;
}
}
}
}
@@ -62,10 +66,8 @@ PgfAbstractParser::~PgfAbstractParser()
for (auto it : state->conts1) {
delete it.second;
}
for (auto it1 : state->conts2) {
for (auto it2 : it1.second) {
delete it2.second;
}
for (auto it : state->conts2) {
delete it.second;
}
State *next = state->next;
@@ -123,12 +125,23 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
}
if (lincat != 0) {
suspend(state,lincat,item);
Cont *&cont = state->conts1[lincat];
if (cont == NULL) {
cont = new Cont;
cont->ccat = NULL;
cont->lincat = lincat;
cont->state = state;
}
interval_t value_i = item->interval(item->rule->args[symcat->d]);
interval_t lin_idx_i = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
auto &suspended = cont->suspended[value_i][lin_idx_i];
suspended.push_back(item);
suspend(cont,item,suspended.size());
}
} else {
interval_t lin_idx = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
Cont *&cont = state->conts2[ccat][lin_idx];
Cont *&cont = state->conts2[ccat];
if (cont == NULL) {
cont = new Cont;
cont->ccat = ccat;
@@ -139,9 +152,12 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
cont->state = state;
}
cont->suspended.push_back(item);
interval_t value_i = item->interval(item->rule->args[symcat->d]);
interval_t lin_idx_i = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
auto &suspended = cont->suspended[value_i][lin_idx_i];
suspended.push_back(item);
if (cont->suspended.size() == 1) {
if (suspended.size() == 1) {
if (ccat->fid <= initial_fid) {
size_t n_items = 0;
vector<ref<PgfItem>> items =
@@ -163,7 +179,7 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
if (it1 != next->completed.end()) {
auto *it2 = it1->second.lookup(ccat->value);
if (it2 != NULL) {
auto *it3 = it2->lookup(lin_idx);
auto *it3 = it2->lookup(lin_idx_i);
if (it3 != NULL) {
CCat *arg = *it3;
Item *new_item = new (item) Item;
@@ -292,21 +308,27 @@ void PgfAbstractParser::complete(Item *item, const PgfTextSpot &spot, bool bind)
if (ccat->prods.size() == 1) {
if (ccat->cont->ccat == NULL)
bu_predict(state, ccat);
size_t n_items = ccat->cont->suspended.size();
for (size_t i = 0; i < n_items; i++) {
Item *new_item = new (ccat->cont->suspended[i]) Item;
combine(state,new_item,ccat);
};
for (auto it1 : ccat->cont->suspended.overlaps(ccat->value)) {
for (auto it2 : it1.second.overlaps(ccat->lin_idx)) {
size_t n_items = it2.second.size();
for (size_t i = 0; i < n_items; i++) {
Item *new_item = new (it2.second[i]) Item;
combine(state,new_item,ccat);
};
}
}
} else {
State *next = state;
while (next != NULL) {
for (auto it : next->conts2[ccat]) {
interval_t lin_idx = it.first;
Cont *cont = it.second;
if (cont != NULL) {
Item *item = cont->suspended[0];
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));
Cont *cont = next->conts2[ccat];
if (cont != NULL) {
for (auto it1 : cont->suspended) {
for (auto it2 : it1.second) {
Item *item = it2.second[0];
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));
}
}
}
next = next->next;
@@ -1267,23 +1289,13 @@ void PgfParser::symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym)
process(item, spot, true);
}
void PgfParser::suspend(State *state,ref<PgfConcrLincat> lincat,Item *item)
void PgfParser::suspend(Cont *cont,Item *item,size_t n_suspended)
{
Cont *&cont = state->conts1[lincat];
if (cont == NULL) {
cont = new Cont;
cont->ccat = NULL;
cont->lincat = lincat;
cont->state = state;
}
cont->suspended.push_back(item);
if (cont->suspended.size() == 1) {
if (n_suspended == 1) {
std::function<void(ref<PgfSymbolCCat>,size_t,vector<ref<PgfItem>>)> f =
[this,state,item,cont](ref<PgfSymbolCCat> symcf, size_t n_items, vector<ref<PgfItem>> items) {
[this,item,cont](ref<PgfSymbolCCat> symcf, size_t n_items, vector<ref<PgfItem>> items) {
PgfItem *xitem = items[0];
ref<PgfItem> xitem = items[0];
Item *new_item = new (item) Item;
PgfSymbol sym = new_item->rule->syms[new_item->dot];
@@ -1308,21 +1320,21 @@ void PgfParser::suspend(State *state,ref<PgfConcrLincat> lincat,Item *item)
arg_ccat->covered = true;
}
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->args[sym_cat->d] = arg_ccat;
process(new_item, state->start, false);
process(new_item, cont->state->start, false);
};
phrasetable_iter(concr->phrasetable,lincat,f);
phrasetable_iter(concr->phrasetable,cont->lincat,f);
} else {
auto it1 = state->completed.find(cont);
if (it1 != state->completed.end()) {
auto it1 = cont->state->completed.find(cont);
if (it1 != cont->state->completed.end()) {
for (auto it2 : it1->second) {
for (auto it3 : it2.second) {
Item *new_item = new (item) Item;
combine(state, new_item, it3.second);
combine(cont->state, new_item, it3.second);
}
}
}
@@ -1452,30 +1464,20 @@ void PgfParseTableMaker::symbol_bind(Item *item, const PgfTextSpot &spot, PgfSym
delete item;
}
void PgfParseTableMaker::suspend(State *state,ref<PgfConcrLincat> lincat,Item *item)
void PgfParseTableMaker::suspend(Cont *cont,Item *item,size_t n_suspended)
{
Cont *&cont = state->conts1[lincat];
if (cont == NULL) {
cont = new Cont;
cont->ccat = NULL;
cont->lincat = lincat;
cont->state = state;
}
cont->suspended.push_back(item);
for (auto it1 : state->completed[cont]) {
for (auto it1 : cont->state->completed[cont]) {
for (auto it2 : it1.second) {
CCat *ccat = it2.second;
if (ccat != NULL) {
Item *new_item = new (item) Item;
combine(state,new_item,ccat);
combine(cont->state,new_item,ccat);
}
}
}
auto pitem = clone_item(item);
auto acat = ref<PgfSymbolACat>::from_ptr((PgfSymbolACat*) &lincat->name);
auto acat = ref<PgfSymbolACat>::from_ptr((PgfSymbolACat*) &cont->lincat->name);
auto phrasetable = phrasetable_insert(concr->phrasetable,acat.tagged(),pitem);
concr->phrasetable = phrasetable;
}
+6 -6
View File
@@ -101,7 +101,7 @@ protected:
PgfTextSpot start, end;
bool needs_bind;
std::map<ref<PgfConcrLincat>,Cont*> conts1;
std::map<CCat*,interval_map<Cont*>> conts2;
std::map<CCat*,Cont*> conts2;
std::map<Cont*,interval_map<interval_map<CCat*>>> completed;
State *next;
@@ -111,7 +111,7 @@ protected:
CCat *ccat;
ref<PgfConcrLincat> lincat;
State *state;
std::vector<Item*> suspended;
interval_map<interval_map<std::vector<Item*>>> suspended;
~Cont();
};
@@ -215,7 +215,7 @@ protected:
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_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym)=0;
virtual void suspend(State *state,ref<PgfConcrLincat> lincat, Item *item)=0;
virtual void suspend(Cont *cont, Item *item, 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 bu_predict(State *state, CCat *ccat)=0;
@@ -247,7 +247,7 @@ class PGF_INTERNAL_DECL PgfParser : private PgfAbstractParser, public PgfExprEnu
virtual State *new_state(const PgfTextSpot &start);
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym);
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym);
virtual void suspend(State *state,ref<PgfConcrLincat> lincat, Item *item);
virtual void suspend(Cont *cont,Item *item,size_t n_suspended);
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);
@@ -288,8 +288,8 @@ private:
virtual State *new_state(const PgfTextSpot &start);
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym);
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym);
virtual void suspend(State *state,ref<PgfConcrLincat> lincat,Item *item);
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
virtual void suspend(Cont *cont, Item *item, size_t n_suspended);
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);
static