# Predicator
Predicator is a secure, non-evaling condition (boolean predicate) engine for end users.
It turns a string like `"score > 600 or income > 9000"` along with a supplied context into a `true` or `false`.
This condition can be stored as an attribute of a model (ex: an Offer model could store a condition indicating if it is available to a customer).
## Usage
### Compilation
The source code can be compiled down to list of instructions.
```elixir
Predicator.compile! "score > 600 or income > 9000"
# [
# ["load", "score"],
# ["lit", 600],
# ["compare", "GT"],
# ["jtrue", 4],
# ["load", "income"],
# ["lit", 9000],
# ["compare", "GT"]
# ]
```
### Evaluating
These instructions can be executed with a Predicator Evaluator in any available language (currently Elixir, and Ruby with others in progress).
```elixir
Predicator.compile!("score > 600 or income > 9000") |> Predicator.evaluate_instructions!(
%{"score" => 590, "income" => "6000"}
)
# false
Predicator.compile!("score > 600 or income > 9000") |> Predicator.evaluate_instructions!(
%{"score" => 590, "income" => "9500"}
)
# true
```
It is also possible to combine these steps:
```elixir
Predicator.evaluate!("score > 600 or income > 9000", %{"score" => 590, "income" => "7500"})
# false
Predicator.evaluate!("score > 600 or income > 9000", %{"score" => 590, "income" => "9500"})
# true
```
## Installation
The package can be installed by:
1. Adding to your list of dependencies in `mix.exs`:
```elixir
def deps do
[{:predicator, "~> 0.9"}]
end
```
or if you want to use the ecto types for predicator you can add the predicator_ecto lib.
```elixir
def deps do
[
{:predicator, "~> 0.9"},
{:predicator_ecto, ">= 0.0.0"},
]
end
```
### TODO:
- [ ] Lex and parse parens
- [ ] Lex and parse `date`, `duration`, `ago`, `fromnow`