RSS
English French German Spanish  

Mini guida Prolog – Parte IX: i predicati predefiniti “assert” e “retract”

Aprile 12, 2012

Linguaggi di Programmazione

Print Friendly
Share
Prolog - Assert Retract

Come abbiamo visto fin dall’inizio del corso, una teoria Prolog è un insieme finito di clausole definite ciascuna delle quali può essere un fatto, ossia una affermazione sempre vera, oppure una regola, cioè l’espressione di una conseguenza che diventa vera quando tutte le precondizioni sono soddisfatte. Ci sono però almeno due distinte interpretazioni sostanziali per il concetto di fatto (o regola priva di body) che occorre in questa sede ricordare: il postulato e la definizione (ad esempio 0! = 1 oppure padre(antonio,luigi)) ed il lemma (inteso come risultato acquisito di un complesso procedimento deduttivo già completato).

Dal seguente predicato fact/2:

fact(0,1) :- !.
fact(N,X) :- M is N – 1, fact(M,Y), X is Y * N.

è infatti possibile dedurre, attraverso dimostrazione, che 10! = 3628800 e che 20! = 2432902008176640000. Che cosa accadrebbe però se, come effetto collaterale di ciascuna deduzione, fosse aggiunto uno specifico lemma alla teoria?

Con una nuova teoria del tipo:

fact(10,3628800) :- !.
fact(20,2432902008176640000) :- !.

fact(100,…) :- !.
fact(0,1) :- !.
fact(N,X) :- M is N – 1, fact(M,Y), X is Y * N.

sicuramente ogni successiva valutazione di un fattoriale già calcolato in precedenza diventerebbe meno impegnativa dal punto di vista computazionale, poiché il risultato sarebbe immediatamente disponibile come fatto. Ovviamente una ottimizzazione di questo tipo non porterebbe significativi benefici nel caso del semplice calcolo fattoriale e l’opportunità di una sua applicazione andrebbe valutata caso per caso.

Prolog dispone di alcuni predicati predefiniti in grado di manipolare il contenuto del database. Il predicato assert/1 premette di inserire una clausola nel database (le varianti asserta/1 e assertz/1 permettono di inserire la clausola rispettivamente in cima oppure in coda al database), mentre il predicato retract/1 permette di rimuovere la prima clausola del database compatibile con la richiesta. Ad esempio:

?- assert(cane(fido)).
yes.

?- cane(X).
yes. X / fido

?- retract(cane(X)).
yes. X / fido

?- cane(X).
no.

Sfruttando il predicato asserta/1 (occorre infatti essere sicuri che il nuovo fatto sia inserito prima di ogni eventuale regola esistente) è quindi possibile salvare un lemma prodotto:

?- fact(10,X), asserta((fact(10,X):- !)).
yes. X / 3628800

Ritorna alla Home

Nessun commento finora.

Invia una Risposta