#knowledge-base #query #fact #prolog #rules #engine #suiron

bin+lib suiron-rust

A fast Prolog-like inference engine

1 unstable release

0.1.0 May 3, 2023

#3 in #fact

MIT license

380KB
6K SLoC

Suiron - An inference engine written in Rust.

Suiron is a fast inference engine. Its fact/rule definition language is similar to Prolog, but there are some differences.

To understand how to use Suiron, a basic understanding of Prolog is helpful. Here are a couple of useful links:

Logic Programming
cse341

There is an on-line tutorial and test site for Suiron at: klivo.net/suiron

Briefly

An inference engines analyzes facts and rules which are stored in a knowledge base.

Suiron loads facts and rules from a text-format source file, parses them, and writes them to the knowledge base.

Below is an example of a fact, which means "June is the mother of Theodore":

mother(June, Theodore).

Here we see the main difference between Suiron and Prolog. In Prolog, lower case words are atoms (that is, string constants) and upper case words are variables. In Suiron, atoms can be lower case or upper case. Thus mother, June and Theodore are all atoms. Suiron's atoms can even contain spaces.

mother(June, The Beaver).

Suiron's variables are defined by putting a dollar sign in front of the variable name, for example, $Child. A query to determine June's children would be written:

mother(June, $Child).

The anonymous variable must also begin with a dollar sign: $_ . A simple underscore _ is treated as an atom. Below is an example of a rule which contains an anonymous variable:

voter($P) :- $P = person($_, $Age), $Age >= 18.




Facts and rules can also be created dynamically within a Rust application program. The fact mother(June, Theodore) could be created by calling the functions parse_complex() and make_fact().

let term = parse_complex("mother(June, Theodore).");
let fact = make_fact(term);

The query mother(June, $Child) could be created in Rust source as follows:

let mother = atom!("mother");
let june   = atom!("June");
let child  = logic_var!("$Child");
let query  = query!(mother, june, child);

Suiron also supports integer and floating point numbers, which are implemented as 64-bit ints and floats.

let pi = SFloat(3.14159);
let year = SInteger(2023);

If a float and an integer are compared, the integer will be converted to a float for the comparison.

Of course, Suiron supports linked lists, which work the same way as Prolog lists. A linked list can be loaded from a source file:

  …, [a, b, c, d] = [$Head | $Tail], …

or created dynamically in Rust:

let list1 = parse_linked_list("[a, b, c | $X]");
let list2 = make_linked_list(false, terms);

Requirements

Suiron was developed and tested with Rust/Cargo version 1.65.0.

https://www.rust-lang.org/

Cloning

To clone the repository, run the following command in a terminal window:

git clone git@github.com:Indrikoterio/suiron-rust.git

The repository has the following subfolders:

  • suiron-rust/benches
  • suiron-rust/src
  • suiron-rust/suiron_demo
  • suiron-rust/target
  • suiron-rust/tests

The source code for Suiron itself is under /src.

The subfolder /tests has programs which test the basic functionality of the inference engine. Tests can be run by opening a command line interface, moving to the suiron-rust folder and running the following command.

cargo test

The program under /benches (suiron_benchmark.rs) uses the Criterion crate to run a qsort algorithm. On a MacBook Pro, with a 2.8 GHz dual core Intel Core i5 processor, this benchmark runs in about 32 milliseconds. The program can be run with the command cargo bench.

The subfolder /suiron_demo contains a simple demo program which parses English sentences. If you intend to incorporate Suiron into your own project, this is a good reference. See: Suiron Demo

The /target folder holds build results.

Usage

The crate query uses suiron library crate to loads facts and rules from a file, and allows the user to query the knowledge base. Query can be run in a terminal window as follows:

cargo run -- test/kings.txt

The user will be prompted for a query with this prompt: ?-

The query below will print out all father/child relationships.

?- father($F, $C).

After typing <enter>, the program will print out solutions, one after each press of <enter>, until there are no more solutions.

cargo run -- test/kings.txt
?- father($F, $C).
$F = Godwin, $C = Harold II
$F = Godwin, $C = Tostig
$F = Godwin, $C = Edith
$F = Tostig, $C = Skule
$F = Harold II, $C = Harold
No more.
?- 

Suiron doesn't have a lot of built-in predicates, but it does have:

  • append
  • functor
  • print
  • print_list
  • nl (new line)
  • include, exclude
  • greater_than, less_than, etc.
  • arithmatic functions: +, -, *, /

Please refer to the test programs for examples of how to use these.

Developer

Suiron was developed by Cleve (Klivo) Lendon.

Contact

To contact the developer, send email to indriko@yahoo.com .
Comments, suggestions and criticism are welcomed.

History

First release, May 2023.

Reference

This inference engine was inspired by the Predicate Calculus Problem Solver presented in chapters 23 and 24 of 'AI Algorithms...' by Luger and Stubblefield. I highly recommend this book.

AI Algorithms, Data Structures, and Idioms in Prolog, Lisp, and Java
George F. Luger, William A. Stubblefield, ©2009 | Pearson Education, Inc.
ISBN-13: 978-0-13-607047-4
ISBN-10: 0-13-607047-7

License

The source code for Suiron is licensed under the MIT license, which you can find here: LICENSE.

Dependencies