Business Rules in Prolog
Given the considerable current discussion about 'terms,' 'facts,' and 'rules' (i.e., in the Business Rules Group, the OMG's Business Rules Working Group, and elsewhere), it might be helpful to illustrate these concepts from a completely different perspective: Since Prolog is based on 1st order predicate calculus and some 2nd order extensions, it is probably one of the oldest (and most mature) rules-based knowledge representation languages.
In this article, I will sketch the usage of 'term,' 'fact,' and 'rule' in Prolog. Note that although Prolog is a language -- and therefore could be considered to be a kind of technology -- in this article I don't want to focus on Prolog as (just another) programming language. I would like to look at it as a tool to "conduct experiments in predicate calculus," which should form the foundation of any business rules approach.
Knowledge in Prolog is basically represented using the following "building blocks" (which I'll explain in more detail with some examples that follow):
- terms -- which represent anything important to the programmer, user, or
domain expert. Terms could either be 'atoms' or 'structures.'
- clauses -- which are built from 'terms' and represent anything that Prolog should believe to be true. Clauses could either be 'facts' or 'rules.'
Terms - - Atoms and Structures*/ ?>
An 'atom' is a simple text string that could be used to name anything (and I literally mean that). In Prolog, these text strings are identifiers that must either start with a lower case character or must be quoted. So, the following examples are all valid atoms:
- 'even this is an atom'
Numbers are also considered as (a special type of) atom, but the difference is not important here.
A 'structure' is an expression based on terms (and thus may include atoms and structures) using some composition rules. Such structures could either be: 'functional terms,' having a fixed number of terms, or 'lists,' consisting of a variable number of terms. Although lists are a very important and extremely powerful data structure, we will not discuss them further here. More relevant in the connection of business rules are functional terms, which are constructed using a 'functor' (an atom) plus a specific number of arguments in parentheses, '(' and ').' Very often, functional terms are used to express predicates (more on this later).
Finally, functional terms having exactly one term can be declared as 'prefix operators' (the argument is after name) or 'postfix operators' (the argument is before name). Functional terms having exactly two arguments can be declared as 'infix operators,' i.e., the name may be written between the two arguments.
Valid examples of structures are thus:
- likes('Jane', apple) ~ or, using infix syntax: 'Jane' likes apple
- is_a('Jane', girl)
- age('Jane', 25)
- parents('Gloria', 'Jack', 'Jane')
- sqrt(plus(multiply(a, a), multiply(b, b))) ~ an example of nested structures
However, so far terms are just tokens (either simple or structured) that are used to represent anything important to humans. Any interpretation of the semantics of those terms is completely up to the humans reading (or writing) them. Nothing has been said about whether or not they are true, nor has any kind of definition been given for those tokens. (Prolog, in contrast to humans, doesn't care about definitions.)
Clauses - - Facts and Rules*/ ?>
Facts Represent Knowledge
As soon as an atom or a functional term is asserted to Prolog's knowledge base, it becomes a 'clause' (or a 'proposition' in logic calculus terminology). From that point on, Prolog believes that this term is true, i.e., it is now an important piece of knowledge worth remembering. This is usually represented by a terminating dot '.' at the end of a term.
The following examples show some simple 'fact clauses.' (Note the dot at the end.)
- '7 is a prime'.
- '8 is a prime'. Prolog believes that, if that is what you assert!
- age('Jane', 25).
- likes('Jane', apple).
- parents('Gloria', 'Jack', 'Jane').
- is_a('Jane', girl).
Note that the first three clauses tell Prolog that things called 'girl,' 'Jane,' and 'likes' exist. Also note that the second example represents a fact about an instance 'Jane,' whereas the first example represents a fact about the existence of the concept 'girl.' However, this distinction is irrelevant to Prolog; it is completely a matter of the human reader's interpretation.
The first two examples about primes (items 4 & 5) are atomic propositions (of propositional logic), whereas the second two examples (items 6 & 7) are (an incorrect) part of the definition of the predicate 'prime.' Although the two variants represent absolutely the same content, the expressions based on predicate logic can be more flexibly used as we will see later. They express that the numbers '7' and (incorrectly) '8' own the property of "being prime." This can be understood in the same way that 8th clause states that 'Jane' owns the property of "being a girl."
The remaining examples (items 9 through 12) relate two or more terms to each other, i.e., they represent some kind of association between (or participation of) terms. Note that the last example even relates an instance to a concept.
Moving from Facts to Rules
The types of clause shown above are called 'facts' since they are always (i.e., unconditionally) true. Facts are represented using 'terms' (i.e., atoms and/or functional terms). Now, there is a special atom ':- ' (called 'if') that turns a 'fact' into a 'rule.' Specifically, the expression
Proposition1 :- Proposition2.
Proposition1 can be derived, if
is found to be true. In other words,
Proposition1 is provable
Proposition2. This is what Prolog calls a 'rule,'
which is simply a special kind of fact -- one that is true only under certain conditions.
Rules, therefore, are still represented using terms.
Along with rules usually comes the concept of a 'logical, existential quantified variable.' This core concept of predicate calculus is represented in Prolog by an identifier starting with an upper case letter (to avoid an explicit 'all' quantifier " for each variable). The following examples show some very simple rules:
- fruit(X) :- member(X, [apple, pear, orange, banana]).
- smaller(X, Y) :- X < Y.
- woman(X) :- girl(X).
- good_customer(Cust) :-
credit_limit(Cust, CL), CL > 10000,
The first two examples state a conditional fact (i.e., a rule) that is based on the internal predicates 'member' and '<'. The first example even uses a 'list' to represent a set of fruits. The third example shows a rule that is based on a fact previously stated: any X is a woman, if this X is a girl. (Whether or not this is correct at the domain level, Prolog believes this.)
Finally, the fourth rule is an example of a conjunction as a condition (expressed by a simple comma ',') as well as having more than one logical variable in the rule (Cust and CL). However, remember that every rule is still a functional term composed of the atom ':- ' and two sub-structures (the fact-head and the body-condition).
As a summary, we can conclude with the following observations, which are Prolog's view on terms, facts, and rules:
- A term is either atomic or a structure.
- If a term is atomic, it is a symbol (or name or identifier or representation)
of any concept.
- If a term is a structure (i.e., complex), this structure may represent the structural
nature of a concept.
- As soon as a term is asserted, it becomes a predicate expressing a property of
a concept, or an association between two or more concepts.
- A fact is a term that is known to exist and/or to be true.
- A rule is a fact that is true only under certain conditions.
- Even a fact or a rule is represented by a term, which in turn represents the concept of the fact or rule. (This is the mantra.)
Although this was a very informal introduction into the programming language Prolog (and its foundation, predicate calculus), I hope it has brought some insight to knowledge representation in (predicate) logic.
# # #