Crate suiron

Source
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:

    Logic Programming
    cse341

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.

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.

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.