Prolog/Primi passi

Wikibooks, manuali e libri di testo liberi.
Indice del libro

Primi passi[modifica]

Una volta installato il tuo Prolog, scriviamo il primo programma e diamolo in pasto al nostro interprete (per vedere se tutto funziona). Accendi il text editor e crea un file di testo semplicissimo scrivendo solo queste parole:

umano(john).

Sii preciso, la maiuscola è importante in Prolog, come il punto. Questo sarà il tuo programma (noto come database o conoscenza di base). Salvalo come prolog1.pl. Nota: L'estensione .pl non è ufficialmente associata con prolog e questo può causare conflitti se programmi in Perl, che usa ugualmente .pl. Se questo costituisce un problema puoi usare .pro o .pr o una a tuo piacere. Adesso avvia l'interprete di Prolog. Molti interpreti di Prolog mostrano una finestra con diverse linee di informazioni seguite da una linea come quella qui sotto:

? - 

con un cursore dietro. C'è di solito un menu per caricare file nell'interprete. Se non c'è questo menu puoi scrivere così:

consult('FILEPATH').

e premi invio. Ancora una volta sii preciso niente maiuscole e ricorda il punto. Sostituisci FILEPATH con il nome e la directory del file. Per esempio se hai collocato il file nella directory C:\My Documents\Prolog\prolog1.pl allora usa

consult('c:/my documents/prolog/prolog1.pl').

o la scorciatoia

['c:/my documents/prolog/prolog1.pl'].

L'interprete dovrebbe comunicarti che il file è stato caricato correttamente. Se non fosse così consulta il file di aiuto o i documenti o il manuale a tua disposizione. Dopo alcune informazioni vedrai comparire:

?-

Per vedere se tutto funziona scrivi:

umano(john).

(non dimenticare il punto) e premi Invio. Prolog risponderà con un sentito:

Yes.

Digita:

umano(Who).

e prolog risponderà

Who = john

Premi invio e prolog terminerà con Yes per poi tornare alla linea di comando.

Per uscire da prolog digita

halt.

Sintassi, Fatti e interrogazioni[modifica]

La linea umano(john). nell'esempio precedente era una proposizione di prolog in forma di predicato, chiamata anche fatto. I Predicati consistono di una parola e di uno o più caratteri,scritti in minuscolo, possibilmente seguiti da un numero di termini. Quelli sotto sono esempi di predicati validi:

umano(john)
padre(david, john)
abc(def,ghi,jkl,m)
albero
p(a,f,d)

I termini (le parole nelle parentesi) possono prendere molte forme, ma per ora ci agganceremo alle costanti. Queste sono parole, ancora tutte in minuscolo. Il primo carattere, sia di un predicato sia di una costante, deve essere una lettera. Usando i predicati possiamo aggiungere un fatto ad un programma:

umano(john).
umano(suzie).
umano(eliza).
uomo(david).
uomo(john).
donna(suzie).
donna(eliza).
parente(david, john).
parente(john, eliza).
parente(suzie, eliza).

Osserva il punto '.' dietro ogni linea per mostrare la fine della stessa. Questo è molto importante, se lo dimentichi il tuo interprete non comprenderà il programma. Dovresti anche essere consapevole che i nomi scelti per i predicati ed i termini non dicono assolutamente nulla all'interprete di Prolog. Devono essere scelti per consentire di comprendere bene il programma, per la leggibilità. Potremmo sostituire facilmente la parola umano con qualsiasi altra parola e l'interprete non ne vedrebbe la differenza.

Se carichiamo il programma sopra illustrato nell'interprete possiamo interrogare il computer. Se digiti:

umano(john).

prolog risponderà

Yes.

se digiti:

donna(john).

prolog risponderà

No.

Questo sembrerà noiosamente ovvio, ma è importante vederlo nel modo giusto. Se chiedi a prolog umano(john)., significa che stai chiedendo a prolog se quest'affermazione è vera. Chiaramente il prolog non può valutare se l'affermazione è vera, semplicemente sta consultando il suo file. Semplicemente controlla che una della affermazioni contenute nella knowledge base sia vera ed in tal caso risponde yes; no nel caso contrario. Nota: se chiedi a prolog:

 ?- umano(david).

Prolog risponderà No perché non trova niente nel database.

Variabili[modifica]

Quello che stiamo facendo non è un vero e proprio linguaggio espressivo. Possiamo aumentare l'espressività di un linguaggio utilizzando le variabili nel nostro percorso di apprendimento. Una variabile è una parola, proprio come termini e predicati, con l'eccezione che inizia con la lettera maiuscola ed ha dopo di sé lettere sia maiuscole che minuscole. Considera la seguente interrogazione:

umano(A).

Adesso il termine del predicato è una variabile. Prolog tenterà di legare un termine alla variabile. In altre parole, tu stai chiedendo a prolog di cosa ha bisogno A affinché umano(A) sia vera.

?- umano(A).

Prolog risponderà

A = john

Vera perché il database contiene la linea umano(john). Se premi invio, prolog risponderà Yes e rimanderà il cursore. Se premi il punto e virgola (';') prolog mostrerà il resto delle possibilità:

A = suzie ;
A = eliza ;
No.

Dopo eliza, prolog risponde No, indicando che le possibilità ulteriori si sono esaurite. Se prolog viene interrogato con più di una variabile esso mostrerà tutte le istanze delle variabili per la quale l'interrogazione è vera :

 ?- parente(Parent, Child).

 Parent = david
 Child = john ;

 Parent = john
 Child = eliza ;

 Parent = suzie
 Child = eliza ;

 No

Quando prolog riceve una domanda con una variabile controlla tutte le linee del programma, e cerca di unificare ogni predicato con la domanda. Questo significa che controllerà se la domanda coincide con il predicato quando le variabili vengono istanziate in un certo modo. Prolog può unificare umano(A) con umano(john) mettendo insieme A e john, ma non può mettere insieme uomo(A) con umano(john), perché i predicati sono diversi.

Per rendere le cose un po' difficili, possiamo usare due predicati nella stessa domanda, per esempio:

 ?- umano(A), parente(B,A).

Adesso stiamo chiedendo a prolog se c'è un umano A che ha un parente B. La virgola tra i due predicati equivale a un and, indicando così che entrambi i predicati necessitano di essere veri affinché sia vera la domanda. Prolog troverà un'istanza che renda il primo predicato vero, quindi cercherà di rendere vero il secondo (servendosi dell'istanza del primo). Trovato un modo per rendere la proposizione vera, come nel caso precedente, se premi punto e virgola, Prolog cercherà altre soluzioni provando prima per altre istanze del secondo predicato e poi ripeterà il processo provando per le tutte le rimanenti istanze modificando di volta in volta il primo predicato.

Nell'esempio precedente prolog trova umano(david) nel programma ed unifica A con david. Per verificare il secondo predicato, crea una istanza per parente(B, david). Se non trova nulla cerca una nuova istanza per umano(A). Poi tenta A = john. Quindi istanzia parente(B, john). Trova B = david nella linea parente(david, john) e quindi risulta

A = john
B = david 

Se premi il punto e virgola cercherà una nuova istanza per il secondo predicato. Se fallisce trova una nuova istanza per il primo e così fino alla fine del database.

Esiste una variabile speciale chiamata anonima, per la quale viene usata il carattere sottolineatura (_). Quando usi questo carattere in una domanda, significa che non ti importa di come è istanziata la variabile, ie non ti importa a quale termine sia collegata, anche se è collegata a qualcosa. Se chiedi a prolog

 ?- parente(A, _). 

Prolog risponderà

A = david;
A = john;
A = suzie;

Non importa di come istanziare _. Comunque se chiedi a prolog

 ?- abc(_,_,_).

Questo non sarà vero per default, prolog ha bisogno di un'istanza per tutte le tre variabili anonime nel database, come abc(d,e,f). Puoi usare anche la variabile anonima nel tuo database. Ponendo:

umano(_).

Nel tuo archivio si avrà che ogni termine,esista o meno, sarà umano. Così la domanda:

 ?- umano(abc)

sarebbe vera . In questo contesto la variabile anonima è usata per affermare una proprietà di tutti gli oggetti anziché di uno solo . Se vogliamo affermare che un gruppo specifico di oggetti ha una certa proprietà, abbiamo bisogno di regole. La prossima sezione tratterà di questo.

Esempi[modifica]

umano(al).

Questa sezione tratta delle regole cioè di un modo generico per stabilire se un generico predicato è vero.

Regole[modifica]

Siamo molto lontani da una vera e propria programmazione,abbiamo appena definito degli oggetti e le loro proprietà. Il primo passo per programmare in prolog è l'uso delle regole. Tramite le regole stabiliamo che un predicato è vero, assunto che gli altri predicati siano veri. Una regola si presenta in questa forma:

a :- b, c, d.

Questo significa che a è vera se b, c e d sono vere. Se abbiamo il seguente database

a :- b, c, d.
b.
c.
d :- e.
e.

e chiediamo a prolog se a è vera

 ?- a.

prolog prenderà a (o obiettivo o goal) a e genererà i sottobiettivi o sub-goals b, c and d.Possiamo vedere che b e c sono veri, direttamente, dal momento che sono fatti, mentre d è vera solo se e è vera,con e sotto-obiettivo. Dal momento che anche e è un fatto, prolog risponderà yes.

Regole con Variabili[modifica]

Possiamo usare anche termini con predicati.

car(corvette) :- haruote(corvette), hafinestrini(corvette).

stabilisce che una corvette è un'auto se ha ruote e finestrini. Questa non è una affermazione molto utile, potremmo semplicemente stabilire che una corvette è una macchina con:

car(corvette).

Noi possiamo comunque usare le variabili nelle regole. Così per esempio possiamo stabilire che un oggetto è una macchina ogniqualvolta abbia ruote e finestrini:

car(A) :- haruote(A), hafinestrini(A).
haruote(corvette).
hafinestrini(corvette).

La prima linea stabilisce che affinché auto(A) sia vera, ha ruote(A) e ha finestrini(A) devono essere veri. Se chiediamo a prolog se la corvette è una macchina con:

 ?- car(corvette).

legherà A a corvette, e otterrà i subgoal haruote(corvette) e hafinestrini(corvette). Se proviamo queste affermazioni allora car(corvette) dev'essere vera. Quando usiamo le variabili in un programma dobbimo ricordarci che una variabile non significa niente senza la sentenza ad essa legata. Se due affermazioni usano la stessa variabile A, non è la stessa variabile. Per esempio:

bird(A) :- hapiume(A).
cane(A) :- abbaia(A).

La A nella prima linea mostra semplicemente che il termine del predicato uccello deve esser lo stesso del predicato ha piume e non ha niente a che fare con la A nella seconda linea.

Ritorniamo ora al nostro programma originale e aggiungiamo qualche regola.

umano(david).
umano(john).
umano(suzie).
umano(eliza).
uomo(david).
uomo(john).
donna(suzie).
donna(eliza).
parente(david, john).
parente(john, eliza).
parente(suzie, eliza).

padre(X,Y) :- parente(X,Y), uomo(X).
madre(X,Y) :- parente(X,Y), donna(X).

Chiediamo a prolog chi è il padre di eliza:

?- padre(X, eliza).

X = john ;
No

Ora metti tutti i padri nel database con i loro rispettivi figli:

?- padre(Father, Child).

Father = david
Child = john ;

Father = john
Child = eliza ;

No

Adesso le madri

?- madre(Mother,Child).
Mother = suzie
Child = eliza;
No

Esempi[modifica]

partner(john, gloria).
partner(david, britney).
partner(gino, topino).
partner(john, karen).	
sex(john, man).		% maschietti
sex(david, man).
sex(gino, man).
sex(bobbysolo, man).
sex(karen, woman).	        % femminucce
sex(sasha, woman).
sex(gloria, woman).
havechild(john, sasha).	% genitori
havechild(john, david).
havechild(karen, sasha).
havechild(gloria, david).
isfather(A, B) :- sex( A, man), havechild( A, B). 
ismother(A, B) :- sex( A, woman), havechild(A,B).
parents(A, F, M) :- isfather(F, A), sex(F, man), ismother(M,A), sex(M,woman).
Interrogazioni[modifica]
?- consult('prolog1.pl').     % carico il programma
% prolog1.pl compiled 0.00 sec, 288 bytes
true.
?- umano( Person ).
Person = john ;
Person = david ;
Person = gino ;
Person = bobbysolo ;
Person = karen ;
Person = gloria.
?- partner( john, Who ).
Who = gloria ;
Who = karen.
?- sex(karen, woman).
true.
?- havechild(john, Child).
Child = sasha ;
Child = david.
?- isfather( john, sasha).
true .
?- parents( david, Father, Mother).
Father = john,
Mother = gloria .
?- parents( sasha, Father, Mother).
Father = john,
Mother = karen .

Esercizi[modifica]


Precedente: Introduzione; Successivo: