Probabilistic programming for the web
Install using nodejs:
npm install -g webppl
Run webppl programs:
webppl myprogram.wppl
Upgrade webppl:
npm update -g webppl
webppl is released under the MIT License.
We encourage you to contribute to webppl! Check out our guidelines for contributors and join the webppl-dev mailing list.
git clone https://github.com/probmods/webppl.git
cd webppl
npm install
npm install -g nodeunit grunt-cli
To use the webppl
command line tool from any directory, add the webppl directory to your $PATH
.
Running webppl programs:
webppl examples/geometric.wppl
Compiling webppl programs to Javascript:
webppl examples/geometric.wppl --compile --out geometric.js
The compiled file can be run using nodejs:
node geometric.js
Before committing changes, run grunt (which runs tests and linting):
grunt
If grunt doesn't succeed, the continuous integration tests will fail as well.
To only run the tests, do:
npm test
To only run the linter:
grunt gjslint
For more semantic linting, try:
grunt hint
If gjslint complains about style errors (like indentation), you can fix many of them automatically using:
grunt fixjsstyle
To compile webppl for use in browser, run:
npm install -g browserify
browserify -t brfs src/browser.js > compiled/webppl.js
Packages can also be used in the browser. For example, to include the webppl-viz
package use:
browserify -t [./src/bundle.js --require webppl-viz] -t brfs src/browser.js > compiled/webppl.js
Multiple --require
arguments can be used to include multiple packages.
To debug WebPPL programs running in Chrome, enable pause on JavaScript exceptions in the Chrome debugger. To debug WebPPL programs running in nodejs, use node-inspector as follows:
// 1. Install node-inspector (only need to do this once)
npm install -g node-inspector
// 2. Add "debugger;" statements to my-program.wppl to indicate breakpoints
// 3. Run your compiled program in debug mode (will pause automatically)
node --debug-brk webppl my-program.wppl
// 4. (In separate terminal:) Load node inspector, resume program execution in node-inspector
node-inspector
WebPPL packages are regular Node.js packages optionally extended to include WebPPL code and headers.
To make a package available in your program use the --require
argument:
webppl myFile.wppl --require myPackage
WebPPL will search the following locations for packages:
- The
node_modules
directory within the directory in which your program is stored. - The
.webppl/node_modules
directory within your home directory. Packages can be installed into this directory withnpm install --prefix ~/.webppl myPackage
.
Packages can be loaded from other locations by passing a path:
webppl myFile.wppl --require ../myPackage
Packages can extend WebPPL in three ways:
You can automatically prepend WebPPL files to your code by added a wppl
entry to package.json
. For example:
{
"name": "my-package",
"webppl": {
"wppl": ["myLibrary.wppl"]
}
}
Any regular Javascript code within a package is made available in WebPPL as a global variable. The global variable takes the same name as the package except when the package name includes one or more -
characters. In such cases the name of the global variable is obtained by converting the package name to camelCase.
For example, if the package my-package
contains this file:
// index.js
module.exports = {
myAdd: function(x, y) { return x + y; }
};
Then the function myAdd
will be available in WebPPL as myPackage.myAdd
.
If your Javascript isn't in an index.js
file in the root of the package, you should indicate the entry point to your package by adding a main
entry to package.json
. For example:
{
"name": "my-package",
"main": "src/main.js"
}
Note that packages must export functions as properties of an object. Exporting functions directly will not work as expected.
Sometimes, it is useful to define external functions that are able to access WebPPL internals. Header files have access to the following:
- The store, continuation, and address arguments that are present at any point in a WebPPL program.
- The
env
container which allows access toenv.coroutine
among other things.
Let's use the example of a function that makes the current address available in WebPPL:
-
Write a Javascript file that exports a function. The function will be called with the
env
container and should return an object containing the functions you want to use:// addressHeader.js module.exports = function(env) { function myGetAddress(store, k, address) { return k(store, address); }; return { myGetAddress: myGetAddress }; };
-
Add a
headers
entry topackage.json
:{ "name": "my-package", "webppl": { "headers": ["addressHeader.js"] } }
-
Write a WebPPL file that uses your new functions (without module qualifier):
// addressTest.wppl var foo = function() { var bar = function() { console.log(myGetAddress()); } bar(); }; foo();
-
Update version in dev:
git checkout dev npm version patch // or minor, or major; prints new version number
-
Merge into master
git checkout master git merge dev grunt
-
Push to remotes and npm
git push origin dev git push origin master git push origin v0.0.1 // again, use version printed by "npm version" command above npm publish