README.md

# tinypp

[![Package Version](https://img.shields.io/hexpm/v/tinypp)](https://hex.pm/packages/tinypp)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/tinypp/)

`tinypp` is a tiny Gleam package to do *probabilistic programming* (hence the
name).
It is inspired by the probabilistic programming language
[*Church*](https://web.stanford.edu/~ngoodman/papers/churchUAI08_rev2.pdf)
after reading [this fun paper](https://dl.acm.org/doi/10.1145/3759429.3762631).

It allows you to program probability distributions with discrete support, making
heavy use of Gleam's `use`-syntax.
The main functions are `sample`, `condition` and `query`:
- `use x <- sample(distribution)`: State that `x` is supposed to follow
  `distribution`.
- `use <- condition(predicate)`: State that `predicate` should hold.
- `query(quantity)`: State that you are interested in the distribution of
  `quantity`.

See the example below on how put these together.

```sh
gleam add tinypp
```
```gleam
import gleam/float
import gleam/int
import gleam/io
import tinypp.{pmf, normalize, sample, condition, query}
import tinypp/distribution.{uniform}

pub fn main() -> Nil {
  // What is the probability that a die shows a value greater than three if we
  // know that the value is even?
  let distribution_greater_three = {
    let die = uniform([1, 2, 3, 4, 5, 6])
    use value <- sample(die)
    use <- condition(int.is_even(value))
    query(value > 3)
  }
  let p_greater_three = pmf(normalize(distribution_greater_three), True)
  io.println("P(value > 3 | value is even) = " <> float.to_string(p_greater_three))
}
```

In the [examples](examples/) folder, you can find more elaborate examples,
including Bayesian linear regression.


## Development

```sh
gleam test  # Run the tests
```