From c37e7b5a7aaf432115e05a3b2714b6cb85227fcf Mon Sep 17 00:00:00 2001 From: Krasimir Angelov Date: Mon, 11 May 2026 15:41:02 +0200 Subject: [PATCH] use overlapping intervals to detect unifiable terms --- src/runtime/c/pgf/intervalmap.h | 123 +++++++++++++++++++++++++++++--- src/runtime/c/pgf/parser.cxx | 120 ++++++++++++++++--------------- src/runtime/c/pgf/parser.h | 12 ++-- 3 files changed, 182 insertions(+), 73 deletions(-) diff --git a/src/runtime/c/pgf/intervalmap.h b/src/runtime/c/pgf/intervalmap.h index aff038ed5..e78b139f6 100644 --- a/src/runtime/c/pgf/intervalmap.h +++ b/src/runtime/c/pgf/intervalmap.h @@ -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 operator *() const { + return std::pair + (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 diff --git a/src/runtime/c/pgf/parser.cxx b/src/runtime/c/pgf/parser.cxx index 56972bbf9..a68a7ae4b 100644 --- a/src/runtime/c/pgf/parser.cxx +++ b/src/runtime/c/pgf/parser.cxx @@ -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::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::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::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> 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::untagged(item->syms[item->dot]); - td_predict(next,cont,prod,item,item->rule->args[symcat->d],ref::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::untagged(item->syms[item->dot]); + td_predict(next,cont,prod,item,item->rule->args[symcat->d],ref::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 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,size_t,vector>)> f = - [this,state,item,cont](ref symcf, size_t n_items, vector> items) { + [this,item,cont](ref symcf, size_t n_items, vector> items) { - PgfItem *xitem = items[0]; + ref 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 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 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::from_ptr((PgfSymbolACat*) &lincat->name); + auto acat = ref::from_ptr((PgfSymbolACat*) &cont->lincat->name); auto phrasetable = phrasetable_insert(concr->phrasetable,acat.tagged(),pitem); concr->phrasetable = phrasetable; } diff --git a/src/runtime/c/pgf/parser.h b/src/runtime/c/pgf/parser.h index d735e57c3..5033a5298 100644 --- a/src/runtime/c/pgf/parser.h +++ b/src/runtime/c/pgf/parser.h @@ -101,7 +101,7 @@ protected: PgfTextSpot start, end; bool needs_bind; std::map,Cont*> conts1; - std::map> conts2; + std::map conts2; std::map>> completed; State *next; @@ -111,7 +111,7 @@ protected: CCat *ccat; ref lincat; State *state; - std::vector suspended; + interval_map>> 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 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 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 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