next up previous Sommario
Next: 7.4 Costrutti per il Up: 7. Il linguaggio Gödel Previous: 7.2 Il Type System   Sommario

7.3 Strumenti per la metaprogrammazione

Molte applicazioni della programmazione logica si basano su tecniche di metaprogrammazione; un metaprogramma è un programma che usa un altro programma (detto programma oggetto) come dati: quindi oltre ai compilatori, ai debuggers e ai trasformatori di programmi, anche i sistemi di basi di conoscenza consistono di un programma oggetto (la base di conoscenza) e di metaprogrammi (gli interpreti e gli assimilatori di conoscenza).

D'altro canto i sistemi Prolog disponibili non forniscono strumenti soddisfacenti per scrivere metaprogrammi. Ciò è dovuto principalmente al fatto che non esiste una chiara distinzione tra livello oggetto e metalivello e non sono disponibili strumenti linguistici espliciti per la rappresentazione di espressioni del livello oggetto al metalivello. Potendo disporre di una appropriata rappresentazione, anche i metaprogrammi sono una teoria del primo ordine tipata e si riesce a dare una controparte dichiarativa ai predicati metalogici del Prolog, come var, nonvar, assert, retract.



Per evidenziare i problemi dovuti alla mancanza di questa rappresentazione, consideriamo un tipico metaprogramma, l'interprete solve standard.


\begin{displaymath}solve(empty) \leftarrow\end{displaymath}


\begin{displaymath}solve(x \& y) \leftarrow solve(x) \wedge solve(y) \end{displaymath}


\begin{displaymath}solve (x) \leftarrow clause(x,y) \wedge solve(y) \end{displaymath}

Il programma oggetto contenente la clausola


\begin{displaymath}p(x,y) \leftarrow q(x,y) \end{displaymath}

viene rappresentato per mezzo della clausola


\begin{displaymath}clause(p(x,y) , q(x,y) ) \leftarrow \end{displaymath}

che appare nella definizione di clause.

Il significato dichiarativo dell'interprete solve non è chiaro perché le variabili nella definizione di clause e quelle nella definizione di solve hanno portata su differenti domini.

Una soluzione è quella di usare una rappresentazione non ground, che consiste nell'introdurre i tipi nel linguaggio in cui è scritto il metaprogramma: una variabile del livello oggetto verrebbe rappresentata come una variabile del metalivello.

Anche in questo caso ci sono problemi semantici insuperabili, per esempio legati al predicato var; considerando i goal


\begin{displaymath}\leftarrow var(x) \wedge solve(p(x)) \end{displaymath}


\begin{displaymath}\leftarrow solve(p(x)) \wedge var(x) \end{displaymath}

se lanciati rispetto al programma oggetto consistente solo della clausola $ p(a) \leftarrow $, avrebbero come risultato che il primo ha successo mentre il secondo fallisce.



Si passa quindi a considerare la rappresentazione ground che consiste nel rappresentare le espressioni del livello oggetto per mezzo di termini ground al metalivello. In particolare, una variabile del livello oggetto è rappresentata da un termine ground al metalivello. Si riescono così a dare appropriate definizioni per controparti dichiarative dei predicati metalogici var e nonvar del Prolog. Nel Prolog var ha anche un uso "di controllo": una funzione equivalente viene ottenuta in Gödel per mezzo di una regola di computazione flessibile che sarà esposta in seguito.

Usando la rappresentazione ground è possibile dare anche una controparte dichiarativa ai predicati Prolog assert e retract. L'idea è che i programmi oggetto non vengono rappresentati come metaprogrammi, ma come termini del metalivello. Quindi risulta più chiara la semantica di programmi che manipolano la rappresentazione di programmi oggetto creandone dinamicamente di nuovi.

Stando la evidente maggiore importanza della rappresentazione ground, il Gödel fornisce ampi strumenti per maneggiarla, cosa che non succede per quella non ground, che deve essere totalmente a carico del programmatore.


next up previous Sommario
Next: 7.4 Costrutti per il Up: 7. Il linguaggio Gödel Previous: 7.2 Il Type System   Sommario
Roberto Giungato 2001-03-14