Contents Representation of lists Some operations on lists Operator notation Arithmetic
Representation of Lists The list is a simple data structure used in non- numeric programming. A list is a sequence of any number of terms. –[ ann, tennis, tom, skiing] An empty list is written as a Prolog atom [ ]. A list can be viewed as consisting of two things: –the first item, called the head of the list; –the remaining part of the list, called the tail.
Representation of Lists For [ann, tennis, tom, skiing], the head is ann and the tail is the list: [tennis, tom, skiing]. In general, the head can be anything; the tail has to be a list. The head and tail are then combined into a structure by a special functor (depending upon the Prolog implementation). –.(Head, Tail) –.(ann,.(tennis,.(tom,.(skiing,))))
Representation of Lists.... ann tennis tom skiing [ ]
Representation of Lists L=[a,b,c] L=[a|Tail] Tail=[b,c] [a,b,c]=[a,|[b,c]] =[a,b|[c]] =[a,b,c|]
Some Operations on Lists Membership member(b,[a,b,c]) is true member(b,[a,[b,c]]) is not true X is a member of L if either (1) X is the head of L, or (2) X is a member of the tail of L. member(X,[X|Tail]). member(X,[Head|Tail]):- member(X,Tail).
Some Operations on Lists Concatenation conc([a,b],[c,d],[a,b,c,d]) is true, but conc([a,b],[c,d],[a,b,a,c,d]) is false. (1) If the first argument is the empty list then the second and the third arguments must be the same list. conc(,L,L). (2) If the first argument of conc is a non-empty list then it has a head and a tail and must look like this: [X|L1] conc([X|L1],L2,[X|L3]):- conc(L1,L2,L3). L1XL2 L3X
Some Operations on Lists member1(X,L):- conc(_, [X|_],L).
Some Operations on Lists Adding an item add(X,L,[X|L]). Deleting an item: –If X is the head of the list then the result after the deletion is the tail of the list. –If X is in the tail then it is deleted from there. delete( X,[X|Tail,Tail). delete(X,[Y|Tail],[Y|Tail1]):- delete(X,Tail,Tail1).
Some Operations on Lists ?-delete(a,[a,b,a,a],L). L=[b,a,a]; L=[a,b,a]; no ?-delete(a,L,[1,2,3]). L=[a,1,2,3]; L=[1,a,2,3]; L=[1,2,a,3]; L=[1,2,3,a]; no insert(X,List,BiggerList):- delete(X,BiggerList,List). Member2(X,List):- delete(X,List,_).
Some Operations on Lists Sublist sublist([c,d,e],[a,b,c,d,e,f]) is true, but sublist([c,e],[a,b,c,d,e]) is not. The Prolog program for sublist can be based on the same idea as member1. –S is a sublist of L if (1) L can be decomposed into two lists, L1 and L2, and (2) L2 can be decomposed into two lists, S and L3. sublist(S,L):- conc(L1,L2,L), conc(S,L3,L2). L1SL3 L L2
Some Operations on Lists Permutations ?-permutation([a,b,c],P). P=[a,b,c]; P=[a,c,b]; P=[b,a,c]; …
Some Operations on Lists The program –If the first list is empty then the second list must also be empty –If the first list is not empty and it has the form [X|L], then a permutation can be constructed by first permute L obtaining L1 and then insert X at any position into L1. permutation(,). permutation([X|L],P);- permutation(L,L1), insert(X,L1,P). LX L1 permute L
Some Operations on Lists permutation2(,). permutation(L,[X|P]):- delete(X,L,L1), permutation2(L1,P).
Operator Notation An infix expression, for example, 2*a+b*c, can be written in Prolog as: +(*(2,a),*(b,c)). Since we normally prefer to have expressions written in infix style, Prolog caters for this notational covenience. Prolog will therefore accept the expression as: 2*a+b*c. This will be, however, only the external representation of the object, which will be automatically converted into the usual form of Prolog terms. Thus operators in Prolog are merely a notational extension.
Operator Notation In order that Prolog properly understands expressions such as a+b*c, Prolog has to know that * binds stronger than +. The precedence of operators decides what is the correct interpretation of expressions. For example, a+b*c can be understood either as +(a,*(b,c)) or as *(+(a,b),c). The general rule is that the operator with highest precedence is the principal functor of the term. If expression containing + and * are to be understood according to our normal convention, then + has to have a higher precedence than *.
Operator Notation A programmer can define her own operators. For example, we can define the atoms has and support as infix operators and then write in the program facts like peter has information. floor supports table. These facts are exactly equivalent to: has(peter, information). Supports(floor, table).
Operator Notation A programmer can define new operators by inserting the program special kinds of clauses, sometimes called directives, which act as operator definitions. An operator definition must appear in the program before any expression containing that operator. :- op(600, xfx,has). This tells Prolog that we want to user has as an operator, whose precedence is 600 and its type is xfx, which is a kind of infix operator. The form specifier xfx suggests that the operator, denoted by f, is between the two arguments denoted by x.
Operator Notation Operators are normally used, as functor, only to combine objects into structures and not to invoke action on data. Operators are atoms, and their precedence must be in some range which depends on the implementation. (Assume [1,1200] here.) There are three groups of operator types : –infix operators: xfx, xfy, yfx –prefix operators: fx, fy –postfix operators: xf, yf
Operator Notation There is a difference between x and y. We need to introduce the concept of the precedence of argument. –If an argument is enclosed in parentheses or it is an unstructured object then its precedence is 0; –If an argument is a structure, then its precedence is equal to the precedence of its principal functor. x represents an argument whose precedence must be strictly lower than that of the operator. y represents an argument whose precedence is lower or equal to that of the operator.
Operator Notation These rules help to disambiguate expression with several operators of the same precedence. For example, the expression, a-b-c, is normally understood as (a-b)-c, and not a-(b-c). –To achieve the normal interpretation the operator – has to be defined as yfx. – – c a b Precedence 500 Prec. 0 – – b c Precedence 500 a Prec. 0
Operator Notation Consider the prefix operator not. –If not is defined as fy then the expression not not p is legal. But if not is defined as fx then this expression is illegal because the argument to the first not is not p.
Operator Notation Predefined operators in the Prolog system: :-op(1200,xfx,:-). :-op(1200,fx,[:-,?-]). :-op(1100,xfy,;). :-op(1000,xfy,,). :-op(700,xfx,[=,is,,=<,==,=\=,\==,=:=]). :-op(500,,yfx,[+,-]). :-op(500,fx,[+,-,not]). :-op(400,yfx,[*,/,div]). :-op(300,xfx,mod).
Operator Notation The use of operators can greatly improve the readability of programs. ~(A&B) ~A v ~B equivalent(not(and(A,B)), or(not(A),not(B))). :-op(800,xfx, ). :-op(700,xfy,v). :-op(600,xfy,&). :-op(500,fy,~).
Arithmetic The means for numerical computing in Prolog are rather simple: –+, –, *, /, mod ?-X=1+2. X=1+2 ?-X is 1+2. X=3 ?-X is 3/2,Y is 3 div 2. X=1.5 Y=1 ?-277*37>10000. Yes ?-born(Name,Year), Year>=1950,Year=<1960.
?-1+2=:=2+1. yes ?-1+2=2+1. no ?-1+A=B=2. A=2 B=1
Arithmetic Given two positive integers, X and Y, their greatest common divisor, D, can be found according to three cases: –If X and Y are equal then D is equal to X. –If X<Y then D is equal to the greatest common divisor of X and Y–X. –If Y<X then do the same as in the preceding case with X and Y interchanged. gcd(X,X,X). gcd(X,Y,D):- X<Y,Y1 is Y-X, gcd(X,Y1). gcd(X,Y,D):- Y<X, gcd(Y,X,D).
Arithmetic length(,0). length([_|Tail],N):- length(Tail,N1), N is N1+1.