Special-purpose extension of Python -- new kinds of objects

R

Robert Dodier

Hello,

I have an idea, thus far half-baked, to create a language called
Ephemeral, for "flexible modeling & reasoning language".
I'd like some advice about how to go about implementing it.

Ephemeral would be Python plus additional constructs to support
decision analysis -- what's needed are essentially specifications
of probability and utility functions. Let's not worry about whether
such a language would be usefult to anyone.

The goal here is to merge the description of the probability and
utility stuff with Python in general. I would like for objects
of these new types to appear in ordinary Python functions so that
they can be manipulated. Here's an example:

# "dn" == "decision network", an Ephemeral construct;
# this part is parsed separately from the python code
dn my_example:
chance X:
cpd: gaussian [mean: 25, std_dev: 75]
chance Y:
cpd: gaussian [mean: 12, std_dev: 19]
chance Z = X + Y

# this part is ordinary python code; nodes, cpd, parents, and
# and posterior are constructed automatically from above description
def __main__:
print my_example.nodes # "[X, Y, Z]"
print my_example.X.cpd # "gaussian [mean: 25, std_dev: 75]"
print my_example.Z.parents # "[X, Y]"
print my_example.Z.posterior # "gaussian [mean: 37, std_dev: 77.4]"


One way to look at this is that it is ordinary Python code with
new kinds of objects embedded in it. Another approach would be to
embed Python functions in a decision network. I think that it will
generally be more powerful and flexible to embed the new stuff in
Python rather than vice versa. How can I start going about this?

Are there other projects that have a similar spirit --
extending Python with special purpose language constructs?

Thanks for any comments,
Robert Dodier
 
P

Paul Rubin

# "dn" == "decision network", an Ephemeral construct;
# this part is parsed separately from the python code
dn my_example:
chance X:
cpd: gaussian [mean: 25, std_dev: 75]
chance Y:
cpd: gaussian [mean: 12, std_dev: 19]
chance Z = X + Y

I don't see what good this does. You can do the same thing with
ordinary Python classes.
 
J

Jeff Epler

There have been lots of discussions on how to add domain-specific
extensions to Python. You would do well to read these threads somewhere
like google groups, they're relevant to the topic at hand.

In your case, you could re-cast the "decision network" in terms of class
definitions, and get pretty similar behavior if those classes have the
right behavior in metaclasses:
class my_example(DN):
class X(Chance):
cpd = gaussian(mean=25, std_dev=75)
class Y(Chance):
cpd = gaussian(mean=12, std_dev=19)
Z = X + Y
using the class statement, you can create a namespace with some values
in it, and then do some processing of those values (for instance, to
precompute the .nodes values). If you're very fond of your syntax, then
consider using strings as the easiest way. Docstring abuse has been
seen before, and would look something like this:
class my_example(DN): """
chance X:
cpd: gaussian [mean: 25, std_dev: 75]
chance Y:
cpd: gaussian [mean: 12, std_dev: 19]
chance Z = X + Y
"""
either using docstrings or an external file, you'll need a parser.
There is a languishing PEP about exposing the Python parser generator to
Python code, so that you could write your own grammar with the same
level of power as Python's grammar. There are lots of other package,
such as yapps and spark which are also suitable for writing parsers.

Once you have a parser and use external files, it's possible to extend
Python's import system to load files of your type automatically with
the import statement. This is an advanced topic, though.

Jeff
 
P

Paul Rubin

Jeff Epler said:
In your case, you could re-cast the "decision network" in terms of class
definitions, and get pretty similar behavior if those classes have the
right behavior in metaclasses:
class my_example(DN):
class X(Chance):
cpd = gaussian(mean=25, std_dev=75)
class Y(Chance):
cpd = gaussian(mean=12, std_dev=19)
Z = X + Y

When you say Z = X + Y, you've added two classes together. Can you
actually do that with metaclasses?
 
R

Robert Dodier

Paul Rubin said:
# "dn" == "decision network", an Ephemeral construct;
# this part is parsed separately from the python code
dn my_example:
chance X:
cpd: gaussian [mean: 25, std_dev: 75]
chance Y:
cpd: gaussian [mean: 12, std_dev: 19]
chance Z = X + Y

I don't see what good this does. You can do the same thing with
ordinary Python classes.

Thanks for your interest. I want to make it possible to experiment
with notations that don't correspond to Python syntax. For example,
to write "X ~ gaussian(mu,sigma2)", or to write "Y <- (X1, X2, X3)",
say.

The larger goal is to make the decision model description as
natural as possible for people that work on decision problems.
Development effort should focus on the decision model, which,
in interesting problems, may be much larger and more complex
than the ordinary Python glue code around it.

Languages such as BUGS, S, dot, and Netica express the sorts
of ideas that I want in Ephemeral.

Robert Dodier
 
D

David C. Fox

Robert said:
[email protected] (Robert Dodier) said:
# "dn" == "decision network", an Ephemeral construct;
# this part is parsed separately from the python code
dn my_example:
chance X:
cpd: gaussian [mean: 25, std_dev: 75]
chance Y:
cpd: gaussian [mean: 12, std_dev: 19]
chance Z = X + Y

I don't see what good this does. You can do the same thing with
ordinary Python classes.


Thanks for your interest. I want to make it possible to experiment
with notations that don't correspond to Python syntax. For example,
to write "X ~ gaussian(mu,sigma2)", or to write "Y <- (X1, X2, X3)",
say.

The larger goal is to make the decision model description as
natural as possible for people that work on decision problems.
Development effort should focus on the decision model, which,
in interesting problems, may be much larger and more complex
than the ordinary Python glue code around it.

Personally, I would first write all of the code for performing
calculations in pure Python, using the usual OO notation. Then you can
always add a parser which translates the mathematical syntax into OO.

David
 
R

Robert Dodier

Jeff Epler said:
In your case, you could re-cast the "decision network" in terms of class
definitions, and get pretty similar behavior if those classes have the
right behavior in metaclasses: [...]

I'd rather not try to shoehorn the decision model description into
a description in terms of Python classes. I'd like to try to keep
the description as natural as possible.
If you're very fond of your syntax, then consider using strings
as the easiest way. Docstring abuse has been seen before, and
would look something like this: [...]

I've implemented similar systems by loading files in one format
or another -- XML was the latest attempt; I won't be trying that
again -- and, to explore just how far the integration with Python
can be taken, I'm wondering what it would take to merge the model
description with Python. I'd like to have Python in the model
(to return probability & utility values) as well as model in the
Python.
There is a languishing PEP about exposing the Python parser generator to
Python code, so that you could write your own grammar with the same
level of power as Python's grammar. There are lots of other package,
such as yapps and spark which are also suitable for writing parsers.

Yes, I've seen the PEP in question (PEP 269), I'll take a closer
look. I'll look at yapps and spark too.
Once you have a parser and use external files, it's possible to extend
Python's import system to load files of your type automatically with
the import statement. This is an advanced topic, though.

Well, that's not out of the question. Can you give a reference
to a starting point for hacking on the import system?

Thanks for your interest. I appreciate your help.

Robert Dodier
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,174
Messages
2,570,940
Members
47,484
Latest member
JackRichard

Latest Threads

Top