Expand description
§Suiron
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 online 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 has a parser which loads these facts and rules from a text-format source file.
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.
Re-exports§
pub use unifiable::*;
pub use unifiable::Unifiable::*;
pub use substitution_set::*;
pub use logic_var::*;
pub use s_linked_list::*;
pub use s_complex::*;
pub use solutions::*;
pub use parse_terms::*;
pub use parse_goals::*;
pub use rule_reader::*;
pub use token::*;
pub use tokenizer::*;
pub use parse_stack::*;
pub use operator::*;
pub use goal::*;
pub use rule::*;
pub use knowledge_base::*;
pub use solution_node::*;
pub use solution_node_and_or::*;
pub use built_in_print::*;
pub use built_in_append::*;
pub use built_in_filter::*;
pub use built_in_functor::*;
pub use built_in_predicates::*;
pub use built_in_functions::*;
pub use built_in_comparison::*;
pub use built_in_arithmetic::*;
pub use built_in_print_list::*;
pub use built_in_count::*;
pub use built_in_join::*;
pub use time_out::*;
pub use infix::*;
pub use benchmark::*;
Modules§
- benchmark
- Module for benchmarking.
- built_
in_ append - Appends terms (including lists) to make a new linked list.
- built_
in_ arithmetic - Suiron’s arithmetic functions: add, subtract, multiply, divide.
- built_
in_ comparison - Suiron’s comparison functions: equal, less_than, greater_than, etc.
- built_
in_ count - Functions to support the built-in predicate count().
- built_
in_ filter - Functions to support the built-in predicates include() and exclude().
- built_
in_ functions - Functions to support Suiron’s built-in functions (SFunction).
- built_
in_ functor - Gets the functor and arity of a complex term.
- built_
in_ join - Functions which support join().
- built_
in_ predicates - Functions to support built-in predicates.
- built_
in_ print - Support for built-in predicate print().
- built_
in_ print_ list - Support functions for the built-in predicate print_list().
- goal
- A logic expression to be solved (proven true or false).
- infix
- Defines infixes for built-in predicates and functions.
- knowledge_
base - Defines a dictionary of predicates (facts and rules).
- logic_
var - Functions to support logic variables and the global LOGIC_VAR_ID.
- macros
- Utilities for creating logic variables, complex terms, lists, etc.
- operator
- A base type for And and Or logic operators, etc.
- parse_
goals - Utilities for parsing goals and queries.
- parse_
stack - LIFO stack for parsing. Used by the tokenizer.
- parse_
terms - Functions for parsing unifiable terms and lists of terms.
- rule
- Defines a fact or rule.
- rule_
reader - Functions to read Suiron facts and rules from a file.
- s_
complex - Functions to support complex terms.
- s_
linked_ list - Functions to support Suiron lists.
- solution_
node - A SolutionNode is a node in a proof tree.
- solution_
node_ and_ or - Functions to support logical And and Or operators.
- solutions
- Functions which search for and format solutions.
- substitution_
set - A substitution set is an array of bindings for logic variables.
- time_
out - Functions for limiting execution time.
- token
- A leaf or branch node of a token tree. Used for parsing.
- tokenizer
- Functions which tokenize text strings to a generate goals.
- unifiable
- Unifiable terms (atoms, numbers, logic variables, complex terms, etc.).
Macros§
- add_
rules - Adds facts and rules to a knowledge base.
- and_
goal - Creates an And operator, and wraps it in a Goal.
- anon
- Creates an anonymous variable.
- atom
- Makes an atom from a string slice.
- chars_
to_ string - Converts a vector or array of chars to a String.
- cons_
node - Constructs one node of a singly linked list.
- empty_
ss - Creates an empty substitution set, pointed to by an Rc-pointer.
- logic_
var - Creates a logic variable from a string slice and an optional ID.
- or_goal
- Creates an Or operator, and wraps it in a Goal.
- pred
- Creates a built-in predicate or complex term, and wraps it in a Goal.
- query
- Creates a query from a list of terms.
- rc_cell
- Creates a smart pointer to mutable data.
- scomplex
- Creates a complex term (= compound term).
- sfunction
- Creates a built-in function.
- slist
- Builds a Suiron list.
- str_
to_ chars - Converts a string slice to a vector of characters.
- unify
- Creates a Unify goal.