/* COMMENTS: Comments in Prolog are written like this */ /* GNU PROLOG: The Prolog system on Imada is GNU Prolog. See http://pauillac.inria.fr/~diaz/gnu-prolog/ for more info Invoked by "gprolog" Once gprolog is running, a script is (re)loaded by "['script.pl']." */ /* BASIC SYNTAX: CONSTANTS are either alphanumeric strings starting with lowercase letter (underscore is allowed in string too, string may contain any character if surrounded by single quotes), or they are numbers. Examples: george, a, you_may_use_underscore, '4youEye$only' 234, 34.67, -3.8, 34.2e-4 VARIABLES are alphanumeric strings (underscore allowed too) starting with uppercase letter. Examples: X, Result, NumberOfReports, My_tax LISTS and TUPLES may be combine these. Examples: (peter,alice,23.5,(34,jens)) (X,Y,top) [peter,alice,[],[[[2,3],[3]],0],(peter,alice)] [Head|Tail] STRUCTURES consist of name (functor) and arguments (components) in parentheses. They may be thought of both as boolean functions (predicates), and as data structures (records). Nullary structures use no parentheses. Examples: peter owns(peter,volvo_S60) owns(peter,X) owns(X,volvo_S60) CLAUSES (in script) specifies boolean functions (predicates) by specifying what makes them true. They are of the form S. or S :- S'. where S and S' are structures. Examples: alice. owns(peter,volvo_S60). owns(alice,X). owns(peter,X) :- car(X),smart(X). Note that they end in a period. The chars :- denote <= (i.e. "implied by"). A clause with :- is called a rule. By far the most used structure on the right-hand side of a rule is ,(S1, S2) where S1 and S2 are structures and , denotes boolean AND. The AND is usually written as an infix operator, and due to associativity can be written without parentheses. In other words, the usual right-hand side of a rule is of the form S1,S2,...,Si. This denotes boolean AND of the structures S1,S2,...,Si. One predicate may have several clauses. The predicate is considered true if at least one of the clauses for it is true - i.e. the clauses of a predicate are combined by boolean OR. A Prolog program consists of a set of clauses. */ /* UNIFICATION: Unification of two structures tests if they can possibly be equal (using pattern matching). If parts of the structures are variables, successful unification INSTANTIATES the variables in question. Examples: [1,peter,X,(Y,20)] and [Z,peter,alice,(2,20)] will unify succesfully, and the following instantiations will take place: X = alice Y = 2 Z = 1 (X,X) and (20,20) will unify succesfully and X will be instantiated to 20. (X,X) and (19,20) will not unify succesfully. Nothing will be instantiated. X and Y will unify, and X and Y will now co-refer (must have same value, if one later is instantiated to something specific, the other is too). [H|T] will unify with [1,2,3,4]. H will be instantiated to 1, and T will be instantiated to [2,3,4]. More list examples on p. 53. */ /* Goals are boolean questions asked by the user (at prompt in gprolog). Prolog will try to SATISFY a goal using unification. This is a search procedure among the clauses of the script. The clauses of a predicate are tested for unification with goal one by one, topmost first. Rules give rise to subgoals (the structures of the right-hand side). The search follows these in what is effectively a depth first exhaustive search for a proof (based on the clauses of the program) of satisfaction of the original goal. Instantiations are undone when backtracking, and re-instantiated during repeated search. Prolog stops at first solution (if any), and displays any instantiated variables. All solutions can be generated. (typing ';' repeatedly, of 'a' once). /********** Examples *************/ /* Identity check, two versions */ id(X,X). id2(X,Y) :- X = Y. /* id(3,3) is true, id(3,X) is true and instantiates X=3 */ male(peter). male(paul). female(alice). female(beatrice). female(clepatra). pair(X,Y) :- male(X),female(Y). possiblePair(X,Y) :-pair(X,Y), likes(X,Y), likes(Y,X). likes(peter,alice). likes(alice,peter). likes(paul,alice). likes(paul,beatrice). likes(paul,clepatra). myAppend([],L,L). myAppend([X|L1],L2,[X|L3]) :- myAppend(L1,L2,L3). /* here | ?- myAppend([1,2],[3],L3). gives the answer L3 = [1,2,3]. | ?- myAppend(L1,[3],[1,2,3]). gives the answer L1 = [1,2] | ?- myAppend(L1,L2,[1,2,3]). gives the answers L1 = [] L2 = [1,2,3] L1 = [1] L2 = [2,3] L1 = [1,2] L2 = [3] L1 = [1,2,3] L2 = [] */ factorial(0,1). factorial(N,F) :- N>0, N1 is N-1, factorial(N1,F1), F is N * F1. /* Here, '>' is a built-in predicate which is written as an infix operator. The arguments must instantiated to numerical values (or be numerical constants) at the time satisfaction is attempted. The same applies to '-'. Note that N-1 is a structure, not a number. The built-in predicate 'is' evaluates such a structure, finding its numerical equivalent, and unifies the result with the left argument to 'is'. The question | ?- factorial(3,F). gives the answer F = 6, but | ?- factorial(N,6). gives an error because variables taking part in '>' and 'is' are not instantiated. */