CMPS 350 Lab 04: Prolog

resources:
prolog tutorial
gnu prolog manual
Prolog predicates listing
ch. 16.4 - 16.6.6 of Sebesta
Prolog docs (Appendix A)
YA Prolog Tutorial
/examples/week04/

PART A

Your job in PART A is to complete a knowledge base in lab04.pl. Start by copying lab04.pl:
 

    $ cp /home/fac/melissa/public_html/cs350-f15/examples/week04/lab04.pl . 

The facts are given to you. The one predicate that will test the inferences in your knowledge base is: likes(X,Y), meaning "X likes Y." The universe of discourse is a set of animals, U={fido,kitty,tweety,ratatat}. Predicates are some characteristics of animals. The rules determine what kind of animal a member is. The inference engine infers which animal likes another animal.

Prolog variables (X,Y,etc.) begin with uppercase and predicate names or literals (loves, dog, animal, etc.) in lowercase. Note that discontiguous predicates are ignored - put like predicates together. Hint: If you make a change to your knowledge base, the safest thing to do is to exit prolog and reload the code from scratch. The file lab04.pl runs two initialization commands so that your script can be compiled and executed. Comment these commands out while testing your code at the interactive prompt. Put them back in when you submit your file.

# comment out while testing your code
:- initialization(q1).    
:- initialization(end). 
Leave these rules in your file.
q1 :- findall(X, (likes(X,Y), format('~n~w ~w',[X,Y])),_).
end :- writeln('#'), halt.

The facts below are given to you. Do NOT add additional facts. The goal is to let the inference engine do the work by applying the rules and reaching conclusions given these facts.

% FACTS. 
mammal(kitty).
mammal(ratatat).
mammal(fido).
claws(kitty).
tail(ratatat).
bestfriend(fido).
feathers(tweety).

Your job is to convert the 9 logical statements shown below into prolog rules.

% If X is a mammal then X has fur. 
% If X has fur and X has a tail then X is a rat. 
% If X has claws and X has fur then X is a cat.
% If X is a cat then X meows.
% If X has feathers then X is a bird.
% If X is a bestfriend and X has fur then X is a dog.
% If X is a dog and Y meows then X likes Y.
% If X is a cat and Y is a bird then X likes Y.
% If X is a cat and Y is a rat then X likes Y.

One query is adequate to test your knowledge base: "Who likes whom?" If everything is correst the answer shown below should be displayed.

:- likes(X,Y). 
fido kitty
kitty tweety
kitty ratatat

PART B

The material for part B of the lab is derived from "Tutorial 2: Operators and Arithmetic" of James Power's Prolog tutorial. In part B you will use Prolog to compute some arithmetic functions. The concept of a "variable" in Prolog differs from imperative languages. A variable is part of a predicate clause in Prolog. Variables are not assigned values in memory locations. Variables may be bound to a value by the 'is' operator, but within a single predicate clause, a variable cannot change value. Variables must be bound to a value before evaluation. How Prolog handles variables is shown in the following examples:

  | ?- I is I + 1.  <= this is an error because 'I' does not have a value 
  uncaught exception: error(instantiation_error,(is)/2)

  | ?- I is 6.  <== clause satisfied by I = 6
  I = 6

  | ?- I is 6, I is I + 1.  <= clause satisfied by I=6 and I=7  (impossible) 
  no

  | ?- I is 6, J is I + 1.  <= clause satisfied by I=6 and J=6+1
  I = 6
  J = 7
  yes

  | ?- N is 2, P is N * 2. <= satisfied by N=2 and P = 2*2" 
  N = 2
  P = 4
  yes

  | ?- I is 6, I is 7.  <== satisfied by I = 6 and I=7  (impossible)
  no
The binding of a variable to a value is in effect until the next statement. You also need to know how to do something in Prolog that you would normally do with a function in an imperative language. For example, how would you achieve the result of this simple function in Prolog?
 
  /* convert fahrenheit to celsius */
  float convert ( float far ) {
     return 5/9 * ( far - 32)
  }
Since Prolog is a logic language, first state the problem as a logical expression:
   For all X, if R is 5/9 * (X - 32), then R is the celsius conversion of X.
The equivalent Prolog predicate rule is shown below (R denotes result). Note that you cannot use numbers in predicate names.
   convert(X,R) :- X, R is 5/9 * (X - 32).   
What about a function to return the absolute value of an integer?
   int abs ( int num ) {
     if (num < 0 ) return -num
     else return num;
   }
This is expressed in predicate logic as: "for all X, X < 1, if R is -X OR for all X, X >= 0, if R is X, then R is the absolute value of X. And in Prolog:
   abs(X,R) :- X < 1, R is -X. 
   abs(X,R) :- X >= 1, R is X. 

For more examples copy this code:
 
  $ cp /home/fac/melissa/public_html/cs350-f15/examples/week04/math.pl .

Part B Instructions

Add to lab04.pl Prolog rules to accomplish the following.

1. Predicate rules to compute the maximum of three numbers. Example: 
       max3(5,10,3,X). should return 10.  
   Hint: code a max2(X,Y,R) that max3 can use.

2. Predicate rules that return the number of moves in the Towers 
   of Hanoi problem. Example:
         moves(3,R) 
   will return 7. 

   This is a recursive algorithm:
       moves(n) = moves(n-1) + moves(n-1) + 1. moves(1) = 1.

HOW YOUR CODE WILL BE GRADED

Your code must include with these queries:
% QUERIES
q1 :- writeln('Who likes whom? '),
      findall(X, (likes(X,Y), format('~w ~w~n',[X,Y])),_).
q2 :- write('Move cnt for 5: '),
      findall(X, (moves(5,X), format('~w',[X])),_).
q3 :- nl, write('Max(7,3,9)? '),
      findall(X, (max3(7,3,9,X), format('~w ~n',[X])),_).
end :- writeln('done.'), halt. 
Include these initializations at the top of your file:
% INITIALIZATIONS

:- initialization(q1).
:- initialization(q2).
:- initialization(q3).
:- initialization(end).

You do not need to send anything to me. The file lab04.pl for this lab must reside in this directory in your account:

  /home/stu/{username}/cs350/lab04/lab04.pl 
Sample output:
 $ gplc lab04.pl
 $ ./lab04
 Who likes whom? 
 fido kitty
 kitty tweety
 kitty ratatat
 Move cnt for 5: 31
 Max(7,3,9)? 9 
 done.