Termini Costanti
Atomi
Numeri (studiare la matematica del Prolog)
?- 10 = 5+5.
No
?- 10 is 5+5.
Yes
?- X is 5+5.
X = 10 Yes
?- 10 is X+5.
ERROR: Arguments are not sufficiently instantiated Variabili (variabile anonima: )
Strutture
Strutture f(t
1,...,t
n) Funtore applicato a termini
libro(’Le tigri di Mompracem’,autore(emilio,salgari)) 3+X
C’` e qualche differenza sintattica tra strutture e fatti?
(Studiare: Operatori)
Strutture e alberi libro
Le tigri di Mompracem autore
emilio salgari
Rappresentazione di alberi binari
/* is_tree(T) : T e’ un albero binario */
is_tree(empty).
is_tree(t(Left, _, Right)) :- is_tree(Left),
is_tree(Right).
/* occorrenza di un elemento in un albero binario */
in_tree(El, t(_, El, _)).
in_tree(El, t(Left, _, _)) :- in_tree(El, Left).
in_tree(El, t(_, _, Right)) :- in_tree(El, Right).
Le due regole di in tree si possono compattare in una regola sola, utilizzando il ; (OR):
/* occorrenza di un elemento in un albero binario */
in_tree(El, t(_, El, _)).
in_tree(El, t(Left, _, Right)) :- in_tree(El, Left);
in_tree(El, Right).
Alberi binari di ricerca
/* inserimento in un ABR */
ins_abr(El, empty, t(empty, El, empty)).
ins_abr(El, t(Left, El, Right), t(Left, El, Right)).
ins_abr(El,t(Left,Middle,Right),t(LeftN, Middle, Right)) :- El < Middle,
ins_abr(El, Left, LeftN).
ins_abr(El,t(Left,Middle,Right),t(Left, Middle, RightN)) :- El > Middle,
ins_abr(El, Right, RightN).
/* ricerca in un ABR */
search_in_abr(El, t(_, El, _)).
search_in_abr(El, t(Left, Middle, _)) :- El < Middle,
search_in_abr(El, Left).
search_in_abr(El, t(_, Middle, Right)) :- El > Middle,
search_in_abr(El, Right).
Classificazione dei termini Il Prolog `e un linguaggio a tipizzazione dinamica
Predicati predefiniti per riconoscere il tipo di un termine var, nonvar
?- var(X).
X = _G147 Yes
?- var(padre(X)).
No
?- X=Y, Y=23, var(X).
No
integer, float, number atom
atomic
?- atom(pippo).
Yes
?- atom(3).
No
?- atomic(3).
Yes
Accesso ai componenti e costruzione delle strutture:
functor, arg e Univ
?- functor(f(a,b,c),F,N).
F = f N = 3 Yes
?- functor(X,f,3).
X = f(_G199, _G200, _G201) Yes
?- arg(2,f(a,b,c),X).
X = b Yes
?- f(a,b,c) =.. X.
X = [f, a, b, c] /* [f, a, b, c] e’ una LISTA */
Yes
Liste
Una lista `e un oggetto strutturato: si pu`o rappresentare utilizzando un funtore, ad esempio cons, e una costante per la lista vuota, ad esempio nil
cons(a,cons(b,cons(c,nil))) is_lst(nil).
is_lst(cons(_,X)) :- is_list(X).
elemento(X,cons(X,_)).
elemento(X,cons(_,Y)) :- elemento(X,Y).
?- elemento(b,cons(a,cons(b,cons(c,nil)))).
Yes
La struttura dati predefinita per le liste [a, b, c] Lista vuota: []
Il “cons” `e l’operatore . (prefisso) oppure | (infisso)
?- [a,b,c] = .(a,.(b,.(c,[]))).
Yes
?- [a,b,c] = [a | [b | [c | [] ] ] ].
Yes
?- [a,b,c] = [X|Y].
X = a
Y = [b, c]
Yes
Gli elementi delle liste possono essere di tipo qualsiasi, non necessariamente omogeneo
?- X = [1, pippo, padre(pippo), [a,b,c]].
X = [1, pippo, padre(pippo), [a, b, c]]
Yes
?- X = .(pippo,pluto).
X = [pippo|pluto]
Yes
Si possono rappresentare alberi, coppie e tuple mediante liste.
Rappresentazione di alberi n-ari mediante liste
is_ntree([_|Tlist]) :-
is_ntreelist(Tlist).
is_ntreelist([]).
is_ntreelist([T|Tlist]) :- is_ntree(T),
is_ntreelist(Tlist).
/* selettori */
root([X|_], X).
left([_,L|_], L).
treerest([X,_|Rest], [X|Rest]).
?- is_ntree([1,[2],[3,[4],[5]]]).
Yes
?- T = [1,[2],[3,[4],[5]]], root(T,R), left(T,L), treerest(T,Rest).
T = [1, [2], [3, [4], [5]]]
R = 1 L = [2]
Rest = [1, [3, [4], [5]]]
Predicati predefiniti sulle liste Le “operazioni” su liste: member, append, length, delete ...
in Prolog sono relazioni
?- member(X,[1,2,3]), X>2.
X = 3
?- append(X,[4,5],[1,2,3,4,5]).
X = [1, 2, 3]
?- length(X,3).
X = [_G224, _G227, _G230]
?- delete([1,2,1,3,1,4], 1, X).
X = [2, 3, 4]
?- delete([1,2,1,3,1,4], X, [2, 3, 4]).
X = 1
Vedere sul manuale di SWI-Prolog: library(lists).
Esempio: concatenazione di liste (append `e predefinito)
/* concat(X,Y,Z): Z e’ la concatenazione di X e Y */
concat([],X,X).
concat([X|L1],L2,[X|L3]) :- concat(L1,L2,L3).
?- concat([a,b],[c],X).
X = [a, b, c]
Yes
?- concat(X,[b,c],[a,b,c]).
X = [a]
Yes
?- concat(X,Y,[a,b,c]).
X = []
Y = [a, b, c] ; X = [a]
Y = [b, c] ;
X = [a, b]
Y = [c] ;
X = [a, b, c]
Y = [] ;
No
listing
?- listing(append).
% Foreign: append/1
append([], A, A).
append([A|B], C, [A|D]) :- append(B, C, D).
Yes
Altri esempi /* -- ultimo elemento di una lista -- */
last(X,List) :- append(_,[X],List).
/* -- elementi vicini in una lista -- */
next_to(X,Y,List) :- append(_,[X,Y|_],List).
/* -- appartenenza a una lista: definizione alternativa -- */
elemento(X,List) :- append(_,[X|_],List).
/* --- costruzione di un ABR da una lista --- */
from_list([], empty).
from_list([Head|Tail], Abr) :- from_list(Tail,Tree), ins_abr(Head,Tree,Abr).
Quali dei predicati definiti fin qui sono “reversibili”?
Esempio: rappresentazione di automi non deterministici
s1
s2 a
b
a
b s3
a b