README.md

# Trilean

An implementation of the K3+ [three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). The third value in this library is `Trilean.maybe()` This is an extension of Kleene's strong logic of indeterminacy.

Three value logics allow reasoning in face of uncertainty. For example

```
iex> will_a_sea_battle_be_fought_tomorrow = Trilean.maybe()
...> nice_day_tomorrow = true
...>
...> _should_i_pack_a_picnic = (
...>   will_a_sea_battle_be_fought_tomorrow
...>   |> Trilean.and(nice_day_tomorrow)
...>   |> Trilean.possible?()
...> )
true
```

I should pack a picnic because it will be a nice day and there could be a spectacle to watch. (The sea battle problem is Aristotle's formulation of the [contingent futures problem](https://en.wikipedia.org/wiki/Problem_of_future_contingents) on which three value logics can shed some light.)

```
iex> will_a_sea_battle_be_fought_tomorrow = Trilean.maybe()
...> nice_day_tomorrow = false
...>
...> _should_i_pack_a_picnic = (
...>   will_a_sea_battle_be_fought_tomorrow
...>   |> Trilean.and(nice_day_tomorrow)
...>   |> Trilean.possible?()
...> )
false
```
I should not pack a picnic even though there could be a spectacle because it will be a crummy day.

All expressions evaluate the same as they would in normal boolean logic if their inputs are true or false. If, however, one or more of the inputs is `:maybe` then the output may become indeterminate. For example:

```
iex> Trilean.and(true, true)
true
iex> Trilean.and(true, false)
false
iex> Trilean.and(true, Trilean.maybe())
Trilean.maybe()
```

## Operators

Operators for common uses are defined in `Trilean.Operators`

```
iex> use Trilean.Operators
...> will_a_sea_battle_be_fought_tomorrow = maybe()
...> nice_day_tomorrow = true
...>
...> _should_i_pack_a_picnic =
...>   (will_a_sea_battle_be_fought_tomorrow &&& nice_day_tomorrow)
...>   |> Trilean.possible?()
true
```

Supported operators are
 - `~~~`: Trilean.not/1
 - `|||`: Trilean.or/2
 - `&&&`: Trilean.and/2
 - `~>`: Trilean.implies/2
 - `<~>`: Trilean.equivalence/2

## Guards

Guards provided in `Trilean.Guards`.

```
iex> defmodule Picnic do
...>   use Trilean.Guards
...>   use Trilean.Operators
...>
...>  def pack_one?(sea_battle, nice_day) when is_possible(sea_battle),
...>    do: (sea_battle &&& nice_day) |> Trilean.possible?
...>  def pack_one(_,_), do:  false
...> end
...>
...> Picnic.pack_one?(Trilean.maybe(), true)
true
```
## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `trilean` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:trilean, "~> 0.1.0"}
  ]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/trilean](https://hexdocs.pm/trilean).