martedì 29 novembre 2011

La legge di Astrazioni deficitarie.

La legge di Astrazioni deficitarie.

da Joel Spolsky
Lunedi, November 11, 2002
C'è un pezzo fondamentale di magia nella progettazione di Internet che si basano su ogni singolo giorno. Succede nel protocollo TCP, uno dei blocchi fondamentali di Internet.
TCP è un modo per trasmettere i dati che sono affidabili . Con questo voglio dire: se si invia un messaggio attraverso la rete utilizzando il protocollo TCP, che arriverà, e non saranno alterati o danneggiati.
Noi usiamo TCP per molte cose, come il recupero pagine web e l'invio di email. L'affidabilità del protocollo TCP è il motivo per ogni e-mail emozionante da appropriazione indebita africani Oriente arriva nella lettera-perfetto stato. O gioia.
In confronto, c'è un altro metodo di trasmissione dati chiamato IP che è inaffidabile . Nessuno promette che i dati arriveranno, e potrebbe avere incasinato prima che arrivi. Se si invia un mucchio di messaggi con IP, non stupitevi se solo la metà di loro arrivano, e alcuni di questi sono in un ordine diverso rispetto all'ordine in cui sono stati inviati, e alcuni di loro sono stati sostituiti da messaggi alternativi , forse contenente le immagini di oranghi bambino adorabile, o più probabilmente solo un sacco di spazzatura illeggibile che sembra l'oggetto di spam Taiwan.
Ecco la parte magica: TCP si basa su IP. In altre parole, il protocollo TCP è obbligato a trasmettere in qualche modo dati in modo affidabile utilizzando solo uno strumento inaffidabile .
Per illustrare perché questo è magia, considerare quanto segue moralmente equivalente, anche se un po 'ridicolo, lo scenario del mondo reale.
Immaginate che abbiamo avuto modo di invio di attori di Broadway a Hollywood che ha coinvolto mettendoli in auto e li guida attraverso il paese. Alcune di queste vetture incidentate, uccidendo gli attori poveri. A volte gli attori si ubriacavano sulla strada e rasata la testa o ha tatuaggi nasale, diventando così troppo brutta per lavorare a Hollywood, e spesso gli attori arrivati ​​in un ordine diverso da quello che avevano indicato, perché tutti preso strade diverse. Immaginate ora un nuovo servizio chiamato Hollywood Express, che ha emesso gli attori a Hollywood, garantendo che avrebbero (a) arrivare (b) in ordine (c) in perfette condizioni. La parte magica è che Hollywood Express non dispone di alcun metodo di consegna degli attori, oltre al metodo inaffidabile di collocarle in auto e li guida attraverso il paese. Hollywood Express funziona controllando che ogni attore arriva in perfette condizioni e, se non lo fa, richiamando l'home office e chiedendo che gemello dell'attore invece l'invio. Se gli attori arrivano nell'ordine sbagliato Hollywood Check li riorganizza. Se un UFO di grandi dimensioni in via di Area 51 va in crash in autostrada in Nevada, rendendolo impraticabile, tutti gli attori che è andato in quel modo sono deviati via Arizona e Hollywood Express non ha nemmeno dire al registi in California quello che è successo. Per loro, sembra proprio come gli attori stanno arrivando un po 'più lentamente del solito, e non hanno mai nemmeno sentito circa l'incidente UFO.
Che è, approssimativamente, la magia del TCP. E 'ciò che gli informatici amano chiamare un astrazione : una semplificazione di qualcosa di molto più complicato che sta succedendo sotto le coperte. Come si è visto, un sacco di programmazione consiste nella costruzione di astrazioni. Che cos'è una libreria stringa? E 'un modo per fingere che i computer possono manipolare le stringhe con la stessa facilità si possono manipolare i numeri. Che cosa è un file system? E 'un modo per fingere che un disco rigido non è davvero un mucchio di filatura piatti magnetici in grado di memorizzare i bit in certi luoghi, ma piuttosto un sistema gerarchico di cartelle-dentro-cartelle contenenti i singoli file che a loro volta costituite da una o più stringhe di byte.
Torna a TCP. In precedenza per ragioni di semplicità ho raccontato una piccola bugia, e alcuni di voi hanno vapore che esce orecchie da adesso perché questa è fib facendo impazzire. Ho detto che il protocollo TCP garantisce che il messaggio arriverà. Non ha, in realtà. Se il serpente domestico ha masticato attraverso il cavo di rete che porta al computer, e non i pacchetti IP possono ottenere attraverso, quindi TCP non può fare nulla al riguardo e il messaggio non arriva. Se tu fossi brusco con gli amministratori di sistema della vostra azienda e vi puniti collegando un hub è in sovraccarico, solo alcuni dei pacchetti IP otterrà attraverso, e TCP funzionerà, ma tutto sarà molto lento.
Questo è ciò che io chiamo un astrazione che perde . TCP tenta di fornire una completa astrazione di una rete sottostante inaffidabile, ma a volte, le perdite di rete attraverso l'astrazione e si sente le cose che l'astrazione non riesco a proteggere l'utente da. Questo è solo un esempio di quello che ho chiamato la Legge di Astrazioni Leaky:
Tutti i non-banale astrazioni, in qualche misura, si perde.

Astrazioni fallire. A volte un po ', a volte molto. Ci sono perdite. Le cose vanno male. Succede dappertutto quando si hanno astrazioni. Ecco alcuni esempi.
  • Qualcosa di semplice come l'iterazione su un grande array bidimensionale può avere prestazioni radicalmente diverso se lo si fa in orizzontale piuttosto che verticale, a seconda del "grano del legno" - una direzione può portare a errori di pagina molto più che nella direzione opposta ed errori di pagina sono lenti. Anche i programmatori di montaggio dovrebbero essere autorizzati a pretendere di avere un grande spazio indirizzo piatto, ma la memoria virtuale significa che è davvero solo una astrazione, che le perdite quando c'è un page fault e la memoria certo recupera prendere nanosecondi modo più memoria altre operazioni di recupero.
  • Il linguaggio SQL è pensato per astrarre i passi procedurali necessari per interrogare un database, che permette invece di definire semplicemente ciò che si desidera e lasciare che la figura del database i passi procedurali per interrogare esso. Ma in alcuni casi, alcune query SQL sono migliaia di volte più lento di altre query logicamente equivalenti. Un famoso esempio di questo è che alcuni server SQL sono notevolmente più veloci se si specifica ", dove a = b e b = c e a = c" che se si specifica solo ", dove a = b e b = c" anche se il set di risultati è lo stesso. Non dovresti avere a cuore l'procedura, solo le specifiche. Ma a volte le fughe di notizie astrazione e le cause delle prestazioni orribili e si deve uscire l'analizzatore di query piano e studiare ciò che ha fatto male, e capire come rendere il vostro eseguire query più rapidamente.
  • Anche se le librerie di rete come NFS e SMB consentono di considerare il file su macchine remote "come se" fossero locali, a volte la connessione diventa molto lento o va giù, e il file si ferma agire come se fosse locale, e come programmatore si deve scrivere il codice per affrontare questo. L'astrazione di "file remoto è lo stesso file locale" fughe . Ecco un esempio concreto per gli amministratori di sistema Unix. Se mettete home directory degli utenti 'su NFS unità montate (una astrazione), e agli utenti di creare file. Avanti per inoltrare tutte le proprie email da qualche altra parte (un'altra astrazione), e il server NFS va giù mentre nuova e-mail è in arrivo, i messaggi non verranno inoltrati in quanto il file. forward non verrà trovato. La perdita nel astrazione effettivamente causato alcuni messaggi per essere caduto sul pavimento.
  • Classi C + + stringa si suppone che consentono di far finta che le stringhe sono di prima classe di dati. Essi cercano di astrarre il fatto che le stringhe sono duri e consentono di agire come se fossero così facile come numeri interi. Quasi tutte le classi C + + stringa di sovraccaricare l'operatore + in modo da poter scrivere s + "bar" per concatenare. Ma sapete una cosa? Non importa quanti sforzi facciano, non c'è C + + stringa di classe sulla Terra che vi permettono di digitare "pippo" + "bar" , perché le stringhe letterali in C + + sono sempre s char * 'mai, stringhe. L'astrazione è aperta una falla che la lingua non consente di spina. (Ironicamente, la storia della evoluzione del C + + nel corso del tempo può essere descritto come una storia di cercare di tappare le falle nella astrazione stringa. Perché non si può semplicemente aggiungere una classe nativa stringa al linguaggio stesso mi sfugge in questo momento. )
  • E non si può guidare il più velocemente quando piove, anche se la vostra auto è tergicristalli e fari e un tetto e una stufa, che vi proteggerà da preoccuparsi del fatto che piove (che astrarre il tempo), ma Ecco, tu devi preoccuparti di aquaplaning (o aquaplaning in Inghilterra) ea volte la pioggia è così forte non si può vedere molto avanti in modo da andare più lento sotto la pioggia, perché il tempo non potrà mai essere completamente astratto lontano, a causa della legge di astrazioni che perde.
Uno dei motivi per la legge di astrazioni che perde è problematico è che significa che in realtà non astrazioni semplificarci la vita tanto quanto avrebbero dovuto. Quando mi sto allenando a qualcuno di essere un programmatore C + +, sarebbe bello se non ho mai dovuto insegnare loro s char * 'e aritmetica dei puntatori. Sarebbe bello se potessi andare direttamente alle stringhe STL. Ma un giorno faranno scrivere il codice "pippo" + "bar" , e le cose veramente bizzarre che accadrà, e poi dovrò smettere e di insegnare loro tutto su char * 's comunque. Oppure un giorno cercherò di chiamare una funzione API di Windows che viene documentato come aventi un argomento OUT LPTSTR e non saranno in grado di capire come chiamarla fino a quando non conoscere s char * ', e puntatori, e Unicode , e wchar_t, ed i file header TCHAR, e tutta quella roba che le perdite su.
Nell'insegnamento qualcuno sulla programmazione COM, sarebbe bello se potessi semplicemente insegnare loro come usare il wizard di Visual Studio e tutte le funzionalità di generazione del codice, ma se qualcosa va storto, non avranno la più vaga idea di quello che è successo o come eseguire il debug e recuperare da esso. Ho intenzione di insegnare loro tutto IUnknown e CLSID e ProgID e ... oh, l'umanità!
Nell'insegnamento qualcuno su ASP.NET programmazione, sarebbe bello se potessi semplicemente insegnare loro che possono fare doppio clic su cose e poi scrivere il codice che viene eseguito sul server quando l'utente fa clic su queste cose. Infatti ASP.NET astrae la differenza tra la scrittura del codice HTML per gestire cliccando su un collegamento ipertestuale ( <a> ) e il codice per gestire cliccando su un pulsante. Problema: i progettisti ASP.NET necessari per nascondere il fatto che in HTML, non c'è modo di inviare un modulo da un collegamento ipertestuale. Lo fanno generando poche righe di JavaScript e allegando un gestore onclick per il collegamento ipertestuale. Le perdite di astrazione, però. Se l'utente finale ha disattivato JavaScript, l'applicazione ASP.NET non funziona correttamente, e se il programmatore non capisce quello che è stato ASP.NET astrarre via, semplicemente non avrà alcuna idea di cosa è sbagliato.
La legge di astrazioni che perde significa che ogni volta che qualcuno esce con un nuovo codice wizzy generazione strumento che dovrebbe renderci tutti sempre in modo efficiente, si sente un sacco di persone dire "imparare a farlo manualmente, quindi utilizzare lo strumento Wizzy per risparmiare tempo. " Strumenti di generazione di codice che pretendono qualcosa di astratto, come tutte le astrazioni, perdite, e l'unico modo per affrontare le perdite è competente per conoscere come funzionano le astrazioni e ciò che sono astrazione. Così le astrazioni ci salvi l'orario di lavoro, ma non ci salvano tempo di apprendimento.
E tutto questo vuol dire che paradossalmente, anche se abbiamo sempre più in alto strumenti di programmazione a livello di astrazioni sempre meglio, diventando un abile programmatore è sempre più difficile.
Durante il mio primo stage di Microsoft, ho scritto le biblioteche stringa per girare su Macintosh. Un compito tipico: scrivere una versione di strcat che restituisce un puntatore alla fine della stringa nuova. Poche righe di codice C. Tutto quello che facevo era giusto da K & R - un libro sottile sul linguaggio di programmazione C.
Oggi, per lavorare su CityDesk, ho bisogno di sapere di Visual Basic, COM, ATL, C + +, InnoSetup, Internet Explorer interni, espressioni regolari, DOM, HTML, CSS e XML. Tutti gli strumenti di alto livello rispetto al vecchio K & R roba, ma devo ancora conoscere il K & R o roba sto pane tostato.
Dieci anni fa, avremmo potuto immaginare che nuovi paradigmi di programmazione avrebbe reso più semplice la programmazione ormai. Infatti, le astrazioni abbiamo creato nel corso degli anni non ci permettono di affrontare nuovi ordini di complessità nello sviluppo di software che non abbiamo a che fare con dieci o quindici anni fa, come la programmazione GUI e programmazione di rete. E mentre questi grandi strumenti, come moderni OO forme linguaggi basati su, cerchiamo di ottenere un sacco di lavoro incredibilmente in fretta, all'improvviso un giorno abbiamo bisogno di capire un problema in cui l'astrazione trapelato, e ci vogliono 2 settimane. E quando avete bisogno di assumere un programmatore di fare la maggior parte di programmazione VB, non è sufficiente per assumere un programmatore VB, perché avranno completamente bloccati nel catrame ogni volta che le fughe di notizie astrazione VB.

lunedì 14 novembre 2011

Id in Rdf e OWL

3.1.1. Classi Semplici con Nome
Class, rdfs:subClassOf

Il concetto fondamentale in un dominio deve corrispondere alle classi che sono alla radice delle varie strutture ad albero che ne rappresentano la tassonomia. Ogni individuo nel mondo di OWL è un membro della classe owl:Thing. Per questo motivo ogni nuova classe definita dall'utente sarà implicitamente una sottoclasse della owl:Thing. Le classi radice di uno specifico dominio, possono essere definite semplicemente dichiarandone il nome. OWL permette anche la definizione della classe vuota, owl:Nothing.
Per il nostro esempio del dominio dei vini, abbiamo creato tre classi radice: Winery(Azienda Vinicola), Region(Regione), e ConsumableThing(Bene consumabile).
<owl:Class rdf:ID="Winery"/> 
<owl:Class rdf:ID="Region"/> 
<owl:Class rdf:ID="ConsumableThing"/> 
Da notare che per ora abbiamo solo detto che esistono classi a cui sono stati dati questi nomi, mediante la sintassi 'rdf:ID='. Formalmente noi non sappiamo niente altro di queste classi se non il fatto che esistono, grazie all'uso di etichette che le definiscono mediante i termini comuni in lingua Inglese. E fino a che le classi esistono solamente, potrebbero non avere nessun membro. Per quello che sappiamo fino a questo punto, le classi potrebbero essere anche state chiamate Thing1, Thing2, e Thing3.
E' importante ricordare che le definizioni possono essere incrementali e distribuite. In particolare avremo molto da dire successivamente riguardo la classe Winery.
La sintassi rdf:ID="Region" è usata per introdurre un nome come parte della sua definizione. Questo è il costrutto rdf:ID attribute ([RDF], 7.2.22) che risulta del tutto simile al più familiare attributo ID definito dall'XML. All'interno di questo documento, potremmo ora riferirci alla classe Region usando il termine #Region, ad esempio scrivendo rdf:resource="#Region". Altre ontologie possono invece riferirvisi usando la sua forma completa, "http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#Region".

RDF Risorse, Proprietà, e valore della proprietà

RDF Risorse, Proprietà, e valore della proprietà

RDF identifica le cose utilizzando identificatori Web (URI), e descrive le risorse con proprietà e valori di proprietà.
Spiegazione del valore delle risorse, proprietà e di proprietà:
  • Una risorsa è tutto ciò che può avere un URI, come "http://www.w3schools.com/rdf"
  • Una proprietà è una risorsa che ha un nome, come "autore" o "home page"
  • Il valore  è il valore di una proprietà, come ad esempio "Jan Egil Refsnes" o "http://www.w3schools.com" (si noti che un valore di proprietà può essere un'altra risorsa)
Il seguente documento RDF potrebbe descrivere la risorsa "http://www.w3schools.com/rdf":
<? Xml version = "1.0"?>

<RDF>
  <Descrizione About="http://www.w3schools.com/rdf">
    <author> Jan Egil Refsnes </ autore>
    <homepage> http://www.w3schools.com </ homepage>
  </ Descrizione>
</ RDF>
lampadaL'esempio sopra è semplificata. Spazi dei nomi vengono omessi.

Le dichiarazioni RDF

La combinazione di una risorsa, una proprietà e un valore di proprietà forma una dichiarazione (nota come predicato soggetto e oggetto di una dichiarazione).
Diamo un'occhiata ad alcune affermazioni esempio per ottenere una migliore comprensione:
Dichiarazione: "L'autore di http://www.w3schools.com/rdf è Jan Egil Refsnes".
  • L'oggetto della dichiarazione di cui sopra è: http://www.w3schools.com/rdf
  • Il predicato è: autore
  • L'oggetto è: Jan Egil Refsnes
Dichiarazione: "La homepage di http://www.w3schools.com/rdf è http://www.w3schools.com".
  • L'oggetto della dichiarazione di cui sopra è: http://www.w3schools.com/rdf
  • Il predicato è: homepage
  • L'oggetto è: http://www.w3schools.com

web semantico -- Ontologie - owl

La natura delle ontologie
L’OWL, come detto, è una componente delle attività dedicate al Semantic Web. Questi sforzi si pongono l’obiettivo di rendere le risorse presenti sul Web più accessibili e comprensibili per le applicazioni, attraverso l’aggiunta di informazioni supplementari che descrivano i dati sui quali occorre effettuare delle elaborazioni. Poiché il Semantic Web è, per sua natura, una realtà distribuita, l’OWL deve permettere di raccogliere le informazioni tra le più disparate fonti. Questo è in parte realizzato consentendo alle ontologie di collegarsi fra loro, prevedendo meccanismi per l’importazione delle informazioni le une dalle altre. Inoltre il linguaggio non tratta le descrizioni delle risorse come informazioni da confinare in un singolo file o come destinate esclusivamente ad un determinato ambito di validità, ma le considera di valenza globale (open world assumption). Una classe C1, anche se definita originariamente nell’ontologia O1, può essere estesa e/o specializzata in altre ontologie. Questa caratteristica implica che le nuove ontologie non possono ritrattare ciò che è dichiarato in quelle precedenti. Sebbene le nuove informazioni possano essere contraddittorie, i fatti e le implicazioni possono solo essere aggiunti, mai eliminati. L’evenienza di queste contraddizioni è qualcosa che i costruttori di ontologie devono tenere in debita considerazione. Ci si aspetta comunque che saranno tool automatici ad evidenziare queste inconsistenze.
Namespace
Prima di poter utilizzare un insieme di termini, occorre una precisa specifica dei vocabolari che saranno utilizzati. Una prima componente standard di tutte le ontologie include un insieme di dichiarazioni di namespace XML, incluso nel tag di apertura rdf:RDF.
Questa sezione fornisce un metodo per interpretare senza ambiguità gli identificatori e rende il resto dell’ontologia decisamente più leggibile.
Un primo esempio (per la catalogazione dei vini di una cantina), in notazione RDF/XML, è riportato di seguito:
La prima dichiarazione identifica il namespace di default per questa ontologia; dal momento che un qualified name (QName) senza prefisso si riferisce all’ontologia corrente è sempre bene prevedere un’assegnazione di questo tipo. La seconda definisce l’URI base per questo documento che sarà utilizzato per “completare” tutti gli URIref relativi. Il terzo namespace indica che, in questo documento, gli elementi col prefisso owl: devono essere interpretati come riferimenti ai concetti estratti dal namespace associato all’URIref http://www.w3.org/2002/07/owl#. Questa è una dichiarazione convenzionale usata per introdurre il vocabolario OWL. Le restanti dichiarazioni stabiliscono che i prefissi rdf:, rdfs: e xsd: fanno riferimento ai costrutti definiti da RDF e RDF Schema ed ai datatype di XML Schema.
Intestazione e corpo delle ontologie OWL
Una volta definiti i namespace che saranno utilizzati, il secondo passo è includere una collezione di asserzioni che riguardano l’ontologia stessa, raggruppate sotto il tag owl:Ontology (annotation). Queste asserzioni sono definite attraverso tag dedicati e si occupano di specificare commenti, controllo di versione, inclusione di altre ontologie, eccetera.
1<owl:Ontology rdf:about="">
2<rdfs:comment>Un’ontologia OWL di esempio</rdfs:comment>
3<owl:priorVersion rdf:resource="http://example.org/20031215/wine"/>
4<owl:imports rdf:resource="http://example.org/20040210/food"/>
5<rdfs:label>Ontologia dei Vini</rdfs:label>
6...
7</owl:Ontology>
In questa sezione si inseriscono di norma tutti i metadati relativi al documento e spesso sono presenti informazioni non direttamente collegate all’ontologia. Questo accade perché tali documenti non sono sempre utilizzati per descrivere un’ontologia nel significato tradizionale del termine: in alcune applicazioni le ontologie non riguardano gli individual ma solo le classi e le proprietà per descrivere, in generale, il dominio di riferimento. L’attributo rdf:about fornisce un nome o un riferimento per l’ontologia. Quando il valore è una stringa vuota, ossia il caso più comune, il nome dell’ontologia è l’URI base dell’elemento owl:Ontology. Tipicamente questo è l’URI del documento che contiene l’ontologia anche se, con l’uso di xml:base, è possibile sostituire quello predefinito. Specificando il tag owl:imports è possibile importare un’ontologia all’interno di un’altra: questo significa che, per l’ontologia corrente, saranno valide tutte le asserzioni presenti nell’ontologia importata. Per utilizzare al meglio l’ontologia importata è conveniente assegnarle un namespace. È bene precisare che l’importazione può anche fallire, fondamentalmente per la non reperibilità o disponibilità delle risorse, problema molto frequente in un ambiente distribuito come il Web. Si noti che, per utilizzare il vocabolario OWL, non è stato necessario importare il file di ontologia owl.rdf ed anzi questa importazione è sconsigliata. Questa sezione è seguita dalle effettive asserzioni che costituiscono l’ontologia, le quali si concludono col tag di chiusura </rdf:RDF> che segna la fine del documento. Un’ontologia scritta in OWL contiene, essenzialmente, una sequenza di annotazioni, assiomi e fatti. Le annotazioni, alcune delle quali già analizzate in precedenza, sono usate per dare un nome all’ontologia, per registrare informazioni sull’autore e sull’ontologia stessa, per importare altre ontologie, ecc.. La parte centrale invece è composta da assiomi e fatti, che forniscono le informazioni sulle classi, sulle proprietà e sugli individual (istanze di proprietà e classi) ad ognuno dei quali è assegnato un identificatore nella forma di un URIref. Innanzitutto è importante chiarire che le classi denotano insiemi di individual; le proprietà, invece, legano gli individual ad altre informazioni e sono divise in quattro gruppi distinti:
  • data-valued, esplicitano i valori delle proprietà degli individual;
  • individual-valued, mettono in relazione un individual con gli altri;
  • annotation, includono commenti riguardo a individual, classi, proprietà e nomi di ontologie;
  • ontology properties, connettono le ontologie tra loro.
In OWL sono previste due classi predefinite, entrambe appartenenti al namespace owl:. La classe con identificatore owl:Thing è la classe di tutti gli individual, la classe owl:Nothing indica, conseguentemente, la classe vuota: entrambe sono parte di OWL Lite. Per quanto riguarda le annotation, ce ne sono molte predefinite in OWL, alcune delle quali mutuate dall’RDF: owl:versionInfo, rdfs:label, rdfs:comment, rdfs:seeAlso, e rdfs:isDefinedBy. Esistono anche proprietà di default per la descrizione dell’ontologia quali owl:imports, owl:priorVersion, owl:backwardCompatibleWith, e owl:incompatibleWith. Per quanto concerne i fatti, essi sono sostanzialmente di due tipologie. La prima tipologia fornisce informazioni riguardo un particolare individual, specificando le classi cui appartiene, le proprietà possedute ed i relativi valori. Ad un individual può essere assegnato un individualID facoltativo (alcuni individual sono anonimi: blank node) che può essere utilizzato per riferirsi ad esso. La seconda tipologia di fatti è utilizzata principalmente per operare sugli identificatori degli individual (renderli identici o distinti). Gli assiomi sono utilizzati per fornire informazioni relativamente a classi e proprietà. In particolare essi sono usati per associare a queste ultime una parziale o completa specifica delle loro caratteristiche. La definizione degli assiomi presenta delle differenze tra OWL Lite e OWL DL. Ogni assioma di classe nella versione Lite contiene una collezione di classi più generali ed una collezione di restrizioni sulle proprietà locali, nella forma di restriction construct. Questi ultimi stabiliscono il range di una proprietà, quanti valori sono permessi, e l’elenco di quelli obbligatori. La classe così specificata è resa equivalente all’intersezione tra le classi e le restrizioni o ad un suo sottoinsieme. In OWL DL un assioma di classe è costituito da un insieme di descrizioni, le quali possono essere classi più generali, restrizioni, set di individual e combinazioni booleane tra queste. Le classi possono inoltre essere specificate tramite enumerazione, rese equivalenti o disgiunte. Le proprietà possono essere equivalenti ad altre o esserne una specializzazione; possono essere rese funzionali, funzionali inverse, simmetriche o transitive, e vi si possono associare domini e range. Tuttavia molte informazioni che riguardano le proprietà sono più agevolmente espresse mediante restrizioni in cui è possibile specificare range validi localmente e cardinalità. In definitiva le ontologie permettono di rappresentare le risorse in maniera più completa di quanto si possa fare con RDF, disponendo di costrutti decisamente più efficaci ed espressivi. È bene ribadire, comunque, che le caratteristiche aggiuntive di cui dispone l’OWL non sono state implementate direttamente in RDF (nonostante queste fossero effettivamente emerse durante la fase di analisi) al fine di soddisfare i requisiti di modularità e stratificazione previsti in sede di progetto.
Caratteristiche di RDF in OWL
Collegate allo Schema RDF, sono incluse le seguenti caratteristiche OWL.
  • Class: una classe definisce un gruppo di individui che sono legati tra di loro perché condividono le stesse proprietà. Per esempio, Deborah e Frank appartengono ambedue alla classe Persona. Le classi possono essere organizzate in una gerarchia di specializzazione usando subClassOf. Esiste una classe integrata molto più generale chiamata Thing che è la classe di tutti gli individui ed è una superclasse di tutte le classi OWL. Esiste anche una classe integrata specifica chiamata Nothing che è la classe che non ha istanze ed è una sottoclasse di tutte le classi OWL.
  • rdfs:subClassOf: gerarchie di classe possono essere create grazie ad una o più istruzioni secondo cui una classe è una sottoclasse di un’altra classe. Per esempio, si può affermare che la classe Persona è una sottoclasse della classe Mammifero. Un ragionatore può dedurre da ciò che se un individuo è una Persona, allora è anche un Mammifero.
  • rdf:Property: le proprietà possono essere usate per stabilire relazioni tra individui oppure da individui a valori di dati. Esempi di proprietà possono essere haFiglioFiglia, haParente, haFratelloSorella, e haEtà. I primi tre esempi possono essere usati per collegare un’istanza di una classe Persona ad un’altra istanza della classe Persona (e pertanto sono occorrenze di ObjectProperty) mentre l’ultimo (haEtà) può essere usato per collegare un’istanza della classe Persona ad un’istanza del tipo di dati NumeroIntero (e pertanto è un’occorrenza di DatatypeProperty). Sia owl:ObjectProperty sia owl:DatatypeProperty sono sottoclassi della classe rdf:Property di RDF.
  • rdfs:subPropertyOf: gerarchie di proprietà possono essere create attraverso una o più istruzioni secondo le quali una proprietà è una sottoproprietà di una o più altre proprietà. Per esempio, si può affermare che haFratelloSorella è una sottoproprietà di haParente. Da ciò un ragionatore può dedurre che se un individuo è collegato ad un altro dalla proprietà haFratelloSorella, allora esso è collegato all’altro dalla proprietà haParente.
  • rdfs:domain: il dominio di una proprietà limita gli individui a cui si applica la proprietà. Se una proprietà collega un individuo ad un altro individuo e se la proprietà ha una classe per uno dei propri domini, allora l’individuo deve appartenere alla classe. Per esempio, si può affermare che la proprietà haFiglioFiglia ha il dominio Mammifero. Un ragionatore può quindi dedurre che se Frank haFiglioFiglia Anna, allora Frank deve essere un Mammifero. Si osservi che rdfs:domain è chiamata limitazione globale in quanto la limitazione viene affermata in base alla proprietà e non solo in base alla proprietà quando è associata con una particolare classe.
  • rdfs:range: la portata (range) di una proprietà limita gli individui che la proprietà può avere come suoi valori. Se la proprietà collega un individuo ad un altro individuo e se la proprietà ha una classe come sua portata, allora l’altro individuo deve appartenere alla classe portata (range). Per esempio, si può dichiarare che la proprietà haFiglioFiglia possiede la portata di Mammifero. Da ciò un ragionatore può dedurre che se Louise è collegata a Deborah attraverso la proprietà haFiglioFiglia (per es., Deborah è la figlia di Louise), allora Deborah è un Mammifero. La portata è anche una limitazione globale tanto quanto il dominio di cui sopra.

domenica 13 novembre 2011

Esempi SPARQL e dbpedia

About: Silvio Berlusconi
An Entity of Type : person, from Named Graph : http://dbpedia.org, within Data Space : dbpedia.org
About DBpedia

Property    Value
dbpedia-owl:abstract    
    * Silvio Berlusconi ist ein italienischer Politiker und Unternehmer.
dbpedia-owl:activeYearsEndDate    
    * 2010-10-04 (xsd:date)
dbpedia-owl:activeYearsStartDate    
    * 2010-05-05 (xsd:date)
dbpedia-owl:almaMater    
    * dbpedia:University_of_Milan
dbpedia-owl:birthDate    
    * 1936-09-29 (xsd:date)
dbpedia-owl:birthPlace    
    * dbpedia:Milan
    * dbpedia:Kingdom_of_Italy_(1861–1946)
dbpedia-owl:child    
    * dbpedia:Marina_Berlusconi
    * dbpedia:Pier_Silvio_Berlusconi
    * dbpedia:Barbara_Berlusconi
dbpedia-owl:deputy    
    * dbpedia:Giulio_Tremonti
dbpedia-owl:office    
    * Acting
    * Minister of Foreign Affairs
    * Minister of Health
dbpedia-owl:orderInOffice    
    * Prime Minister of Italy
dbpedia-owl:otherParty    
    * dbpedia:Forza_Italia
dbpedia-owl:party    
    * dbpedia:The_People_of_Freedom
dbpedia-owl:president    
    * dbpedia:Carlo_Azeglio_Ciampi
    * dbpedia:Giorgio_Napolitano
    * dbpedia:Oscar_Luigi_Scalfaro
dbpedia-owl:profession    
    * dbpedia:Businessperson
dbpedia-owl:region    
    * dbpedia:Molise
    * dbpedia:Latium
    * dbpedia:Lombardy
    * dbpedia:Campania
dbpedia-owl:residence    
    * dbpedia:Arcore
    * dbpedia:Kingdom_of_Italy_(1861–1946)
dbpedia-owl:spouse    
    * dbpedia:Veronica_Lario
dbpedia-owl:successor    
    * dbpedia:Lamberto_Dini
    * dbpedia:Livia_Turco
    * dbpedia:Romano_Prodi
dbpedia-owl:thumbnail    
    * http://upload.wikimedia.org/wikipedia/commons/
    thumb/4/43/Silvio_Berlusconi_%282010%29.jpg/200px-Silvio_Berlusconi_%282010%29.jpg
dbpedia-owl:wikiPageExternalLink    
    * http://www.newyorker.com/reporting/2008/11/03/081103fa_fact_stille
    * http://www.margheritaonline.it/stampa/scheda.php?id_stampa=4671
    * http://www.ifex.org/en/content/view/full/66079/
    * http://www.forza-italia.it/
    * http://news.bbc.co.uk/1/hi/world/europe/2055418.stm
dbpprop:after    
    * dbpedia:Jean_Chrétien
    * dbpedia:Francesco_Amirante
dbpprop:birthDate    
    * 1936-09-29 (xsd:date)
dbpprop:birthPlace    
    * dbpedia:Milan
    * dbpedia:Kingdom_of_Italy_(1861–1946)
dbpprop:children    
    * dbpedia:Marina_Berlusconi
    * dbpedia:Pier_Silvio_Berlusconi
    * dbpedia:Barbara_Berlusconi
    * Luigi
    * Eleonora
dbpprop:dateOfBirth    
    * 29 (xsd:integer)
dbpprop:deputy    
    * dbpedia:Giulio_Tremonti
dbpprop:name    
    * Silvio Berlusconi
    * Berlusconi, Silvio
dbpprop:office    
    * dbpedia:Ministry_of_Economic_Development_(Italy)
    * dbpedia:Minister_of_Foreign_Affairs_(Italy)
dbpprop:otherparty    
    * Forza Italia
dbpprop:party    
    * The People of Freedom
dbpprop:placeOfBirth    
dbpprop:president    
    * dbpedia:Carlo_Azeglio_Ciampi
    * dbpedia:Giorgio_Napolitano
    * dbpedia:Oscar_Luigi_Scalfaro
dbpprop:profession    
    * dbpedia:Businessperson
dbpprop:religion    
    * Roman Catholicism
dbpprop:residence    
    * Arcore, Italy
dbpprop:shortDescription    
    * Italian politician, entrepreneur, and media proprietor
dbpprop:signature    
    * Silvio Berlusconi Signature.svg
dcterms:subject    
    * category:A.C._Milan
    * category:Italian_businesspeople
    * category:The_People_of_Freedom_politicians
    * category:Living_people
    * category:1936_births
    * category:Newspaper_publishers_(people)
    * category:Italian_billionaires
rdf:type    
    * owl:Thing
    * dbpedia-owl:Person
    * http://schema.org/Person
    * yago:Person100007846
    * yago:CurrentNationalLeaders
    * yago:PrimeMinistersOfItaly
    * foaf:Person
    * yago:PeopleFromMilan
    * dbpedia-owl:OfficeHolder
    * yago:LivingPeople
    * yago:ItalianMassMediaOwners
    * http://umbel.org/umbel/rc/PrimeMinister_HeadOfGovernment
    * yago:ForzaItaliaPoliticians
    * yago:ItalianBillionaires
    * http://umbel.org/umbel/rc/Politician
    * yago:ThePeopleOfFreedomPoliticians
    * http://umbel.org/umbel/rc/PersonWithOccupation
rdfs:comment    
    * Silvio Berlusconi es un político y empresario italiano,
    actualmente primer ministro de Italia y líder del partido El Pueblo de la Libertad.
    Es asimismo propietario del equipo de fútbol AC Milan.
rdfs:label    
    * Silvio Berlusconi
    * Silvio Berlusconi
    * Silvio Berlusconi
foaf:depiction    
    * http://upload.wikimedia.org/wikipedia/commons/4/43/Silvio_Berlusconi_%282010%29.jpg
foaf:page    
    * http://en.wikipedia.org/wiki/Silvio_Berlusconi
foaf:surname    
    * Berlusconi
is dbpedia-owl:firstLeader of   
    * dbpedia:Italian_Senate_election_in_Lombardy,_2001
    * dbpedia:Italian_general_election,_2001
is dbpedia-owl:starring of   
    * dbpedia:Videocracy_(film)
    * dbpedia:Claudio_Scajola
is owl:sameAs of   
    * http://www4.wiwiss.fu-berlin.de/flickrwrappr/photos/Silvio_Berlusconi
    * http://data.nytimes.com/27152631733516660623
    * yago-res:Silvio Berlusconi
is foaf:primaryTopic of   
    * http://en.wikipedia.org/wiki/Silvio_Berlusconi

Esempi SPARQL e php

While the code may look complex at first blush, it is actually a straightforward tool.

We will begin by taking a quick glance at the first dozen lines:

  // URL to DB Pedia's SPARQL endpoint.
  $url = 'http://dbpedia.org/sparql';

  // The SPARQL query to run.
  $sparql = '
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    SELECT ?uri ?name ?label
    WHERE {
      ?uri foaf:name ?name .
      ?uri rdfs:label ?label
      FILTER (?name = "The Beatles")
      FILTER (lang(?label) = "en")
    }
  ';

  // We first set up the parameters that will be sent.
  $params = array(
    'query' => $sparql,
    'format' => 'application/sparql-results+xml',
  );

  // DB Pedia wants a GET query, so we create one.
  $data = http_build_query($params);
  $url .= '?' . $data;


The snippet above shows all of the preparation we must make to run the query.

We begin with a base $url, which points to the DBPedia SPARQL endpoint. Next we write our SPARQL query. The query above is the same as the one we saw earlier in this article.

With the query and the base URL, we need to build a full URL to access the remote server. This is done with the $params array. There we create the name/value pairs that will be condensed into a GET string by http_build_query(). Note that we set the MIME type as the value of the $params['format'] entry. This is to tell the remote server what kind of data we expect to have returned.

A SPARQL query need not return information encoded as XML. Other data formats are equally capable of representing SPARQL query results. XML is probably the most widely used, though, and is the easiest for us to parse.

In the last line of the snippet above, we assemble our base URL and query params into a complete URL.

Next, we need to execute the query and handle the results.

<?php
  // Next, we simply retrieve, parse, and output the contents.
  $qp = qp($url, 'head');

  // Get the headers from the resulting XML.
  $headers = array();
  foreach ($qp->children('variable') as $col) {
    $headers[] = $col->attr('name');
  }

  // Get rows of data from result.
  $rows = array();
  $col_count = count($headers);
  foreach ($qp->top()->find('results>result') as $row) {
    $cols = array();
    $row->children();
    for ($i = 0; $i < $col_count; ++$i) {
      $cols[$i] = $row->branch()->eq($i)->text();
    }
    $rows[] = $cols;
  }
?>

We begin by creating a new QueryPath object, stored in $qp. Based on the CSS query, we can see that it will be pointed to the header element in the returned results. This element will contain the names of each of the returned variables of data.

From there, we build an array of $headers, getting the name of each returned variable. These we will use to generate the headers in our table. The headers come back in variable elements, and each variable has a name attribute. To fetch them, then, we select the variables and loop through them, retrieving the name attribute of each.

Next comes the fancy part. We need to loop through each result and fetch each variable out of each result. Or, to use the table metaphor we SQL developers are familiar with, we loop through each row, and fetch each column of data. This is al accomplished in the this foreach loop:

foreach ($qp->top()->find('results>result') as $row) {
  $cols = array();
  $row->children();
  for ($i = 0; $i < $col_count; ++$i) {
    $cols[$i] = $row->branch()->eq($i)->text();
  }
  $rows[] = $cols;


When this loop is finished, there will be an array of rows, each of which will have an array of columns. The index of the columns should match the index of the headers array. That is how we correlate headers to columns. You may also notice that we use QueryPath's 'branch() method in combination with eq() so that we can (relatively cheaply) get the text for each column.

With this complete, the next thing to do is format the table output:

Esempi SPARQL

Abstracts of movies starring Tom Cruise, released before 1999

SELECT ?subject ?label ?released ?abstract WHERE {
?subject rdf:type <http://dbpedia.org/ontology/Film>.
?subject dbpedia2:starring <http://dbpedia.org/resource/Tom_Cruise>.
?subject rdfs:comment ?abstract.
?subject rdfs:label ?label.
FILTER(lang(?abstract) = "en" && lang(?label) = "en").
?subject <http://dbpedia.org/ontology/releaseDate> ?released.
FILTER(xsd:date(?released) < "2000-01-01"^^xsd:date).
} ORDER BY ?released
LIMIT 20

----
The official websites of companies with more than 50000 employees

SELECT DISTINCT ?subject
                ?employees
                ?homepage
  WHERE
    {
      ?subject  rdf:type               <http://dbpedia.org/class/yago/Company108058098>  .
      ?subject  dbpedia2:numEmployees  ?employees
        FILTER  ( xsd:integer(?employees) >= 50000 )                                     .
      ?subject  foaf:homepage          ?homepage                                         .
    }
  ORDER BY  DESC(xsd:integer(?employees))
  LIMIT  20
  ----

Cities with more than 2 million habitants

SELECT ?subject ?population WHERE {
?subject rdf:type <http://dbpedia.org/ontology/City>.
?subject <http://dbpedia.org/ontology/populationUrban> ?population.
FILTER (xsd:integer(?population) > 2000000)
}
ORDER BY DESC(xsd:integer(?population))
LIMIT 20

---------------

Querying the Infobox Ontology

SELECT *
  WHERE
    {
      ?e <http://dbpedia.org/ontology/series>         <http://dbpedia.org/resource/The_Sopranos>  .
      ?e <http://dbpedia.org/ontology/releaseDate>    ?date                                       .
      ?e <http://dbpedia.org/ontology/episodeNumber>  ?number                                     .
      ?e <http://dbpedia.org/ontology/seasonNumber>   ?season
    }
  ORDER BY DESC(?date)
 
-----

Executing a SPARQL Query from QueryPath

Executing a SPARQL Query from QueryPath

The Semantic Web. It is a concept that has sparked heated debate for years. While the debate may continue to rage for some time, there are already a host of technologies that can be used to build advanced applications based on XML technology. In this article, we will see how the SPARQL query language can be used to retrieve XML information from remote semantic databases (usually called SPARQL endpoints).
QueryPath already contains all of the tools necessary for running a SPARQL query and handling the results. This is not because QueryPath has been specially fitted to the task, but because SPARQL uses technologies that are widely supported: XML and HTTP. Since QueryPath can be used to make HTTP requests and then digest the XML results, we can use it to execute SPARQL queries and handle the results.
In this article, we will look at a basic SPARQL query, and see how we can use QueryPath to execute it and parse the returned results.
While SPARQL will be introduced here, it is far too robust a language to be explained in a short article. One starting point is the SPARQL Working Group home page.
The queries presented in this chapter will be run against DBPedia, a semantic version of Wikipedia. It makes all of the content from Wikipedia available as semantic content.

The SPARQL Query: A Brief Anatomy

Let's begin by looking at the SPARQL query that we will be running:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?uri ?name ?label
WHERE {
  ?uri foaf:name ?name .
  ?uri rdfs:label ?label
  FILTER (?name = "The Beatles")
  FILTER (lang(?label) = "en")
}
The query above begins by defining two prefixes:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
A prefix is a convenient method for representing a namespace URI with a short string. Above, we create one for the Friend of a Friend namespace (foaf:) and one for the RDF Schema namespace (rdfs). Now, whenever we need to represent entities from those two schemata, we can just use the short prefix instead of the full URL.
The next part of the code above is the actual query:
SELECT ?uri ?name ?label
WHERE {
  ?uri foaf:name ?name .
  ?uri rdfs:label ?label
  FILTER (?name = "The Beatles")
  FILTER (lang(?label) = "en")
}
We are going to use the URI a lot, and it is easy to get hung up on the URI as a URL expressing a location. However, you are better off thinking of the URI as a unique identifier for an object -- a unique identifier that just happens to also be "dereferenceable". We can, in fact, use the URI to access information over the network (in this case).
If you have developed SQL before, this should look vaguely familiar. It functions similarly to a SQL SELECT operation. Here's what the code above does, phrased in plain English:
  1. Select the uri, name, and label
  2. where...
  3. the uri has the name ?name (or, where the uri's name is stored in ?name)
  4. the uri has a label ?label
  5. the name is "The Beatles"
  6. the language of the label is English
There are a few things to note about the structure of the query.
First, remember that the URI (?uri), is just a unique identifier. It is functioning sort of like a primary key for each object we query.
Second, the items that begin with question marks (?) are variables. Their value is assigned when the query is being executed.
Third, the items in the WHERE clause are not simply restrictive, as they are in SQL. In fact, the purpose of lines 3 and 4 isn't so much to limit the items returned, but to express a relationship between items. The general pattern of lines 3 and 4 is:
?subject ?relationship ?object
So ?uri foaf:name ?name can be understood to mean "Some object ID (subject) named (relationship) Some name(object)". As you may have guessed, foaf:name expresses the relationship "is named". Likewise, rdfs:label expresses the relationship "is labeled".
Assuming that we did not have the two FILTER functions, the query would simply return all objects (together with their names and labels) that had a name and a label.
The FILTER function is used to limit what content is returned. Above, we used two filters:
FILTER (?name = "The Beatles")
  FILTER (lang(?label) = "en")
The first filter says that the value of ?name must match (exactly) the string "The Beatles". Keep in mind that a given item may have multiple foaf:name items. The filter need only match one of the items.
The second filter requires that the label's language be in English. RDFS labels in the DBPedia database tend to have attributes indicating the language of the label. We are only interested in the English language content. In the query above, if we omit this, we will see results in Chinese, German, and Spanish, as well as other languages.
Putting this all together, then, our query will return the URI, the name, and the label for any URIs in the database that...
  • Have a name
  • Have a label
  • Have a name that is "The Beatles"
  • Have a label that is in English.
Next, we're ready to see how this query can be run against a remote, publicly available SPARQL endpoint (server) from QueryPath.

Running the Query

The query is, by far, the most complex aspect of our sample code. Here's what the entire code looks like:
<?php
require '../src/QueryPath/QueryPath.php';
 
// We are using the dbpedia database to execute a SPARQL query.
 
// URL to DB Pedia's SPARQL endpoint.
$url = 'http://dbpedia.org/sparql';
 
// The SPARQL query to run.
$sparql = '
  PREFIX foaf: <http://xmlns.com/foaf/0.1/>
  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
  SELECT ?uri ?name ?label
  WHERE {
    ?uri foaf:name ?name .
    ?uri rdfs:label ?label
    FILTER (?name = "The Beatles")
    FILTER (lang(?label) = "en")
  }
';
 
// We first set up the parameters that will be sent.
$params = array(
  'query' => $sparql,
  'format' => 'application/sparql-results+xml',
);
 
// DB Pedia wants a GET query, so we create one.
$data = http_build_query($params);
$url .= '?' . $data;
 
// Next, we simply retrieve, parse, and output the contents.
$qp = qp($url, 'head');
 
// Get the headers from the resulting XML.
$headers = array();
foreach ($qp->children('variable') as $col) {
  $headers[] = $col->attr('name');
}
 
// Get rows of data from result.
$rows = array();
$col_count = count($headers);
foreach ($qp->top()->find('results>result') as $row) {
  $cols = array();
  $row->children();
  for ($i = 0; $i < $col_count; ++$i) {
    $cols[$i] = $row->branch()->eq($i)->text();
  }
  $rows[] = $cols;
}
 
// Turn data into table.
$table = '<table><tr><th>' . implode('</th><th>', $headers) . '</th></tr>';
foreach ($rows as $row) {
  $table .= '<tr><td>';
  $table .= implode('</td><td>', $row);
  $table .= '</td></tr>';
}
$table .= '</table>';
 
// Add table to HTML document.
qp(QueryPath::HTML_STUB, 'body')->append($table)->writeHTML();
?>