canrun 0.5.0

A logic programming library inspired by the *Kanren family of language DSLs.
Documentation
# Quick Start Explained

First, we import some basic parts:
```rust
use canrun::{LVar, both, either, unify, Query};
```

Next, we create "logic variables" to represent the unresolved parts of the goals we're about to create.

```rust
# use canrun::{LVar, both, either, unify, Query};
let x = LVar::new();
let y = LVar::new();
# let goal = both(unify(x, y), unify(1, x));
```
Each [`LVar`](crate::LVar) is parameterized by the type it may be bound to, which is typically inferred but can be specified if needed (e.g. `LVar::<i32>::new()`).

With our variables prepped, we're ready to create our first goal.
```rust
# use canrun::{LVar, both, either, unify, Query};
# let x = LVar::new();
# let y = LVar::new();
let goal = both(unify(x, y), unify(1, x));
```

The outer [`both`](crate::goals::both) goal will succeed if both of its nested goals succeed. The other two [`unify`](crate::goals::unify) goals are essentially asserting that their two parameters are equal (in a sense... see the [more detailed attempt to explain unification](crate::Unify)). So if `x` and `y` are equal (and nothing in this goal precludes that assertion), and `x` and `1` are equal, then...

Now it's time to collect our results. We can do this with a [query](crate::Query):
```rust
# use canrun::{LVar, both, either, unify, Query};
# let x = LVar::new();
# let y = LVar::new();
# let goal = both(unify(x, y), unify(1, x));
let result: Vec<_> = goal.query(y).collect();
assert_eq!(result, vec![1])
```

In order to extract results out of a goal, we need to be looking for something specific and relevant. In this case, we're basically saying, "I made a few assertions about how `x`, `y` and `1` are related. Now, what are the possible ["reified"](crate::Reify) values of `y`? The result is collected into a `Vec` containing every possible value that unifies with the `y` logical variable. In this case: `vec![1]`.

We can also get multiple possible results. For example, what if we say that it could be [`either`](crate::goals::either) `1` or `2`?

```rust
# use canrun::{LVar, both, either, unify, Query};
# let x = LVar::new();
# let y = LVar::new();
let goal = both(
    unify(x, y),
    either(unify(1, x), unify(2, x))
);
let result: Vec<_> = goal.query(y).collect();
assert_eq!(result, vec![1, 2])
```

We can also query for multiple variables, given the relevent [`Reify`](crate::Reify) implementations (provided for tuples and a few basic std collections).


```rust
# use canrun::{LVar, both, either, unify, Query};
# let x = LVar::new();
# let y = LVar::new();
# let goal = both(
#     unify(x, y),
#     either(unify(1, x), unify(2, x))
# );
let result: Vec<_> = goal.query((x, y)).collect();
assert_eq!(result, vec![(1, 1), (2, 2)])
```

Note that the results will match the shape of the query.

## Next
- Read up on the available [goal functions]crate::goals
- Learn more about how to [query for results]crate::Query
- Implement [`Unify` for your own types]crate::Unify