https://github.com/probcomp/sppl.jl
A small DSL for programming sppl across PythonCall.jl
https://github.com/probcomp/sppl.jl
Last synced: 11 months ago
JSON representation
A small DSL for programming sppl across PythonCall.jl
- Host: GitHub
- URL: https://github.com/probcomp/sppl.jl
- Owner: probcomp
- License: apache-2.0
- Created: 2020-10-26T19:44:26.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-10-17T20:08:18.000Z (over 2 years ago)
- Last Synced: 2025-05-08T22:56:57.522Z (11 months ago)
- Language: Julia
- Homepage:
- Size: 238 KB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

[](https://probcomp.github.io/SPPL.jl/dev)
> Julia bindings for using [`sppl`](https://github.com/probcomp/sppl) across [PythonCall.jl](https://github.com/cjdoris/PythonCall.jl).
### Example usage
Allows the usage of direct string macros:
```julia
spn = sppl"""
Nationality ~= choice({'India': 0.5, 'USA': 0.5})
if (Nationality == 'India'):
Perfect ~= bernoulli(p=0.10)
if (Perfect == 1):
GPA ~= atomic(loc=10)
else:
GPA ~= uniform(loc=0, scale=10)
else:
Perfect ~= bernoulli(p=0.15)
if (Perfect == 1):
GPA ~= atomic(loc=4)
else:
GPA ~= uniform(loc=0, scale=4)
"""
```
as well as the usage of a native macro with native structures:
```julia
spn = @sppl begin
nationality ~ SPPL.Choice([:India => 0.5, :USA => 0.5])
perfect ~ SPPL.Bernoulli(0.1)
gpa ~ SPPL.Atomic(4)
end
println(spn)
```
```
(nationality = ,
perfect = ,
gpa = ,
model = )
```
Of course, you can use native abstractions:
```julia
@sppl function foo(x::Float64)
nationality ~ SPPL.Choice([:India => x, :USA => 1 - x])
perfect ~ SPPL.Bernoulli(0.1)
gpa ~ SPPL.Atomic(4)
end
```
which expands to produce a generator:
```
:(function foo(x::Float64)
gpa = Main.IndianGPA.SPPL.Id(:gpa)
nationality = Main.IndianGPA.SPPL.Id(:nationality)
perfect = Main.IndianGPA.SPPL.Id(:perfect)
command = Main.IndianGPA.SPPL.Sequence(
Main.IndianGPA.SPPL.Sample(nationality,
SPPL.Choice([:India => x, :USA => 1 - x])),
Main.IndianGPA.SPPL.Sample(perfect, SPPL.Bernoulli(0.1)),
Main.IndianGPA.SPPL.Sample(gpa, SPPL.Atomic(4))
)
model = command.interpret()
namespace = (nationality = Main.IndianGPA.SPPL.Id(:nationality),
perfect = Main.IndianGPA.SPPL.Id(:perfect),
gpa = Main.IndianGPA.SPPL.Id(:gpa),
model = model)
namespace
end)
```
### Syntax
There are a few special pieces of syntax which the user should keep in mind. Some of these points make the macro parsing unambiguous, others are more for convenience.
- `Sample` statements are expressed using `~` syntax.
- `Transform` expressions (a polynomial for example, expressed in Python as `X[1] ~ 8 * W[2]**2 + 5`) are specified a "special" operator `.>`.
- The Julia ternary expression `foo ? b1 : b2` is allowed - this desugars into `IfElse`.
- Array declarations are performed using the library-provided `array` function interface. Array declarations must be made (!) before indexing/use - or else macro parsing will return an error.
- `==` desugars to `<<` on the Python side (this creates an `event` - a condition).
- The `for` expression is allowed - but you are restricted to only supply `UnitRange{Int64}` instances for the parsing/semantics to work properly.
Examples of each of these points can be found in the [`examples` directory](https://github.com/femtomc/SPPL.jl/tree/master/examples). These `examples` come directly from the [sppl Jupyter notebooks](https://github.com/probcomp/sppl/tree/master/examples). If you'd like to help port these over, just setup a PR!