1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write...

42
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]). ecursion and Lists

description

3 asserta/1. assertz/1 assert/1 retract/1 retractall/1 Example: assertz(fib(N,F)).

Transcript of 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write...

Page 1: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 2: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

?-

Page 3: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

3

asserta/1.assertz/1assert/1retract/1retractall/1

Example:

assertz(fib(N,F)).

Page 4: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 5: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 6: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

6

asserta/1.assertz/1assert/1retract/1retractall/1

Example:

assertz(fib(N,F)).

Page 7: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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)).

Page 8: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

8

leng([ ], 0).leng([H|T], Len) :- leng(T, Len1),

Len is Len1 + 1.

Finding the length of a list

Page 9: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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.

Page 10: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 11: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 12: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

12

I/O

Page 13: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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]

Page 14: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 15: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 16: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 17: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 18: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 19: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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”

Page 20: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

20

File I/O

Page 21: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 22: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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.

Page 23: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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).

Page 24: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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”

Page 25: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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?-

Page 26: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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, “!”

Page 27: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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]).

 

Page 28: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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.

Page 29: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

?-

Page 30: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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).

Page 31: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 32: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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.

Page 33: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 34: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 35: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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).

Page 36: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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).

Page 37: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

?-

Page 38: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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).

Page 39: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 40: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

Page 41: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

?-

Page 42: 1 member(X,[Y| _ ] ) :- X = Y. member(X, [ _ | Y]) :- member(X, Y). It would be easier to write this…

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

?-