forked from GitHub/gf-core
83 lines
3.0 KiB
C++
83 lines
3.0 KiB
C++
#ifndef PROBSPACE_H
|
|
#define PROBSPACE_H
|
|
|
|
/*
|
|
* The probspace is an index where abstract functions are ordered by
|
|
* the tripple of (category,probability,name). Here the category is
|
|
* any of the categories used in the type of the function.
|
|
*
|
|
* When a new function is created, it is inserted first in
|
|
* the namespace of functions and after that in the probspace.
|
|
* The insertion in the probspace is done once for every category in
|
|
* the type of the function. The insertion with a result category is
|
|
* always done after the insertion with the argument categories.
|
|
* This means that we can easily identify functions which return a given
|
|
* category by just checking that:
|
|
*
|
|
* entry->cat == ref<PgfText>::from_ptr(&fun->type->name);
|
|
*
|
|
* The later is important when the index is used in tree generation
|
|
* and parsing.
|
|
*
|
|
* The index has the following uses:
|
|
*
|
|
* - When a category is removed we must also remove all functions that
|
|
* use it in their types, otherwise the data will be inconsistant.
|
|
* We use the index to find which functions to remove.
|
|
*
|
|
* - When a lincat is removed we must remove all lins from the same
|
|
* language which depend on the lincat. We identify them through
|
|
* the abstract types and whence through this index.
|
|
*
|
|
* - When we do exhaustive or random generation, we need to know
|
|
* which functions return a given category. We simply go through
|
|
* the index but also check the above condition to distinguish the case
|
|
* where the category is consumed from the case where the category is
|
|
* returned. In exhaustive generation, to ensure that all results
|
|
* are returned in decreasing probability order, we must consume
|
|
* functions in the same order. This is the reason why we keep the
|
|
* index sorted by probability.
|
|
*
|
|
* - When a function is removed, we must remove it both from
|
|
* the namespace as well as from the probspace. Since the index is
|
|
* sorted by function name, as well, we use that to find which entry
|
|
* to remove.
|
|
*
|
|
*/
|
|
struct PGF_INTERNAL_DECL PgfProbspaceEntry {
|
|
ref<PgfText> cat;
|
|
ref<PgfAbsFun> fun;
|
|
|
|
bool is_result();
|
|
};
|
|
|
|
typedef ref<Node<PgfProbspaceEntry>> PgfProbspace;
|
|
|
|
PGF_INTERNAL_DECL
|
|
PgfProbspace probspace_insert(PgfProbspace space,
|
|
ref<PgfAbsFun> fun);
|
|
|
|
PGF_INTERNAL_DECL
|
|
PgfProbspace probspace_delete(PgfProbspace space,
|
|
ref<PgfAbsFun> fun);
|
|
|
|
PGF_INTERNAL_DECL
|
|
PgfProbspace probspace_delete_by_cat(PgfProbspace space, PgfText *cat,
|
|
PgfItor* itor, PgfExn *err);
|
|
|
|
PGF_INTERNAL_DECL
|
|
bool probspace_iter(PgfProbspace space, PgfText *cat,
|
|
std::function<bool(ref<PgfAbsFun>)> &f, bool all);
|
|
|
|
/* Given a random number from 0 to 1, select a random function from
|
|
* the given category */
|
|
PGF_INTERNAL_DECL
|
|
ref<PgfAbsFun> probspace_random(PgfProbspace space,
|
|
PgfText *cat, prob_t rand,
|
|
const std::set<ref<PgfAbsFun>> &excluded);
|
|
|
|
PGF_INTERNAL_DECL
|
|
void probspace_release(PgfProbspace space);
|
|
|
|
#endif
|