Introduzione al modello RDF

Questa sezione descriverà il  Resource Description Framework model.

Risorse

RDF (Resource Description Framework) è un modello per immagazzinare le informazioni. Dato un insieme di risorse, in cui ogni risorsa è qualcosa, come una persona, una canzone, una pagina web o un bookmark, RDF è usato per creare relazioni tra queste risorse.  Qualcuno pensa a RDF come a un linguaggio XML per descrivere i dati. Comunque, il formato XML è solo un modo per immagazzinare le informazioni in un file. Se stai tentando di imparare RDF, farlo attraverso la sintassi XML potrebbe confonderti; invece, di seguito il modello RDF sarà discusso abbastanza in dettaglio per comprenderlo senza discutere la sintassi XML.

Pensa a una rete o un grafico di nodi interconnessi. I nodi sono connessi attraverso varie relazioni. Per esempio, disiamo che ogni nodo rappresenti una persona. Ogni persona potrebbe essere in relazione con un'altra persona perché sono fratelli, genitori, coniugi, impiegati o nemici. Ogni interconnessione viene detta relazione.

Un altro tipo di relazione sono le proprietà fisiche di un nodo. Per esempio, il nome o l'età di una persona. Queste relazioni sarebbero chiamate 'nome' o 'età' invece di 'fratello' o 'genitore'

RDF è usato per descrivere queste relazioni. In realtà non include direttamente i nodi, ma lo fa in maniera indiretta, dal momento che le relazioni puntano ai nodi. In qualsiasi momento, potremmo inserire un nuovo nodo, come un neonato e tutto quello che dobbiamo fare è aggiungere due relazioni genitore, una per genitore.

In RDF i nodi possono essere di due tipi general, risorse e letterali. Un letterale è un valore reale, come il nome 'Sandra' o il numero '7'. Puoi pensare a un letterale come una stringa usata in un linguaggio di programmazione. Una risorsa è rappresentativa di qualcosa, quasi come un oggetto in un linguaggio di programmazione.  Per esempio, una persona sarebbe una risorsa, mentre il nome un letterale.

In RDF, alle risorse vengono dati degli URI in modo da identificarle. Dal momento che gli URI sono unici, possiamo identificare una risorsa specifica. Il valore dell'URI non ha molta importanza per RDF, dal moemento che è usato come identificatore.  Però puoi usare una qualche convenzione, come usare un URI che include un numero di serie per identificare un oggetto fisico.

Triple

Possiamo aggiungere relazioni tra due risorse o tra una risorsa e un letterale.  Queste relazioni sono spesso chiamate triple o archi. Ecco qualche esempio:

<http://www.xulplanet.com/rdf/people/Sandra>  ->  name     ->  Sandra
<http://www.xulplanet.com/rdf/people/Sandra> -> gender -> female
<http://www.xulplanet.com/rdf/people/Sandra> -> sibling ->
<http://www.xulplanet.com/rdf/people/Kevin>
<http://www.xulplanet.com/rdf/people/Kevin> -> gender -> male

In questa documentazione, useremo la convenzione che gli elementi scritti in parenesi angolari sono risorse, e quelli che non lo sono sono letterali. Sopra, abbiamo definito quattro triple. La prima indica che c'è una risorsa

<http://www.xulplanet.com/rdf/people/Sandra>

con nome 'Sandra'. La seconda indica che la stessa risorsa è di genere femminile. La terza tripla indica che il fratello è un'altra risorsa

<http://www.xulplanet.com/rdf/people/Kevin>

La quarta specifica il genere della risorsa

<http://www.xulplanet.com/rdf/people/Kevin>.

Non è stato fornito un nome per la risorsa

<http://www.xulplanet.com/rdf/people/Kevin>

Al lettore umano, potremmo probabilmente ipotizzare che il nome è come il letterale 'Kevin', a il computer non avrà modo di capirlo.  Possiamo usare qualsiasi tipo di URI per la risorsa; per esempio la seguente potrebbe essere accettabile

<urn:x-person:S1>  ->  name  ->   Sandra

La risorsa <urn:x-person:S1> non significa niente per un lettore umano, e potrebbe essere incomprensibile anche a un computer. In realtà, una URI che abbia meno significato per un lettore umano, potrebbe essere meglio dal momento che <http://www.xulplanet.com/rdf/people/Sandra> non funzionerebbe se qualcun altro si chiamasse Sandra. Nota che il fatto che è usato un URI http non significa che è associato con una pagina accessibile tramite HTTP, anche se potreseti mettere qualcosa di relativo a quell'URL da scaricare. Invece potresti usare semplicemente del tuo sito web quando crei URI, per assicurare unicità, dal momento che le altre persone non dovrebbero usarlo.

L'URI è solo un identificatore.  A RDF non importa che cosa sia. Ma se lo stesso URI è usato in diversi posti, si riferiscono tutti alla stessa risorsa. Nell'esempio precedente, sono stati fatti diversi riferimenti a<http://www.xulplanet.com/rdf/people/Sandra>, ma rappresentano tutti una sola cosa.

Anche se non abbiamo specificato un nome per la risorsa <http://www.xulplanet.com/rdf/people/Kevin> questo non significa che non ne abbia uno. Se una tripla non è specificata nel grafico, non bisognerebbe dedurre che quel valore non esiste, invece potrebbe significare che il valore è sconoscito, o che verrà fornito in seguito.

Una cosa da notare nell'esempio è che non abbiamo specificato se Kevin è il fratello/sorella di Sandra, abbiamo usato solo il termine "sibling" [NdT: "sibling" in inglese può essere tradotto come fratello o sorella, come in italiano "coniuge" può essere sia marito che moglie]. Comunque, il sistema potrebbe immaginarlo usando solo le informazioni fornite e un pò di logica. Per esempio se fosse detto al sistema che un fratello è un "sibling" maschio, il sistema potrebbe determinare che Kevin è il fratello di Sandra usando solo due triple

<http://www.xulplanet.com/rdf/people/Sandra>  ->  sibling  ->
<http://www.xulplanet.com/rdf/people/Kevin>
<http://www.xulplanet.com/rdf/people/Kevin> -> gender -> male

Comunque, con solo queste due regole, il sistema non può determinare se Sandra p sorella o il fratello di Kevin, dal momento che queste due regole non indicano il sesso di Sandra. Per questo, avremmo bisogno della regola appropriata dell'esempio precedente.

RDF ci fa fare risorse, letterali, e anche le etichette degli archi (come 'sibling'). Perciò potremmo fare una nuova etichetta in ogni momento.

<http://www.xulplanet.com/rdf/people/Sandra>  -> bestFriend  ->
<http://www.xulplanet.com/rdf/people/Christine>

L'etichetta 'bestfriend' e altre usate sopra è chiamata predicato. Il lato sinistro di ogni tripla è chiamata soggetto e quella destra oggetto o target. Il soggetto sarà sempre una risorsa, mentre il target può essere una risorsa o un letterale. Non avrai mai una relazione letterale - letterale.

Per assicurare unicità, anche i predicati sono identificati con URI. Ci sarà un unico URI per ogni predicato. Per esempio, l'URI di 'sibling' potrebbe essere <http://www.xulplanet.com/rdf/people/sibling>.

Generalmente, le etichette dei predicati saranno simili, così si può usare lo stile dei namespaces XML per riferirsi a loro.  Quindi in realtà l'ultimo esempio sarebbe così:
<http://www.xulplanet.com/rdf/people/Sandra>  ->
<http://www.xulplanet.com/rdf/people/bestFriend> ->
<http://www.xulplanet.com/rdf/people/Christine>

Per gli scopi di questa documentazione, lasceremo qualche volta fuori il namespace del predicato per semplificare gli esempi. Anche i predicati sono risorse e potresti associare relazioni tra un predicato e qualche altra cosa. Questo in genere si fa per definire proprietà che descrivono il significato del predicato, per formare un vocabolario formale per quel predicato.

Puoi avere triple multiple con lo stesso soggetto e predicato, se vuoi:

<http://www.xulplanet.com/rdf/people/Sandra>  ->  name  ->  Sandra
<http://www.xulplanet.com/rdf/people/Sandra> -> name -> Sandy

Qui, la stessa risorsa ha una tripla con lo stesso predicato, ma con un target diverso. In questo esempio, potremmo assumere che diversi nomi sono stati inseriti per intendere soprannomi. RDF non ordina i nomi, ogni nome ha la stessa importanza. Non credere che siccome Sandra è la prima tripla scritta ha più significato di Sandy.

Diciamo che decidiamo di aggiungere un'altra persona di nome Sandra:

<http://www.xulplanet.com/rdf/people/SandraJr>  ->  name  ->  Sandra

La risorsa è diversa che negli altri esempi, perché rappresenta una persona diversa, comunque hanno entrambe lo stesso nome. Con la maggior parte delle API RDF, so può fare un ricerca in entrambe i sensi. Se tutto quello che hai è il nome Sandra, puoi ottenere tutte le risorse con quel nome con ricercando al contrario

Tipi

A volte è utile identificare che tipo di cosa sia una risorsa, allo stesso modo in cui un sistema orientato agli oggetti usa le classi. RDF usa un tipo per questo scopo. Siccome ci sono solo due tipi generali, risorsa e letterale, si può dare un tipo preciso ad ogni risorsa. Per esempio, alla risorsa Sandra potrebbe essere dato un tipo "persona". Il valore del tipo dovrebbe essere un'altra risorsa che potrebbe significare che si possono associare ulteriori informazionie con il tipo stesso.

Come con le altre proprietà, il tipo è specificato con una tripla:

<http://www.xulplanet.com/rdf/people/Sandra>  ->  rdf:type  ->
<http://xmlns.com/wordnet/1.6/Person>

La risorsa <http://xmlns.com/wordnet/1.6/Person> è usata per rappresentare una persona. L'URI è da WordNet, che fornisce gli URI risorsa per le parole. Il predicato è rdf:type che è il nome del namespace RDF, dal momento che il predicato 'type' è incluso in RDF. Il nome completo è'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'.

Qui, usiamo 'rdf:' come abbreviazione del namespace RDF, come faremmo in XML. Questo è fatto solo per semplificare l'esempio, il predicato è sempre il nome completo con il namespace.

Possiamo anche creare i nostri tipi. Nell'esempio sotto associamo il tipo come il tipo di una risorsa, che a giudicare dall'URI potrebbe essere un poema. 

<http://www.xulplanet.com/rdf/something/785>  ->  rdf:type  ->  
<http://www.xulplanet.com/rdf/example/Poem>

Alcuni tipi di liste

RDF ha alcuni tipi predefiniti per rappresentare liste di cose. Pensa a un esempio precedente dove Sandra aveva due nomi. Era stato detto che i nomi non erano in un ordine particolare. A volte, può essere utile avere la possibilità di inserire un certo numero di valori in un ordine particolare.  Dovresti essere in grado di pensare a modi di risolvere questo problema, per esempio usando predicati come 'nome1' 'nome2' ecc. RDF ha un meccanismo proprietario per fare questo tipo di cose.

In RDF, un predicato che è un numero preceduto da un underscore è usato come un elemento di una lista. Per esempio, rdf:_1 è usato per indicare il primo elemento di una lista. Ancora una volta usiamo il namespace RDF. Per esempio, potremmo creare una lista di cose usando:

<http://www.xulplanet.com/rdf/people/Karen>  ->  rdf:_1  ->
<http://www.xulplanet.com/rdf/people/Sandra>
<http://www.xulplanet.com/rdf/people/Karen> -> rdf:_2 ->
<http://www.xulplanet.com/rdf/people/Kevin>
<http://www.xulplanet.com/rdf/people/Karen> -> rdf:_3 ->
<http://www.xulplanet.com/rdf/people/Jack>

Qui, <http://www.xulplanet.com/rdf/people/Karen> ha tre elementi nella lista. Noi, come umani, potremmo presumere che i tre elementi siano i figli di Karen. Il sistema non lo sa, ma la tua applicazione potrebbe fare questa assunzione. I tre predicati non sono speciali in ogni modo, dal momento che avremmo potuto usare "nome1", "nome2", "nome3". Comunque, dal momento che RDF ha i predicati di prima incorporati, dovremmo usarli se possibile.

Siccome rdf:_XXX sono predicati come ogni altro, potremmo anche specificare valori multipli con li stesso numero o omettere alcuni valori:
<http://www.xulplanet.com/rdf/people/Karen>  ->  rdf:_1  ->
<http://www.xulplanet.com/rdf/people/Sandra>
<http://www.xulplanet.com/rdf/people/Karen> -> rdf:_6 ->
<http://www.xulplanet.com/rdf/people/Kevin>
<http://www.xulplanet.com/rdf/people/Karen> -> rdf:_6 ->
<http://www.xulplanet.com/rdf/people/Billy>
<http://www.xulplanet.com/rdf/people/Karen> -> rdf:_8 ->
<http://www.xulplanet.com/rdf/people/Jack>

Quella qui sopra è una lista con quattro elementi. Comunque, i numeri non sono sequenziali. Creare triple come queste non viene fatto spesso, ma una lista dove mancano dei numeri può essere trovata dove è stato rimosso un elemento.

Per far sì che RDF tratti questi predicati numerati in maniera speciale (ricorda che sono solo predicati ordinari) RDF ha anche bisogno che usi un tipo speciale per le liste. Ci sono diversi tipi di liste:

Negli esempi sopra, useremmo rdf:Seq se volessimo che gli elementi siano in un ordine specifico. Useremmo rdf:Bag se non fosse importante l'ordine degli elementi. Questo potrebbe sembrare uguale all'uso di predicati 'name' multipli, comunque, se il tipo è rdf:Bag sappiamo che la risorsa deve contenere una lista di nomi, invece di uno soltanto. Per i nomi, potremmo usare invece un Alt, dal momento che un'applicazione avrà bisogno di usare solo uno dei nomi alla volta.

Assegnamo questi tipi come qualsiasi altro tipo

<http://www.xulplanet.com/rdf/people/Karen>  ->  rdf:type  ->
<http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq>

Qui come target è usato il namespace completo per 'rdf'. Ora che Karen è un rdf:Seq, possiamo aggiungere i tre bambini di prima. Un problema qui è che ora che Karen è del tipo rdf:Seq, non è del tipo Person. Potremmo risolvere questo assegnando un secondo tipo a Karen, come faremmo con altri predicati. Una soluzione migliore sarebbe usare una seconda risorsa come segnaposto per la lista di figli di Karen. Karen rimarrà una Person, ma la lista di bambini sarà un rdf:Seq.

<http://www.xulplanet.com/rdf/people/Karen>       ->  rdf:type  ->
<http://xmlns.com/wordnet/1.6/Person>
<http://www.xulplanet.com/rdf/people/Karen> -> children ->
<http://www.xulplanet.com/rdf/people/KarensKids>
<http://www.xulplanet.com/rdf/people/KarensKids> -> rdf:type ->
<http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq>
<http://www.xulplanet.com/rdf/people/KarensKids> -> rdf:_1 ->
<http://www.xulplanet.com/rdf/people/Sandra>
<http://www.xulplanet.com/rdf/people/KarensKids> -> rdf:_2 ->
<http://www.xulplanet.com/rdf/people/Kevin>
<http://www.xulplanet.com/rdf/people/KarensKids> -> rdf:_3 ->
<http://www.xulplanet.com/rdf/people/Jack>

Abbiamo detto che Karen è una Person, e le abbiamo dato una relazione con una risorsa <http://www.xulplanet.com/rdf/people/KarensKids> attravers il predicato 'children'. Invece di associare i tre bambini direttamente con Karen, li associamo con questa risorsa (children, appunto). Questa ulteriore risorsa è di tipo rdf:Seq. Il risultato è che a Karen vengono dati tre bambini, ma ha ancora un tipo Person univoco.

In termini di RDF, non dobbiamo specificare esplicitamente l'URI di <http://www.xulplanet.com/rdf/people/KarensKids>. Dal momento che il percorso sopra è usato comunemente, RDF permette l'uso di nodi anonimi, e spesso viene generato per te un URI casuale. Tecnicamente, non hanno URI, ma puoi ancora manipolarli come risorse, e aggiungere e rimuovere le triple associate con loro.

In tutti gli esempi sopra, abbiamo solo definito le triple. Ogni linea ha un soggetto, un predicato e un complemento. Anche quando definiamo tipi e liste, usiamo sempre triple per definirli. RDF è solo una lista di triple, o di relazioni tra le cose.

Una cosa interessante di RDF è che possiamo prendere una lista di triple da una sorgente e combinarle con triple di un'altra sorgente. Dal momento che l'ordine non importa, questo avrebbe lo stesso effetto che avrebbe se noi avessimo specificato di iniziare con entrambe. Per esempio, facciamo finta che un'altra sorgente ha fornito la seguente tripla:

<http://www.xulplanet.com/rdf/people/KarensKids>  ->  rdf:_4  ->
<http://www.xulplanet.com/rdf/people/Wendy>

Quando combinata con l'esempio precedente, significherebbe che Karen adesso ha quattro bambini invece di tre. Questo è un aspetto importante di RDF (il fatto di essere in grado di aggregare dati da sorgenti multiple).

Esempi di triple

All'interno di un browser, i bookmarks possono essere immagazzinati come una serie di triple RDF.

  <urn:x-mark:1>  ->  Name         ->  XULPlanet.com
<urn:x-mark:1> -> URL -> <http://www.xulplanet.com>
<urn:x-mark:1> -> LastVisited -> Sept 8, 2003
<urn:x-mark:2> -> Name -> mozilla.org
<urn:x-mark:2> -> URL -> <http://www.mozilla.org>

Questo esempio ha cinque triple che descrivono due bookmarks. Ogni bookmark ha un Name e un URL, e uno di loro ha un predicato LastVisited. I valori di URL sono impostati a un'altra risorsa, che significa che potrebbero essere usati in altre triple.

Se hai diversi tipi di bookmarks, potresti creare un Tipo per ognuno. Per esempio, la tua applicazione può avere un concetto di una sottoscrizione memorizzato come bookmark, e potresti usare un Tipo per questo:

  <urn:x-mark:1>  ->  rdf:type  ->  http://www.xulplanet.com/rdf/example/Subscription

Potresti usare la convenzione che un bookmark che sia un Seq è una cartella di bookmarks. Gli elementi di Seq sarebbero i bookmarks memorizzati nella cartella.

  <urn:x-mark:folder>  ->  rdf:type  <http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq>
<urn:x-mark:folder> -> rdf:_1 <urn:x-mark:1>
<urn:x-mark:folder> -> rdf:_2 <urn:x-mark:2>

Questo è solo un esempio dei tipi di dati che possono essere memorizzati con RDF. Quasi ogni tipo di dati può essere maneggiato con RDF.