README.md in mini_kraken-0.1.13 vs README.md in mini_kraken-0.2.00

- old
+ new

@@ -2,26 +2,33 @@ [![Build Status](https://travis-ci.org/famished-tiger/mini_kraken.svg?branch=master)](https://travis-ci.org/famished-tiger/mini_kraken) [![Gem Version](https://badge.fury.io/rb/mini_kraken.svg)](https://badge.fury.io/rb/mini_kraken) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/famished-tiger/mini_kraken/blob/master/LICENSE.txt) ### What is __mini_kraken__ ? -An implemention of the [miniKanren](http://minikanren.org/) relational programming language in Ruby. +A library containing an implementation of the [miniKanren](http://minikanren.org/) +relational programming language in Ruby. *miniKanren* is a small language for relational (logic) programming. Based on the reference implementation, in Scheme from the "The Reasoned Schemer" book. Daniel P. Friedman, William E. Byrd, Oleg Kiselyov, and Jason Hemann: "The Reasoned Schemer", Second Edition, ISBN: 9780262535519, (2018), MIT Press. ### Features +- Pure Ruby implementation, not a port from another language +- Object-Oriented design +- No runtime dependencies + +### miniKanren Features - [X] == - [X] run\* -- [X] fresh +- [X] fresh +- [X] conde - [X] conj2 - [X] disj2 - [X] defrel ### TODO -- [ ] conde + - [ ] Occurs check List-centric relations from Chapter 2 - [ ] caro - [ ] cdro @@ -44,12 +51,85 @@ Or install it yourself as: $ gem install mini_kraken -## Usage +## Examples -TODO: Write usage instructions here +The following __MiniKraken__ examples use its DSL (Domain Specific Language). + +### Example 1 +Let's first begin with a rather simplistic example. + +```ruby +require 'mini_kraken' # Load MiniKraken library + +extend(MiniKraken::Glue::DSL) # Add DSL method to self (object in context) + +result = run_star('q', equals(q, :pea)) +puts result # => (:pea) +``` + +The two first lines in the above code snippet are pretty standard: +- The first line loads the `mini_kraken` library. +- The second line add the DSL methods to the current object. + +The next line constitutes a trivial `miniKanren` program. +The aim of a `miniKanren` program is to find one or more solutions involving provided variable(s) +and satisfying one or more goals. +In our example, the `run_star` method instructs `MiniKraken` to find all solutions, +knowing that each successful solution: +- binds a value to the provided variable `q` and +- meets the goal `equals(q, :pea)`. + +The goal `equals(q, :pea)` succeeds because the logical variable `q` is _fresh_ (that is, + not yet bound to a value) and will be bound to the symbol `:pea` as a side effect + of the goal `equals`. + +So the above program succeeds and the only found solution is obtained by binding + the variable `q` to the value :pea. Hence the result of the `puts` method. + +### Example 2 + The next example illustrates the behavior of a failing `miniKanren` program. + + ```ruby + require 'mini_kraken' # Load MiniKraken library + + extend(MiniKraken::Glue::DSL) # Add DSL method to self (object in context) + + # Following miniKanren program fails + result = run_star('q', [equals(q, :pea), equals(q, :pod)]) + puts result # => () + ``` +In this example, we learn that `run_star` can take multiple goals placed in an array. +The program fails to find a solution since it is not possible to satisfy the two `equals` goals simultaneously. In that case, the `run_star` return an empty list represented as `()` in the output. + + +### Example 3 + The next example shows the use two logical variables. + +```ruby +# In this example and following, one assumes that DSL is loaded as shown in Example 1 + +result = run_star(['x', 'y'], [equals(:hello, x), equals(y, :world)]) +puts result # => ((:hello :world)) +``` + +This time, `run_star` takes two logical variables -`x` and `y`- and successfully finds the solution `x = :hello, y = :world`. + +### Example 4 + The next example shows the use of `disj2` goals. + ```ruby + result = run_star(['x', 'y'], + [ + disj2(equals(x, :blue), equals(x, :red)), + disj2(equals(y, :sea), equals(:mountain, y)) + ]) + puts result # => ((:blue :sea) (:blue :mountain) (:red :sea) (:red :mountain)) + ``` + + Here, `run_star` takes two logical variables and two `disj2` goals. A `disj2` succeeds if any of its arguments succeeds. + This program finds four distinct solutions for x, y pairs. ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.