suiron/
lib.rs

1//! # Suiron
2//!
3//! Suiron is a fast inference engine.
4//! Its fact/rule definition language is similar to Prolog, but there are some differences.
5//!
6//! To understand how to use Suiron, a basic understanding of
7//! [Prolog](https://en.wikipedia.org/wiki/Prolog) is helpful.
8//! Here are a couple of useful links:
9//!
10//! &nbsp; &nbsp; [Logic Programming](http://athena.ecs.csus.edu/~mei/logicp/prolog.html)<br>
11//! &nbsp; &nbsp; [cse341](https://courses.cs.washington.edu/courses/cse341/12au/prolog/basics.html)
12//!
13//! There is an online tutorial and test site for Suiron at:
14//! [klivo.net/suiron](https://klivo.net/suiron)
15//!
16//! ## Briefly
17//!
18//! An inference engines analyzes facts and rules which are stored in a knowledge base.
19//!
20//! Suiron has a parser which loads these facts and rules from a text-format source file.
21//!
22//! Below is an example of a fact, which means "June is the mother of Theodore":
23//!
24//! <pre>mother(June, Theodore).</pre>
25//!
26//! Here we see the main difference between Suiron and Prolog.
27//! In Prolog, lower case words are `atoms` (that is, string constants) and upper case
28//! words are variables. In Suiron, atoms can be lower case or upper case. Thus `mother`,
29//! `June` and `Theodore` are all atoms. Suiron's atoms can even contain spaces.
30//!
31//! <pre>mother(June, The Beaver).</pre>
32//!
33//! Suiron's variables are defined by putting a dollar sign in front of the variable name,
34//! for example, $Child. A query to determine June's children would be written:
35//!
36//! <pre>mother(June, $Child).</pre>
37//!
38//! The anonymous variable must also begin with a dollar sign: $\_ .
39//! A simple underscore `_` is treated as an atom.
40//! Below is an example of a rule which contains an anonymous variable:
41//!
42//! <pre>voter($P) :- $P = person($_, $Age), $Age >= 18.</pre>
43//!
44//! <br><hr><br>
45//!
46//! Facts and rules can also be created dynamically within a Rust application program.
47//! The fact mother(June,&nbsp;Theodore) could be created by calling the functions
48//! parse_complex() and make_fact().
49//!
50//! <pre>
51//! let term = parse_complex("mother(June, Theodore).");
52//! let fact = make_fact(term);</pre>
53//!
54//! The query mother(June, $Child) could be created in Rust source as follows:
55//!
56//! <pre>
57//! let mother = atom!("mother");
58//! let june   = atom!("June");
59//! let child  = logic_var!("$Child");
60//! let query  = query!(mother, june, child);</pre>
61//!
62//! Suiron also supports integer and floating point numbers, which are
63//! implemented as 64-bit ints and floats.
64//!
65//! <pre>
66//! let pi = SFloat(3.14159);
67//! let year = SInteger(2023);</pre>
68//!
69//! If a float and an integer are compared, the integer will be converted to
70//! a float for the comparison.
71//!
72//! Of course, Suiron supports linked lists, which work the same way as Prolog lists.
73//! A linked list can be loaded from a source file:
74//!
75//! <pre>
76//!   …, [a, b, c, d] = [$Head | $Tail], …</pre>
77//!
78//! or created dynamically in Rust:
79//!
80//! <pre>
81//! let list1 = parse_linked_list("[a, b, c | $X]");
82//! let list2 = make_linked_list(false, terms);</pre>
83//!
84//! ## Requirements
85//!
86//! Suiron was developed and tested with Rust/Cargo version 1.65.0.
87//!
88//! [https://www.rust-lang.org/](https://www.rust-lang.org/)
89//!
90//! ## Cloning
91//!
92//! To clone the repository, run the following command in a terminal window:
93//!
94//! <pre>
95//! git clone git@github.com:Indrikoterio/suiron-rust.git</pre>
96//!
97//! The repository has the following subfolders:
98//!
99//! - suiron-rust/benches
100//! - suiron-rust/src
101//! - suiron-rust/suiron_demo
102//! - suiron-rust/target
103//! - suiron-rust/tests
104//!
105//! The source code for Suiron itself is under /src.
106//!
107//! The subfolder /tests has programs which test the basic functionality of the
108//! inference engine. Tests can be run by opening a command line interface, moving
109//! to the suiron-rust folder and running the following command.
110//!
111//! <pre>cargo test</pre>
112//!
113//! The program under /benches (suiron_benchmark.rs) uses the Criterion crate
114//! to run a qsort algorithm. On a MacBook Pro, with a 2.8 GHz dual core Intel Core i5
115//! processor, this benchmark runs in about 32 milliseconds. The program
116//! can be run with the command `cargo bench`.
117//!
118//! The subfolder /suiron_demo contains a simple demo program which parses
119//! English sentences. If you intend to incorporate Suiron into your own project,
120//! this is a good reference.
121//! See: [Suiron Demo](../../../suiron_demo/target/doc/suiron_demo/index.html)
122//!
123//! The /target folder holds build results.
124//!
125//! ## Usage
126//!
127//! The crate `query` uses `suiron` library crate to loads facts and rules
128//! from a file, and allows the user to query the knowledge base.
129//! Query can be run in a terminal window as follows:
130//!
131//! <pre>
132//! cargo run -- test/kings.txt</pre>
133//!
134//! The user will be prompted for a query with this prompt: ?-
135//!
136//! The query below will print out all father/child relationships.
137//!
138//! <pre>
139//! ?- father($F, $C).</pre>
140//!
141//! After typing &lt;enter&gt;, the program will print out solutions,
142//! one after each press of &lt;enter&gt;, until there are no more solutions.
143//!
144//! <pre>
145//! cargo run -- test/kings.txt
146//! ?- father($F, $C).
147//! $F = Godwin, $C = Harold II
148//! $F = Godwin, $C = Tostig
149//! $F = Godwin, $C = Edith
150//! $F = Tostig, $C = Skule
151//! $F = Harold II, $C = Harold
152//! No more.
153//! ?- </pre>
154//!
155//! Suiron doesn't have a lot of built-in predicates, but it does have:
156//!
157//! - append
158//! - functor
159//! - print
160//! - print_list
161//! - nl (new line)
162//! - include, exclude
163//! - greater_than, less_than, etc.
164//! - arithmatic functions: +, -, *, /
165//!
166//! Please refer to the test programs for examples of how to use these.
167//!
168//! ## Developer
169//!
170//! Suiron was developed by Cleve (Klivo) Lendon.
171//!
172//! ## Contact
173//!
174//! To contact the developer, send email to indriko@yahoo.com .<br>
175//! Comments, suggestions and criticism are welcomed.
176//!
177//! ## History
178//!
179//! First release, May 2023.
180//!
181//! ## Reference
182//!
183//! This inference engine was inspired by the Predicate Calculus Problem Solver
184//! presented in chapters 23 and 24 of 'AI Algorithms...' by Luger and Stubblefield.
185//! I highly recommend this book.
186//!
187//!<blockquote>
188//! AI Algorithms, Data Structures, and Idioms in Prolog, Lisp, and Java<br>
189//! George F. Luger, William A. Stubblefield, ©2009 | Pearson Education, Inc.<br>
190//! ISBN-13: 978-0-13-607047-4<br>
191//! ISBN-10: 0-13-607047-7<br>
192//!</blockquote>
193//!
194//! ## License
195//!
196//! The source code for Suiron is licensed under the MIT license,
197//! which you can find here: [LICENSE](../../../LICENSE.txt).
198//!
199
200pub mod unifiable;
201pub mod substitution_set;
202pub mod logic_var;
203pub mod s_linked_list;
204pub mod s_complex;
205pub mod solutions;
206pub mod parse_terms;
207pub mod parse_goals;
208pub mod rule_reader;
209pub mod token;
210pub mod tokenizer;
211pub mod parse_stack;
212pub mod operator;
213pub mod goal;
214pub mod rule;
215pub mod knowledge_base;
216pub mod solution_node;
217pub mod solution_node_and_or;
218pub mod built_in_print;
219pub mod built_in_append;
220pub mod built_in_filter;
221pub mod built_in_functor;
222pub mod built_in_predicates;
223pub mod built_in_functions;
224pub mod built_in_comparison;
225pub mod built_in_arithmetic;
226pub mod built_in_print_list;
227pub mod built_in_count;
228pub mod built_in_join;
229pub mod time_out;
230pub mod infix;
231pub mod benchmark;
232
233#[macro_use]
234pub mod macros;
235
236pub use unifiable::*;
237pub use unifiable::Unifiable::*;
238pub use substitution_set::*;
239pub use logic_var::*;
240pub use s_linked_list::*;
241pub use s_complex::*;
242pub use solutions::*;
243pub use parse_terms::*;
244pub use parse_goals::*;
245pub use rule_reader::*;
246pub use token::*;
247pub use tokenizer::*;
248pub use parse_stack::*;
249pub use operator::*;
250pub use goal::*;
251pub use rule::*;
252pub use knowledge_base::*;
253pub use solution_node::*;
254pub use solution_node_and_or::*;
255pub use built_in_print::*;
256pub use built_in_append::*;
257pub use built_in_filter::*;
258pub use built_in_functor::*;
259pub use built_in_predicates::*;
260pub use built_in_functions::*;
261pub use built_in_comparison::*;
262pub use built_in_arithmetic::*;
263pub use built_in_print_list::*;
264pub use built_in_count::*;
265pub use built_in_join::*;
266pub use time_out::*;
267pub use infix::*;
268pub use benchmark::*;