pub enum Unifiable {
Nil,
Anonymous,
Atom(String),
SFloat(f64),
SInteger(i64),
LogicVar {
id: usize,
name: String,
},
SComplex(Vec<Unifiable>),
SLinkedList {
term: Box<Unifiable>,
next: Box<Unifiable>,
count: usize,
tail_var: bool,
},
SFunction {
name: String,
terms: Vec<Unifiable>,
},
}
Variants§
Nil
In a linked list, Nil indicates that a node has no next node (i.e. is last).
Anonymous
The anonymous variable, $_, unifies with anything. Use anon! to create.
Atom(String)
A string constant. Use atom! to construct.
SFloat(f64)
64-bit floating point number.
SInteger(i64)
64-bit integer.
LogicVar
Logic variables have an ID number, which is used as an index
into a substitution set.
A logic variable name should start with a dollar sign,
followed by a letter. For example: $X.
Use logic_var! to construct.
SComplex(Vec<Unifiable>)
Complex (or compound) term. Eg. symptom(flu, $Symp).
Implemented as a vector of unifiable terms.
Use scomplex! to construct.
SLinkedList
Represents a node in a linked list of unifiable terms.
term
- Holds a value (any Unifiable term).
next
- Points to next node, must be SLinkedList
or Nil
.
count
- The number of nodes in the list.
tail_var
- Boolean . True indicates that the last term is a tail variable.
Examples of lists: [a, b, c, d], [$Head | $Tail]
Use slist! to construct.
SFunction
This variant defines built-in functions, such as add(), join(), etc.
Built-in functions produce a unifiable term from a list of arguments.
Implementations§
Source§impl Unifiable
impl Unifiable
Sourcepub fn key(&self) -> String
pub fn key(&self) -> String
Creates a key (= predicate name) for indexing into a knowledge base.
The name of a predicate consists of its functor plus its arity,
separated by a slash. For example, for the fact loves(Chandler, Monica)
,
the functor is loves
and the arity is 2, therefore the name of the
predicate is loves/2
.
§Arguments
- self - SComplex
§Return
- key
§Panics
- If self is not a complex term.
§Usage
use suiron::*;
let cmplx = parse_complex("loves(Chandler, Monica)").unwrap();
let key = cmplx.key();
println!("{}", key); // Should print: loves/2
Sourcepub fn unify<'a>(
&'a self,
other: &'a Unifiable,
ss: &'a Rc<SubstitutionSet<'a>>,
) -> Option<Rc<SubstitutionSet<'a>>>
pub fn unify<'a>( &'a self, other: &'a Unifiable, ss: &'a Rc<SubstitutionSet<'a>>, ) -> Option<Rc<SubstitutionSet<'a>>>
Tries to unify two terms.
Two terms can be unified if they are identical, if one of the terms is an unbound variable, or if one of the terms is a bound variable whose ground term matches the other term. For example:
1: verb = verb
Terms are identical. Unification succeeds.
2: $X = verb
If $X is unbound, unification succeeds.
3: $Y = verb
If $Y was previously bound to verb
,
unification succeeds.
4: $Z = verb
If $Z was previously bound to pronoun
,
unification fails.
In examples 1, 2 and 3 above, unification succeeds, so the method will return a substitution set. For example 4, the method will return None.
In examples 1 and 3, the substitution set is returned unchanged.
In example 2, a new binding must be registered. This method will create a new substitution set, copy in the previous bindings, add the new binding ($X to verb), and return the new substitution set.
§Arguments
- self - a unifiable term
- other unifiable term
- SubstitutionSet
§Returns
- SubstitutionSet or None
§Usage
use std::rc::Rc;
use suiron::*;
let x = logic_var!(next_id(), "$X");
let age = SInteger(37);
let ss = empty_ss!();
match x.unify(&age, &ss) {
Some(ss) => { print_ss(&ss); },
None => { println!("Cannot unify."); },
}
The above should print:
----- Substitution Set ----- 0 Nil 1 37 ----------------------------
Sourcepub fn recreate_variables(self, recreated_vars: &mut VarMap) -> Unifiable
pub fn recreate_variables(self, recreated_vars: &mut VarMap) -> Unifiable
Recreates logic variables to give them unique IDs.
The scope of a logic variable is the rule in which it is defined. For example, the two rules below both have a variable named $X, but the $X in father is different from the $X in mother.
father($X, $Y) :- parent($X, $Y), male($X).
mother($X, $Y) :- parent($X, $Y), female($X).
For rules stored in the knowledge base, the ID of all variables is 0, the default. When a rule is fetched from the knowledge base, its variables must be replaced (recreated) with variables which have unique IDs.
A variable may appear more than once in a rule. In the rule father/2, above, the variable $X appears 3 times, but each instance must have the same ID. The map recreated_vars holds the IDs of previously recreated variables. Thus, the first appearance of $X is given an ID number, and each subsequent occurrence of $X is given the same ID.
§Arguments
- self
- previously recreated variable IDs
§Return
- new term
§Usage
use suiron::*;
let s = "mother($X, $Y) :- parent($X, $Y), female($X).";
let rule = parse_rule(s).unwrap();
// IDs of $X and $Y are 0.
let recreated_rule = rule.recreate_variables(&mut VarMap::new());
println!("{}", recreated_rule);
// Should print:
// mother($X_1, $Y_2) :- parent($X_1, $Y_2), female($X_1).
Sourcepub fn replace_variables(&self, ss: &SubstitutionSet<'_>) -> Unifiable
pub fn replace_variables(&self, ss: &SubstitutionSet<'_>) -> Unifiable
Replaces logic variables in an expression with the constants (atoms and numbers) which they are ultimately bound to, in order to display solutions.
§Arguments
- self
- SubstitutionSet
§Return
- new term
§Usage
use std::rc::Rc;
use suiron::*;
let loves = atom!("loves");
let alf = atom!("Alfalfa");
let x = logic_var!(20, "$X");
// Make query: loves(Alfalfa, $X)
let c = scomplex!(loves, alf, x.clone());
let mut ss = empty_ss!();
let dar = atom!("Darla");
ss = x.unify(&dar, &ss).unwrap();
let c2 = c.replace_variables(&ss);
println!("{}", c2); // Prints: loves(Alfalfa, Darla)