mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
introduce a version of namespace_iter with a lambda function
This commit is contained in:
@@ -631,6 +631,24 @@ void namespace_iter(Namespace<V> map, PgfItor* itor, PgfExn *err)
|
||||
return;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
bool namespace_iter(Namespace<V> map, std::function<bool(ref<V>)> &f)
|
||||
{
|
||||
if (map == 0)
|
||||
return true;
|
||||
|
||||
if (!namespace_iter(map->left, f))
|
||||
return false;
|
||||
|
||||
if (!f(map->value))
|
||||
return false;
|
||||
|
||||
if (!namespace_iter(map->right, f))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
void namespace_iter_prefix(Namespace<V> map, PgfText *prefix, PgfItor* itor, PgfExn *err)
|
||||
{
|
||||
|
||||
@@ -463,23 +463,6 @@ void pgf_iter_categories(PgfDB *db, PgfRevision revision,
|
||||
} PGF_API_END
|
||||
}
|
||||
|
||||
struct PgfItorConcrHelper : PgfItor
|
||||
{
|
||||
PgfDB *db;
|
||||
txn_t txn_id;
|
||||
PgfItor *itor;
|
||||
};
|
||||
|
||||
static
|
||||
void iter_concretes_helper(PgfItor *itor, PgfText *key, object value, PgfExn *err)
|
||||
{
|
||||
PgfItorConcrHelper* helper = (PgfItorConcrHelper*) itor;
|
||||
ref<PgfConcr> concr = value;
|
||||
object rev = helper->db->register_revision(concr.tagged(), helper->txn_id);
|
||||
helper->db->ref_count++;
|
||||
helper->itor->fn(helper->itor, key, rev, err);
|
||||
}
|
||||
|
||||
PGF_API
|
||||
void pgf_iter_concretes(PgfDB *db, PgfRevision revision,
|
||||
PgfItor *itor, PgfExn *err)
|
||||
@@ -490,13 +473,14 @@ void pgf_iter_concretes(PgfDB *db, PgfRevision revision,
|
||||
DB_scope scope(db, READER_SCOPE);
|
||||
ref<PgfPGF> pgf = db->revision2pgf(revision, &txn_id);
|
||||
|
||||
PgfItorConcrHelper helper;
|
||||
helper.fn = iter_concretes_helper;
|
||||
helper.db = db;
|
||||
helper.txn_id = txn_id;
|
||||
helper.itor = itor;
|
||||
|
||||
namespace_iter(pgf->concretes, &helper, err);
|
||||
std::function<bool(ref<PgfConcr>)> f =
|
||||
[txn_id,db,itor,err](ref<PgfConcr> concr) {
|
||||
object rev = db->register_revision(concr.tagged(), txn_id);
|
||||
db->ref_count++;
|
||||
itor->fn(itor, &concr->name, rev, err);
|
||||
return (err->type == PGF_EXN_NONE);
|
||||
};
|
||||
namespace_iter(pgf->concretes, f);
|
||||
} PGF_API_END
|
||||
}
|
||||
|
||||
@@ -1609,30 +1593,19 @@ void pgf_create_category(PgfDB *db, PgfRevision revision,
|
||||
struct PGF_INTERNAL_DECL PgfDropItor : PgfItor
|
||||
{
|
||||
ref<PgfPGF> pgf;
|
||||
ref<PgfConcr> concrete;
|
||||
PgfText *name;
|
||||
};
|
||||
|
||||
static
|
||||
void iter_drop_cat_helper2(PgfItor *itor, PgfText *key, object value, PgfExn *err)
|
||||
{
|
||||
ref<PgfConcr> concr = value;
|
||||
PgfText* name = ((PgfDropItor*) itor)->name;
|
||||
|
||||
drop_lin(concr, name);
|
||||
}
|
||||
|
||||
static
|
||||
void iter_drop_cat_helper(PgfItor *itor, PgfText *key, object value, PgfExn *err)
|
||||
{
|
||||
ref<PgfPGF> pgf = ((PgfDropItor*) itor)->pgf;
|
||||
|
||||
PgfDropItor itor2;
|
||||
itor2.fn = iter_drop_cat_helper2;
|
||||
itor2.pgf = 0;
|
||||
itor2.concrete = 0;
|
||||
itor2.name = key;
|
||||
namespace_iter(pgf->concretes, &itor2, err);
|
||||
std::function<bool(ref<PgfConcr>)> f =
|
||||
[key,err](ref<PgfConcr> concr) {
|
||||
drop_lin(concr, key);
|
||||
return (err->type == PGF_EXN_NONE);
|
||||
};
|
||||
namespace_iter(pgf->concretes, f);
|
||||
|
||||
ref<PgfAbsFun> fun;
|
||||
Namespace<PgfAbsFun> funs =
|
||||
@@ -1672,8 +1645,6 @@ void pgf_drop_category(PgfDB *db, PgfRevision revision,
|
||||
PgfDropItor itor;
|
||||
itor.fn = iter_drop_cat_helper;
|
||||
itor.pgf = pgf;
|
||||
itor.concrete = 0;
|
||||
itor.name = name;
|
||||
PgfProbspace funs_by_cat =
|
||||
probspace_delete_by_cat(pgf->abstract.funs_by_cat, &cat->name,
|
||||
&itor, err);
|
||||
|
||||
@@ -373,11 +373,6 @@ struct PGF_INTERNAL_DECL PgfAbsCatCounts
|
||||
prob_t prob;
|
||||
};
|
||||
|
||||
struct PGF_INTERNAL_DECL PgfProbItor : PgfItor
|
||||
{
|
||||
Vector<PgfAbsCatCounts> *cats;
|
||||
};
|
||||
|
||||
static
|
||||
PgfAbsCatCounts *find_counts(Vector<PgfAbsCatCounts> *cats, PgfText *name)
|
||||
{
|
||||
@@ -399,38 +394,6 @@ PgfAbsCatCounts *find_counts(Vector<PgfAbsCatCounts> *cats, PgfText *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
void collect_counts(PgfItor *itor, PgfText *key, object value, PgfExn *err)
|
||||
{
|
||||
PgfProbItor* prob_itor = (PgfProbItor*) itor;
|
||||
ref<PgfAbsFun> absfun = value;
|
||||
|
||||
PgfAbsCatCounts *counts =
|
||||
find_counts(prob_itor->cats, &absfun->type->name);
|
||||
if (counts != NULL) {
|
||||
if (isnan(absfun->prob)) {
|
||||
counts->n_nan_probs++;
|
||||
} else {
|
||||
counts->probs_sum += exp(-absfun->prob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void pad_probs(PgfItor *itor, PgfText *key, object value, PgfExn *err)
|
||||
{
|
||||
PgfProbItor* prob_itor = (PgfProbItor*) itor;
|
||||
ref<PgfAbsFun> absfun = value;
|
||||
|
||||
if (isnan(absfun->prob)) {
|
||||
PgfAbsCatCounts *counts =
|
||||
find_counts(prob_itor->cats, &absfun->type->name);
|
||||
if (counts != NULL) {
|
||||
absfun->prob = counts->prob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PgfReader::read_abstract(ref<PgfAbstr> abstract)
|
||||
{
|
||||
this->abstract = abstract;
|
||||
@@ -447,24 +410,42 @@ void PgfReader::read_abstract(ref<PgfAbstr> abstract)
|
||||
abstract->cats = cats;
|
||||
|
||||
if (probs_callback != NULL) {
|
||||
PgfExn err;
|
||||
err.type = PGF_EXN_NONE;
|
||||
Vector<PgfAbsCatCounts> *cats = namespace_to_sorted_names<PgfAbsCat,PgfAbsCatCounts>(abstract->cats);
|
||||
|
||||
PgfProbItor itor;
|
||||
itor.cats = namespace_to_sorted_names<PgfAbsCat,PgfAbsCatCounts>(abstract->cats);
|
||||
std::function<bool(ref<PgfAbsFun>)> collect_counts =
|
||||
[cats](ref<PgfAbsFun> absfun) {
|
||||
PgfAbsCatCounts *counts =
|
||||
find_counts(cats, &absfun->type->name);
|
||||
if (counts != NULL) {
|
||||
if (isnan(absfun->prob)) {
|
||||
counts->n_nan_probs++;
|
||||
} else {
|
||||
counts->probs_sum += exp(-absfun->prob);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
namespace_iter(abstract->funs, collect_counts);
|
||||
|
||||
itor.fn = collect_counts;
|
||||
namespace_iter(abstract->funs, &itor, &err);
|
||||
|
||||
for (size_t i = 0; i < itor.cats->len; i++) {
|
||||
PgfAbsCatCounts *counts = &itor.cats->data[i];
|
||||
for (size_t i = 0; i < cats->len; i++) {
|
||||
PgfAbsCatCounts *counts = &cats->data[i];
|
||||
counts->prob = - logf((1-counts->probs_sum) / counts->n_nan_probs);
|
||||
}
|
||||
|
||||
itor.fn = pad_probs;
|
||||
namespace_iter(abstract->funs, &itor, &err);
|
||||
std::function<bool(ref<PgfAbsFun>)> pad_probs =
|
||||
[cats](ref<PgfAbsFun> absfun) {
|
||||
if (isnan(absfun->prob)) {
|
||||
PgfAbsCatCounts *counts =
|
||||
find_counts(cats, &absfun->type->name);
|
||||
if (counts != NULL) {
|
||||
absfun->prob = counts->prob;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
namespace_iter(abstract->funs, pad_probs);
|
||||
|
||||
free(itor.cats);
|
||||
free(cats);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user