Costruzione di un meta-motore di ricerca usando Prolog:

Transcript

Costruzione di un meta-motore di ricerca usando Prolog:
UNIVERSITÀ CA’ FOSCARI DI VENEZIA
FACOLTÀ DI SCIENZE MATEMATICHE, FISICHE E NATURALI
CORSO DI LAUREA SPECIALISTICA IN INFORMATICA
Approfondimento per il corso di “Linguaggi Logici”
“WWW Programming with Computational Logic System”
Autore: Gaglio Elia (809477)
Prof.ssa: Annalisa Bossi
Anno Accademico: 2006/07
Indice:
Abstract……………………………………………………………………….. pag. 3
1. LogicWeb: come integrare la Programmazione Logica con il WWW
1.1 Perché integrare la LP al WWW?.............................................................pag. 4
1.2 Che cos’è LogicWeb?...............................................................................pag. 4
1.3 Un esempio pratico: un “Page Searcher” logico………………………...pag. 6
2. PiLLoW: una libreria per integrare la LP e il WWW
2.1 Perché PiLLoW è stato sviluppato?..........................................................pag. 8
2.2 Come si può scrivere una applicazione cgi-bin di base?..........................pag. 8
2.3 Trattare documenti HTML come insiemi di termini Prolog…………….pag. 9
2.4 Come effettuare l’accesso a documenti WWW…………………………pag. 11
3. Costruzione di un meta-motore di ricerca logico:
3.1 I problemi che affliggono i motori di ricerca tradizionali………….……pag. 12
3.2 Soluzione: implementazione di meta-motori di ricerca………….……...pag. 12
3.3 Le funzionalità del meta-search engine “PrologCrawler”………….……pag. 13
3.4 Interfacciamento con i motori di ricerca………………………………...pag. 13
3.5 Implementazione di “PrologCrawler”…………………………………...pag. 14
4. LP nel Web Moderno:
4.1 Dalla LP + WWW fino al “Semantic Web”……………………………..pag. 19
4.2 Metalog: come aggiungere ragionamento al Web...………………..……pag. 21
4.3 xml.pl: Parsing XML with Prolog.………………...……………….……pag. 25
5. Conclusioni…………………………………………………………………..pag. 29
6. Bibliografia……………………………………….……………………….…pag. 30
2
Abstract:
Con il termine “WWW Programming with Computational Logic System” si intende la possibilità di
sviluppare applicazioni Web sfruttando i paradigmi e le tecniche specifiche della programmazione
logica.
Obiettivo di questo approfondimento è quello di proporre un insieme di esempi che permettano di
dimostrare come la programmazione logica (LP) possa essere affiancata alle moderne ed emergenti
applicazioni WWW, in modo da ottenere dei vantaggi in termini di tempi e complessità nel loro
sviluppo. Ecco quindi che verranno descritti degli spunti di ricerca valutati interessanti e che hanno
permesso tale integrazione.
Gli articoli analizzati sono stati inseriti in ordine cronologico, al fine di far notare come nel corso
degli anni siano stati realizzati lavori sempre più apprezzabili e come la congiunzione LP e WWW
abbia portato a spunti e lavori interessanti.
Il primo articolo proposto descrive LogicWeb, un progetto di ricerca svolto dall’Università di
Melbourne nel periodo a cavallo del 1996/97 e che è stato un buon punto di partenza per proporre
alcune applicazioni WWW “logiche”. Tra di esse si è scelto di presentare un PageSearcher, ovvero
un’applicazione che permette di effettuare delle ricerche di pagine Web sulla base di una lista di
keywords passate in input.
In seguito sono state proposte altre soluzioni per sviluppare applicazioni WWW in modo semplice e
veloce, sfruttando librerie e strumenti di base che permettano un risparmio di tempo e di sforzi. Un
esempio del genere viene da PiLLoW, una libreria sviluppata nel 1997 e che permette la
generazione di documenti HTML, trattandoli come insieme di termini di Herbrand.
Partendo da questi strumenti sono stati realizzati diversi lavori, tra i quali si può citare, ad esempio,
un meta-motore di ricerca logico sviluppato in un progetto di ricerca dell’Università di Pisa nel
1999 e denominato “PrologCrawler”. Quest’ultimo progetto risulta essere interessante sia per
l’obiettivo che si prefigge (l’eliminazione di alcuni problemi che affliggono le ricerche effettuate
nel web mediante i classici motori di ricerca), sia per il metodo di sviluppo che sfrutta in modo
esplicito alcune tecniche della programmazione logica.
Dopo aver proposto tali esempi viene riportata una conclusione del lavoro, includendo una
considerazione sull’importanza della LP nel Web moderno, il cosiddetto “Semantic Web”,
introdotto esplicitamente dal consorzio W3C nel 2001. Verrà proposto un primo caso di studio, nel
quale si analizzerà Metalog, un progetto del 2004 basato sull’idea della costruzione di un sistema
“query/logical” che permetta di effettuare ragionamenti sugli oggetti presenti nel Web garantendo
un livello che sia il più possibile “user-friendly”.
Infine si analizzerà il modulo xml.pl, il quale permette un parsing efficiente di documenti XML e
XHTML e che riveste un punto di partenza interessante per la realizzazione di diverse tipologie di
applicazioni e di programmi scritti in Prolog.
3
1. LogicWeb: come integrare la Programmazione Logica con il WWW:
1.1 Perché integrare la LP al WWW?
LogicWeb nasce dall’idea di poter integrare la programmazione logica con il World Wide Web
(WWW). Come tutti sanno la programmazione logica è basata sulla Logica Matematica, dove la
computazione è costituita da un insieme di assiomi e di regole, da cui poter fare delle deduzioni.
Le proprietà che essa garantisce sono molto apprezzabili e solide. Tra di esse possiamo includere:
- una vista dichiarativa dei programmi che si possono realizzare,
- un modo uniforme per rappresentare i dati e la computazione,
- una semantica di base ben fondata.
Negli ultimi anni si è assistito ad uno sviluppo enorme di Internet e di tutte le applicazioni ad esso
collegate. In particolar modo, le applicazioni che manipolano Database, i tools di ricerca di
informazioni ed altre applicazioni, sono diventate la chiave per un utilizzo efficiente del WWW.
Da qui è nata l’idea di integrare il tutto con la programmazione logica, visti i vantaggi che essa
garantisce e che sono stati illustrati precedentemente. Infatti le pagine web scritte in HTML
standard hanno un “comportamento statico e scarsamente programmabile”. Difatti:
-
-
La semantica dei links cliccabili in una pagina è fissata ad una semplice relazione attraverso la
quale la pagina richiesta viene scaricata e visualizzata. In questo modo la pagina che contiene il
link e la pagina che viene referenziata non hanno risposta della dereferenziazione che viene
effettuata.
Una pagina web non può processare query più generali di un semplice hyperlink.
Non ci sono modi per una pagina di poter collezionare e manipolare dati da altre risorse e in più
generale di poter creare delle relazioni tra pagine.
Proprio da questi limiti si è studiato un modo per rendere il Web e le sue applicazioni più
programmabile, e maggiormente trattabile da un punto di vista semantico.
1.2 Che cos’è LogicWeb?
L’idea di base di LogicWeb è quella di poter trattare le pagine web come dei moduli di
programmazione logica. In questo modo le pagine possono diventare delle entità di informazione,
che possono essere interrogate mediante le query utente.
L’utilizzo della programmazione logica permette di estendere i fondamenti teorici che essa rispetta
al mondo WWW, permettendo quindi dei grossi miglioramenti a livello applicazione. In particolare,
si riescono ad ottenere vantaggi specifici in fase di ricerca di informazioni, grazie all’utilizzo della
tecnica del backtracking, nelle applicazioni di pattern matching visto l’utilizzo delle tecniche di
unificazione e si ha la possibilità di definire una semantica per ogni tipo di estensione Web.
LogicWeb permette una corrispondenza tra le pagine Web e i programmi logici costituiti da fatti e
regole. Da ciò nascono dei moduli detti LogicWeb modules, che permettono di dare una semantica
a tutto ciò di cui disponiamo in ambito WWW.
Infatti, una pagina web caratterizzata dall’avere una URL <URL> corrisponde ad un modulo il cui
nome è il termine m_id(<URL>). Tale modulo contiene i seguenti due fatti:
my_id(<URL>) che permette di memorizzare la URL della pagina;
4
h_text(<HTML source>) che permette di memorizzare il codice HTML della pagina;
In questo modo è possibile modellare una semplice pagina web. I vantaggi che si ottengono da ciò
sono molto interessanti: la pagina può essere parserizzata al fine di estrarre un insieme di fatti, come
ad esempio una collezione di links:
<A HREF=&quothttp://www.cs.mu.oz.au/~swloke/logicweb.html"&gtLogicWeb</A>
è rappresentabile dal seguente fatto:
link("LogicWeb","http://www.cs.mu.oz.au/~swloke/logicweb.html").
E’ chiaro quindi che si possono definire altre clausole associate ad una pagina web, le quali permettono di definire il comportamento della pagina stessa e di effettuare delle query. Tutte queste clausole vengono denominate “live clauses”.
Le live clauses permettono di effettuare delle operazioni interessanti attraverso le diverse pagine
web, sfruttando l’utilizzo di nuovi operatori che estendono i programmi logici Prolog “classici”. Tra
essi si possono citare:
-
context switching: mediante questo operatore un modulo LogicWeb può utilizzare le clausole
di un altro modulo. La sintassi è la seguente:
m_id (<URL>)#>Goal
In questo modo è possibile richiamare il goal Goal anche se non fa parte del modulo
corrente. Mediante l’operatore #> è possibile effettuare la referenziazione di un modulo
esterno (dove il modulo rappresenta la pagina Web di url URL), il quale verrà
automaticamente caricato nel sistema client che ne fa la sua richiesta (nel caso in cui non sia
stato già caricato con qualche operazione precedente).
Esiste anche l’operatore :>, che funziona allo stesso modo del predicato prima descritto, ad
eccezione del fatto che fallisce nel caso in cui la pagina a cui si punta non sia stata già
caricata.
-
union: permette l’unione di due moduli LogicWeb. Tale operatore è utile nel momento in cui
bisogna effettuare la valutazione di una query rispetto a due o più moduli logici.
La sintassi risulta essere la seguente:
lw_union (ListOfModules)#>Goal
In questo modo è possibile effettuare la valutazione del goal Goal mediante l’unione dei
moduli inseriti in ListOfModules.
-
relationship: è stato definito un predicato attraverso il quale è possibile definire una relazione
tra coppie di pagine. La sua sintassi è la seguente:
related (<URL1>,<URL2>)
E’ chiaro perciò che l’utilizzo combinato di questi nuovi operatori porta ad un grosso vantaggio
nello sviluppo di applicazioni di svariato tipo, in particolar modo quelle relative alla ricerca di
parole o oggetti presenti all’interno delle pagine web. Infatti è molto interessante la possibilità che
viene offerta di poter combinare tra loro componenti di pagine differenti in un'unica nuova pagina.
5
1.3 Un esempio pratico: un “Page Searcher Logico”:
Un esempio interessante di applicazione realizzabile web realizzabile con Prolog e con alcuni
operatori introdotti in precedenza è un Page Searcher, ovvero un’applicazione che permette di
effettuare delle ricerche di pagine Web, passando in input una o più keywords.
La maggior parte dei siti presenti nel Web offre dei motori di ricerca basati su indici realizzati da
robot. In questo esempio verranno effettuate delle ricerche sfruttando le regole definite nella
programmazione logica per guidare la ricerca e poter definire il “grado di interesse” delle pagine
correlate.
Utilizzando la programmazione logica è possibile ottenere dei vantaggi grazie alla semplificazione
dell’intera fase di ricerca, merito di una semplicità nel definire le relazioni tra le entità coinvolte
(ovvero le pagine Web) e la capacità di esprimere informazioni complesse.
L’algoritmo è codificato sfruttando una serie “live clauses” all’interno della pagina web
pgssearch.html, attraverso la quale è possibile inserire le query di ricerca. Una volta inserita
l’interrogazione l’applicazione invoca il seguente goal:
?- pgs_search(<Keywordlist>,<PassScore>,<NumOfPgs>)
Il programma quindi effettua una selezione delle pagine Web di interesse esaminando il fatto
located_at/2 nel file pgssearch.html. La ricerca segue i links ad altre pagine effettuando una ricerca
“breadth-first” ed assegnando un punteggio a ciascuna pagina in base alla rilevanza con la keyword
list definita. Naturalmente il programma mantiene traccia delle pagine visitate.
In seguito, il risultato della ricerca viene proposto all’utente creando una pagina web apposita e
riportando solamente le pagine che hanno superato il PassScore, ovvero il limite minimo di
keyword presenti nella pagina. Il numero di risultati riportato è un parametro di input per l’utente.
La misura della rilevanza di una pagina dipende dal numero di occorrenze della keyword dalla lista
iniziale, o di keywords correlate alla lista originale. La relazione di correlazione è definita mediante
il fatto related/2.
Per ciascuna pagina visitata si effettua il parsing delle informazioni presenti nei links e si
memorizza il tutto nel fatto link (<label>,<URL>). In questo modo si crea una corrispondenza tra
una URL e una label e nel caso in cui una label contenga una keyword, l’URL associata viene
automaticamente inserita in coda alla lista delle pagine Web da visitare.
Il fatto located/2, inoltre, funge da puntatore alle pagine web da visitare.
E’ interessante notare che, poiché l’insieme delle pagine definito dal fatto related/2 si sviluppa
mentre vengono trovate nuove pagine, keywords considerate non correlate precedentemente
possono diventare correlate in seguito. Tale comportamento è catturato dal predicato
path_related/3, che permette di inferire circa la correlazione tra due keywords:
path_related(X,Y,VisitedNodes):- M:>related(X,Y),
not(member(Y,VisitedNodes)).
path_related(X,Z,VisitedNodes):- M:>related(X,Y),
not(member(Y,VisitedNodes)),
path_related(Y,Z,[Y|VisitedNodes]).
Forma un grafo diretto tra due
keywords, nel caso siano correlate
Istanziato con moduli differenti, mediante il
backtracking e cercando attraverso i fatti esistenti
contenuti nel fatto related/2
6
Dopo che un numero sufficiente di pagine è stato ritrovato si effettua la costruzione di una pagina di
risultato, da proporre all’utente. Per effettuare la costruzione si sfruttano i seguenti predicati:
build_head/2, build_body/3, build_whole/3
Ad esempio:
build_head(&quotInteresting URLs",Head)
effettua un’istanziazione di Head con la stringa passata in input. Ciò è equivalente al codice HTML:
“<HEAD>\n
<TITLE>Interesting URLs</TITLE>\n
</HEAD>”
Questo semplice esempio introdotto permette di dimostrare diverse caratteristiche tipiche di
LogicWeb:
-
E’ possibile considerare e manipolare diverse pagine Web sfruttando l’operatore #>.
E’ possibile effettuare il parsing delle informazioni contenute nei link di una pagina ed
effettuarne la memorizzazione. Inoltre, il parsing e la possibilità di costruire delle relazioni tra
link possono essere estesi e resi più complessi.
Il fatto located/2 permette di stabilire una relazione tra le pagine e quindi di arricchire le
relazioni già presenti e rilevate in precedenza.
7
2. PiLLoW: una libreria per integrare la LP e il WWW:
2.1 Perché PiLLoW è stato sviluppato?
La possibilità di integrare le applicazioni WWW con la programmazione logica è una area di ricerca
che nel corso degli anni ha dimostrato un grosso sviluppo e dei risultati molto convincenti. In
particolare molte applicazioni che oggi la fanno da padrone, come motori di ricerca, applicazioni
che sfruttano Database, ecc. ben si sposano ad uno sviluppo che sfrutta le tecniche della
programmazione logica.
In particolare, la LP condivide molte caratteristiche presenti in linguaggi di programmazione recenti
e utilizzati per la programmazione in rete. Tali caratteristiche includono la gestione dinamica della
memoria, una buona robustezza di base e la possibilità di effettuare una compilazione che
costruisca del bytecode. Oltre a tutto ciò la LP offre delle tecniche di meta-programmazione molto
sofisticate e raffinate e una semantica ben definita.
Facendo leva su tutte queste proprietà si è deciso di sviluppare una libreria apposita che permetta di
costruire in modo semplice e veloce delle applicazioni Web “logiche” (ovvero che sfruttano la LP).
Da quest’idea è nata PiLLoW, una libreria che genera documenti HTML o XML trattandoli come
insieme di termini di Herbrand e permette la costruzione di form e di tools più complessi, utili per
ricerche e parsing di documenti WWW.
Vista la vastità degli esempi che possono essere proposti, ci si concentra verso quei predicati e
quelle strutture di PiLLoW che permettono lo sviluppo di applicazioni WWW utilizzate per
effettuare l’accesso e il parsing di documenti web.
2.2 Come si può scrivere una applicazione cgi-bin di base?
Un modo semplice per scrivere un’applicazione WWW è quello di utilizzare gli script CGI. Un CGI
eseguibile non è altro che un semplice file eseguibile che viene richiamato da un web server. In
particolare, quando un utente seleziona un indirizzo di un file eseguibile CGI (caratterizzato quindi
dall’estensione .cgi), il browser effettua una richiesta apposita che verrà interpretata da un web
server e farà avviare l’esecuzione dell’eseguibile. Tutti gli output che verranno generati saranno
raccolti in un buffer e in seguito verranno codificati in una pagina web passata all’utente.
Ecco una rappresentazione grafica del funzionamento:
Figura 1: chiamata ad uno script CGI.
8
E’ possibile scrivere eseguibili sfruttando la programmazione logica. In questo modo si potrà vedere
la LP come una soluzione per progettare scripts di diversa natura, utilizzabili ad esempio in ambito
Web. Un semplice esempio di un eseguibile scritto in LP è il seguente:
main :- write('Content-type: text/html'), nl, nl,
write('<HTML>'),
write('Hello world.'),
write('</HTML>').
I linguaggi logici si adattano bene ad essere dei candidati ottimali per essere utilizzati come
linguaggi di scripting. Per rendere più conveniente tale passaggio è utile fornire un modo per
eseguire i programmi logici come degli scripts. Ecco quindi che molti progetti di ricerca sono stati
finalizzati a cercare di rendere semplice il supporto per lo scripting nei maggiori sistemi di LP.
Ad esempio, è possibile sfruttare una lpshell in un sistema di LP, la quale carica il file passato come
primo argomento ed avvia l’esecuzione dal predicato main/1.
In un sistema UNIX è possibile lanciare il seguente programma come uno script che non necessita
di compilazione:
#!/usr/local/bin/lpshell
main(_) :- write('Content-type: text/html'), nl,
write('<HTML>'),
write('Hello world.'),
write('</HTML>').
2.3 Trattare documenti HTML come insiemi di termini Prolog:
Una delle caratteristiche chiave della programmazione logica è quella di effettuare il processamento
sfruttando un insieme di termini di Herbrand. Ecco quindi che può venire naturale pensare di
associare al codice HTML un insieme di termini.
PiLLoW introduce dei predicati che permettono di definire una relazione esplicita tra una pagina
WWW e un insieme di termini di Herbrand. Tali predicati sono:
- output_html(F): il quale accetta F come una lista di termini HTML e invia allo “standard output”
il testo interpretato come una lista di termini in formato HTML.
- html2terms(Chars, Terms): permette di definire una relazione tra una lista di termini HTML e una
di caratteri ASCII, i quali sono l’interpretazione dei termini in formato HTML. Tale predicato è
reversibile: esiste infatti output_html/2 che trasforma termini HTML in caratteri.
Ecco un insieme di strutture Prolog che rappresentano le principali funzionalità HTML esistenti:
Strutture generali:
Fondamentalmente HTML definisce due tipi di componenti:
- HTML elements: caratterizzati da una forma tipo “<NAME Attributes>”;
- HTML environment: caratterizzati da una forma <NAME Attributes> Text </NAME>.
Le principali strutture Prolog che permettono di definire queste due tipologie di costrutti sono le
9
seguenti:
-
Name$Atts: permette di rappresentare un elemento HTML di nome Name e attributi Atts.
Ad esempio:
img$[src='images/map.gif',alt='A map',ismap]
è convertito in HTML in questo modo:
<img src="images/map.gif" alt="A map" ismap>
-
name(Text): rappresenta un environment HTML di nome name che include un testo Text.
Ad esempio:
address('[email protected]')
è convertito in HTML in questo modo:
<address>[email protected]</address>
-
name(Atts,Text): rappresenta un environment HTML di nome name, attributi Atts e che include
il testo Text. Ad esempio:
a([href='http://www.clip.dia.fi.upm.es/'],'Clip home')
è convertito in HTML in questo modo:
<a href="http://www.clip.dia.fi.upm.es/">Clip home</a>
- env(Name,Atts,Text): è equivalente all’ultima strutura.
Strutture specifiche:
PiLLoW permette la definizione di strutture specifiche, presenti nei documenti HTML, come:
- start: usata per definire l’inizio di un documento. E’ equivalente a <html>.
- end: utilizzata per definire la fine di un documento. E’ equivalente a </hmtl>.
- $: produce l’inizio di un nuovo paragrafo (<p>).
- comment: permette l’inserimento di un commento HTML.
- image(Addr): utilizzata per inserire l’indirizzo Addr di un’immagine.
Questi sono solo alcune delle strutture che sono definibili. Inoltre è presente un predicato specifico,
html_expansion/2, che permette di definire nuove strutture. Se aggiungiamo questa caratteristica al
fatto che sono state definite in seguito delle strutture apposite per generare specifiche strutture
HTML, come gli input elements delle form, capiamo che sono generabili praticamente tutte le
strutture HTML esistenti. In questo modo è possibile facilitare la generazione di documenti HTML
di diversa complessità e livello.
10
2.4 Come effettuare l’accesso a documenti WWW:
Nelle pagine precedenti è stato descritto un metodo per generare documenti HTML in modo
semplice e veloce. A questo punto è da chiedersi se sia possibile accedere in modo
equivalentemente semplice ad insieme di documenti presenti in Internet. Tale caratteristica è
indispensabile per la costruzione di applicazioni più complesse, come ad esempio tools di ricerca
analizzatori di contenuti, ecc.
Anche in questo caso PiLLoW viene in aiuto: essa fornisce infatti una rappresentazione interna per
trattare le URL (Uniform Resource Locator) e fornisce un insieme di predicati che effettuano la
conversione da tale rappresentazione verso una forma testuale. In particolare, i predicati utili in
questo contesto sono i seguenti:
-
url_info(URL,Info): converte una url URL in una struttura interna denominata Info. Ad
esempio:
url_info(‘http://www.dsi.unive.it/llog/lezione2.pdf’, Info)
ritorna:
Info=http(‘www.dsi.unive.it’, 80, “/llog/lezione2.pdf”)
-
url_info_relative(URL,BaseInfo,Info): converte una url relativa etichettata con URL e che
appare nella pagina HTML riferita da BaseInfo in una struttura url_info completa ed etichettata
con Info. Ad esempio:
url_info_relative(“/llog/lezione2.pdf”,
http(‘www.dsi.unive.it’, 80, “/llog/lezione2.pdf”)
restituisce:
Info=http(‘www.dsi.unive.it’, 80, “/llog/lezione2.pdf”)
-
fetch_url(URL,Request,Response): permette di effettuare il fetch di un documento presente in
Internet. Naturalmente URL è l’url associata al documento e definita
mediante una struttura url_info. Request, invece, è una lista di opzioni che
specifica i parametri della richiesta, mentre Response è una lista che include i
parametri della risposta.
Alcuni dei parametri di richiesta sono:
head: per specificare l’interesse solo all’header del documento.
timeout(Time): indica il tempo massimo di attesa per la risposta.
if_modified_since(Date): ritorna un documento solo se è più nuovo della data
specificata.
Mentre nella lista dei parametri di risposta possiamo trovare:
content(Content): ritorna in Content il documento testuale, espresso come una
lista di caratteri.
status(Type, Code, Phrase): ritorna lo status della risposta: Type può indicare
un fallimento, un successo, un re-direct, ecc.
location(URL): indica dove il documento è stato spostato.
last_modified(Date): permette di ottenere la data dell’ultima modifica.
-
html2terms(Chars,Terms): oltre all’utilizzo precedentemente illustrato, permette di effettuare un
parsing del codice HTML, ottenuto ad esempio mediante fetch_url. Il
risultato che si ottiene è una lista di termini HTML presente in Terms che è
normalizzata: contiene solo le strutture comment/1, declare/1, env/3 e $/2.
11
3. Costruzione di un meta-motore di ricerca logico:
3.1 I problemi che affliggono i motori di ricerca tradizionali:
La continua espansione del World Wide Web (WWW) ha reso indispensabile la costruzione e il
mantenimento di di tools per la ricerca delle informazioni presenti in rete. Ecco quindi che oggi
possiamo disporre di diversi motori di ricerca, i quali presentano delle caratteristiche
implementative differenti tra loro.
Esistono però dei problemi di diversa natura dietro queste applicazioni, i quali rendono le ricerche
spesso difficili e caratterizzate da dei risultati poco soddisfacenti. Tra queste problematiche
possiamo citare:
−
−
−
il metodo di operare da parte dei diversi motori di ricerca risulta essere sempre lo stesso:
esistono degli spiders che effettuano delle scansioni costanti della rete al fine di effettuare delle
indicizzazioni delle pagine presenti. Nella realtà però, la percentuale di pagine che sono
effettivamente indicizzate è piccolo.
molto spesso le risposte che vengono fornite nel momento in cui un motore di ricerca viene
interrogato sono errate. Ad esempio, molto spesso capita di imbattersi in pagine che non
esistono più, o pagine scorrelate rispetto alle keywords passate in input alla query.
il numero di risposte che viene fornito all'utente è troppo elevato e ridondante. Resta il fatto che
questo problema è di difficile misurazione, visto che la qualità dei risultati forniti varia dal caso
trattato.
Per poter sopperire a queste carenze si è pensato di affiancare ai motori di ricerca tradizionali dei
meta-motori di ricerca che permettano di ottenere dei risultati migliori sfruttando in modo
ottimizzato e combinato i tool di ricerca già presenti nel WWW.
3.2 Soluzione: implementazione di meta-motori di ricerca:
Un meta-motore di ricerca effettua ricerche nel Web combinando i risultati forniti dai diversi motori
di ricerca già esistenti. L'idea quindi è semplice: sfruttare in modo combinato le risorse presenti nel
WWW in modo da sopperire alle carenze precedentemente illustrate.
Un meta-motore di ricerca fornisce un'interfaccia utente simile a quella standard di un motore di
ricerca e lavora integrando le risposte dei diversi motori di ricerca interpellati in fase di esecuzione
della query formulata dall'utente. Anche la presentazione dei risultati risulta essere simile alla
procedura standard di ricerca, infatti viene collezionata e presentata all'utente una pagina contenente
i risultati ottenuti.
L'idea di fondo per sopperire alle carenze di un motore di ricerca standard è quello di poter
combinare i diversi risultati che ritornano più motori di ricerca. Infatti il modo di operare dei motori
di ricerca risulta differente da tool a tool. Esistono motori che inviano la query senza nessuna analisi
sintattica, altri permettono formulazioni di query con diverse sintassi ed altri ancora permettono la
formulazione di query avanzate.
Anche la fase di presentazione dei risultati presenta delle differenze sostanziali: in alcuni casi viene
effettuata una semplice append dei risultati ottenuti, senza effettuare nessun processamento. In altri
casi vengono effettuati dei passaggi di rimozione dei risultati duplicati, in modo da fornire dei
risultati più apprezzabili per l'utente.
12
3.3 Le funzionalità del meta-search engine “PrologCrawler”:
Nelle prossime pagine verrà descritto come è possibile realizzare un meta-motore di ricerca
denominato “PrologCrawler system”. Per realizzare tale tool si sfrutterà il compilatore SICStus
Prolog e la libreria PiLLoW, precedentemente descritta.
Le funzionalità del meta-motore possono essere descritte in base al metodo di esecuzione della
query utente e al tipo di processamento effettuato per ottenere la collezione dei risultati.
PrologCrawler supporta l'utilizzo dei connettivi logici AND, OR, NOT all'interno delle stringhe
della query. Nel momento in cui l'utente inserisce la query viene effettuato una sua conversione
sulla base della sintassi del motore di ricerca che dovrà essere interpellato. Ad esempio:
Specifica Query
Mickey AND mouse NOT goofy
Query inviata ad “Excite”
Mickey AND mouse AND NOT goofy
Query inviata a “Yahoo”
+ Mickey + mouse - goofy
Un'altra caratteristica chiave di PrologCrawler è la possibilità lasciata all'utente di specificare il
numero massimo di risultati che debbano essere riportati nella pagina di visualizzazione finale.
La fase di processamento dei risultati ottenuti è stato suddiviso in due parti, sulla base del livello di
complessità di operazioni da eseguire:
−
−
Simple Processing: esso include una fase di ordinamento dei risultati (sulla base di diversi
criteri, quali ordine alfabetico, titolo, indirizzo, rilevanza, ecc.), rimozione degli indirizzi
duplicati e rimozione delle “pagine secondarie”che sono considerate ridondanti.
Ad esempio, se si ottiene la pagina “www.dsi.unive.it/llog/slides” allora tutte le pagine tipo
“www.dsi.unive.it/llog/slides/cap1.pdf” saranno considerate secondarie ed eliminate.
Advanced Processing: questa fase include un check per verificare l'esistenza dei links che sono
ritornati all'utente. In caso di links fasulli essi verranno eliminati dalla lista.
Alla fine di queste diverse fasi PrologCrawler fornirà il risultato finale all'utente in formato HTML
standard, mettendo insieme le diverse parti delle pagine che sono ritornate dai motori di ricerca che
sono stati interrogati.
3.4 Interfacciamento con i motori di ricerca:
Una fase da dover affrontare è come interfacciare PrologCralwer con i motori di ricerca
commerciali che vengono utilizzati. Infatti il meta-motore di ricerca lavora in background e si
presentano due problemi, risolvibili con delle scelte fatte ad hoc:
−
Come interrogare il motore di ricerca?
Per poter risolvere questo problema si possono utilizzare le caratteristiche degli script CGI
(Common Gateway Interface) sfruttati dai motori di ricerca. Infatti una query utente genera un
indirizzo URL che lancia un programma di ricerca nel server. Ad esempio, se si effettua una
ricerca sfruttando la keyword “prolog” si genera una nuova pagina che ha il seguente indirizzo
(l'esempio è basato sul motore di ricerca Altavista):
http://www.altavista.com/cgi-bin/query?pg=q&kl=XX&q=prolog
13
Tale pagina lancia il programma query col parametro q settato con la stringa “prolog”.
−
Come si possono estrarre i risultati della ricerca dalla pagina HTML ritornata dal motore di
ricerca?
La soluzione introdotta in PrologCrawler è quella di analizzare il codice HTML della pagina
ritornata al fine di filtrare i links e di invocare altri processi correlati.
3.5 Implementazione di “PrologCrawler”:
Il sistema PrologCrawler è stato scritto sfruttando SICStus Prolog 3.7.1 e la libreria PiLLoW,
espressamente pensata per la progettazione di applicazioni WWW di questo genere.
Il funzionamento di PrologCrawler è semplice: l'utente utilizza un browser per aprire
PrologCrawler, il quale sfrutta uno script CGI per poter essere accessibile da una pagina HTML
standard. Mediante questa pagina web l'utente può formulare la query.
In seguito lo script CGI lancia il programma che effettua la meta-ricerca e ritorna i risultati in una
nuova pagina che è ritornata e visualizzata sempre mediante il browser.
Figura 2: Le interazioni in Prolog Crawler.
Il sistema interno è caratterizzato da un modulo Main, il quale passa i parametri di ricerca e gestisce
l'esecuzione degli altri moduli. Infatti, dopo aver ricevuto i parametri di input il modulo Main attiva
il modulo Search, il quale è incaricato di inviare la query ai motori di ricerca e di collezionare i
risultati relativi.
Il modulo Search attiva una serie di istanze del modulo Queryengine (esiste un'istanza per ciascun
motore di ricerca interpellato). L'esecuzione di queste diverse istanze avviene in parallelo e i
risultati vengono poi collezionati dal modulo Search, il quale riporta il tutto al Main.
In seguito il modulo Main attiva il modulo Process, il quale ha il compito di elaborare l'insieme dei
risultati ottenuti dai motori di ricerca disponibili. Il modulo Process può effettuare una “simple
processing”, rimuovendo i duplicati e i links secondari, oppure una “advanced processing”
effettuando il check dei links realmente esistenti.
Infine il moduloSorting effettua l'ordinamento della lista sulla bse dei criteri prestabiliti e il modulo
BuildHTML è incaricato di costruire il risultato da passare al browser dell'utente.
14
Figura 3: la struttura interna del sistema.
Il modulo Main:
All'interno del modulo Main possiamo trovare le seguenti clausole. Nel caso in cui venga effettuata
una ricerca semplice si invoca la clausola:
run(simple(Query,Nres,Ord),ResultsPage):s_search(Query,Nres,Results),
s_process(Nres,Results,FilteredResults),
sort(FilteredResults,Ord,SortedResults),
build_html(SortedResults,ResultsPage).
Argomento di input: contiene i parametri di ricerca
Argomento di output: istanziato con un
(la query utente, il numero di risultati richiesti e il
termine Prolog che rappresenta la pagina
criterio di ordinamento dei risultati).
HTML ritornata all’utente
Nel caso di una ricerca avanzata la clausola invocata risulta simile alla precedente, ad eccezione di
due parametri addizionali, MaxTime che indica il tempo massimo di risposta ed E_check, il quale è
un flag che indica l’esistenza della risposta associata. Ecco la struttura:
15
run(adv(Query,Nres,Ord,MaxTime,E_check),ResultsPage):a_search(Query,Nres,MaxTime,Results),
a_process(Nres,E_check,Results,FilteredResults)
sort(FilteredResults,Ord,SortedResults),
build_html(SortedResults,ResultsPage).
In entrambi i casi i moduli “Search” e “Process” sono invocati mediante due predicati ai quali sono
passati i parametri in input presenti nella testa della clausola. Naturalmente esistono predicati
differenti a seconda che la ricerca effettuata sia semplice o avanzata.
Come illustrato in precedenza il modulo Search attiva diverse istanze del modulo Queryengine, le
quali lavorano in parallelo. Ciascuna di queste istanze è incaricata di inviare la query ad uno dei
motori di ricerca impiegati.
Il modulo Queryengine viene attivato invocando una system call exec, ovvero un’operazione di
sistema che viene utilizzata in SICStus Prolog per passare un comando ad una nuova shell per
un’esecuzione.
Quando una delle istanze di Queryengine termina, crea un file contenente i risultati. Il modulo
Search quindi effettua un check per l’esistenza di tali files nell’attesa della terminazione di tutte le
istanze.
Il problema più grosso da dover affrontare per l’esecuzione di una query in diversi motori di ricerca
è data dalle sintassi differenti che i motori impiegano. Per poter arginare tale problema il modulo
Queryengine è stato progettato in 3 sotto-moduli:
Figura 4: il modulo Queryengine.
Il modulo build_url ha il compito di costruire la URL necessaria per far partire il motore di ricerca
attraverso una ricerca espressa dalla query associata. In particolare, la struttura di tale sotto-modulo
è la seguente:
16
build_url(Engine,Query,Nres,URL):convert_query(Query,Engine,NewQuery),
__engine_data(Engine,Engine_URL,Str1,Str2),
compose(Engine_URL,Str1,NewQuery,Str2,Nres,URL).
Termine utilizzato per passare il
Predicato che è impiegato per trasformare la stringa della
nome del motore di ricerca
query nella sintassi specifica del motore di ricerca usato
Proviamo a rendere più chiara la spiegazione sfruttando un semplice esempio. Se avessimo la
seguente chiamata:
build_url(nlight,’prolog+cgi’,20,URL)
il termine con funzionalità output “URL” verrebbe istanziato in questo modo:
http(’northernlight.com’,80,’/nlquery.fcg?qr=prolog+AND+cgi&us=20’)
che rappresenta l’URL:
http://northernlight.com/nlquery.fcg?qr=prolog+AND+cgi&us=20
Continuiamo l’analisi del modulo build_url analizzando il predicato engine_data/4, il quale è
definito come un insieme di clausole che contengono le informazioni sintattiche sul modo in cui le
stringhe che rappresentano le query sono formate nei diversi motori di ricerca.
Ecco quindi uno spaccato di questo predicato:
engine_data(altavista,‘www.altavista.com’,
‘/cgi-bin/query?pg=aq&q=’,
[]).
engine_data(excite,‘search.excite.com’,
‘/search.gw?c=web&search=’,‘&perPage=’).
engine_data(nlight,’northernlight.com’,
‘/nlquery.fcg?qr=’,’&us=’).
...
Naturalmente nella costruzione di un meta-motore di ricerca non potevano mancare alcune parti di
codice nelle quali si sfruttano delle primitive presenti all’interno della libreria PiLLoW. Infatti, il
modulo Fetch, sfrutta delle primitive sviluppate per l’accesso a pagine WWW.
Tale modulo è presente all’interno del predicato get_page/3, il quale, come mostrato qui sotto, data
un’URL e un intero che rappresenta il TimeOut per la connessione utilizzata, ritorna il contenuto
della pagina web corrispondente, nella forma di un termine Prolog.
17
get_page(URL,TimeOut,PageTerm):fetch_url(URL,[timeout(TimeOut),from(‘[email protected]’)],
Answer),
-----member(content_type(text,html,_),Answer),
-----member(content(Page),Answer),
html2terms(Page,PageTerm).
Mediante fetch_url si ottiene il codice HTML
Primitiva utilizzata per convertire il contenuto
(inserito in “Answer”) della pagina puntata
HTML della pagina “Page” in termini Prolog
dall’URL passata insieme ad altri parametri.
Proprio la conversione effettuata da html2terms/2 è di particolare utilità per il modulo Parse, sottomodulo di Queryengine. Il compito di tale modulo è quello di analizzare la pagina HTML prodotta
dall’altro sotto-modulo Fetch per ottenere la lista dei risultati ritornati dal motore di ricerca.
html2terms/2 lavora in questo modo:
dato un tag nella forma:
<tagname attributes> text </tagname>
effettua una conversione nel termine: env(tagname,attributes,text)
Tale conversione viene effettuata in modo ricorsivo. Inoltre la struttura del termine originale viene
preservata e il modulo Parse può sfruttare il meccanismo dell’unificazione per estrarre
ricorsivamente la lista dei risultati dalla corrispondente struttura ad albero.
Proprio l’idea di sfruttare il meccanismo dell’unificazione per l’analisi dei contenuti di una pagina
HTML, semplifica notevolmente lo sviluppo e l’intera procedura, rispetto ad una soluzione standard
basata su una tecnica di matching tra stringhe.
18
4. LP nel Web Moderno:
4.1 Dalla LP + WWW fino al “Semantic Web”:
Il successo del World Wide Web è sicuramente promosso ed incoraggiato da nuove forme di
comunicazione e di business. In particolare, i contenuti che si possono trovare all’interno del Web
sono cresciuti in modo esponenziale nel corso degli ultimi anni ed è quindi necessario che essi siano
“machine-undrestandable”, ovvero comprensibili ad una macchina, affinché possano essere
interpretati ed indicizzati in modo efficace.
Per riuscire ad ottenere questo risultato si è passati a definire una nuova tipologia di linguaggio:
XML. L’obiettivo di XML è di disporre di un meccanismo di scambio di dati che sia efficiente e
che, allo stesso tempo, garantisca una sintassi semplice e un grado di strutturazione ben definita. In
linea con questi principi si è poi passati a riportare nel Web le tecniche di Knowledge
Representation (KR) per descrivere la semantica dei contenuti web e permettere delle inferenze su
di essi.
Da queste idee, il W3C introdusse nel 2001 il “Semantic Web”, ribattezzato il Web del futuro. In
merito ad esso, Tim Berners Lee disse:
“I computer devono avere accesso a collezioni strutturate di informazioni e ad insiemi di regole di
inferenza che possano essere usate per condurre ragionamenti automatizzati.”
“La sfida del Semantic Web è perciò quella di fornire un linguaggio che possa esprimere sia dati
che regole.”
“Aggiungere la logica al Web è il primo compito che ha il Semantic Web oggi. Essa è il mezzo per
poter esprimere un insieme di regole di inferenza.”
Ecco quindi che per poter risolvere i problemi che affliggono il Web, ovvero l’ambiguità delle
informazioni presenti al suo interno e la mancanza di informazione machine-undrestandable, è
necessario mettere insieme diverse componenti, correlate tra loro in modo stretto attraverso una
struttura a pila e nella quale la logica riveste un ruolo centrale:
Figura 5: Lo stack del “Semantic Web”.
19
Sfruttando la logica è possibile effettuare dei ragionamenti automatici sulle informazioni presenti
nel Web. In particolare gli obiettivi del livello logico sono quelli di sfruttare l’insieme di asserzioni
che si possono trovare nel Web per poter derivarne conoscenza e realizzare dei sistemi in grado di
formulare ogni principio logico. In questo modo si permette ai computer di ragionare per inferenza.
Ad esempio, se si verificasse una situazione del genere:
Un'azienda decide che se qualcuno vende più di 100 dei suoi prodotti, questi diventa membro del
club del Super Venditore.
Un programma logico ora può seguire questa regola per fare una semplice deduzione:
"John ha venduto 102 cose, così John è un membro del Club del Super Venditore".
Una volta costruiti questi sistemi "logici", essi potranno essere utilizzarli per provare qualcosa. In
questo modo persone in tutto il mondo potranno scrivere istruzioni logiche e la macchina potrà
seguire questi link "semantici" per costruire dimostrazioni. Quando si riescono a costruire sistemi
che seguono la logica, diventa naturale utilizzarli come prove. Ad esempio:
I record delle vendite aziendali mostrano che Jane ha venduto 55 cruscotti e 66 rotelle. Il sistema
di inventariato ci dice che cruscotti e rotelle sono entrambi differenti prodotti dell'azienda. Le
regole matematiche incorporate dichiarano che 55+66=121 e che 121 è più di 100. E, come già
sappiamo, chi vende più di 100 prodotti diventa membro del club del Super Venditore. Il computer
mette insieme queste regole logiche in una prova che Jane è un Super Venditore.
Figura 6: Utilizzo di regole logiche nel Semantic Web.
In questo modo si potrà costruire un Web di processori di informazione. I più intelligenti saranno
dei "motori euristici" che seguiranno queste regole costruite per disegnare conclusioni, e
posizionare i risultati ottenuti sul Web come un insieme di prove.
20
4.2 Metalog: come aggiungere ragionamento al Web:
Grazie all’enorme diffusione che il Web ha ottenuto negli ultimi anni, la necessità di disporre di un
“Web intelligente” è diventata una caratteristica sempre più ricercata. Da questo spunto è nato
Semantic Web, un progetto proposto dal W3C.
Esso fa uso di un “linguaggio semantico”, denominato RDF, che permette di effettuare dei
ragionamenti. In particolare, RDF non definisce esplicitamente la semantica, ma fornisce una base
per poterla esprimere. Infatti ogni risorsa presente o citata nel Web potrà essere descritta e sarà vista
come un oggetto unico, identificabile mediante una URI (Uniform Resource Identifier). Il data
model RDF è così composto:
- Resources: ogni cosa descritta da un’espressione RDF è detta risorsa.
- Properties: una proprietà è un aspetto specifico, una relazione, una caratteristica, ecc.
- Statements: è una t-upla composta da un soggetto (risorsa), un predicato (proprietà) e un oggetto
(valore).
Ad esempio, considerando l’espressione:
Oreste Signore è l’autore del DocumentoX”
Otterremmo la seguente tripla:
Resource: http://www.w3c.it/Oreste/DocX
Property: author
Value: Oreste Signore
Figura 7: rappresentazione grafica di uno statement RDF.
Partendo da queste basi si è potuto definire il progetto Metalog, il primo sistema basato su un
insieme di query logiche per il Semantic Web. Esso è stato definito per sopperire due carenze
evidenti del Web: la mancanza di ragionamento e quindi la possibilità di comprendere il significato
delle informazioni trattate, e la possibilità di portare queste tecnologie avanzate alla più grossa fetta
di utenza possibile.
Metalog sfrutta un interfaccia costruita in PNL (Pseudo Natural Language), il quale è molto simile
al linguaggio naturale e quindi permette un interfacciamento semplice con le tecnologie più
complesse presenti nel Semantic Web. In particolare, Metalog interfaccia il PNL con un’estensione
logica della semantica definita con RDF, detta MLL (Metalog Logical Level) e basata su
un’estensione del modello RDF stesso, detta MML (Metalog Model Level). In questo modo si ha un
arricchimento di RDF grazie all’impiego di un modello che offra una vista logica delle
informazioni.
Metalog Model Level (MML):
MML è un’ estensione di RDF che sfrutta un insieme di operatori logici. Tutti i nuovi operatori
forniti sono rappresentati in modo uniforme nel modello RDF: un operatore denotato con la URI α,
21
avente gli operandi β1,….,βk, è codificato in questo modo:
MML fornisce gli operatori logici di base, denotati in questo modo: ml:and, ml:or ed ml:imply.
Viene anche fornito un operatore di negazione e i classici operatori di negazione (>=, <=, ecc.).
Infine viene fornito un ml:name extension, utilizzato per etichettare le variabili.
Metalog Logic Level (MLL):
MLL è la logica che esprime la semantica di MML. Essenzialmente è un sottoinsieme di equazioni
della logica del prim’ordine. Ecco come viene effettuato il mapping tra MML e MLL:
- ml:and, ml:or ed ml:imply, not sono convertiti nella congiunzione, disgiunzione, implicazione e
negazione logica;
- gli operatori matematici sono mappati secondo la loro logica naturale;
- i letterali e gli URI Reference sono mappati in costanti;
- ml:name, ml:annotation, ml:ns sono mappati in costanti distinte;
- ciascuna tripla (S,P,O) viene mappata in P(S,O);
- i container che trattano insiemi di k oggetti sono mappati in operatori k-ari SEQk, applicati a
ciascuno dei k operandi, descritti in questo modo:
Pseudo Natural Language (PNL):
Come detto precedentemente, un obiettivo di Metalog è quello di fornire un interfaccia che sia
semplice ed intuitiva per qualsiasi utente. Perciò Metalog utilizza dei “discorsi”, che sono sentenze
in PNL. Ad esempio, definiamo il seguente discorso:
22
Quando questo programma viene caricato in Metalog, viene colorato in modi differenti, al fine di
comprendere le diverse parti del discorso. La prima, la seconda, la quinta e la settima sentenza sono
colorate di rosso, essendo dei commenti (superflui al discorso). La terza e la quarta sentenza sono
colorate di verde, essendo delle rappresentazioni (utili per denotare delle associazioni).
Infine la sesta e l’ottava sentenza sono colorate di blu, essendo delle asserzioni o query.
Un’asserzione è una sentenza dove definiamo precisamente qualcosa e che termina con (.), mentre
una query è una sentenza dove chiediamo qualcosa a Metalog e termina con (?).
Perciò i tre tipi di sentenza definiti in Metalog sono:
- rappresentazioni;
- asserzioni;
- query.
Come lavora Metalog?
Come è stato detto in precedenza, il PNL fornisce un livello superiore al logic layer. Il metodo per
passare da un livello all’altro è quello di effettuare un parsing accurato al fine di estrarre il
significato logico corrispondente delle diverse sentenze.
In particolare, Metalog sfrutta un insieme di keywords riservate, e la posizione all’interno della
sentenza determina il loro significato. A ciascuna sentenza vengono quindi inserite tali keywords
riservate, il nome, le variabili, ecc. e poi si procede alla sua traduzione.
Le tre classi principali di keywords riservate sono le seguenti:
- congiunzione (and);
- disgiunzione (or);
- implicazione (then, imply, implies).
Metalog definisce anche altre classi di keywords, tra le quali operatori matematici di base (add,
plus, sub, ecc.), operatori per confronti ed uguaglianze, ecc.
Uno dei cardini di Metalog è l’utilizzo di PNL. Esso è stato pensato come un linguaggio di semplice
lettura (e di conseguenza semplice da capire) e che permette una non ambiguità in tutto ciò che si
scrive. Infatti vengono utilizzati dei simboli speciali (come (,)) che permettono di eliminare
qualsiasi ambiguità dalle sentenze.
Esiste però uno svantaggio da pagare: non è possibile scrivere tutto ciò che si vuole, infatti è
disponibile un livello di costruzione delle sentenze semplice e limitativo.
Metalog computabile:
Nel caso in cui si voglia analizzare MLL, è necessario definire un insieme caratterizzato dal
possedere delle proprietà computazionali che possano essere sfruttate in modo efficiente. Ad
esempio, si può sfruttare la programmazione logica (caratterizzata dalle clausole di Horn) ed
utilizzare Prolog come mezzo di interfacciamento. In questo modo le regole di mapping sono chiare
e possono essere così descritte:
23
E’ da notare il fatto che la regola 1 è differente dalla 2 solo perché essa viene applicata nel
momento in cui si sta effettuando la traduzione di una sentenza.
Nel caso dei contenitori di operandi è stata definita una tabella di mapping apposita:
Costruzione di query con Metalog:
Dopo aver descritto il metodo utilizzato per scrivere discorsi più o meno complessi con Metalog, si
passa ad uno studio del metodo di costruzione di query. Supponendo di disporre di un sistema in cui
è definita una relazione di derivazione (ad esempio, a --| b significa che da a segue b), un linguaggio
di query dovrebbe essere in grado di rispondere a domande del tipo “è vero che da a derivo b?”.
Esiste però il problema di dover esprimere la relazione di derivazione con un linguaggio naturale
(come inglese, italiano, ecc.).
La via d’uscita è quella di esprimere una semplice classe di query per chiedere se qualcosa è vero,
oppure no. Ciò può essere sintetizzato in questo modo --| a, e in linguaggio naturale corrisponde a
“è vero che …?”.
A questo punto è possibile sfruttare la seguente relazione:
(a --| b) sse (--| se a allora b)
In questo modo ci si può liberare della relazione di derivazione e sfruttare questa strategia per
esprimere le query. Metalog vede le query come delle particolari sentenze che terminano con (?) e
non effettua una combinazione del meccanismo di inferenza con l’interfaccia fornita.
Uno dei maggiori obiettivi del progetto Metalog è quello di fornire delle risposte che siano il più
possibili significative. Ciò è possibile sfruttando un processo di istanziazione delle risposte (dove le
variabili libere sono legate ai risultati, come in Prolog) denominato feedback. Esso si basa su una
ricomputazione della risposta per cercare di modellarla in una forma simile al linguaggio naturale.
24
Per ottenere ciò si usano delle annotazioni speciali, le quali codificano a livello RDF le
informazioni. Ad esempio, una query potrebbe ritornare:
JOHN IS “tall like tower”
insieme ad un set opportuno di rappresentazioni, utili per comprendere la risposta. In questo modo
l’informazione riguardante le rappresentazioni non viene persa durante la fase in cui si sfrutta un
motore di inferenza e si riesce, quindi, a creare un informazione “user-friendly”.
4.3 xml.pl: Parsing XML with Prolog:
L’XML (eXtensible Markup Language) è stato introdotto dal consorzio W3C. Esso è uno standard
di descrizione di documenti e permette di definire nuovi linguaggi di marcatura (come XHTML),
specializzati nel descrivere una particolare tipologia di documento. In questo modo si vuole
raggiungere l’obiettivo di poter effettuare degli scambi di dati efficienti attraverso la rete.
Negli ultimi anni sono state definite delle librerie che permettono di effettuare il parsing di
documenti XML tramite Prolog. Dai primi progetti orientati verso una parserizzazione di documenti
più vicini ad HTML (la libreria PiLLoW ne è un esempio), sono emersi nuovi spunti di ricerca. Un
esempio viene dalla definizione del modulo xml.pl. Esso permette di effettuare il parsing di
documenti XML con Prolog (il modulo può essere utilizzato senza problemi in SICStus) e fornisce
un insieme di applicazioni Prolog con un “Document Value Model” associato. La bontà di tale
progetto di ricerca è testimoniata dal numero di applicazioni in cui è stato usato efficacemente.
Inoltre, il codice e un’applicazione Windows che sfrutta xml.pl, sono stati resi free, in modo da
incoraggiare l’utilizzo di Prolog con XML.
Specifiche:
xml.pl include 3 predicati di base. In particolare, il primo predicato è caratterizzato dal possedere 2
modalità differenti:
xml_parse({+Controls},+?Chars,?+Document)
Questo predicato effettua il parsing di Chars, una lista di codice, da/verso una struttura dati nella
forma tipica XML: (<attributes>, <content>), dove:
<attributes> è una lista di attributi del tipo <name> = <char data> presenti nel documento.
<content> è una lista che comprende insiemi di occorrenze tra:
pcdata( <char data>)  testo
comment( <char data>)  commenti XML
namespace( <URI>, <prefix>, <element>)
element( <tag>, <attributes>, <content>)  <tag>..</tag> che include <content>
oppure <tag /> se è vuoto.
instructions( <name>, <char data>)  <? <name> <char data> ?>
cdata( <char data>)  <![CDATA[ <char data>]]>
doctype( <tag>, <doctype id>)  DTD <!DOCTYPE .. >
25
E’ interessante notare che nel passaggio Chars  Document, il parsing non richiede dei documenti
che siano strettamente ben formati secondo le specifiche XML. Infatti, se Chars non rappresenta un
documento XML ben formato, il documento Document verrà istanziato ad un termine così definito:
malformed(<attributes>,<content>)
dove <content> può includere: unparsed( <char data> )  testo non parserizzato
out_of_context( <tag> )  <tag> non chiuso
Invece, nel passaggio Document  Chars il parsing richiede che il documento Document sia ben
formato secondo XML. Nel caso in cui si rilevi un errore, un’eccezione “Domain” viene sollevata,
in modo da rilevare sotto-termine che ha causato l’errore.
La lista di elementi etichettata con Controls è così strutturata:
extended_characters(<bool>)  per settare l’utilizzo di caratteri usati in XHTML
format( <bool>)  utilizzata per rimouovere eventuali layout
remove_attribute_prefixes( <bool>)  utile per la rimozione di prefissi ridondanti
allow_ampersand( <bool>)  usata per ammettere i carateri ampersand (&) in PCDATA
Nel passaggio Document  Chars è anche previsto:
format( <bool>)  usato per indentare l’elemento a cui è associato.
xml_subterm(+XMLTerm,?Subterm)
Questo predicato unifica Subterm con un sottotermine di Term. In particolare esso è molo utile
quando si vuole testare o cercare un sottotermine annidato all’interno di un documento. Ad
esempio:
Si vogliono trovare nel documento “books.xml” tutti I titoli dei capitoli che contengono la parola
“XML”, senza riguardo del suo livello di profondità:
xml_query( q9, element(results, [], Titles) ) :element_name( Title, title ),
append( "XML", _Back, Suffix ),
input_document( 'books.xml', Books ),
findall(
Title,
(
xml_subterm( Books, Title ),
xml_subterm( Title, TextItem ),
text_value( TextItem, TextValue ),
26
append( _Prefix, Suffix, TextValue )
),
Titles
).
xml_pp(+XMLDocument)
PrediEcato utilizzato per effettuare la stampa in output del documento XMLDocument.
L’idea che ha portato alla definizione del modulo xml.pl è basata sul fatto che un termine Prolog
può rappresentare un documento che ha la stessa struttura de documento stesso, creando quindi una
corrispondenza tra termini Prolog e codice XML:
Ad esempio, data un’immagine SVG così definita:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/.../svg10.dtd"
[
<!ENTITY redblue "fill:red; stroke:blue; stroke-width:1">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
<circle cx=" 25 " cy=" 25 " r=" 24 " style="&redblue;"/>
</svg>
Può essere convertita in termini Prolog:
xml( [version="1.0", standalone="no"],
[
doctype( svg, public( "-//W3C//DTD SVG 1.0//EN",
"http://www.w3.org/.../svg10.dtd" ) ),
namespace( 'http://www.w3.org/2000/svg', "",
element( svg,
[width="500", height="500"],
[
element( circle,
[cx="25", cy="25", r="24", style="fill: red;
stroke: blue; stroke-width: 1"],
[] )
] )
)
] ).
27
xml.pl permette una manipolazione efficiente di ciascuna tipologia di nodo presente all’interno di
un documento XML. Infatti, la maggior parte delle tipologie di nodi sono rappresentate mediante
dei funtori Prolog differenti tra loro, mentre i dati sono rappresentati come stringhe:
<tag>  atomi
<name>  atomi
<URI>  atomi
<char data>  stringa
<bool>  true o false
L’utilizzo di funtori distinti tra loro per le strutture di mark-up permette un utilizzo efficiente della
ricorsione per trattare i documenti stessi, mentre associando ai dati degli insiemi di stringhe si possono ottenere delle facilitazioni nello sviluppo di applicazioni per il pasrsing di tali contenuti.
28
5. Conclusioni:
Attraverso un insieme di esempi pratici presentati nelle sezioni precedenti, si è cercato di dimostrare
come la LP possa essere affiancata al mondo del World Wide Web. In particolare, nel corso
dell’ultimo decennio sono stati concentrati molti sforzi di ricerca per sfruttare le caratteristiche della
LP, in modo da ottenere un insieme di applicazioni Web che potessero essere più complete e che
avessero associata una semantica ben definita.
Gli esempi proposti hanno messo in luce come la ricerca di un insieme di informazioni o di
documenti attraverso il Web, possa essere nettamente migliorata sfruttando i paradigmi di
programmazione della LP. L’obiettivo principale che essa aveva inizialmente in tali progetti
(LogicWeb, PiLLoW, ecc.) era proprio quello di introdurre una struttura ben definita alle
applicazioni Web.
Ma la LP può essere utilizzata anche per altre tipologie di applicazioni, come ad esempio la
costruzione e la consultazione di Database deduttivi, la possibilità di costruire pagine Web
rappresentandole come termini dell’universo di Herbrand e sfruttandone tutte le proprietà associate,
ecc. Proprio lo stile di programmazione ad alto livello che essa permette, rappresenta una
caratteristica chiave che rende lo sviluppo di applicazioni più rapido e semplice e tale da permettere
di associarvi una semantica. Ciò è dimostrato anche dal largo impiego che viene fatto della LP
all’interno del Semantic Web e del ruolo chiave che essa riveste nello sviluppo del Web moderno.
I primi lavori proposti si collocano in uno scenario in cui il WWW non prevede ancora delle
strutture e dei linguaggi ben definiti come XML. Proprio queste caratteristiche hanno spinto i
ricercatori a sfruttare la LP per poter dare una struttura di base per le applicazioni e i contenuti
presenti nel Web. L’introduzione di XML da parte del W3C come linguaggio che permetta di
definire una struttura di base per i dati, ha accentuato maggiormente il ruolo della logica e della LP
come componenti base per la definizione di una semantica che permetta di progettare sistemi
intelligenti su cui fare deduzioni. Inoltre essa può essere affiancata ad HTML e XML e risulta
un’ottima componente per costruire dei parser efficienti. Proprio l’idea di poter effettuare un
mapping tra le strutture dei documenti Web e termini Prolog ha portato a costruire librerie ed
estensioni molto interessanti, come xml.pl, che possono essere affiancate a diverse release Prolog
(es. SICStus).
Il ruolo centrale di logica e LP all’interno del Semantic Web è dimostrato anche dalla loro posizione
occupata all’interno dello stack in cui sono riportate le componenti fondamentali e le associazioni
che intercorrono tra loro. Il caso di studio riportato (Metalog) è un primo esempio di come si possa
aggiungere intelligenza e una vista logica delle informazioni presenti nel Web, mantenendo un
grado di semplicità che permetta di rivolgere a qualsiasi fascia d’utenza tali concetti.
Si può quindi concludere dicendo che è stato fatto molto in merito all’introduzione della logica e
della LP nel mondo Web e partendo da queste idee si dovrebbero concentrare ancora di più gli
sforzi di ricerca, in modo che alcune problematiche, quali, ad esempio, la scarsa efficienza nel
momento in cui si debbano costruire applicazioni che sfruttino in modo massiccio un insieme di
operazioni di rete, possano essere superate, rendendo la LP una componente sempre utilizzabile nel
momento in cui si vogliano costruire applicazioni WWW.
29
6. Bibliografia:
[1] LogicWeb: Using Logic Programming to Extend the World Wide Web,
Seng Wai Loke Department of Computer Science, The University of Melbourne, Australia, 1997
[2] Logic Programming with the World-Wide Web,
Seng Wai Loke Department of Computer Science, The University of Melbourne, Australia, 1996
[3] The PiLLoW/CIAO Library for Internet/WWW Programming using
Computational Logic Systems,
D. Cabeza, M. Hermenegildo, and S. Varmaa, 1st Workshop on Logic Programming Tools for
INTERNET Applications, JICSLP, 1997.
[4] A Prolog Meta-Search Engine for the World Wide Web,
Emanuele Bolognesi & Antonio Brogi Department of Computer Science University of Pisa, 1999.
[5] W3C Semantic Web Activity,
http://www.w3.org/2001/sw/.
[6] Towards a People’s Web: Metalog,
Massimo Marchiori, Department of Computer Science, University of Venice & W3C Consortium,
2004
[7] SICStus Prolog User’s Manual,
Swedish Institute of Computer Science, Release 3.12.2 Maggio 2005.
30