Introduction

This article describe how to write a simple Artificial Intelligence
application with Erlang, by using a rule production system.

To reach this objective, we will exploit the ERESYE tool, an
Erlang Inference Engine that allows rule-based systems to be written
directly in Erlang.

As it is widely known, a rule-based system is composed by a knowledge
base, which stores a set of facts representing the
"universe of discourse" of a given application, and a set of
production rules, which are used to infer knowledge and/or reason
about the knowledge. A rule is activated when one or more facts match the
template(s) given in the rule declaration: in such a case, the body of the
rule contains a code that is thus executed

In ERESYE, facts are expressed by means of Erlang tuples or
records, while rules are written using standard Erlang function clauses,
whose declaration reports, in the clause head, the facts or fact templates
that have to be matched for the rule to be activated and executed.

For more information about rule-based inference engines and expert
systems, you can refer to the book:S. Russell and P. Norvig. Artificial Intelligence: A Modern
Approach/2E. Prentice Hall, 2003.

To write an AI application with ERESYE the following steps have to be
performed:

Indentify your universe of discourse and determine the facts that have
to be used to represent such a world;

Indentify the rules that you need and write them by using, e.g.
first-order-logic predicates or even natural language;

Implement the system by writing your rules as Erlang function clauses,
according to the modality required by ERESYE.

Surely you have to obtain the ERESYE tool: it is not publicly advertised on
a web page but it can be easily obtained by dropping an email to one of its
author, Francesca Gangemi or Corrado Santoro
(csanto@diit.unict.it).

The Application: the Domain of Relatives

We will design a system able to derive new knowledge using some
inference rules and starting from a small set; as a sample application, we
chose the domain of relatives: we will start from some base concepts, such
as
parent, male and female, and then, by means of a
proper set of rules, we will derive the concepts of mother,
father,
sister, brother, grandmother and grandfather.

According to the list above, we will first derive the facts that will be
used to represent our concepts. Given the set of relationships above, they
will be represented by means of the following facts:

#

Concept

Fact / Erlang tuple

1

X is male

{male, X}

2

X is female

{female, X}

3

X is Y's parent

{parent, X, Y}

4

X is Y's mother

{mother, X, Y}

5

X is Y's father

{father, X, Y}

6

X is Y's sister

{sister, X, Y}

7

X is Y's brother

{brother, X, Y}

8

X is Y's grandmother

{grandmother, X, Y}

9

X is Y's grandfather

{grandfather, X, Y}

Concepts 1, 2 and 3 will be used as a base to derive the other ones.

Deriving new concepts by means of rules

Concept: "mother". The rule to derive the concept of
mother is quite straightforward:
if X is female and X is Y's parent then X is Y's mother.

From the point of view of ERESYE, since knowledge is stored in the
knowledge base of the engine, the rule above is translated into the
following one: if the facts {female, X} and {parent, X,
Y} are asserted in the knowledge base, then we assert the fact
{mother, X, Y}.

Please note the guard, which is needed to ensure that when Y and Z are
bound to the same value, the rule is not activated (indeed this is possible
since the same fact can match both the first and second
"parent" pattern).

Concept: "brother". Given the previous one, this
concept is now quite simple to implement:

Concepts: "grandmother" and "grandfather".
The former concept can be expressed by means of the rule:
if X is Y's mother and Y is Z's parent, then X is Z's
grandmother. The latter concept is now obvious. Both can be
implemented using the following ERESYE rules:

As the listing reports, creating a new ERESYE engine implies to call the
function eresye:start/1, giving the name of the engine to be
created.

Then, we have to add the rules to the engine by using the function
eresye:add_rule/2: it takes two arguments, the name of the engine
and a tuple representing the function in the form {Module,
FuncName}; obviously the function Module:FuncName must be
exported. Function add_rule has to be called for each rule that
has to be added; for this reason, the code above has an iteration over the
list of rules written before.

Finally, we populate the inference engine with a set of sample facts by
giving them, in a list, to the function eresye:assert/2.
To test our rules, we considered the relationships in the Figure below and
assert only the facts for
male, female and parent.

Following the call to function relatives:start/0, the engine is
created and populated; if no errors occurred, the rules should have been
processed and the new facts derived. To check this, we can use the function
eresye:get_kb/1, which returns the list of facts asserted into the
knowledge base of a given engine:

<p>The facts returned conform to the relationships depicted in the figure

above, thus proving that the rules written are really working.

As the example shows, function eresye:query_kb/2 takes the
engine name as the first argument, while, for the second parameter, a tuple
has to be specified, representing the fact template to be matched; in such
a tuple, the atom '_' plays the role of a wildcard. However, to
specify a more complex matching, a fun can be used as a tuple
element; this fun has to return a boolean value which indicates if
the element matches the template. For example, to select both Alice's and
Anna's brothers, we can use the following function call:

Conclusions

This HowTo not only shows how to use the ERESYE engine to write an AI
application, but also highlights the versatility of the Erlang language:
the characteristics of functional and symbolic programming, together with
the possibility of performing introspection of function declaration,
can be successfully exploited for application domains which are completely
new for Erlang but can surely be very interesting.