Lista de exercícios de Inteligência Artificial do professor Marcelino Pequeno. Universidade Federal do Ceará. Por Cassiano Carvalho Rocha e Silveira Neto.

Questão 1. Defina o predicado last(X,L) que testa se X é o último elemento da lista L.

Prolog:

last(X,[X]).
last(X,[_|R]):- last(X, R).

Explicação:X é elemento de uma lista unitária com X. O outro caso é uma lista de cabeça e cauda, procuramos X na cauda.

Questão 2. Defina a relação flatten/2 (que lineariza uma lista) de forma a que, por exemplo:

| ?- flatten([a,b,[c,d],[],[[[e,f]],g],h],X).
X = [a,b,c,d,e,f,g,h] ?
Yes

Prolog:

flatten(Xs,Ys) :- flatten(Xs,[],Ys).
 
flatten([X|Xs],As,Ys) :- flatten(Xs,As,As1), flatten(X,As1,Ys).
flatten(X,As,[X|As]) :- integer(X).
flatten(X,As,[X|As]) :- atom(X), X\=[].
flatten([],Ys,Ys).

Explicação: A flatten/2 é uma interface para a flatten/3. integer(X), atom(X), X\=[] são formas de capturar os casos base.

Questão 3. Defina um predicado no_dupl/2 que remova os duplicados de uma lista.

Prolog:

no_doubles(Xs, Ys):-no_doubles_1(Xs, [], Ys).
 
no_doubles_1([], Ys, Ys).
no_doubles_1([X|Xs], As, Ys):-
  member(X, As),
  no_doubles_1(Xs, As, Ys).
no_doubles_1([X|Xs], As, Ys):-
  nonmember(X, As),
  no_doubles_1(Xs, [X|As], Ys).
 
member(X,[X|Xs]).
member(X,[Y|Ys]):-member(X,Ys).
 
nonmember(X,[Y|Ys]):-X=\=Y, nonmember(X,Ys).
nonmember(X,[]).

Explicação: no_doubles/2 faz uma interface com no_doubles_1/3. member(X,Xs) é verdadeiro se X é membro da lista Xs. nonmember(X,Xs) é verdadeiro se X é não membro da lista Xs.

Questão 4. 4- Defina um predicado enumerar(+N,+M,+P,?L) que gera a lista L de números entre N e M, a passo P. Por exemplo:
?- enumerar(3,10,2,L).
L = [3,5,7,9] ?
Yes

Prolog:

enumerar(N, M, P, [N]) :-
	N + P > M.
 
enumerar(N, M, P, L) :-
	N1 is N + P,
	enumerar(N1, M, P, L1),
	append([N], L1, L).

Explicação: Quando n+p é maior que M, então retorna uma lista unitária só ocm N.
Quando não, criamos uma outra lista enumerar com um intervalo menor e concatenamos por [N].