1 unstable release
0.1.0 | May 3, 2023 |
---|
#7 in #fact
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:
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.
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_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.