350 likes | 487 Views
3. Lists, Operators, Arithmetic. 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.
E N D
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 ?-List1=[a,b,c], List2=.(a,.(b,.(c,.[]))). List1=[a,b,c] List2=[a,b,c] ?-Hobbies1=.(tennis,.(music,[])), Hobbies2=[skiing,food], L=[ann,Hobbies1,tom,Hobbies2]. Hobies1=[tennis,music] Hobbies2=[skiing,food] L=[ann,[tennis,music],tom,[skiing,food]]
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). X L1 L2 X L3
Some Operations on Lists ?-conc([a,b,c],[1,2,3],L). L=[a,b,c,1,2,3] ?-conc([a,[b,c],d],[a,[],b]). ?-conc(L1,L2,[a,b,c]). L1=[] L2=[a,b,c]; L1=[a] L2=[b,c]; L1=[a,b] L2=[c]; L1=[a,b,c] L2=[]; no ?-conc(Before,[may}After], [jan,feb,mar,apr,may,jun, jul,aug,sep,oct,nov,dec]). Before=[jan,feb,mar,apr] After=[jun,jul,aug,sep,oct, nov,dec] ?-conc(_,[Month1,may,Month2|_], [jan,feb,mar,apr,may,jun, jul,aug,sep,oct,nov,dec]). Month1=apr Month2=jun ?-L1=[a,b,z,z,c,z,z,z,d,e], conc(L2,[z,z,z|_],L1). L1=[a,b,z,z,c,z,z,z,d,e] L2=[a,b,z,z,c]
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]; 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). L L1 S L3 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. X L permutation([],[]). permutation([X|L],P);- permutation(L,L1), insert(X,L1,P). permute L L1
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.
– b c 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. – – a – c Prec. 0 Prec. 0 a b Precedence 500 Precedence 500
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 :-op(800,xfx,<===>). :-op(700,xfy,v). :-op(600,xfy,&). :-op(500,fy,~). equivalent(not(and(A,B)), or(not(A),not(B))).
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.
Arithmetic ?-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.