ITEC 380 - Prolog


Prolog - Introduction


A Sample Database

   % A sample database.  
   % marks comments
   % in file family.P

   % FACTS
      male(bob).             % bob is male
      parent(jill, bill).    % jill is parent of bill
      parent(bob, bill).    
   
      
   % RULES
    father(TheDad, TheChild) :- parent(TheDad, TheChild),
                male(TheDad). 

      % TheDad is the father of TheChild 
      %  if TheDad is the parent of TheChild and TheDad is male

      % Use meaningful variable names:
      %        father(X, Y) :- parent(X, Y), male(X). 
      %       X is the father of Y if X is the parent of Y 
      %                           and X is male
      
      %    ":-" read as "if"
      %    ","  read as "and"
   


Example Queries (Slightly Edited)
      >/usr/local/bin/xsb
                               % prolog prompt is ?-
      ?- [family].             % load file family.P 
      yes                      % It worked

      ?- male(bob).            % Is bob male?
      yes
      ?- male(jill).          
      no
      ?- male(tom)           
      no

      ?- female(bob)           % Not in database
      Undefined predicate female/1

      ?- parent(bob)           % Not in database
      Undefined predicate parent/1

      ?- parent(bob, bill).    % match
      yes

      ?- father(bob, bill).    % uses the rule!
      yes

      ?- halt.                 % or use ^D
      >


A Bit of Syntax


Trace

?- [family].
yes

?- trace.
yes

?- father(bob, bill).
0 Call: father(bob, bill)
1 Call: parent(bob, bill)
1 Exit: parent(bob, bill)
2 Call: male(bob)
2 Exit: male(bob)
0 Exit: father(bob, bill)
yes


Queries with Variables

Variables can also be used in queries.

 ?- male(X).            % Who is male?
 X = bob
 yes

 ?- parent(X, bill).    % Multiple answers
 X = jill,              % Type any characters

 X = bob;               % Another answer

 no                     % No more answers

 findall(X, parent(X, bill), L). %  ALL ANSWERS
 L = [jill, bob]
 yes

 ?- father(X, X).    % No one is father of himself
 no                  % Both X's stand for the same thing


Trace with Variables
      ?- father(bob, Child).     % bob is father of whom 
      Child = bill
      yes

?- father(bob, bill).
0 Call: father(bob, Child)
1 Call: parent(bob, Child)
1 Exit: parent(bob, bill)
2 Call: male(bob)
2 Exit: male(bob)
0 Exit: father(bob, bill)
yes


Backtracking
      ?- father(Dad, bill).  % Who is father of bill
      Dad = bob
      yes

?- father(bob, bill).
0 Call: father(Dad, bill)
1 Call: parent(Dad, bill)
1 Exit: parent(jill, bill)   % Jill is a parent of bill
2 Call: male(jill)           % Is jill male?
2 Fail: male(jill)           %   No
1 Redo: parent(jill, bill)   % Prolog tries to find another parent 
1 Exit: parent(bob, bill)
3 Call: male(bob)
3 Exit: male(bob)
0 Exit: father(bob, bill)
yes



Backtracking - A New Family Database


Singleton and Anonymous variables

Arithmetic with "is''


Arithmetic and Testing with Variables

More Arithmetic with Variables


Equality Operator

Relational Operators


Factorial


Prolog trace
?- fac(3, X)             % X and F share
0  Call: fac(3, X)       % N is 3
1  Call: 3 > 1
1  Exit: 3 > 1
2  Call: 2 is 3 - 1      % D is 2
2  Exit: 2 is 3 - 1
3  Call: fac(2, F')      % fac(N', F') 
                        %% New N and F: N' is 2
4  Call: 2 > 1
4  Exit: 2 > 1
5  Call: 1 is 2 - 1      % D' is 1
5  Exit: 1 is 2 - 1
6  Call: fac(1, F'')     % fac(N'', F'') 
                        %% New N and F: N'' is 1
6  Exit: fac(1, 1)       % F'' is  1

7  Call: 2 is 2 * 1      % F' is  N' * F''
7  Exit: 2 is 2 * 1      % F' is  N' * F''

3  Exit: fac(2, 2)       % New N and F
8  Call: 6 is 3 * 2      % F is  N * F'
8  Exit: 6 is 3 * 2      % F is  N * F'
0  Exit: fac(3, 6)      % New N and F: N' is 2


Read and Write


Fibonacci

fib(0,1).     /* Two base cases */
fib(1,1).     

fib(N, Result) :- N>1, 
            NM1 is N - 1, 
            NM2 is N - 2,     
            fib(NM1, Result1),      /* Recursive */
            fib(NM2, Result2),      
            Result is Result1 + Result2.

fibdemo1(N)  :- fib(N, Result), write(Result). 

fibdemo2     :- read(N), fib(N, Result), write(Result).


% Initial conditions can be passed to base case
% as in fib(0)=fib0, fib(1)=fib1, fn = fn-1 + fn-2
% Example: fib3(4, 2, 9, X)  gives X=31
%    since  11 + 20 = 42

fib3(0, Fib0, _, Result) :- Result=Fib0.
fib3(1, _, Fib1, Result) :- Result=Fib1.

fib3(N, Fib0, Fib1, Result) :- N >1,
                    NM1 is N - 1,
                    NM2 is N - 2,
                    fib3(NM1, Fib0, Fib1, Result1),
                    fib3(NM2, Fib0, Fib1, Result2),
                    Result is Result1 + Result2.


Other points
% Fac and fib calculate results as the
%   recursive calls return
% Results can also be calcuated as calls are made
%   and the final result is returned from base case

% Example: division by repeated subtraction:
%   Q = N / D

% This divide calculates after the returns

div1(N, D, Q) :- N >= 0, 
                 D > N, 
                 Q=0.

div1(N, D, Q) :- D > 0, 
                 N >= D, 
                 NMD is N - D, 
                 div1(NMD, D, Q1), 
                 Q is Q1 + 1.

% This divide calculates as the recursive calls
%  are made and passes result back
%  It needs a helper rule to initialize P

div2(N, D, P, Q) :- N > 0, 
                    D > N, 
                    Q=P.

div2(N, D, P, Q) :- D > 0, 
                    N >=D, 
                    NMD is N-D, 
                    PP1 is P+1, 
                    div2(NMD, D, PP1, Q).

div3(N, D, R) :- div2(N, D, 0, R).


Other points


Other points


Order matters


Order matters - Continued


Order Matters - Another Example (Skip)

Terminology (Skip)

Lists

Notation (Skip)

Head and Tail


Instantiating Lists

Instantiating Lists

More List Instantiation

Still More List Instantiation

Let's Write Some List Predicates


List Predicates - Some Implementations
printlist([]) :- nl.
printlist([H|T]) :- write(H), printlist(T).

% Reverse print list?  Trace??
% Notice how we split apart the list in the parameter!

%member: what is the base case?
member(X, [X|_]).
member(X, [_|L]) :- member(X,L).
% Trace and fill in info


append([], List, List).
append([H|L1], L2, [H|L3]) :- append(L1, L2, L3).

%append: build the list as append returns
%append: what if the base is append(List, [], List)


rev([],[]).
rev([H|T], List) :- rev(T, List2), 
                    append(List2, [H], List).


Building Lists

Built in predicates
Here are some built predicates. Many you could define yourself.

Some examples: quicksort, 8 queens


ITEC 380 Page,
Last modified on