GNU Prolog - Prolog Tutorial and Help page for CSC 212

R. Little, A. Parkin and D. Church, updated Dec. 14, 2006

For comments, suggestions, requests or to report errors, please email Bill Gorman:
bgorman AT csc DOT uvic DOT ca

Table of Contents


Getting Started

  1. Where to find Prolog
    To begin working with the Prolog programming language, you will first need to make use of a Prolog interpreter. The interpreter used for Prolog in the labs is GNU Prolog. GNU Prolog is open source software available from Project GNU here. To begin, either log into one of the Linux machines in ECS (ECS 242 or 342) and open up a new shell terminal window, or SSH into one of the lab machines from a Windows OS machines in one of the Windows labs, or from home (a list of the machines in ECS 242 can be found here).
  2. The Prolog Interpreter
    For the purpose of the following examples and explanations, it is assumed that we have SSH'd into u-linux.csc.uvic.ca, in room ECS 242, or that, on the same machine in ECS 242, have opened a shell terminal window. At the prompt, type the word gprolog to execute the Prolog interpreter:

    u-linux% gprolog
    GNU Prolog 1.2.16
    By Daniel Diaz
    Copyright (C) 1999-2002 Daniel Diaz
    | ?-


    Note that the prompt has now changed to | ?- , this indicates that you are now running inside of the GProlog interpreter.
  3. Getting Help
    We can now begin entering commands into the interpreter. Note that in order to get help we need to 'interupt' the interpreter. To do this we use <ctrl>-<c> to interupt the interpreter, and then at the resulting prompt type h to get the help list. Note the following example:

    | ?- ***Hit the ctrl-c here***
    Prolog interruption (h for help) ? h
       a  abort        b  break
    c continue e exit
    d debug t trace
    h/? help
    Prolog interruption (h for help) ?

  4. Exiting the Interpreter
    How to leave the Prolog environment? In order to exit Prolog, at the | ?- prompt type halt. (note that you must type a period after the command halt in the interpreter). This will return you to the shell terminal prompt. Note, again, that the command halt must be followed by a period:

    | ?-> halt.
    u-linux%

Basic Prolog

  1. Entering commands
    The following is an excerpt from gnu-prolog site. <--Click on the link to see the original.
    All prolog queries, rules and facts must end with a period. The GNU Prolog top-level is built on a classical read-execute-write loop that also allows for re-executions (when the query is not deterministic) as follows: Here is an example of execution of a query (``find the lists X and Y such that the concatenation of X and Y is [a,b]''):
    | ?- append(X,Y,[a,b,c]).
     
    X = []
    Y = [a,b,c] ? ;    (here the user presses ; to compute another solution)
     
    X = [a]
    Y = [b,c] ? a    (here the user presses a to compute all remaining solutions)
     
    X = [a,b]
    Y = [c]    (here the user is not asked and the next solution is computed)
     
    X = [a,b,c]
    Y = []    (here the user is not asked and the next solution is computed)
     
    no   (no more solution)
  2. Queries and Clauses
    The interactive Prolog interpreter is designed to run queries against its loaded list of predicates. It is possible, however, to add to the definitions while running the interpreter, from the console. To do this, we begin by entering the [user]. command. Then enter your list of predicates, hitting ENTER after the last line of the predicate list, followed by a <CTRL>-<D>. For example:
    | ?- [user].
    compiling user for byte code...
    factorial(0,1).
    factorial(N,F) :-
    N>0,
    N1 is N-1,
    factorial(N1,F1),
    F is N * F1.
    **Here you hit <CTRL>-<D> on the empty line**
    user compiled, 7 lines read - 826 bytes written, 139242 ms

    (1 ms) yes
    | ?-
    factorial(5, W).

    W = 120 ?

Loading Files

  1. Completing an assignment in Prolog can be a work of frustration if, each time you start the Prolog interpreter, you have have to re-enter the code you were working on. Prolog has a procedure for loading a file containing code you have defined into the current environment. The command to load a file is consult, and if you need to re-load a file that you have made changes to, the command is reconsult. The following example demonstrates loading a file named grammar.pl, and then listing the file:
    | ?-consult('grammar.pl').
    compiling /home/username/grammar.pl for byte code...
    /home/username/grammar.pl compiled, 25 lines read - 2095 bytes written, 18 ms

    (1 ms) yes
    | ?-
    listing.

    d([the|A], A).
    d([a|A], A).

    n([dog|A], A).
    n([cat|A], A).
    n([gardener|A], A).
    n([policeman|A], A).
    n([butler|A], A).

    s(A, B) :-
            np(A, C),
            vp(C, B).

    v([chased|A], A).
    v([saw|A], A).

    np(A, B) :-
            d(A, C),
            n(C, B).

    vp(A, B) :-
            v(A, C),
            np(C, B).

    (1 ms) yes
    | ?-

    **NOTE**
    The actual contents of the file grammar.pl is listed below in green. Comparing it to the results of the listing observe that Prolog uses its own variable names and excludes the comments.
    Content listing of the file grammar.pl
    %File: grammar.pl
    %Example of a small generative grammar with 3 re-write rules
    %and 9 lexical entries (facts).
    
    %Rules
    %Each rule has two argument variables that represent lists.
    %The first list is the input to the rule and the second is
    %used to keep track of the remaining input.
    
    s(L1,L) :- np(L1,L2), vp(L2,L).
    np(L1,L) :- d(L1,L2), n(L2,L).
    vp(L1,L) :- v(L1,L2), np(L2,L).
    
    %Lexicon
    %Each lexical entry represents a word and its lexical category.
    
    d([the|L],L).
    d([a|L],L).
    n([dog|L],L).
    n([cat|L],L).
    n([gardener|L],L).
    n([policeman|L],L).
    n([butler|L],L).
    v([chased|L],L).
    v([saw|L],L).