diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index 45685c82d..64009ee72 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -119,7 +119,6 @@ typedef struct { PgfFlags* aflags; PgfAbsFuns* funs; PgfAbsCats* cats; - PgfAbsFun* abs_lin_fun; PgfEvalGates* eval_gates; } PgfAbstr; @@ -262,8 +261,8 @@ typedef struct { typedef GuSeq PgfSequences; typedef struct { - PgfAbsFun* absfun; - PgfExprProb *ep; + GuSeq* absfuns; + prob_t prob; int funid; size_t n_lins; PgfSequence* lins[]; diff --git a/src/runtime/c/pgf/linearizer.c b/src/runtime/c/pgf/linearizer.c index 12b047b13..187f52525 100644 --- a/src/runtime/c/pgf/linearizer.c +++ b/src/runtime/c/pgf/linearizer.c @@ -40,15 +40,23 @@ pgf_lzr_index(PgfConcr* concr, switch (gu_variant_tag(prod)) { case PGF_PRODUCTION_APPLY: { PgfProductionApply* papply = data; - PgfCncOverloadMap* overl_table = - gu_map_get(concr->fun_indices, papply->fun->absfun->name, - PgfCncOverloadMap*); - if (!overl_table) { - overl_table = gu_new_addr_map(PgfCCat*, GuBuf*, &gu_null_struct, pool); - gu_map_put(concr->fun_indices, - papply->fun->absfun->name, PgfCncOverloadMap*, overl_table); + + size_t n_absfuns = gu_seq_length(papply->fun->absfuns); + for (size_t i = 0; i < n_absfuns; i++) { + PgfAbsFun* absfun = + gu_seq_get(papply->fun->absfuns, PgfAbsFun*, i); + + PgfCncOverloadMap* overl_table = + gu_map_get(concr->fun_indices, absfun->name, + PgfCncOverloadMap*); + if (!overl_table) { + overl_table = gu_new_addr_map(PgfCCat*, GuBuf*, &gu_null_struct, pool); + gu_map_put(concr->fun_indices, + absfun->name, + PgfCncOverloadMap*, overl_table); + } + pgf_lzr_add_overl_entry(overl_table, ccat, papply, pool); } - pgf_lzr_add_overl_entry(overl_table, ccat, papply, pool); break; } case PGF_PRODUCTION_COERCE: { @@ -148,7 +156,7 @@ pgf_cnc_resolve(PgfCnc* cnc, static PgfCncTree pgf_cnc_resolve_app(PgfCnc* cnc, size_t n_vars, PgfPrintContext* context, - PgfCCat* ccat, GuBuf* buf, GuBuf* args, + PgfCCat* ccat, PgfCId abs_id, GuBuf* buf, GuBuf* args, GuPool* pool) { GuChoiceMark mark = gu_choice_mark(cnc->ch); @@ -164,6 +172,7 @@ pgf_cnc_resolve_app(PgfCnc* cnc, capp->ccat = ccat; capp->n_vars = n_vars; capp->context = context; + capp->abs_id = abs_id; redo:; int index = gu_choice_next(cnc->ch, gu_buf_length(buf)); @@ -175,7 +184,6 @@ redo:; gu_buf_get(buf, PgfProductionApply*, index); gu_assert(n_args == gu_seq_length(papply->args)); - capp->abs_id = papply->fun->absfun->name; capp->fun = papply->fun; capp->fid = 0; capp->n_args = n_args; @@ -470,7 +478,7 @@ redo:; gu_map_iter(overl_table, &clo.fn, NULL); assert(clo.ccat != NULL && clo.buf != NULL); - ret = pgf_cnc_resolve_app(cnc, n_vars, context, clo.ccat, clo.buf, args, pool); + ret = pgf_cnc_resolve_app(cnc, n_vars, context, clo.ccat, efun->fun, clo.buf, args, pool); if (gu_variant_is_null(ret)) { gu_choice_reset(cnc->ch, mark); if (gu_choice_advance(cnc->ch)) @@ -483,7 +491,7 @@ redo:; goto done; } - ret = pgf_cnc_resolve_app(cnc, n_vars, context, ccat, buf, args, pool); + ret = pgf_cnc_resolve_app(cnc, n_vars, context, ccat, efun->fun, buf, args, pool); } goto done; } diff --git a/src/runtime/c/pgf/lookup.c b/src/runtime/c/pgf/lookup.c index 5918275c1..fe55733fd 100644 --- a/src/runtime/c/pgf/lookup.c +++ b/src/runtime/c/pgf/lookup.c @@ -803,7 +803,12 @@ pgf_lookup_ctree_to_expr(PgfCncTree ctree, PgfExprProb* ep, switch (cti.tag) { case PGF_CNC_TREE_APP: { PgfCncTreeApp* fapp = cti.data; - *ep = fapp->fun->absfun->ep; + if (gu_seq_length(fapp->fun->absfuns) > 0) + *ep = gu_seq_get(fapp->fun->absfuns, PgfAbsFun*, 0)->ep; + else { + ep->expr = gu_null_variant; + ep->prob = fapp->fun->prob; + } n_args = fapp->n_args; args = fapp->args; break; @@ -923,8 +928,15 @@ pgf_lookup_sentence(PgfConcr* concr, PgfType* typ, GuString sentence, GuPool* po size_t n_cncfuns = gu_seq_length(concr->cncfuns); for (size_t i = 0; i < n_cncfuns; i++) { PgfCncFun* cncfun = gu_seq_get(concr->cncfuns, PgfCncFun*, i); - for (size_t lin_idx = 0; lin_idx < cncfun->n_lins; lin_idx++) { - pgf_lookup_index_syms(lexicon_idx, cncfun->lins[lin_idx]->syms, cncfun->absfun, pool); + + size_t n_absfuns = gu_seq_length(cncfun->absfuns); + for (size_t j = 0; j < n_absfuns; j++) { + PgfAbsFun* absfun = + gu_seq_get(cncfun->absfuns, PgfAbsFun*, j); + + for (size_t lin_idx = 0; lin_idx < cncfun->n_lins; lin_idx++) { + pgf_lookup_index_syms(lexicon_idx, cncfun->lins[lin_idx]->syms, absfun, pool); + } } } diff --git a/src/runtime/c/pgf/parser.c b/src/runtime/c/pgf/parser.c index cb59b2a55..7370e00c6 100644 --- a/src/runtime/c/pgf/parser.c +++ b/src/runtime/c/pgf/parser.c @@ -710,8 +710,8 @@ pgf_new_item(PgfParsing* ps, PgfItemConts* conts, PgfProduction prod) case PGF_PRODUCTION_APPLY: { PgfProductionApply* papp = pi.data; item->args = papp->args; - item->inside_prob = papp->fun->ep->prob; - + item->inside_prob = papp->fun->prob; + int n_args = gu_seq_length(item->args); for (int i = 0; i < n_args; i++) { PgfPArg *arg = gu_seq_index(item->args, PgfPArg, i); @@ -1265,8 +1265,12 @@ pgf_parsing_add_transition(PgfParsing* ps, PgfToken tok, PgfItem* item) ps->tp = gu_new(PgfTokenProb, ps->out_pool); ps->tp->tok = tok; ps->tp->cat = item->conts->ccat->cnccat->abscat->name; - ps->tp->fun = papp->fun->absfun->name; ps->tp->prob = item->inside_prob + item->conts->outside_prob; + ps->tp->fun = "_"; + + if (gu_seq_length(papp->fun->absfuns) > 0) + ps->tp->fun = + gu_seq_get(papp->fun->absfuns, PgfAbsFun*, 0)->name; } } else { if (!ps->before->needs_bind && cmp_string(¤t, tok, ps->case_sensitive) == 0) { @@ -1794,19 +1798,25 @@ pgf_result_production(PgfParsing* ps, case PGF_PRODUCTION_APPLY: { PgfProductionApply* papp = pi.data; - PgfExprState *st = gu_new(PgfExprState, ps->pool); - st->answers = answers; - st->ep = *papp->fun->ep; - st->args = papp->args; - st->arg_idx = 0; + size_t n_absfuns = gu_seq_length(papp->fun->absfuns); + for (size_t i = 0; i < n_absfuns; i++) { + PgfAbsFun* absfun = + gu_seq_get(papp->fun->absfuns, PgfAbsFun*, i); - size_t n_args = gu_seq_length(st->args); - for (size_t k = 0; k < n_args; k++) { - PgfPArg* parg = gu_seq_index(st->args, PgfPArg, k); - st->ep.prob += parg->ccat->viterbi_prob; + PgfExprState *st = gu_new(PgfExprState, ps->pool); + st->answers = answers; + st->ep = absfun->ep; + st->args = papp->args; + st->arg_idx = 0; + + size_t n_args = gu_seq_length(st->args); + for (size_t k = 0; k < n_args; k++) { + PgfPArg* parg = gu_seq_index(st->args, PgfPArg, k); + st->ep.prob += parg->ccat->viterbi_prob; + } + + gu_buf_heap_push(ps->expr_queue, &pgf_expr_state_order, &st); } - - gu_buf_heap_push(ps->expr_queue, &pgf_expr_state_order, &st); break; } case PGF_PRODUCTION_COERCE: { @@ -2355,15 +2365,20 @@ pgf_morpho_iter(PgfProductionIdx* idx, PgfProductionIdxEntry* entry = gu_buf_index(idx, PgfProductionIdxEntry, i); - PgfCId lemma = entry->papp->fun->absfun->name; - GuString analysis = entry->ccat->cnccat->labels[entry->lin_idx]; - - prob_t prob = entry->ccat->cnccat->abscat->prob + - entry->papp->fun->absfun->ep.prob; - callback->callback(callback, - lemma, analysis, prob, err); - if (!gu_ok(err)) - return; + size_t n_absfuns = gu_seq_length(entry->papp->fun->absfuns); + for (size_t j = 0; j < n_absfuns; j++) { + PgfAbsFun* absfun = + gu_seq_get(entry->papp->fun->absfuns, PgfAbsFun*, j); + PgfCId lemma = absfun->name; + GuString analysis = entry->ccat->cnccat->labels[entry->lin_idx]; + + prob_t prob = entry->ccat->cnccat->abscat->prob + + absfun->ep.prob; + callback->callback(callback, + lemma, analysis, prob, err); + if (!gu_ok(err)) + return; + } } } @@ -2569,7 +2584,7 @@ pgf_ccat_set_viterbi_prob(PgfCCat* ccat) { return INFINITY; prob_t viterbi_prob = INFINITY; - + size_t n_prods = gu_seq_length(ccat->prods); for (size_t i = 0; i < n_prods; i++) { PgfProduction prod = @@ -2581,7 +2596,7 @@ pgf_ccat_set_viterbi_prob(PgfCCat* ccat) { switch (inf.tag) { case PGF_PRODUCTION_APPLY: { PgfProductionApply* papp = inf.data; - prob = papp->fun->ep->prob; + prob = papp->fun->prob; size_t n_args = gu_seq_length(papp->args); for (size_t j = 0; j < n_args; j++) { diff --git a/src/runtime/c/pgf/printer.c b/src/runtime/c/pgf/printer.c index 153130b54..29f8eb29e 100644 --- a/src/runtime/c/pgf/printer.c +++ b/src/runtime/c/pgf/printer.c @@ -206,15 +206,17 @@ pgf_print_cncfun(PgfCncFun *cncfun, PgfSequences* sequences, gu_printf(out,err,"S%d", (seq - ((PgfSequence*) gu_seq_data(sequences)))); } - gu_puts(")", out, err); - - if (cncfun->absfun != NULL) { - gu_puts(" [", out, err); - pgf_print_cid(cncfun->absfun->name, out, err); - gu_puts("]", out, err); + gu_puts(") [", out, err); + + size_t n_absfuns = gu_seq_length(cncfun->absfuns); + for (size_t i = 0; i < n_absfuns; i++) { + PgfAbsFun* absfun = + gu_seq_get(cncfun->absfuns, PgfAbsFun*, i); + + pgf_print_cid(absfun->name, out, err); } - - gu_puts("\n", out, err); + + gu_puts("]\n", out, err); } static void diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c index d7094c9d5..c97b52125 100644 --- a/src/runtime/c/pgf/reader.c +++ b/src/runtime/c/pgf/reader.c @@ -549,17 +549,6 @@ pgf_read_abstract(PgfReader* rdr, PgfAbstr* abstract) abstract->cats = pgf_read_abscats(rdr, abstract); gu_return_on_exn(rdr->err, ); - - abstract->abs_lin_fun = gu_new(PgfAbsFun, rdr->opool); - abstract->abs_lin_fun->name = "_"; - abstract->abs_lin_fun->type = gu_new(PgfType, rdr->opool); - abstract->abs_lin_fun->type->hypos = NULL; - abstract->abs_lin_fun->type->cid = "_"; - abstract->abs_lin_fun->type->n_exprs = 0; - abstract->abs_lin_fun->arity = 0; - abstract->abs_lin_fun->defns = NULL; - abstract->abs_lin_fun->ep.prob = INFINITY; - abstract->abs_lin_fun->ep.expr = gu_null_variant; } static PgfCIdMap* @@ -776,22 +765,38 @@ pgf_read_sequences(PgfReader* rdr) static PgfCncFun* pgf_read_cncfun(PgfReader* rdr, PgfAbstr* abstr, PgfConcr* concr, int funid) { - PgfCId name = pgf_read_cid(rdr, rdr->tmp_pool); + size_t n_absfuns = pgf_read_len(rdr); + GuSeq* absfuns = + gu_new_seq(PgfAbsFun*, n_absfuns, rdr->opool); + prob_t prob; + if (n_absfuns == 0) + prob = 0; + else { + prob = INFINITY; + for (size_t i = 0; i < n_absfuns; i++) { + PgfCId name = pgf_read_cid(rdr, rdr->tmp_pool); + gu_return_on_exn(rdr->err, NULL); + + PgfAbsFun* absfun = + gu_seq_binsearch(abstr->funs, pgf_absfun_order, PgfAbsFun, name); + + if (prob > absfun->ep.prob) + prob = absfun->ep.prob; + + gu_seq_set(absfuns, PgfAbsFun*, i, absfun); + } + } + + size_t n_lins = pgf_read_len(rdr); gu_return_on_exn(rdr->err, NULL); - size_t len = pgf_read_len(rdr); - gu_return_on_exn(rdr->err, NULL); - - PgfAbsFun* absfun = - gu_seq_binsearch(abstr->funs, pgf_absfun_order, PgfAbsFun, name); - - PgfCncFun* cncfun = gu_new_flex(rdr->opool, PgfCncFun, lins, len); - cncfun->absfun = absfun; - cncfun->ep = (absfun == NULL) ? NULL : &absfun->ep; + PgfCncFun* cncfun = gu_new_flex(rdr->opool, PgfCncFun, lins, n_lins); + cncfun->absfuns = absfuns; + cncfun->prob = prob; cncfun->funid = funid; - cncfun->n_lins = len; + cncfun->n_lins = n_lins; - for (size_t i = 0; i < len; i++) { + for (size_t i = 0; i < n_lins; i++) { size_t seqid = pgf_read_int(rdr); gu_return_on_exn(rdr->err, NULL); @@ -878,7 +883,6 @@ pgf_read_lindefs(PgfReader* rdr, PgfConcr* concr) ccat->lindefs = gu_new_seq(PgfCncFun*, n_funs, rdr->opool); for (size_t j = 0; j < n_funs; j++) { PgfCncFun* fun = pgf_read_funid(rdr, concr); - fun->absfun = concr->abstr->abs_lin_fun; gu_seq_set(ccat->lindefs, PgfCncFun*, j, fun); } } @@ -899,7 +903,6 @@ pgf_read_linrefs(PgfReader* rdr, PgfConcr* concr) ccat->linrefs = gu_new_seq(PgfCncFun*, n_funs, rdr->opool); for (size_t j = 0; j < n_funs; j++) { PgfCncFun* fun = pgf_read_funid(rdr, concr); - fun->absfun = concr->abstr->abs_lin_fun; gu_seq_set(ccat->linrefs, PgfCncFun*, j, fun); } } diff --git a/src/runtime/c/pgf/writer.c b/src/runtime/c/pgf/writer.c index 57c7e3c76..865d27826 100644 --- a/src/runtime/c/pgf/writer.c +++ b/src/runtime/c/pgf/writer.c @@ -579,8 +579,15 @@ pgf_write_sequences(PgfSequences* seqs, PgfWriter* wtr) static void pgf_write_cncfun(PgfCncFun* cncfun, PgfConcr* concr, PgfWriter* wtr) { - pgf_write_cid(cncfun->absfun->name, wtr); - gu_return_on_exn(wtr->err, ); + size_t n_absfuns = gu_seq_length(cncfun->absfuns); + pgf_write_len(n_absfuns, wtr); + for (size_t i = 0; i < n_absfuns; i++) { + PgfAbsFun* absfun = + gu_seq_get(cncfun->absfuns, PgfAbsFun*, i); + + pgf_write_cid(absfun->name, wtr); + gu_return_on_exn(wtr->err, ); + } pgf_write_len(cncfun->n_lins, wtr); gu_return_on_exn(wtr->err, ); diff --git a/src/runtime/c/sg/sg.c b/src/runtime/c/sg/sg.c index bcb97f55e..72a67eb8e 100644 --- a/src/runtime/c/sg/sg.c +++ b/src/runtime/c/sg/sg.c @@ -1305,20 +1305,26 @@ sg_update_fts_index(SgSG* sg, PgfPGF* pgf, GuExn* err) for (size_t funid = 0; funid < n_funs; funid++) { PgfCncFun* cncfun = gu_seq_get(concr->cncfuns, PgfCncFun*, funid); - SgId key = 0; - rc = find_function_rowid(sg, &ctxt, cncfun->absfun->name, &key, 1); - if (rc != SQLITE_OK) { - sg_raise_sqlite(rc, err); - goto close; - } + size_t n_absfuns = gu_seq_length(cncfun->absfuns); + for (size_t i = 0; i < n_absfuns; i++) { + PgfAbsFun* absfun = + gu_seq_get(cncfun->absfuns, PgfAbsFun*, i); - for (size_t lin_idx = 0; lin_idx < cncfun->n_lins; lin_idx++) { - PgfSequence* seq = cncfun->lins[lin_idx]; - rc = insert_syms(sg, crsTokens, seq->syms, key); + SgId key = 0; + rc = find_function_rowid(sg, &ctxt, absfun->name, &key, 1); if (rc != SQLITE_OK) { sg_raise_sqlite(rc, err); goto close; } + + for (size_t lin_idx = 0; lin_idx < cncfun->n_lins; lin_idx++) { + PgfSequence* seq = cncfun->lins[lin_idx]; + rc = insert_syms(sg, crsTokens, seq->syms, key); + if (rc != SQLITE_OK) { + sg_raise_sqlite(rc, err); + goto close; + } + } } } }