Advertisement

The Knowledge Representation Corner: Procedural vs. Declarative

By on

Click to learn more about author Adam Pease.

Programmers that are new to ontology may be prone to think that any tool or language can be used to represent terms, definitions, and facts about the world. After all, as programmers, we’re used to solving problems in code and know that whether we use Perl, C++, Java, LISP or any other language that we can still get the job done. The choice of language is about being efficient and effective, or comfortable from our history of use of a language, rather than whether it’s strictly possible to implement a solution. A college classmate of mine once decided to write his operating system assignment in Commodore Vic20 Basic, because the language choice was unrestricted and he needed more of a challenge. He could do that because Vic20 Basic was effectively comparable to any other language available to the students at the time, whether PDP11 Assembly, or Pascal. Formalists as well as practitioners may cite “turing equivalence” – that a wide variety of programming languages are functionally equivalent.

It may then come as a shock to find out that logics are not equivalent. It’s not a question of syntax, or preferences or aesthetics but an issue of mathematics whether one can express a particular statement in a particular kind of logic. It’s also an issue that is entirely orthogonal to turing equivalence. Turing equivalence is about procedural languages that specify the steps to accomplish something. However, logical languages, such as first order logic, specify what is true, rather than a series of steps to perform. In a logical language it is up to a theorem prover or inference engine to apply transformations or search procedures on the declarative logical theory. Theories are not executed so much as they are searched and transformed. All that is rather high level, so let’s take a look at some examples.

A declarative statement says something that is true, for example

“Paris is the capital of France.”


which might appear in a knowledge representation language as

(capitalOf Paris France)

or in a language like Prolog (more on this later) as

capitalOf(paris,france).

A procedural statement, in contrast, is an instruction to the computer to do something

“Print out the statement ‘Hello world’.”

System.out.println(“Hello world”);

or

“Count to 10.”

for (int i = 1; i < 11; i++) {
System.out.println(i);
}

One still has to command another program to do something with that code, such as compile and execute it. It makes no sense to “execute” a declarative statement. If we execute the Java code above we get…

1

2

3

4

5

6

7

8

9

10

A challenge with this nice clean division between declarative and procedure code is that some modern programming languages have elements of each.

public class Human extends Mammal {…}

This declares the class Human to be a sub-class of Mammal and inherit its relationships (as well as its methods). It’s a declarative statement made in a procedural language.

We also have (thanks to http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse45)

enjoys(vincent,X) :- big_kahuna_burger(X),!,fail.
enjoys(vincent,X) :- burger(X).

burger(X) :- big_mac(X).
burger(X) :- big_kahuna_burger(X).
burger(X) :- whopper(X).

big_mac(a).
big_kahuna_burger(b).
big_mac(c).
whopper(d).

In this set of declarative Prolog statements we have the procedural cut and fail combination (‘!’ is the ‘cut’ command) that prevent Prolog’s backtracking search process from operating. The order of the logical statements matters in this case. In a Prolog program the prolog interpreter executes a search process to find a solution to a query, such as

enjoys(vincent,X)

and the interpreter should find that ‘a’, ‘c’, and ‘d’ satisfy the set of declarative statements above and return those values as answers to the query.

Next we will look at some different logics and their limitations in Part 2 coming soon (August 15, 2016).

Leave a Reply