Skip to content

Commit

Permalink
expose the random generation API
Browse files Browse the repository at this point in the history
  • Loading branch information
krangelov committed Jan 12, 2024
1 parent 1a840d5 commit 73b4b68
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/runtime/python/pgf.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,15 @@ class PGF:
"""
...

def generateRandom(cat : Type, depth : int = 5) -> tuple[Expr,float]:
"""
Generates a random abstract syntax trees of the given type.
The depth parameter specifies the maximal distance between
the root and a leaf in the tree. The float value in
the result is the probability of the tree.
"""
...

def newTransaction(self) -> Transaction:
"""
Starts a new transaction which makes it possible to update
Expand Down
51 changes: 51 additions & 0 deletions src/runtime/python/pypgf.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,54 @@ PGF_functionIsConstructor(PGFObject *self, PyObject *args)
return PyBool_FromLong(isCon);
}

static PyObject *
PGF_generateRandom(PGFObject *self, PyObject *args, PyObject *keywds)
{
static char *kwlist[] = {"cat", "depth", NULL};

Py_ssize_t depth = 5;
TypeObject *start = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|n", kwlist,
&pgf_TypeType, &start, &depth))
return NULL;

PyObject *py_random = PyImport_ImportModule("random");
if (py_random == NULL)
return NULL;

PyObject *py_randint = PyObject_GetAttrString(py_random, "randint");
Py_DECREF(py_random);
if (py_randint == NULL)
return NULL;

PyObject *py_seed = PyObject_CallFunction(py_randint, "nn", 0, PY_SSIZE_T_MAX);
Py_DECREF(py_randint);
if (py_seed == NULL)
return NULL;

size_t seed = PyLong_AsSsize_t(py_seed);
Py_DECREF(py_seed);

PgfExn err;
prob_t prob;
PgfExpr expr =
pgf_generate_random(self->db, self->revision,
NULL, 0,
(PgfType) start, depth,
&seed, &prob,
&marshaller, &unmarshaller,
&err);
if (handleError(err) != PGF_EXN_NONE) {
return NULL;
}

PyObject *res =
Py_BuildValue("Od", (ExprObject *) expr, prob);
Py_DECREF((PyObject *) expr);

return res;
}

static PyObject *
PGF_categoryProbability(PGFObject *self, PyObject *args)
{
Expand Down Expand Up @@ -1490,6 +1538,9 @@ static PyMethodDef PGF_methods[] = {
{"functionIsConstructor", (PyCFunction)PGF_functionIsConstructor, METH_VARARGS,
"Checks whether a function is a constructor"
},
{"generateRandom", (PyCFunction)PGF_generateRandom, METH_VARARGS | METH_KEYWORDS,
"Generates a random abstract syntax trees of the given type"
},
{"categoryProbability", (PyCFunction)PGF_categoryProbability, METH_VARARGS,
"Returns the probability of a category"
},
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

setup(
name = 'pgf-majestic',
version = '2.6',
version = '2.7',
description = 'Python bindings to the Grammatical Framework\'s PGF runtime',
long_description="""\
Grammatical Framework (GF) is a programming language for multilingual grammar applications.
Expand Down

0 comments on commit 73b4b68

Please sign in to comment.