forked from GitHub/gf-core
a new reasoner in the C runtime. It supports tabling which makes it decideable for propositional logic. dependent types and high-order types are not supported yet. The generation is still in decreasing probability order
This commit is contained in:
@@ -181,11 +181,6 @@ GU_DEFINE_TYPE(
|
|||||||
GU_MEMBER(PgfFunDecl, defns, PgfEquationsM),
|
GU_MEMBER(PgfFunDecl, defns, PgfEquationsM),
|
||||||
GU_MEMBER(PgfFunDecl, ep, PgfExprProb));
|
GU_MEMBER(PgfFunDecl, ep, PgfExprProb));
|
||||||
|
|
||||||
GU_DEFINE_TYPE(
|
|
||||||
PgfCatFun, struct,
|
|
||||||
GU_MEMBER(PgfCatFun, prob, double),
|
|
||||||
GU_MEMBER(PgfCatFun, fun, PgfCId));
|
|
||||||
|
|
||||||
static prob_t inf_prob = INFINITY;
|
static prob_t inf_prob = INFINITY;
|
||||||
|
|
||||||
GU_DEFINE_TYPE(prob_t, GuFloating, _);
|
GU_DEFINE_TYPE(prob_t, GuFloating, _);
|
||||||
@@ -196,9 +191,7 @@ GU_DEFINE_TYPE(PgfMetaChildMap, GuMap,
|
|||||||
|
|
||||||
GU_DEFINE_TYPE(
|
GU_DEFINE_TYPE(
|
||||||
PgfCat, struct,
|
PgfCat, struct,
|
||||||
GU_MEMBER(PgfCat, context, PgfHypos),
|
GU_MEMBER(PgfCat, context, PgfHypos));
|
||||||
GU_MEMBER(PgfCat, n_functions, GuLength),
|
|
||||||
GU_FLEX_MEMBER(PgfCat, functions, PgfCatFun));
|
|
||||||
|
|
||||||
|
|
||||||
GU_DEFINE_TYPE(
|
GU_DEFINE_TYPE(
|
||||||
|
|||||||
@@ -131,11 +131,6 @@ struct PgfFunDecl {
|
|||||||
|
|
||||||
extern GU_DECLARE_TYPE(PgfFunDecl, struct);
|
extern GU_DECLARE_TYPE(PgfFunDecl, struct);
|
||||||
|
|
||||||
struct PgfCatFun {
|
|
||||||
double prob;
|
|
||||||
PgfCId fun;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef GuMap PgfMetaChildMap;
|
typedef GuMap PgfMetaChildMap;
|
||||||
extern GU_DECLARE_TYPE(PgfMetaChildMap, GuMap);
|
extern GU_DECLARE_TYPE(PgfMetaChildMap, GuMap);
|
||||||
|
|
||||||
@@ -147,8 +142,7 @@ struct PgfCat {
|
|||||||
prob_t meta_token_prob;
|
prob_t meta_token_prob;
|
||||||
PgfMetaChildMap* meta_child_probs;
|
PgfMetaChildMap* meta_child_probs;
|
||||||
|
|
||||||
GuLength n_functions;
|
GuBuf* functions; // -->PgfFunDecl
|
||||||
PgfCatFun functions[]; // XXX: resolve to PgfFunDecl*?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -155,10 +155,23 @@ pgf_iter_functions_by_cat(PgfPGF* pgf, PgfCId catname,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < abscat->n_functions; i++) {
|
size_t n_functions = gu_buf_length(abscat->functions);
|
||||||
fn->fn(fn, &abscat->functions[i].fun, NULL, err);
|
for (size_t i = 0; i < n_functions; i++) {
|
||||||
if (!gu_ok(err))
|
PgfFunDecl* fun =
|
||||||
return;
|
gu_buf_get(abscat->functions, PgfFunDecl*, i);
|
||||||
|
|
||||||
|
GuVariantInfo i = gu_variant_open(fun->ep.expr);
|
||||||
|
switch (i.tag) {
|
||||||
|
case PGF_EXPR_FUN: {
|
||||||
|
PgfExprFun* efun = i.data;
|
||||||
|
fn->fn(fn, &efun->fun, NULL, err);
|
||||||
|
if (!gu_ok(err))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
gu_impossible();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -643,29 +643,43 @@ typedef struct {
|
|||||||
PgfReader* rdr;
|
PgfReader* rdr;
|
||||||
} PgfIndexFn;
|
} PgfIndexFn;
|
||||||
|
|
||||||
static void
|
|
||||||
pgf_init_meta_probs(GuMapItor* fn, const void* key, void* value, GuExn* err)
|
|
||||||
{
|
|
||||||
(void) (err);
|
|
||||||
|
|
||||||
PgfCId name = *((PgfCId*) key);
|
|
||||||
PgfCat* cat = *((PgfCat**) value);
|
|
||||||
|
|
||||||
cat->name = name;
|
|
||||||
|
|
||||||
cat->meta_prob = INFINITY;
|
|
||||||
cat->meta_token_prob = INFINITY;
|
|
||||||
cat->meta_child_probs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgf_read_to_PgfAbstr(GuType* type, PgfReader* rdr, void* to)
|
pgf_read_to_PgfAbstr(GuType* type, PgfReader* rdr, void* to)
|
||||||
{
|
{
|
||||||
rdr->curr_abstr = to;
|
rdr->curr_abstr = to;
|
||||||
pgf_read_to_struct(type, rdr, to);
|
pgf_read_to_struct(type, rdr, to);
|
||||||
|
}
|
||||||
|
|
||||||
PgfIndexFn clo = { { pgf_init_meta_probs }, rdr };
|
static void*
|
||||||
gu_map_iter(rdr->curr_abstr->cats, &clo.fn, NULL);
|
pgf_read_new_PgfCat(GuType* type, PgfReader* rdr, GuPool* pool,
|
||||||
|
size_t* size_out)
|
||||||
|
{
|
||||||
|
(void) (type && size_out);
|
||||||
|
PgfCat* cat = gu_new(PgfCat, pool);
|
||||||
|
|
||||||
|
cat->name = *((PgfCId*) rdr->curr_key);
|
||||||
|
|
||||||
|
pgf_read_to(rdr, gu_type(PgfHypos), &cat->context);
|
||||||
|
|
||||||
|
cat->meta_prob = INFINITY;
|
||||||
|
cat->meta_token_prob = INFINITY;
|
||||||
|
cat->meta_child_probs = NULL;
|
||||||
|
|
||||||
|
cat->functions = gu_new_buf(PgfFunDecl*, rdr->opool);
|
||||||
|
|
||||||
|
size_t n_functions = pgf_read_len(rdr);
|
||||||
|
for (size_t i = 0; i < n_functions; i++) {
|
||||||
|
double prob;
|
||||||
|
PgfCId name;
|
||||||
|
pgf_read_to_double(gu_type(double), rdr, &prob);
|
||||||
|
pgf_read_to_GuString(gu_type(PgfCId), rdr, &name);
|
||||||
|
|
||||||
|
PgfFunDecl* absfun =
|
||||||
|
gu_map_get(rdr->curr_abstr->funs, &name, PgfFunDecl*);
|
||||||
|
gu_buf_push(cat->functions, PgfFunDecl*, absfun);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cat;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GU_DEFINE_TYPE(PgfLinDefs, GuIntMap, gu_ptr_type(PgfFunIds),
|
static GU_DEFINE_TYPE(PgfLinDefs, GuIntMap, gu_ptr_type(PgfFunIds),
|
||||||
@@ -880,7 +894,8 @@ pgf_read_new_table = GU_TYPETABLE(
|
|||||||
PGF_READ_NEW(PgfFunDecl),
|
PGF_READ_NEW(PgfFunDecl),
|
||||||
PGF_READ_NEW(PgfCCat),
|
PGF_READ_NEW(PgfCCat),
|
||||||
PGF_READ_NEW(PgfCncCat),
|
PGF_READ_NEW(PgfCncCat),
|
||||||
PGF_READ_NEW(PgfConcr)
|
PGF_READ_NEW(PgfConcr),
|
||||||
|
PGF_READ_NEW(PgfCat)
|
||||||
);
|
);
|
||||||
|
|
||||||
PgfReader*
|
PgfReader*
|
||||||
|
|||||||
@@ -8,23 +8,43 @@
|
|||||||
|
|
||||||
typedef struct PgfExprState PgfExprState;
|
typedef struct PgfExprState PgfExprState;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GuBuf* conts;
|
||||||
|
GuBuf* exprs;
|
||||||
|
prob_t outside_prob;
|
||||||
|
} PgfAnswers;
|
||||||
|
|
||||||
struct PgfExprState {
|
struct PgfExprState {
|
||||||
PgfExprState* cont;
|
PgfAnswers* answers;
|
||||||
PgfExpr expr;
|
PgfExprProb ep;
|
||||||
PgfHypos hypos;
|
PgfHypos hypos;
|
||||||
size_t arg_idx;
|
size_t arg_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PGF_EXPR_QSTATE_PREDICT,
|
||||||
|
PGF_EXPR_QSTATE_COMBINE1,
|
||||||
|
PGF_EXPR_QSTATE_COMBINE2
|
||||||
|
} PGF_EXPR_QSTATE_KIND;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PgfExprState *st;
|
prob_t prob;
|
||||||
prob_t cont_prob;
|
PGF_EXPR_QSTATE_KIND kind;
|
||||||
size_t fun_idx;
|
void* single;
|
||||||
PgfCat* abscat;
|
size_t choice_idx;
|
||||||
|
GuBuf* choices;
|
||||||
} PgfExprQState;
|
} PgfExprQState;
|
||||||
|
|
||||||
|
static GU_DEFINE_TYPE(PgfAnswers, abstract);
|
||||||
|
|
||||||
|
typedef GuStringMap PgfAbswersMap;
|
||||||
|
static GU_DEFINE_TYPE(PgfAbswersMap, GuStringMap, gu_ptr_type(PgfAnswers),
|
||||||
|
&gu_null_struct);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GuPool* tmp_pool;
|
GuPool* tmp_pool;
|
||||||
PgfAbstr* abstract;
|
PgfAbstr* abstract;
|
||||||
|
PgfAbswersMap* table;
|
||||||
GuBuf* pqueue;
|
GuBuf* pqueue;
|
||||||
PgfExprEnum en;
|
PgfExprEnum en;
|
||||||
} PgfReasoner;
|
} PgfReasoner;
|
||||||
@@ -32,15 +52,12 @@ typedef struct {
|
|||||||
static int
|
static int
|
||||||
cmp_expr_qstate(GuOrder* self, const void* a, const void* b)
|
cmp_expr_qstate(GuOrder* self, const void* a, const void* b)
|
||||||
{
|
{
|
||||||
PgfExprQState *q1 = (PgfExprQState *) a;
|
PgfExprQState *q1 = *((PgfExprQState **) a);
|
||||||
PgfExprQState *q2 = (PgfExprQState *) b;
|
PgfExprQState *q2 = *((PgfExprQState **) b);
|
||||||
|
|
||||||
prob_t prob1 = q1->cont_prob-log(q1->abscat->functions[q1->fun_idx].prob);
|
|
||||||
prob_t prob2 = q2->cont_prob-log(q2->abscat->functions[q2->fun_idx].prob);
|
|
||||||
|
|
||||||
if (prob1 < prob2)
|
if (q1->prob < q2->prob)
|
||||||
return -1;
|
return -1;
|
||||||
else if (prob1 > prob2)
|
else if (q1->prob > q2->prob)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@@ -56,38 +73,37 @@ pgf_print_expr_state(PgfExprState* st,
|
|||||||
{
|
{
|
||||||
gu_buf_push(stack, int, (gu_seq_length(st->hypos) - st->arg_idx - 1));
|
gu_buf_push(stack, int, (gu_seq_length(st->hypos) - st->arg_idx - 1));
|
||||||
|
|
||||||
if (st->cont != NULL)
|
PgfExprState* cont = gu_buf_get(st->answers->conts, PgfExprState*, 0);
|
||||||
pgf_print_expr_state(st->cont, wtr, err, stack);
|
if (cont != NULL)
|
||||||
|
pgf_print_expr_state(cont, wtr, err, stack);
|
||||||
|
|
||||||
gu_puts(" (", wtr, err);
|
gu_puts(" (", wtr, err);
|
||||||
pgf_print_expr(st->expr, 0, wtr, err);
|
pgf_print_expr(st->ep.expr, 0, wtr, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgf_print_expr_qstate(PgfExprQState* q, PgfAbstr* abstract,
|
pgf_print_expr_state0(PgfExprState* st, PgfAbstr* abstract,
|
||||||
GuWriter* wtr, GuExn* err, GuPool* tmp_pool)
|
GuWriter* wtr, GuExn* err, GuPool* tmp_pool)
|
||||||
{
|
{
|
||||||
PgfCId fun = q->abscat->functions[q->fun_idx].fun;
|
prob_t prob = st->answers->outside_prob+st->ep.prob;
|
||||||
PgfFunDecl* absfun =
|
|
||||||
gu_map_get(abstract->funs, &fun, PgfFunDecl*);
|
|
||||||
|
|
||||||
prob_t prob = q->cont_prob+absfun->ep.prob;
|
|
||||||
gu_printf(wtr, err, "[%f]", prob);
|
gu_printf(wtr, err, "[%f]", prob);
|
||||||
|
|
||||||
size_t n_args = gu_seq_length(absfun->type->hypos);
|
size_t n_args = gu_seq_length(st->hypos);
|
||||||
|
|
||||||
GuBuf* stack = gu_new_buf(int, tmp_pool);
|
GuBuf* stack = gu_new_buf(int, tmp_pool);
|
||||||
if (n_args > 0)
|
if (n_args > 0)
|
||||||
gu_buf_push(stack, int, n_args);
|
gu_buf_push(stack, int, gu_seq_length(st->hypos) - st->arg_idx);
|
||||||
|
|
||||||
if (q->st != NULL)
|
PgfExprState* cont =
|
||||||
pgf_print_expr_state(q->st, wtr, err, stack);
|
gu_buf_get(st->answers->conts, PgfExprState*, 0);
|
||||||
|
if (cont != NULL)
|
||||||
|
pgf_print_expr_state(cont, wtr, err, stack);
|
||||||
|
|
||||||
if (n_args > 0)
|
if (n_args > 0)
|
||||||
gu_puts(" (", wtr, err);
|
gu_puts(" (", wtr, err);
|
||||||
else
|
else
|
||||||
gu_puts(" ", wtr, err);
|
gu_puts(" ", wtr, err);
|
||||||
pgf_print_expr(absfun->ep.expr, 0, wtr, err);
|
pgf_print_expr(st->ep.expr, 0, wtr, err);
|
||||||
|
|
||||||
size_t n_counts = gu_buf_length(stack);
|
size_t n_counts = gu_buf_length(stack);
|
||||||
for (size_t i = 0; i < n_counts; i++) {
|
for (size_t i = 0; i < n_counts; i++) {
|
||||||
@@ -101,107 +117,183 @@ pgf_print_expr_qstate(PgfExprQState* q, PgfAbstr* abstract,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool
|
static PgfExprState*
|
||||||
pgf_reasoner_cat_init(PgfReasoner* rs,
|
pgf_reasoner_combine(PgfReasoner* rs,
|
||||||
PgfExprState* cont, prob_t cont_prob, PgfCId cat,
|
PgfExprState* st, PgfExprProb* ep,
|
||||||
GuPool* pool)
|
GuPool* pool)
|
||||||
{
|
{
|
||||||
// Checking for loops in the chart
|
PgfExprState* nst =
|
||||||
if (cont != NULL) {
|
gu_new(PgfExprState, rs->tmp_pool);
|
||||||
PgfExprState* st = cont->cont;
|
nst->answers = st->answers;
|
||||||
while (st != NULL) {
|
nst->ep.expr =
|
||||||
PgfHypo* hypo = gu_seq_index(st->hypos, PgfHypo, st->arg_idx);
|
gu_new_variant_i(pool, PGF_EXPR_APP,
|
||||||
if (gu_string_eq(hypo->type->cid, cat))
|
PgfExprApp,
|
||||||
return false;
|
.fun = st->ep.expr,
|
||||||
|
.arg = ep->expr);
|
||||||
|
nst->ep.prob = st->ep.prob+ep->prob;
|
||||||
|
nst->hypos = st->hypos;
|
||||||
|
nst->arg_idx = st->arg_idx+1;
|
||||||
|
return nst;
|
||||||
|
}
|
||||||
|
|
||||||
st = st->cont;
|
static void
|
||||||
|
pgf_reasoner_predict(PgfReasoner* rs, PgfExprState* cont,
|
||||||
|
prob_t outside_prob, PgfCId cat,
|
||||||
|
GuPool* pool)
|
||||||
|
{
|
||||||
|
PgfAnswers* answers = gu_map_get(rs->table, &cat, PgfAnswers*);
|
||||||
|
if (answers == NULL) {
|
||||||
|
answers = gu_new(PgfAnswers, rs->tmp_pool);
|
||||||
|
answers->conts = gu_new_buf(PgfExprState*, rs->tmp_pool);
|
||||||
|
answers->exprs = gu_new_buf(PgfExprProb*, rs->tmp_pool);
|
||||||
|
answers->outside_prob = outside_prob;
|
||||||
|
|
||||||
|
gu_map_put(rs->table, &cat, PgfAnswers*, answers);
|
||||||
|
}
|
||||||
|
|
||||||
|
gu_buf_push(answers->conts, PgfExprState*, cont);
|
||||||
|
|
||||||
|
if (gu_buf_length(answers->conts) == 1) {
|
||||||
|
PgfCat* abscat = gu_map_get(rs->abstract->cats, &cat, PgfCat*);
|
||||||
|
if (abscat == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gu_buf_length(abscat->functions) > 0) {
|
||||||
|
PgfExprQState *q = gu_new(PgfExprQState, rs->tmp_pool);
|
||||||
|
q->kind = PGF_EXPR_QSTATE_PREDICT;
|
||||||
|
q->single = answers;
|
||||||
|
q->choice_idx = 0;
|
||||||
|
q->choices = abscat->functions;
|
||||||
|
|
||||||
|
q->prob = answers->outside_prob + gu_buf_get(q->choices, PgfFunDecl*, 0)->ep.prob;
|
||||||
|
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (gu_buf_length(answers->exprs) > 0) {
|
||||||
|
PgfExprQState *q = gu_new(PgfExprQState, rs->tmp_pool);
|
||||||
|
q->prob = cont->ep.prob + gu_buf_get(answers->exprs, PgfExprProb*, 0)->prob;
|
||||||
|
q->kind = PGF_EXPR_QSTATE_COMBINE1;
|
||||||
|
q->single = cont;
|
||||||
|
q->choice_idx = 0;
|
||||||
|
q->choices = answers->exprs;
|
||||||
|
|
||||||
|
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfCat* abscat = gu_map_get(rs->abstract->cats, &cat, PgfCat*);
|
|
||||||
if (abscat == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abscat->n_functions > 0) {
|
|
||||||
PgfExprQState q = {cont, cont_prob, 0, abscat};
|
|
||||||
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PgfExprProb*
|
static PgfExprProb*
|
||||||
pgf_reasoner_next(PgfReasoner* rs, GuPool* pool)
|
pgf_reasoner_next(PgfReasoner* rs, GuPool* pool)
|
||||||
{
|
{
|
||||||
if (rs->pqueue == NULL)
|
if (rs->tmp_pool == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (gu_buf_length(rs->pqueue) > 0) {
|
while (gu_buf_length(rs->pqueue) > 0) {
|
||||||
PgfExprQState q;
|
PgfExprQState* q;
|
||||||
gu_buf_heap_pop(rs->pqueue, &pgf_expr_qstate_order, &q);
|
gu_buf_heap_pop(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
|
|
||||||
|
PgfExprState* st = NULL;
|
||||||
|
switch (q->kind) {
|
||||||
|
case PGF_EXPR_QSTATE_PREDICT: {
|
||||||
|
PgfFunDecl* absfun =
|
||||||
|
gu_buf_get(q->choices, PgfFunDecl*, q->choice_idx);
|
||||||
|
|
||||||
|
st = gu_new(PgfExprState, pool);
|
||||||
|
st->answers = q->single;
|
||||||
|
st->ep = absfun->ep;
|
||||||
|
st->hypos = absfun->type->hypos;
|
||||||
|
st->arg_idx = 0;
|
||||||
|
|
||||||
|
q->choice_idx++;
|
||||||
|
if (q->choice_idx < gu_buf_length(q->choices)) {
|
||||||
|
q->prob = st->answers->outside_prob + gu_buf_get(q->choices, PgfFunDecl*, q->choice_idx)->ep.prob;
|
||||||
|
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PGF_EXPR_QSTATE_COMBINE1: {
|
||||||
|
PgfExprState* cont = q->single;
|
||||||
|
PgfExprProb* ep =
|
||||||
|
gu_buf_get(q->choices, PgfExprProb*, q->choice_idx);
|
||||||
|
st = pgf_reasoner_combine(rs, cont, ep, pool);
|
||||||
|
|
||||||
|
q->choice_idx++;
|
||||||
|
if (q->choice_idx < gu_buf_length(q->choices)) {
|
||||||
|
q->prob = cont->ep.prob + gu_buf_get(q->choices, PgfExprProb*, q->choice_idx)->prob;
|
||||||
|
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PGF_EXPR_QSTATE_COMBINE2: {
|
||||||
|
PgfExprState* cont =
|
||||||
|
gu_buf_get(q->choices, PgfExprState*, q->choice_idx);
|
||||||
|
PgfExprProb* ep = q->single;
|
||||||
|
st = pgf_reasoner_combine(rs, cont, ep, pool);
|
||||||
|
|
||||||
|
q->choice_idx++;
|
||||||
|
if (q->choice_idx < gu_buf_length(q->choices)) {
|
||||||
|
q->prob = ep->prob + gu_buf_get(q->choices, PgfExprState*, q->choice_idx)->ep.prob;
|
||||||
|
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
gu_impossible();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef PGF_REASONER_DEBUG
|
#ifdef PGF_REASONER_DEBUG
|
||||||
{
|
{
|
||||||
GuPool* tmp_pool = gu_new_pool();
|
GuPool* tmp_pool = gu_new_pool();
|
||||||
GuOut* out = gu_file_out(stderr, tmp_pool);
|
GuOut* out = gu_file_out(stderr, tmp_pool);
|
||||||
GuWriter* wtr = gu_new_utf8_writer(out, tmp_pool);
|
GuWriter* wtr = gu_new_utf8_writer(out, tmp_pool);
|
||||||
GuExn* err = gu_exn(NULL, type, tmp_pool);
|
GuExn* err = gu_exn(NULL, type, tmp_pool);
|
||||||
pgf_print_expr_qstate(&q, rs->abstract, wtr, err, tmp_pool);
|
pgf_print_expr_state0(st, rs->abstract, wtr, err, tmp_pool);
|
||||||
gu_pool_free(tmp_pool);
|
gu_pool_free(tmp_pool);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PgfCId fun = q.abscat->functions[q.fun_idx++].fun;
|
if (st->arg_idx < gu_seq_length(st->hypos)) {
|
||||||
PgfFunDecl* absfun =
|
PgfHypo *hypo = gu_seq_index(st->hypos, PgfHypo, st->arg_idx);
|
||||||
gu_map_get(rs->abstract->funs, &fun, PgfFunDecl*);
|
prob_t outside_prob =
|
||||||
|
st->ep.prob+st->answers->outside_prob;
|
||||||
|
pgf_reasoner_predict(rs, st, outside_prob,
|
||||||
|
hypo->type->cid, pool);
|
||||||
|
} else {
|
||||||
|
gu_buf_push(st->answers->exprs, PgfExprProb*, &st->ep);
|
||||||
|
|
||||||
if (q.fun_idx < q.abscat->n_functions) {
|
PgfExprProb* target = NULL;
|
||||||
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
|
||||||
}
|
GuBuf* conts = st->answers->conts;
|
||||||
|
size_t choice_idx = 0;
|
||||||
if (absfun == NULL)
|
PgfExprState* cont =
|
||||||
continue;
|
gu_buf_get(conts, PgfExprState*, 0);
|
||||||
|
if (cont == NULL) {
|
||||||
PgfExprState *st = gu_new(PgfExprState, rs->tmp_pool);
|
target = &st->ep;
|
||||||
st->cont = q.st;
|
cont = gu_buf_get(conts, PgfExprState*, 1);
|
||||||
st->expr =
|
choice_idx++;
|
||||||
gu_new_variant_i(pool, PGF_EXPR_FUN,
|
|
||||||
PgfExprFun,
|
|
||||||
.fun = fun);
|
|
||||||
st->hypos = absfun->type->hypos;
|
|
||||||
st->arg_idx = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
prob_t prob = q.cont_prob+absfun->ep.prob;
|
|
||||||
|
|
||||||
if (st->arg_idx < gu_seq_length(st->hypos)) {
|
|
||||||
PgfHypo *hypo = gu_seq_index(st->hypos, PgfHypo, st->arg_idx);
|
|
||||||
pgf_reasoner_cat_init(rs, st, prob,
|
|
||||||
hypo->type->cid, pool);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
PgfExprState* cont = st->cont;
|
|
||||||
if (cont == NULL) {
|
|
||||||
PgfExprProb* ep = gu_new(PgfExprProb, pool);
|
|
||||||
ep->expr = st->expr;
|
|
||||||
ep->prob = prob;
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
st->cont = cont->cont;
|
|
||||||
st->expr =
|
|
||||||
gu_new_variant_i(pool, PGF_EXPR_APP,
|
|
||||||
PgfExprApp,
|
|
||||||
.fun = cont->expr, .arg = st->expr);
|
|
||||||
st->hypos = cont->hypos;
|
|
||||||
st->arg_idx = cont->arg_idx+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (choice_idx < gu_buf_length(conts)) {
|
||||||
|
PgfExprQState *q = gu_new(PgfExprQState, rs->tmp_pool);
|
||||||
|
q->prob = st->ep.prob + cont->ep.prob;
|
||||||
|
q->kind = PGF_EXPR_QSTATE_COMBINE2;
|
||||||
|
q->single = &st->ep;
|
||||||
|
q->choice_idx = choice_idx;
|
||||||
|
q->choices = conts;
|
||||||
|
|
||||||
|
gu_buf_heap_push(rs->pqueue, &pgf_expr_qstate_order, &q);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target != NULL)
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gu_pool_free(rs->tmp_pool);
|
gu_pool_free(rs->tmp_pool);
|
||||||
rs->tmp_pool = NULL;
|
rs->tmp_pool = NULL;
|
||||||
rs->pqueue = NULL;
|
rs->pqueue = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,17 +307,14 @@ pgf_reasoner_enum_next(GuEnum* self, void* to, GuPool* pool)
|
|||||||
PgfExprEnum*
|
PgfExprEnum*
|
||||||
pgf_generate(PgfPGF* pgf, PgfCId cat, GuPool* pool)
|
pgf_generate(PgfPGF* pgf, PgfCId cat, GuPool* pool)
|
||||||
{
|
{
|
||||||
GuPool* tmp_pool = gu_new_pool();
|
PgfReasoner* rs = gu_new(PgfReasoner, pool);
|
||||||
GuBuf* pqueue = gu_new_buf(PgfExprQState, tmp_pool);
|
rs->tmp_pool = gu_new_pool(),
|
||||||
|
rs->abstract = &pgf->abstract,
|
||||||
|
rs->table = gu_map_type_new(PgfAbswersMap, rs->tmp_pool),
|
||||||
|
rs->pqueue = gu_new_buf(PgfExprQState*, rs->tmp_pool);
|
||||||
|
rs->en.next = pgf_reasoner_enum_next;
|
||||||
|
|
||||||
PgfReasoner* rs =
|
pgf_reasoner_predict(rs, NULL, 0, cat, pool);
|
||||||
gu_new_i(pool, PgfReasoner,
|
|
||||||
.tmp_pool = tmp_pool,
|
|
||||||
.abstract = &pgf->abstract,
|
|
||||||
.pqueue = pqueue,
|
|
||||||
.en.next = pgf_reasoner_enum_next);
|
|
||||||
|
|
||||||
pgf_reasoner_cat_init(rs, NULL, 0, cat, pool);
|
|
||||||
|
|
||||||
return &rs->en;
|
return &rs->en;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user