1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write...
-
Upload
roger-bridges -
Category
Documents
-
view
225 -
download
0
description
Transcript of 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write...
1
member(X,[Y| _ ] ) :- X = Y.member(X, [ _ | Y]) :- member(X, Y).
It would be easier to write this as:
member(X,[X| _ ]).member(X, [ _ | Y]) :- member(X, Y).
?- member(1, [3,4,5,8,1,9]).Yes?- member(X, [prolog, c, ada, haskell]).X= prolog;X= cX= ada;X= haskell;No
Recursion and Lists
2
Other Examples
change(you, i).change(are, [am, not]).change(french, australian).change(do, no).change(X, X). /* catchall */alter([ ], [ ]).alter([H|T], [X|Y]) :- change(H, X), alter(T,Y).
?- alter([you,are,a,computer],R).
R = [i, [am, not], a, computer]
Yes
?- alter([you,are,french],R).
R = [i, [am, not], australian]
Yes
?-
3
asserta/1.assertz/1assert/1retract/1retractall/1
Example:
assertz(fib(N,F)).
4
:-dynamic fibfib(1,1).fib(2,1).fib(N,F) :-
N > 2,N1 is N-1, fib(N1,F1),N2 is N-2, fib(N2,F2),F is F1 + F2,asserta(fib(N,F)).
?- fib(8, F).
F = 21
?- fib(6,F).
F = 8
5
F(6)+
f(5) f(4)+
f(3) f(2)
f(2) f(1)
+
1 1
+
f(4) f(3)+
f(3) f(2) 1
+
f(2) f(1)
+
f(2) f(1)
1 1 1 1 1
6
asserta/1.assertz/1assert/1retract/1retractall/1
Example:
assertz(fib(N,F)).
7
:-dynamic animal/1. % A directive.
animal(tiger).
animal(lion).
animal(monkey).
animal(X):-mamal(X),
asserta(animal(X)).
mamal(cat).
mamal(dog).
?- animal(dog).Yes?- listing(animal).:- dynamic animal/1.animal(dog).animal(tiger).animal(lion).animal(monkey).animal(A) :- mamal(A), asserta(animal(A)).
8
leng([ ], 0).leng([H|T], Len) :- leng(T, Len1),
Len is Len1 + 1.
Finding the length of a list
9
[trace] ?- leng([1,2,3,4,5],Ln).
Call: (6) leng([1, 2, 3, 4, 5], _G405)?creep
Call: (7) leng([2, 3, 4, 5], _G474) ? creep
Call: (8) leng([3, 4, 5], _G474) ? creep
Call: (9) leng([4, 5], _G474) ? creep
Call: (10) leng([5], _G474) ? creep
Call: (11) leng([], _G474) ? creep
Exit: (11) leng([], 0) ? creep
^ Call: (11) _G479 is 0+1 ? creep
^ Exit: (11) 1 is 0+1 ? creep
Exit: (10) leng([5], 1) ? creep
^ Call: (10) _G482 is 1+1 ? creep
^ Exit: (10) 2 is 1+1 ? creep
Exit: (9) leng([4, 5], 2) ? creep
^ Call: (9) _G485 is 2+1 ? creep
^ Exit: (9) 3 is 2+1 ? creep
Exit: (8) leng([3, 4, 5], 3) ? creep
^ Call: (8) _G488 is 3+1 ? creep
^ Exit: (8) 4 is 3+1 ? creep
Exit: (7) leng([2, 3, 4, 5], 4) ? creep
^ Call: (7) _G405 is 4+1 ? creep
^ Exit: (7) 5 is 4+1 ? creep
Exit: (6) leng([1, 2, 3, 4, 5], 5) ? creep
Ln = 5
Yes
leng([ ], 0).leng([H|T], Len) :- leng(T, Len1),
Len is Len1 + 1.
10
remove(X, [ ], [ ]).remove(X, [X|T], C):-
remove(X,T,C).remove(X, [H|T], [H|T1]):- X \= H,
remove(X,T,T1).
?- remove(1,[4,9,8,7,1,9,7,5,1],R).
R = [4, 9, 8, 7, 9, 7, 5]
Removing an element from a list
11
isort([], []).isort([H|T],R):- isort(T,Q),
ins(H,Q,R).ins(X, [], [X]).ins(X, [H|T], [H|R]):- X>H, ins(X,T,R).ins(X, [H|T], [X,H|T]):- X=<H.
?- isort([4,1,9,5,8,3,2],S).
S = [1, 2, 3, 4, 5, 8, 9]
?- isort([a,b,c,d],S).
ERROR: Arithmetic: `c/0' is not a function
Insertion Sort
12
I/O
13
A full-stop must follow a term to be read
?- read(X).|: massey.X = massey Yes?- read(X).|: Y.X = _G185 Yes?- read(X).|: likes(john,mary).X = likes(john, mary) Yes?- read(X), name(X,List).|: massey.X = masseyList = [109, 97, 115, 115, 101, 121]
14
?- write('hello world').hello worldYes?- write('hello world'),nl,nl,tab(9),write('I am here :)').hello world
I am here :)Yes?- write("abc").[97, 98, 99]Yes?- write('abc').abcYes
15
printlst([ ]) :- put('.'), nl.
printlst([H|T]) :- write(H), tab(1), printlst(T).?- write([‘This’,is,a,list]).
[This, is, a, list]
?- printlst([‘This’,is, a,list]).
This is a list .
?- read(X),nl,write(‘Here is what was entered: ‘),write(X).|: massey.
Here is what was entered: masseyX = massey
A predicate for printing a list
16
male(andrew).male(john). male(george). male(greg). male(adam). female(mary). female(jennifer). female(eve). parents(john,george,mary).parents(greg,adam,eve).parents(jennifer, adam,eve).parents(andrew, adam,eve).is_brother_of(X,Y):-male(X),parents(X, Father, Mother),parents(Y, Father,Mother),
X\=Y,write(X),tab(1),write('is'),tab(1),write(Y),write('s sister.').is_sister_of(X,Y):-female(X),parents(X, Father, Mother),parents(Y, Father, Mother),
X\=Y,write(X),tab(1),write('is'),tab(1),write(Y),write('s sister.').
?- is_sister_of(X,Y).jennifer is greg`s sister.X = jenniferY = greg ;jennifer is andrew`s sister.X = jenniferY = andrew
17
Built-in predicates “fail” and “true”
Fail always fails and true always succeeds
?- likes(mary,X).X = john Yes?- likes(mary,X),fail.No?- likes(mary,X),write(X),nl,fail.johnfruitbookNo?- likes(mary,X),write(X),nl,fail ; true.johnFruit ORbookX = _G354 Yes
likes(tom,jerry).likes(mary,john).likes(tom,mouse).likes(tom,jerry).likes(jerry,cheeze).likes(mary,fruit).likes(john,book).likes(mary,book).likes(tom,john).
Output predicates do not re-succeed on backtracking
18
likes(tom,jerry).likes(mary,john).likes(tom,mouse).likes(tom,jerry).likes(jerry,cheeze).likes(mary,fruit).likes(john,book).likes(mary,book).likes(tom,john).?- likes(mary,X), write('Mary likes '), write(X),put('.'), nl, fail.Mary likes john.Mary likes fruit.Mary likes book.No
?- likes(mary,X),write(X),nl,fail;write('reached the OR part').johnfruitbookreached the OR partX = _G471 Yes
19
write('Enter a number X to be raised to the power of 5 '), read(N),
P5 is N**5,write(N),write(‘ to the power of 5 is: '),write(P5).
?- write('Enter a number X to be raised to the power of 5: '), read(N),| P5 is N**5,write(N),write(' to the power of 5 is: '),write(P5).Enter a number X to be raised to the power of 5:|: 2.2 to the power of 5 is: 32N = 2P5 = 32 Yes?-
?- repeat,write('Enter a number X to be raised to the power of 5: '),
| read(N), P5 is N**5,write(N),write(' to the power of 5 is: '),
| write(P5),fail.
Built-in predicate “repeat”
20
File I/O
21
Prolog
accepts input from an input stream
send output to an output stream
Streams can be files or I/O devices
Active streams
are the keyboard and the screen by default (user)
We may only have
one stream open for input and
one open for output
22
tell(Filename) Opens the file named by Filename for writing and makes it the current output stream. It creates the file if it does not exist.
telling(X) Retrieves the current input stream.
told Closes the file opened by the built-in predicate tell.
see(Filename) Opens the file named by Filename for input and makes it the current input straeam.
seeing(X) Retrieves the current input stream.
seen Closes the file opened by the built-in predicate see.
23
?- tell('D:/test.txt').Yes?- telling(X).X = '$stream'(1996248) Yes?- write('testing tell').Yes?- told.Yes
testing tellend_of_file
Contents of D:/test.txt
?- telling(Old),tell(‘D:/test.txt’),write(‘testing’),told,tell(Old).
24
?- tell(‘lksout.txt’),likes(mary,X), write(‘Mary likes ‘),write(X), put(‘.’),nl, fail; told.X = _G662 Yes
likes(tom,jerry).likes(mary,john).likes(tom,mouse).likes(tom,jerry).likes(jerry,cheeze).likes(mary,fruit).likes(john,book).likes(mary,book).likes(tom,john).
Mary likes john.
Mary likes fruit.
Mary likes book.
Contents of the file “lks.txt”
25
Cut: !Eliminates choicesAlways succeeds but stops backtracking
a:-b,c,!,d.a:-e,f.
max(X,Y,Y) :- Y>X.max(X,Y,X). ?- max(1,2,X).X = 2 ;X = 1 ;No?-
max(X,Y,Y) :- Y>X, !. max(X,Y,X). ?- max(1,2,X).X = 2 ;No?-
26
Cut makes programs less readable.
Using cut can make your programs more efficient.
You have to be careful when using cut. Cut, may alter the way your program behaves. When you use cut in a rule, you have to be certain of how your rule will be used. If you are not careful your program may behave strangely.
Built-in predicate cut, “!”
27
Unexpected results: Using member with cut we only get one value for X, which is not what we expect.
member1(X,[X|_]):-!.
member1(X,[_|T]):-member1(X,T).
?- trace.
Yes
[trace] ?- member1(X,[1,2,3,4]).
Call: (6) member1(_G401, [1, 2, 3, 4]) ? creep
Exit: (6) member1(1, [1, 2, 3, 4]) ? creep
X = 1 ;
Fail: (6) member1(1, [1, 2, 3, 4]) ? creep
No
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
No
Member without cut
membernocut(X,[X|_]).
membernocut(X,[_|T]):-membernocut(X,T).
?- membernocut(X,[1,2,3,4]).
28
Efficiency:
Using member without cut here, we are wasting time trying out the second part of the predicate when we know that it will fail.
Call: (7) membernocut(1, [1, 2, 3, 4]) ? creep
Exit: (7) membernocut(1, [1, 2, 3, 4]) ? creep
member succeeded
Redo: (7) membernocut(1, [1, 2, 3, 4]) ? creep
Call: (8) membernocut(1, [2, 3, 4]) ? creep
Call: (9) membernocut(1, [3, 4]) ? creep
Call: (10) membernocut(1, [4]) ? creep
Call: (11) membernocut(1, []) ? creep
Fail: (11) membernocut(1, []) ? creep
Fail: (10) membernocut(1, [4]) ? creep
Fail: (9) membernocut(1, [3, 4]) ? creep
Fail: (8) membernocut(1, [2, 3, 4]) ? creep
Fail: (7) membernocut(1, [1, 2, 3, 4]) ? creep
No
membernocut(X,[X|_]).
membernocut(X,[_|T]):-membernocut(X,T).
?- trace.Yes[trace] ?- membernocut(1,[1,2,3,4]),write('member succeeded'),fail.
29
Using member with cut:
?- trace. Yes[trace] ?- member1(1,[1,2,3,4]),write('member succeeded'),fail. Call: (7) member1(1, [1, 2, 3, 4]) ? creep Exit: (7) member1(1, [1, 2, 3, 4]) ? creepmember succeeded
member1(X,[X|_]):-!.
member1(X,[_|T]):-member1(X,T).
Fail: (7) member1(1, [1, 2, 3, 4]) ? creep
No
?-
30
member(X, [X|T]).
member(X, [H|T]) :- not(X=H), member(X, T).
Using not instead of cut makes your program more clear
member1(X,[X|_]):-!.
member1(X,[_|T]):-member1(X,T).
31
male(andrew).male(john). male(george). male(greg). male(adam). female(mary). female(jennifer). female(eve). parents(john,george,mary).parents(greg,adam,eve).parents(jennifer, adam,eve).parents(andrew, adam,eve).is_brother_of(X,Y):-male(X),parents(X, Father, Mother),parents(Y, Father,Mother), X\=Y.is_sister_of(X,Y):-female(X),parents(X, Father, Mother),parents(Y, Father, Mother),X\=Y.
?- male(X).X = andrew ;X = john ;X = george ;X = greg ;X = adam ;No?-
?- male(X), ! .X = andrew ;No
32
male(andrew).
male(john).
male(george).
male(greg).
male(adam).
female(mary).
female(jennifer).
female(eve).
parents(john,george,mary).
parents(greg,adam,eve).
parents(jennifer, adam,eve).
parents(andrew, adam,eve).
is_brother_of(X,Y):-male(X),!,parents(X, Father, Mother),parents(Y, Father,Mother), X\=Y.
is_sister_of(X,Y):-female(X),!,parents(X, Father, Mother),parents(Y, Father, Mother),X\=Y.
33
apend([],L,L):-!.apend([H|T1],L2,[H|T2]):- apend(T1,L2,T2).
[trace] ?- apend([],[1,2,3,4],L). Call: (6) apend([], [1, 2, 3, 4], _G409) ? creep Exit: (6) apend([], [1, 2, 3, 4], [1, 2, 3, 4]) ? creepL = [1, 2, 3, 4] ; Fail: (6) apend([], [1, 2, 3, 4], [1, 2, 3, 4]) ? creepNo
apend([],L,L).apend([H|T1],L2,[H|T2]):-apend(T1,L2,T2).
[trace] ?- apend([],[1,2,3,4],L). Call: (6) apend([], [1, 2, 3, 4], _G409) ? creep Exit: (6) apend([], [1, 2, 3, 4], [1, 2, 3, 4]) ? creepL = [1, 2, 3, 4] ; Fail: (6) apend([], [1, 2, 3, 4], _G409) ? creepNo
34
?- tell(‘fam.pl’), listing(male/1), told.Yes
male(andrew).
male(john).
male(george).
male(greg).
male(adam).
Contents of the file fam
consult(Filename) :- see(Filename), repeat,
read(X), assert(X),
X=end_of_file, !, seen.
Definition of “consult”
H
35
male(andrew).male(john). male(george). male(greg). male(adam). female(mary). female(jennifer). female(eve). parents(john,george,mary).parents(greg,adam,eve).parents(jennifer, adam,eve).parents(andrew, adam,eve).
?- male(X).X= andrew;X= john;X= george;X= greg;X= adam;
?- female(X).X= mary;X= jennifer;X= eve;
?- parents(X, adam, eve).X= greg;X= jennifer;X= andrew;
?- findall(X, male(X), List).List= [andrew, john, george, greg, adam]?- findall(X, female(X), List).List= [mary, jennifer, eve]?- findall(X, parents(X,adam,eve), List).List= [greg, jennifer, andrew]
findall(X,Term,List).
36
Other examples
?- findall(t(X,Y),parents(X,Y,Z),List).X = _G353Y = _G354Z = _G358List = [t(john, george), t(greg, adam), t(jennifer, adam), t(andrew, adam)] Yes?-
?- findall(t(X,Y),append(X,Y,[a,b]),L).
X = _68
Y = _69
L = [t([],[a,b]),t([a],[b]),t([a,b],[])]
yes
male(andrew).male(john). male(george). male(greg). male(adam). female(mary). female(jennifer). female(eve). parents(john,george,mary).parents(greg,adam,eve).parents(jennifer, adam,eve).parents(andrew, adam,eve).
37
call(Goal) Invoke Goal as a goal.?- call(a=a).
Yes
?- [user].
|: likes(mary,john).
|:
% user compiled 0.02 sec, 152 bytes
Yes
?- call(likes(mary,john)).
Yes
?- call(likes(mary,X)).
X = john
Yes
?- call(likes(X,Y)).
X = mary
Y = john
Yes
?- call(likes(X,mary)).
No
?-
38
?- not(likes(mary,john)).
No
?- not(likes(mary,X)).
No
?- not(likes(mary,george)).
Yes
?-
not(Goal) Succeeds when Goal fails.
Implementation of not using callnot(P):-call(P),!,fail.
not(P).
39
In Prolog, programs and data are made of terms. A term may be: a constant (an atom or a number) 10, ‘abc’, likes, mary a variable X, Y a compound term likes(mary,john), likes(X,Y).
There are several built-in predicates that succeed or fail depending on the type of the term their argument is.
atomic(X) Succeeds if X is bound to an atom, a string or anumber (integer or floating point).
atom(X) Succeeds if X is bound to an atom.
number(X) Succeeds if X is bound to a number (integer or float)
float(X) Succeeds if X is bound to a floating point number
40
?- atom(a).Yes?- atom(X).No?- X=a,atom(X).X = a Yes?- X=a,atomic(X).X = a Yes?- atomic(a).Yes?- atomic(likes).Yes?- atom(likes).Yes
?- atom(1).No?- atom(1.2).No?- atomic(1.2).Yes?- number(5).Yes?- number(1.2).Yes?- float(1).No?- float(1.1).Yes
41
An exampleCounting the number of occurances of an atomcount(Atom,List,N).
count( _ , [ ] , 0 ).count(Atom, [Atom | Tail] , N):- count(Atom,Tail,N1), N is N1 + 1.count(Atom,[ _ | Tail], N):- count(Atom,Tail,N).
?- count(1,[1,2,3,1],N).N = 2 Yes?- count(1,[1,X,Y,Z],N).X = 1Y = 1Z = 1N = 4 % incorrectYes?-
?- L= [1,2,3,X,2],write(L),count(2,L,N).
[1, 2, 3, _G368, 2]
L = [1, 2, 3, 2, 2]
X = 2
N = 3 % incorrect
Yes
?-
42
Solutioncount( _ , [ ] , 0 ).count(Atom,[Head | Tail], N):- atomic(Head),
Atom=Head, count(Atom,Tail,N1), N is N1 + 1;count(Atom,Tail,N).
?- count(1,[1,2,3,1],N).
N = 2
Yes
?- count(1,[1,X,Y,Z],N).
X = _G269
Y = _G272
Z = _G275
N = 1
Yes
?-
?- L= [1,2,3,X,2],write(L),count(2,L,N).
[1, 2, 3, _G371, 2]
L = [1, 2, 3, _G371, 2]
X = _G371
N = 2
Yes
?-