X = genova Y = [milano, roma]?- [10,20,[30,40],cinquanta] = [X|Y].
X = 10 Y = [20, [30, 40], cinquanta]?- [a,b,[C,D,[e]]] = [X|Y].
C = _G4382 D = _G4385 X = a Y = [b, [_G4382, _G4385, [e]]]?- [a]= [X|Y].
X = a Y = []?- [[a, b, c]] = [X|Y].
X = [a, b, c] Y = []
e_una_lista([questo,e,un,paragrafo,sulle,liste]). e_una_lista([la,vispa,teresa,[avea,tra,l,erbetta]]).?-e_una_lista([X|Y]).
X=questo Y=[e,un,paragrafo,sulle,liste]; X=la Y=[vispa,teresa,[avea,tra,l,erbetta]]?-e_una_lista([_|X]).
X=[e,un,paragrafo,sulle,liste]; X=[vispa,teresa,[avea,tra,l,erbetta]]?-e_una_lista([_,_,_,[X|_]]).
X=avea
yes?-membro(b,[c,o,m,p,u,t,e,r]).
no?-membro(c,[m,i,[s,c,e],l,a]).
noNotare che in questo caso la "c" appare in una lista interna alla lista principale. Per questo motivo l'interprete risponde no.
Con il goal:
?- trace, membro(new_york,[boston,chicago,filadelfia,
san_francisco, los_angeles,denver]).si ottiene:
Call: ( 11) membro(new_york, [boston, chicago, filadelfia, san_francisco, los_angeles, denver]) ? Call: ( 12) membro(new_york, [chicago, filadelfia, san_francisco, los_angeles, denver]) ? Call: ( 13) membro(new_york, [filadelfia, san_francisco, los_angeles, denver]) ? Call: ( 14) membro(new_york, [san_francisco, los_angeles, denver]) ? Call: ( 15) membro(new_york, [los_angeles, denver]) ? Call: ( 16) membro(new_york, [denver]) ? Call: ( 17) membro(new_york, []) ? Fail: ( 17) membro(new_york, []) ? Redo: ( 16) membro(new_york, [denver]) ? Fail: ( 16) membro(new_york, [denver]) ? Redo: ( 15) membro(new_york, [los_angeles, denver]) ? Fail: ( 15) membro(new_york, [los_angeles, denver]) ? Redo: ( 14) membro(new_york, [san_francisco, los_angeles, denver]) ? Fail: ( 14) membro(new_york, [san_francisco, los_angeles, denver]) ? Redo: ( 13) membro(new_york, [filadelfia, san_francisco, los_angeles, denver]) ? Fail: ( 13) membro(new_york, [filadelfia, san_francisco, los_angeles, denver]) ? Redo: ( 12) membro(new_york, [chicago, filadelfia, san_francisco, los_angeles, denver]) ? Fail: ( 12) membro(new_york, [chicago, filadelfia, san_francisco, los_angeles, denver]) ? Redo: ( 11) membro(new_york, [boston, chicago, filadelfia, san_francisco, los_angeles, denver]) ? Fail: ( 11) membro(new_york, [boston, chicago, filadelfia, san_francisco, los_angeles, denver]) ? ^
Mentre con il goal:
?- trace, member(los_angeles,[boston,chicago,filadelfia, san_francisco, los_angeles,denver]).
otteniamo
Call: ( 16) membro(los_angeles, [boston, chicago, filadelfia, san_francisco, los_angeles, denver]) ? Call: ( 17) membro(los_angeles, [chicago, filadelfia, san_francisco, los_angeles, denver]) ? Call: ( 18) membro(los_angeles, [filadelfia, san_francisco, los_angeles, denver]) ? Call: ( 19) membro(los_angeles, [san_francisco, los_angeles, denver]) ? Call: ( 20) membro(los_angeles, [los_angeles, denver]) ? Exit: ( 20) membro(los_angeles, [los_angeles, denver]) ? Exit: ( 19) membro(los_angeles, [san_francisco, los_angeles, denver]) ? Exit: ( 18) membro(los_angeles, [filadelfia, san_francisco, los_angeles, denver]) ? Exit: ( 17) membro(los_angeles, [chicago, filadelfia, san_francisco, los_angeles, denver]) ? Exit: ( 16) membro(los_angeles, [boston, chicago, filadelfia, san_francisco, los_angeles, denver]) ?
Notiamo che la ricorsione si ferma quando avviene la chiamata
membro(los_angeles, [los_angeles, denver])
in quanto si può soddisfare questo goal direttamente,
usando il fatto, e non la regola ricorsiva.
Usando i fatti:
genitore(tom,bob). genitore(bob,pat). genitore(pat,jim).
e le clausole:
antenato2(X,Y) :- genitore(X,Z),antenato2(Z,Y). antenato2(X,Y) :- genitore(X,Y).
con il goal:
trace,antenato2(tom,jim).
si ottiene:
Call: ( 12) antenato2(tom, jim) ? Call: ( 13) genitore(tom, _L158) ? Exit: ( 13) genitore(tom, bob) ? Call: ( 13) antenato2(bob, jim) ? Call: ( 14) genitore(bob, _L170) ? Exit: ( 14) genitore(bob, pat) ? Call: ( 14) antenato2(pat, jim) ? Call: ( 15) genitore(pat, _L182) ? Exit: ( 15) genitore(pat, jim) ? Call: ( 15) antenato2(jim, jim) ? Call: ( 16) genitore(jim, _L194) ? Fail: ( 16) genitore(jim, _L194) ? Redo: ( 15) antenato2(jim, jim) ? Call: ( 16) genitore(jim, jim) ? Fail: ( 16) genitore(jim, jim) ? Redo: ( 15) antenato2(jim, jim) ? Fail: ( 15) antenato2(jim, jim) ? Redo: ( 14) antenato2(pat, jim) ? Call: ( 15) genitore(pat, jim) ? Exit: ( 15) genitore(pat, jim) ? Exit: ( 14) antenato2(pat, jim) ? Exit: ( 13) antenato2(bob, jim) ? Exit: ( 12) antenato2(tom, jim) ?
usando la definizione:
antenato3(X,Y) :- genitore(X,Y). antenato3(X,Y) :- genitore(X,Z),antenato3(Z,Y).
ed il goal:
trace, antenato3(tom,jim).
si ottiene:
Call: ( 13) antenato3(tom, jim) ? Call: ( 14) genitore(tom, jim) ? Fail: ( 14) genitore(tom, jim) ? Redo: ( 13) antenato3(tom, jim) ? Call: ( 14) genitore(tom, _L167) ? Exit: ( 14) genitore(tom, bob) ? Call: ( 14) antenato3(bob, jim) ? Call: ( 15) genitore(bob, jim) ? Fail: ( 15) genitore(bob, jim) ? Redo: ( 14) antenato3(bob, jim) ? Call: ( 15) genitore(bob, _L179) ? Exit: ( 15) genitore(bob, pat) ? Call: ( 15) antenato3(pat, jim) ? Call: ( 16) genitore(pat, jim) ? Exit: ( 16) genitore(pat, jim) ? Exit: ( 15) antenato3(pat, jim) ? Exit: ( 14) antenato3(bob, jim) ? Exit: ( 13) antenato3(tom, jim) ?
Definito il predicato:
conc([],L,L). conc([X|L1],L2,[X|L3]) :- conc(L1,L2,L3).
per concatenare due liste:
?- conc([a,b,c],[d,e,f],L). L = [a, b, c, d, e, f] Yes
per dividere in due parti una lista:
?- conc(X,Y,[a,b,c]). X = [] Y = [a, b, c] Yes X = [a] Y = [b, c] Yes X = [a, b] Y = [c] Yes X = [a, b, c] Y = [] Yes
La definizione di sublist è la seguente:
sublist(S,L) :- conc(L2,L3,L), % la lista L viene divisa nelle due parti L2 e L3 conc(L1,S,L2). % la lista L1 viene a sua volta divisa in L1 e S
Un possibile goal è il seguente:
?- sublist([b,c,d],[a,b,c,d,e]).
Le possibili sottoliste di [a,b,c,d,e] si ottengono con il goal
?- sublist(S,[a,b,c,d,e]).Tuttavia se non si vogliono avere fra le rispote liste vuote, si può usare come goal il seguente:
?- sublist(S,[a,b,c,d,e]),S=[_|_].
Il sottogoal S=[_|_] assicura che S abbia
una testa e una coda, e quindi che S non sia la lista vuota.
Avendo dato le seguenti definizioni :
% add add(X,L,[X|L]) %delete delete(X,L,L1). del(X,[T|C],[T|C1]) :- del(X,C,C1). %insert insert(X,L,L1) :- delete(X,L1,L).
si ottiene:
?- add(x,[y,z,t],L). L = [x, y, z, t] Yes ?- del(b,[a,b,c,b,d,b],L). L = [a, c, b, d, b] Yes L = [a, b, c, d, b] Yes L = [a, b, c, b, d] Yes ?- insert(z,[a,b,c,d,e],L). L = [z, a, b, c, d, e] Yes L = [a, z, b, c, d, e] Yes L = [a, b, z, c, d, e] Yes L = [a, b, c, z, d, e] Yes L = [a, b, c, d, z, e] Yes L = [a, b, c, d, e, z] Yes
Scrivete un goal per controllare se [b,c,a] è una permutazione
di [a,b,c].
?- permutazione([a,b,c],[b,c,a]). Yes
Scrivete inoltre un goal per ottenere tutte le permutazioni degli elementi
della lista [a,b,c].
?- permutazione([a,b,c],P). P = [a, b, c] Yes P = [b, a, c] Yes P = [b, c, a] Yes P = [a, c, b] Yes P = [c, a, b] Yes P = [c, b, a] Yes