simple_predicates 0.4.2

A simple local configuration management utility
Documentation


# `simple_predicates` -- a library for modelling simple boolean predicates


A predicate is a formula that can be evaluated to true or false as a function of the values of the variables that occur in it. In `simple_predicates`, the variables denoted by a user-chosen type satisfying the `Eval` trait (which requires `Clone` and `PartialEq`.) The `Eval` trait also provides an associated `Context` type which can be used to provide contextual data needed to resolve the variables. The `Expr`, `Cnf`, and `Dnf` types can be used to construct evaluable expressions.


# Installation

Add the following to your `Cargo.toml`:

```toml
[dependencies]
simple_predicates = "0.2"
```


## Features

| Feature | Description |
| ------- | ----------- |
| "serde" | Enables serialization and deserialization of data using [serde]https://crates.io/crates/serde. |

By default, there are no features enabled.

# Example Usage

Lets say we want to write boolean expressions denoting the possibility of a `Vec` relating to some `u32` values according to the `Vec::contains` method. We start by implementing `Eval`:

```rust
use simple_predicates::Eval;

// Wrapper struct needed because `u32` & `Eval` are both foreign.
#[derive(Clone, PartialEq)]
struct Contains(pub u32);


impl Eval for Contains {
    type Context = Vec<u32>;

    fn eval(&self, data: &Self::Context) -> bool {
        // Evaluate the u32 by checking if it is in the `Vec`.
        data.contains(&self.0)
    }
}

```

Now we can check arbitrary containment conditions on a given `Vec` like so:

```rust
use simple_predicates::Eval;
use simple_predicates::Expr::*;

let items: Vec<u32> = vec![1, 2, 4, 7, 9, 10];

// `eval` is `true` if input contains 4 but not 5.
let expr = And(
    Box::new(Var(Contains(4))),
    Box::new(Not(Box::new(Var(Contains(5))))));

assert!(expr.eval(&items));

```

# Cnf / Dnf

For more complex expressions, the nesting of `And` and `Or` expressions can get very tedious, so the `Cnf` and `Dnf` types are provided to simplify their handling.

The `Cnf` type represents the [Conjunctive Normal Form](https://en.wikipedia.org/wiki/Conjunctive_normal_form) of a boolean expression; a set of expressions which are `And`ed together. The `Dnf` type represents the [Disjunctive Normal Form](https://en.wikipedia.org/wiki/Disjunctive_normal_form) of a boolean expression; a set of expressions which are `Or`ed together.

The `Cnf` and `Dnf` types can only be used if the variable type implements `Eq` and `Hash`. They have identical APIs, so the examples below are representative of either.

# Examples

A `Cnf` can be constructed from an Expr, using the `From` trait:

```rust
use simple_predicates::Eval;
use simple_predicates::Expr::*;

let items: Vec<u32> = vec![1, 2, 4, 7, 9, 10];

let cnf = Cnf::from(
    And(
        Box::new(Var(Contains(4))),
        Box::new(Not(Box::new(Var(Contains(5)))))));

assert!(cnf.eval(&items));

```


A `Cnf` can also be constructed from anything that emits Exprs with the `IntoIterator` trait:

```rust
use simple_predicates::Eval;
use simple_predicates::Expr::*;

let items: Vec<u32> = vec![1, 2, 4, 7, 9, 10];

let cnf = Cnf::from(vec![
    Var(Contains(4)),
    Not(Box::new(Var(Contains(5)))),
]);

assert!(cnf.eval(&items));

```


# License

simple_predicates is licenced with the [MIT license](/license-mit.md) or the [Apache version 2.0 license](/license-apache.md), at your option.