Prolog/Introduzione

Wikibooks, manuali e libri di testo liberi.

Che cos'è il Prolog?[modifica]

Il Prolog è un linguaggio di programmazione dichiarativo. Ciò significa che in Prolog non scrivete che cosa dovrebbe fare il calcolatore linea per linea, come nei linguaggi procedurali C e Java. L'idea generale dietro i linguaggi dichiarativi è descrivere una situazione. Sulla base di questo codice, l'interprete o il compilatore vi dirà una soluzione. Nel caso del Prolog, vi dirà se una frase di Prolog sia vera o no, e, se contiene le variabili, quali valori devono avere.

Ciò può suonare come una panacea per i programmatori, ma la verità è che il Prolog è usato raramente in questo modo. Benché l'idea dichiarativa sia alla base del Prolog, è possibile vedere il codice di Prolog come procedurale. Un programmatore di Prolog lavorerà secondo la parte del codice che sta leggendo o scrivendo. Il Prolog tuttavia, come esperienza di programmazione procedurale, non è utile (si dice spesso che è più facile da imparare per qualcuno che non abbia alcun'esperienza di programmazione procedurale). Il Prolog è considerato un linguaggio difficile da padroneggiare, particolarmente quando l'allievo prova a scorrere velocemente le cose, principalmente a causa del modo differente di pensare che l'allievo deve adottare e della quantità di ricorrenza nei programmi in Prolog.
Una volta imparato ad usarlo correttamente, tuttavia, il Prolog può essere molto potente.

Perché imparare Il Prolog[modifica]

Imparare il Prolog certamente non sarà sempre fruttuoso quanto imparare C++, Java o Python. Il Prolog è più utile nelle zone relative alla ricerca in intelligenza artificiale, quali soluzione dei problemi, la progettazione o l'interpretazione di linguaggio naturale. Alcuni campi che non sono rigorosamente IA (intelligenza artificiale), quale la costruzione di analizzatori o parser, possono anche trarre giovamento notevole dal Prolog.

Tuttavia anche quelli che non lavorano quotidianamente con sistemi di linguaggio naturale possono trarre beneficio dal Prolog. Poiché il Prolog usa determinate tecniche di programmazione che sono considerate difficili o avanzate (come la ricorsione), il Prolog può servire a migliorare la comprensione in queste tecniche.

Un programmatore Prolog certamente avrà una comprensione approfondita di tali concetti come la ricorsione, cercando problem trees e constraint logic programming. Il Prolog può persino servire da strumento di abbozzo per provare le idee di programmazione di base prima di realizzarle con linguaggi procedurali. A causa del legame con la logica dei predicati, imparare il Prolog può condurre ad una comprensione maggiore della logica di predicato (viceversa, chiunque abbia sperimentato la logica di attributo certamente potrà apprendere meglio il Prolog).

Inoltre, se state cercando di migliorare il vostro resume come webdesigner, il Prolog potrebbe non essere la strada da seguire. Il Prolog è ancora principalmente un linguaggio universitario. Ciò non significa che è puramente per fare test o tecniche di outlining. Programmi molto complessi sono stati scritti in Prolog. Soprattutto il Prolog è un linguaggio complesso, potente e elegante, che può ispirare soddisfazione grande ai suoi programmatori (così come una rabbia immensa).

L'apprendimento del Prolog richiede una certa attenzione. Come dichiarato prima, impararlo non è facile. Non funziona naturalmente come i linguaggi procedurali e quindi richiede un modo specifico di pensare. Per impararlo occorre saper apprendere con calma e assorbire bene i concetti prima di andare oltre. È inoltre consigliabile usare più di un testo o manuale nell'apprendimento, per ottenere prospettive multiple su un concetto. Come nota finale, una volta che avrete acquistato padronanza di qualche cosa di ingannevole che non sia spiegato chiaramente qui, sentitevi liberi di modificare questo testo, di modo che altri allievi possano imparare più facilmente.

Prima di iniziare devi installare sul tuo sistema un editor di testo ed un compilatore Prolog. L'editor di testo ti permette di scrivere programmi ed il compilatore Prolog (chiamato anche interprete) ti permetterà di eseguirli.

Compilatori[modifica]

Le seguenti implementazioni di Prolog sono libere (al limite per uso personale o educativo, assicurati di leggere la documentazione legale). Semplicemente scaricane uno ed assicurati di installarlo seguendo le istruzioni del sito web:

  • SWI Prolog: un'implementazione open source semplice e robusta conforme ad entrambi gli standards Prolog (ISO and Edinburgh) ed ha molte librerie extra e predicati built-in. Esiste addirittura un kit di strumenti separato per creare finestre e grafica chiamato XPCE. Supporta varie piattaforme.
  • GNU Prolog: un'implementazione open source relativamente nuova. Ha un supporto per la programmazione in logica vincolata, una estensione di Prolog.
  • tuProlog: un'implementazione open source dell'Università di Bologna.
  • Visual Prolog: un ambiente di sviluppo completo per uno sviluppo in stile orientato agli oggetti di Prolog. Include compilatore, linker, editore, editori per il dialogo grafico, sistema di building, debugger, librerie e molto altro.
  • YAP Prolog: si tratta di un compilatore Prolog molto veloce ed efficiente sviluppato dalla Universidade do Porto.

Le seguenti implementazioni di Prolog sono proprietarie:

  • SICSTUS Prolog: probabilmente la più nota e conosciuta implementazione professionale comprensiva di ambiente di sviluppo per Prolog. ISO-conforme, tante librerie e supporto per la programmazione in logica vincolata. Libero solo per una valutazione.
  • Quintus Prolog: commerciale sempre della SICSTUS. Valutazione gratuita.

Text editor[modifica]

I programmi che scriverai sono dei semplici files di testo, che possono essere letti e scritti da qualsiasi text editor. Alcune implementazioni di Prolog hanno il proprio, per gli altri ecco qui una lista. Molti forniscono le funzioni di base utili per scrivere programmi in Prolog, come indentazione, l'aggiustamento delle parentesi ed alcuni danno anche la possibilità di evidenziare le parti importanti del tuo codice Prolog.

  • Crimson Editor : Un editor di testi libero per Windows con tanti strumenti.
  • GNU Emacs: Una implementazione open-source e libera del classico editor di testi stile Unix. Forse non molto agevole, ma ricco di strumenti.
  • Textpad : Un text-editor ricco per Windows. La prova è gratuita.

Logica proposizionale[modifica]

Searchtool.svg Per approfondire, vedi Logica.

Nella logica proposizionale esistono due fondamentali elementi di base: termini e connettivi. I termini sono rappresentati da lettere (di solito maiuscole), e rappresentano i valori vero e falso, quindi un termine può essere vero o falso, benché non sia sempre chiaro cosa rappresenti veramente. In questo senso essi sono come le variabili in matematica perché rappresentano un valore.

I connettivi, come suggerisce la parola, connettono due termini. Il risultato di questa connessione prende il valore di vero o falso basandosi proprio sul valore dei due termini. Consideriamo per esempio il connettivo AND. Questo connettivo può mettere in relazione i termini A e B per creare la proposizione "A AND B". La proposizione "A AND B" è vera quando sono vere A e B. Se una o entrambe sono false, la proposizione è falsa. I connettivi sono solitamente rappresentati da simboli piuttosto che da parole. La seguente tabella mostra i connettivi più comunemente usati, il loro significato ed i simboli più correntemente usati per rappresentarli.

Nome Uso Significato Simbolo
congiunzione A \land B vera quando entrambe sono vere  \land \quad ,
disgiunzione A \lor B vera quando una o entrambe sono vere  \lor \quad ;
or esclusivo A \oplus B vera quando una e solo una è vera \oplus \quad \underline {\lor} \quad
negazione \lnot A vera quando una e falsa e viceversa  \sim \quad \lnot \quad \bar {q}
implicazione A \rightarrow B vera quando A è vera e B è vera; vera quando A è falsa  \rightarrow \quad \Rightarrow \quad \models
uguaglianza A \leftrightarrow B vera se entrambe false o entrambe vere  \leftrightarrow \quad \Leftrightarrow \quad =

Attenti al significato di implicazione, potrebbe non essere così intuitivo. A => B significa che se A è vera allora è vera anche B, in caso contrario B può essere sia vera che falsa.

Dal momento che ogni termine può prendere alternativamente solo due valori, tutte le possibilità possono essere chiaramente enumerate attraverso una tabella della verità':

A B A e B A or B A xor B not A A => B A<=>B
f f f f f v v v
f v f v v v v f
v f f v v f f f
v v v v f f v v

Il passo successivo consiste nel connettere le due preposizioni, usando i connettivi, per avere proposizioni più complesse, come (A e B) => (B <=> A) o ((A or C) or (A or D)). Nell'ultima proposizione le parentesi vengono omesse dal momento che A or (B or C) è lo stesso che (A or B) or C. Comunque, nel dubbio, è meglio usare le parentesi per maggior chiarezza.

Si possono analizzare proposizioni complesse come questa:

A B A e B A or B (A e B) or (A e C)
f f f f f
f v f v v
v f f v v
v v v v v

Ora possiamo dividere le proposizioni in tre gruppi: valide, insoddisfacenti e soddisfacenti. Le proposizioni valide o tautologie sono sempre vere, non importa che valori prendono. Esempi di proposizioni valide sono A or (not A), A => A or (A => B) or ( A e (not B)). Le Proposizioni insoddisfacenti sono sempre false, eg: A e (not A) or (A <=> B) e (B <=> not(A)). Tutte le altre proposizioni sono soddisfacenti, cioè possono essere sia vere che false, secondo i valori dei loro termini.

Significato e Intenzione[modifica]

Nel linguaggio logico è importantissimo capire che le proposizioni possono essere usate e combinate nei modi più disparati.  A \wedge B , per esempio, non implica alcun significato. È soltanto un modo formale di creare proposizioni logiche. Si può affermare che  A \wedge B è vera, dandole un significato (A e B sono entrambe vere), che può essere usato per derivare ulteriori verità se conosciamo meglio A e B. Si potrebbe chiedere se  A \wedge B è vera, e la risposta potrebbe essere basata su quanto si conosce riguardo A e B. In altre parole , una proposizione logica non significa nulla in sé se non viene riempita con qualcosa. Il lettore necessita di una conoscenza più approfondita allo scopo di fare qualcosa di ulteriore.

Un costrutto logico comune è la conoscenza di base, una collezione di sentenze che sono assunte come sempre vere (in matematica sono chiamate anche postulati), ed una singola proposizione posta in forma di domanda. Occorre capire quale affermazione sia vera, data la conoscenza di base. Consideriamo per esempio la seguente conoscenza di base:

 A \wedge B
 ~B

Con la domanda

A

In questo caso occorre capire se A è vera , data la conoscenza di base. È chiaro che la questione è sicuramente vera, dal momento che  A \wedge B è vera, e B pure. Questa costruzione conoscenza di base/domanda è il modo in cui lavora il Prolog. Puoi scrivere una conoscenza di base (il tuo programma) e chiedere una questione a Prolog.A paragone dei linguaggi di programmazione , la conoscenza di base è il tuo programma , la domanda è il tuo input ed il Prolog svolge il programma risolvendo la tua domanda.

Logica del Primo Ordine[modifica]

La logica del primo ordine (conosciuta anche come logica dei predicati) è simile alla logica proposizionale, solo che usa predicati, variabili e oggetti. Nella logica proposizionale, le proposizioni atomiche sono i più piccoli elementi che possono assumere i valori vero/falso e i termini sono simboli rappresentati da lettere. Nella logica del primo ordine le proposizioni atomiche sono predicati. I predicati hanno un nome (che inizia con la lettera maiuscola) seguito da una o più variabili (che iniziano con la lettera minuscola). Qui sotto abbiamo alcuni esempi di predicati:

  • Predicato(variabile1, variabile2)
  • FratelloDi(sorella, fratello)
  • MadreDi(madre, figlio)
  • HaRuote(cosa)

Queste variabili possono essere istanziate con oggetti. Gli oggetti sono elementi rappresentati da parole che iniziano con la lettera maiuscola. Per esempio, nel predicato HaRuote(cosa) la variabile cosa può essere istanziata con gli oggetti Auto, Bici, o Banana. Basato sull'istanziazione delle variabili, il predicato (HaRuote(Auto) è vero se HaRuote(Banana) è falso). Questi nomi vengono usati solo per migliorare la leggibilità, per i nosti scopi non significano nulla e possono essere sostituiti. HaRuote(Banana) non è funzionalmente differente da X(A). Tuttavia HaRuote(Banana)vera o falsa ha bisogno di essere definita in qualche modo formale (come in una conoscenza di base).

Questi predicati possono essere riuniti in proposizioni, proprio come i termini della logica proposizionale, usando connettivi (i connettivi sono gli stessi della logica proposizionale). Di solito esiste una collezione di proposizioni assunte come vere, per crare una definizione logica di predicati.Una simile collezione di predicati veri o postulati è detta conoscenza di base o knowledgebase. Una conoscenza di base può contenere le seguenti proposizioni:

  • HaRuote(Auto)
  • MadreDi(Elisabetta, Carlo)

Dicendo che il predicato HaRuote è vero, il primo elemento è una macchina e Elisabetta è la madre di Carlo. Per costruire questo tipo di proposizioni con variabili abbiamo bisogno di stabilire cosa vogliamo dire effettivamente quando usiamo quelle variabili. Se HaRuote(x) è vera, vogliamo dire che è valida qualsiasi istanza di x o che esiste almeno una istanza di x in cui HaRuote è vera? Per questo motivo dobbiamo usare dei quantificatori o quantifiers, che hanno il compito di determinare la quantità di una variabile.

Nella logica del primo ordine esistono due quantificatori, il quantificatore universale \forall ed il quantificatore esistenziale \exists.Questi quantificatori vengono piazzati prima di una variabile allo scopo di capire cosa vogliono dire quelle variabili nella proposizione che segue il quantificatore. Per esempio, la frase \forall x HaRuote(x) significa che per qualsiasi possibile istanza di x, HaRuote(x) è vera, quindi che tutti i possibili oggetti di quella frase devono avere le ruote. La frase \exists x HaRuote(x) significa che esiste almeno un oggetto x per il quale il predicato HaRuote(x) è vero, in parole povere che esiste almeno un oggetto con le ruote. Per capire meglio il significato e l'uso dei quantificatori possiamo utilizzare i seguenti esempi:

  • Se x è un veicolo, allora x ha le ruote. (se x non è un veicolo, la proposizione non può dire nulla su x)
\forall x IlVeicolo(x) \Rightarrow HaRuote(x)
  • Se x ha un bambino y e x è un uomo, x è il padre di y.
\forall x, y HaUnBambino(x, y) \wedge Man(x) => PadreDi(x, y)
  • Allora esite un oggetto che non ha le ruote ed è una macchina
\exists x HaRuote(x) \wedge \sim Auto(x)
  • Tutte le madri hanno un figlio
\forall x Madre(x) => \exists y Bambino(y) \wedge HaUnFiglio(x, y)

Logica in Prolog[modifica]

La logica usata in Prolog è una versione della logica del primo ordine, con l'uso delle lettere maiuscole invertite: i predicati iniziano con la lettera minuscola mentre le variabili iniziano con una lettera maiuscola. Un programma in Prolog consiste di una base di conoscenza, in inglese knowledge base, dove ogni proposizione è congiunta ad altri predicati e ad un predicato finale con una implicazione. Per esempio:

\forall a,b,c,dPred1(a, b) \wedge Pred2(b, c) \wedge Pred3(c, d) \Rightarrow Pred4(a)

Una proposizione come questa è chiamata Clausola di Horn. In Prolog la proposizione somiglierebbe a questa:

pred4(A) :- pred1(A, B), pred2(B, C), pred3(C, D).

Nota: il segno di implicazione è al contrario, le virgole sono usate per le congiunzioni, un punto è usato per delimitare una proposizione e tutte le variabili sono universalmente quantificate.

Esempi[modifica]