Travaux Dirigés

Du triplet SPARQL à l'ontologie OWL — 24 exercices pour maîtriser
le Web Sémantique, de la théorie à la pratique.

📚 Cours #2 · #3 · #4 ⏱ ~8h ⚡ 24 exercices 🎯 Du ★ au ★★★★

Mode d'emploi

Ce TD comporte 24 exercices répartis sur les trois dernières parties du cours. Chaque exercice est indépendant, mais la progression est conçue pour être suivie dans l'ordre.

🎓 Légende des difficultés :
★ Facile★★ Moyen★★★ Difficile★★★★ Délire
Les ★★★★ sont optionnels. Ils sont là pour les courageux, les insomniaques, et ceux qui veulent pouvoir dire « j'ai implémenté un raisonneur OWL hier soir, avant le dîner ».
« La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information. » — Albert Einstein (qui aurait adoré SPARQL)
COURS #2

Des Mots aux Faits

Triplets · graphe · unification · Prolog · Turtle

1. Sociologie de comptoir ★

★ Facile

Traduis les phrases suivantes en triplets RDF (sujet → verbe → objet) :

  1. Socrate est un homme.
  2. Platon est un homme.
  3. Tous les hommes sont mortels.
  4. Socrate a mangé une pomme.
  5. La pomme était empoisonnée. (non, pas celle-là, une autre)

Écris chaque triplet sous la forme <sujet> <verbe> <objet>.

💡 Indice : La phrase 3 n'est pas un fait direct, c'est une règle. Elle deviendra une implication en Prolog plus tard.

2. Graphe de connaissances manuel ★

★ Facile

À partir des triplets de l'exercice 1, dessine le graphe de connaissances correspondant (sur papier ou avec un outil de dessin).

Questions :

🏛️ Culture : Ce syllogisme (Socrate est un homme, les hommes sont mortels → Socrate est mortel) a été formalisé par Aristote au IVe siècle av. J.-C. C'est le plus vieux raisonnement formel connu en Occident. Il a fallu attendre 1972 (Prolog) et 2004 (OWL) pour que les ordinateurs puissent le faire automatiquement. 2400 ans de délai, c'est ce qu'on appelle une latence élevée.

3. Unification à la main ★★

★★ Moyen

Applique l'algorithme d'unification aux paires de termes suivantes. Pour chaque paire, indique si l'unification réussit et, si oui, donne la substitution résultante.

  1. homme(X) et homme(socrate)
  2. a_mangé(socrate, Y) et a_mangé(X, pomme)
  3. mortel(X) et mortel (arité différente)
  4. est_un(X, Y) et est_un(socrate, homme)
  5. a_mangé(socrate, X) et a_mangé(Y, Y)
  6. père(Z, fils(Z)) et père(jean, fils(paul))
💡 Indice : L'unification échoue si une variable apparaît des deux côtés d'une manière qui crée une récursion infinie (occur check). Les implémentations Prolog négligent souvent ce test, ce qui peut planter — comme oublier de vérifier le frein à main avant de démarrer.

4. Chaînage avant : enquête criminelle ★★

★★ Moyen

Un meurtre a été commis au manoir. Tu disposes des faits et règles suivants :

% Faits
est_dans(le_cadavre, la_bibliothèque)
est_dans(l_arme, le_salon)
a_le_motif(colonel_moutarde, l_héritage)
a_le_motif(professeur_violet, l_héritage)
est(le_cadavre, mort)

% Règles
suspect(X) ← a_le_motif(X, l_héritage)
est_dans(X, Y) ∧ est_dans(Z, Y) → est_avec(X, Z)
coupable(X) ← suspect(X) ∧ est_avec(X, l_arme)

Applique le chaînage avant pour déterminer qui est coupable. Montre chaque étape de déduction.

💡 Indice : Le chaînage avant part des faits et applique les règles jusqu'à épuisement. C'est comme un détective qui coche des indices sur un tableau : tu commences par ce que tu sais, et tu remplis jusqu'à ce qu'il ne reste plus rien à déduire.

5. Écrire un fichier Prolog ★

★ Facile

Écris un fichier famille.pl au format Prolog qui contient :

Teste ton fichier avec le mini-Prolog du cours : python raisonnement.py.

🧬 Culture : Les généalogies sont le « Hello World » de Prolog. Le premier programme Prolog (écrit par Alain Colmerauer à Marseille en 1972) incluait déjà une base de données familiale. Depuis, des générations d'étudiants ont découvert la logique en demandant « qui est le grand-père de qui ? ». C'est un peu le jeu des 7 familles de l'informatique.

6. Moteur d'inférence maison ★★★

★★★ Difficile

Dans le code du mini-Prolog (fichier raisonnement.py), le chaînage avant est implémenté avec une boucle qui répète l'unification jusqu'à stabilisation.

  1. Ajoute une règle auteur_classique(X) ← a_ecrit(X, Y) ∧ est_consideré(Y, chef_d_oeuvre) et des faits correspondants.
  2. Modifie le moteur pour détecter les cycles (règles qui produisent indéfiniment les mêmes faits).
  3. Implémente une trace optionnelle qui affiche chaque déduction : [DÉDUCTION] règle 3 → nouveau fait : mortel(socrate).
💡 Indice : Pour détecter un cycle, compare l'ensemble des faits avant et après une passe complète. S'il n'a pas changé, c'est fini. Sinon, c'est que quelqu'un a introduit une règle récursive sans cas de base — erreur classique du débutant, comme oublier le return dans une fonction récursive.

7. Parseur Turtle — version à la main ★★

★★ Moyen

Voici un fichier Turtle :

@prefix : <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

:Socrate rdf:type :Homme .
:Homme   rdf:type :Classe .
:Platon  rdf:type :Homme .
:Socrate :aMangé :Pomme .
:Pomme   rdf:type :Fruit .
    
  1. « Déplie » les préfixes pour obtenir des URIs complètes.
  2. Écris les triplets expansés (sujet, prédicat, objet en URIs complètes).
  3. Dans le code de mini_fuseki.py, localise le parseur Turtle et explique en 2-3 phrases comment il transforme ce texte en triplets.

8. RDF vs Graphe orienté ★

★ Facile

En t'appuyant sur les exemples du cours, donne trois différences entre un graphe RDF et un graphe orienté classique (comme ceux qu'on voit en cours de maths).

Exemple de point de départ : les arêtes sont étiquetées par des URIs, pas par des lettres ou des nombres.

🤯 Fun fact : Dans un graphe RDF, les nœuds peuvent aussi être des arêtes (via le reification). C'est comme si dans un réseau routier, les routes pouvaient être aussi des villes. Les mathématiciens appellent ça un « métagraphe ». Les informaticiens appellent ça « une bonne raison de faire une pause café ».
COURS #3

Des Faits aux Concepts

OWL · classes · propriétés · restrictions · constructeurs · raisonnement

9. Hiérarchie de classes : le zoo ★

★ Facile

Organise les classes suivantes en hiérarchie OWL (⊑) :

Animal · Mammifère · Oiseau · Chien · Chat · Canari · ÊtreVivant · Végétal · Rose · Cactus · Carnivore

Quelques contraintes :

Est-ce que la hiérarchie est un arbre ? Pourquoi ?

10. Héritage multiple : le cas de l'ornithorynque ★★

★★ Moyen

L'ornithorynque pond des œufs (comme les oiseaux) mais allaite ses petits (comme les mammifères). Il est aussi venimeux (comme... un serpent ?).

Définis une hiérarchie OWL qui modélise correctement l'ornithorynque sachant que :

Questions :

🇦🇺 Culture : Quand les premiers colons européens ont découvert l'ornithorynque en 1798, ils ont cru à un canular. Ils pensaient que quelqu'un avait cousu un bec de canard sur un corps de castor. La nature avait déjà inventé l'héritage multiple bien avant OWL. En 2020, des chercheurs ont découvert que la sueur d'ornithorynque contient un peptide qui tue les bactéries. Résultat : on étudie son venin pour créer de nouveaux antibiotiques. La leçon : ne jamais sous-estimer une classe bizarre.

11. Propriétés et inférence ★★

★★ Moyen

Soit les axiomes suivants :

Domaine(a_mangé) = Animal
Range(a_mangé)   = Aliment
a_mangé(Socrate, Pomme)
Pomme ⊑ Aliment
Socrate ⊑ ÊtreHumain    (sans déclaration de classe explicite)
    
  1. Quelles déductions le raisonneur peut-il faire ?
  2. Est-ce qu'il peut déduire que Socrate est un Animal ? Pourquoi ?
  3. Est-ce qu'il peut déduire que Pomme est un Aliment ?
💡 Indice : Les axiomes de domaine et range permettent au raisonneur de déduire des types. Si a_mangé(Socrate, Pomme) et que le domaine est Animal, alors Socrate EST un Animal. C'est la base de l'inférence de types en OWL. Flippant, non ?

12. Restrictions : le menu du restaurant ★★

★★ Moyen

Un restaurant souhaite modéliser ses plats en OWL :

Questions :

  1. Un plat qui contient Poisson est-il Végétarien ? Justifie.
  2. Un plat qui contient Oeuf (qui est un Animal sans être Viande) est-il Végétarien ? Est-il Végan ?
  3. Peut-on trouver une pizza qui soit à la fois Végétarien et PlatDeMer ? Quelle pizza ?
🍕 Culture : La pizza Marinara (tomate, ail, origan, huile d'olive) est végane. La Margherita (mozzarella) est végétarienne mais pas végane. Il n'existe pas de pizza à la fois végétarienne ET aux fruits de mer — sauf si tu considères que la Frutti di Mare est un légume de la mer, auquel cas on n'est plus d'accord sur la définition de « légume ». C'est exactement le genre de problème que OWL permet de résoudre. Ou pas.

13. Constructeurs logiques ★★★

★★★ Difficile

En utilisant les constructeurs OWL (⊓ ⊔ ¬ ∃ ∀), traduis les phrases suivantes en expressions logiques :

  1. « Les dauphins sont des mammifères marins. »
  2. « Un herbivore est un animal qui ne mange que des plantes. »
  3. « Les autruches sont des oiseaux qui ne volent pas. »
  4. « Un parent est une personne qui a au moins un enfant. »
  5. « Un chef étoilé est une personne qui a exactement une étoile Michelin. » (allez, un peu de rêve)
  6. « Une personne qui a au moins deux enfants dont au moins un est un garçon et au moins une est une fille. »
💡 Indice : Pour « exactement un », utilise = 1 (cardinalité). Pour « au moins deux », utilise ≥ 2. En OWL, signifie « au moins un », signifie « seulement des ». C'est la nuance entre « j'ai mangé une pomme » (∃) et « je ne mange que des pommes » (∀).

14. Cohérence d'ontologie : détective logicien ★★★

★★★ Difficile

Une ontologie contient les axiomes suivants :

Chat ⊑ Animal
Chien ⊑ Animal
Chat ⊑ ∀ a_pour_meilleur_ami.¬Chien
Félix ⊑ Chat
Médor ⊑ Chien
a_pour_meilleur_ami(Félix, Médor)
    
  1. Représente ces axiomes sous forme de graphe.
  2. L'ontologie est-elle cohérente ? Sinon, explique pourquoi et propose une correction.
  3. Si on retire l'axiome Chat ⊑ ∀ a_pour_meilleur_ami.¬Chien, quels nouveaux faits peut-on déduire ?
💡 Indice : L'ontologie est incohérente si elle permet de déduire à la fois P et ¬P pour une même proposition. C'est un peu comme si on disait « Félix est un chat, les chats n'ont pas de chien pour meilleur ami, mais Félix a Médor (un chien) pour meilleur ami ». Logique, non ? Incohérente, aussi.

15. Classification d'une classe anonyme ★★

★★ Moyen

À l'aide du mini-raisonneur du cours, détermine la classification de l'individu Rex sachant que :

Chien ⊑ Animal
BergerAllemand ⊑ Chien
Rex ⊑ BergerAllemand
Rex ⊑ ∃ a_pour_métier.{chien_policier, chien_d_aveugle}
Animal ⊑ ∃ a_besoin.Manger
    

Quelles sont toutes les classes auxquelles appartient Rex ? Détaille le chemin de classification.

🐕 Culture : Le berger allemand le plus célèbre est Rin Tin Tin, un chien sauvé d'une niche bombardée en France pendant la Première Guerre mondiale, emmené aux États-Unis, et devenu star de cinéma. Il a même eu sa propre étoile sur le Hollywood Walk of Fame. Si on avait eu OWL à l'époque, on aurait pu le classer comme ChienActeurChienDeGuerreStarInternationale. Bref, un chien avec une ontologie bien remplie.

16. Owlready2 : prise en main ★

★ Facile

En te basant sur la démo raisonnement.py --owlready, écris un script Python qui :

  1. Crée une ontologie vide
  2. Définit les classes Animal, Chien, Chat avec Chien ⊑ Animal et Chat ⊑ Animal
  3. Crée deux individus rex et felix avec leurs types
  4. Affiche tous les individus et leurs classes

Teste-le avec python ton_script.py.

17. Pizza Ontology : le chef cuisinier ★★

★★ Moyen

La Pizza Ontology est le « Hello World » du Web Sémantique. Voici un extrait :

Pizza ⊑ ∃ a_ingrédient.Fromage    (toute pizza contient du fromage)
PizzaVégétarienne ⊑ Pizza ⊓ ∀ a_ingrédient.¬Viande
PizzaMargherita ⊑ PizzaVégétarienne
PizzaMargherita ⊑ ∀ a_ingrédient.{Mozzarella, Tomate, Basilic}
    
  1. Est-ce que PizzaMargherita est bien une PizzaVégétarienne ? Démontre-le.
  2. Ajoute une classe PizzaVégane qui ne contient aucun ingrédient d'origine animale.
  3. Le raisonneur HermiT peut-il détecter qu'une pizza est incohérente si on y met à la fois du Fromage et qu'on la déclare PizzaVégane ? Explique.

18. Mini-raisonneur : ajouter la détection de contradiction ★★★★

★★★★ Délire

Dans le code du mini-raisonneur OWL (raisonnement.py), implémente une détection de contradiction :

Pour corser le tout :

💡 Indice : C'est exactement ce que fait le raisonneur HermiT (Java) en coulisses. Toi aussi, tu peux le faire en Python. Enfin, une version simplifiée. HermiT met 3 secondes à classifier la Pizza Ontology. Ton implémentation mettra peut-être 3 minutes. Mais c'est TON raisonneur. Sois fier.
COURS #4

SPARQL, Serveur et Déploiement

SPARQL · Fuseki · API · serveur HTTP · déploiement

19. Premières requêtes SPARQL ★

★ Facile

Écris une requête SPARQL pour chacune des questions suivantes (base : l'ontologie de la famille) :

  1. Trouver tous les individus.
  2. Trouver tous les hommes.
  3. Trouver toutes les relations a_pour_enfant.
  4. Trouver les grands-pères.

Teste-les sur le serveur SPARQL : python mini_fuseki.py --exemple puis http://localhost:8080/sparql.

20. Jointures et FILTER ★★

★★ Moyen

En utilisant la même base, écris les requêtes SPARQL suivantes :

  1. Trouver les personnes qui ont au moins 2 enfants. (indice : FILTER + COUNT ou double pattern)
  2. Trouver les personnes qui sont à la fois parent et enfant (les « maillons » de la chaîne).
  3. Trouver les ancêtres de Sophie sur exactement 3 générations.
💡 Indice : SPARQL permet de chaîner les triplets. ?x :a_pour_enfant ?y . ?y :a_pour_enfant ?z donne les grands-parents. C'est la magie des property paths : ?x :a_pour_enfant+ ?z donne tous les ancêtres en une ligne.

21. CONSTRUCT : fabriquer un nouveau graphe ★★

★★ Moyen

À partir de la base de connaissances familiale, utilise CONSTRUCT pour :

  1. Créer un nouveau graphe avec les relations :est_ancetre_de à partir des relations :a_pour_enfant.
  2. Créer un graphe qui ne contient que les femmes.
  3. Créer un graphe des fratries (personnes qui partagent au moins un parent).
🔨 Culture : CONSTRUCT est l'équivalent en SPARQL du « faire quelque chose avec les données » plutôt que juste les regarder. En SQL, pour créer une nouvelle table, tu fais CREATE TABLE AS SELECT. En SPARQL, c'est CONSTRUCT { ... } WHERE { ... }. Les gars du W3C n'ont pas choisi la simplicité, mais ils ont choisi la puissance. Comme disait un sage : « SPARQL, c'est le SQL du Web Sémantique, en moins lisible mais plus puissant. »

22. API REST du serveur SPARQL ★★★

★★★ Difficile

Le serveur mini_fuseki.py expose une API REST sur /sparql. En utilisant curl :

  1. Envoie une requête SELECT * WHERE { ?s ?p ?o } LIMIT 10 via GET.
  2. Envoie la même requête via POST (Content-Type: application/sparql-query).
  3. Ajoute l'en-tête Accept: application/sparql-results+json pour obtenir du JSON.
  4. Parse le JSON avec Python (requests ou urllib) et affiche les résultats dans un tableau formaté.
💡 Indice : Les accolades {} doivent être échappées en shell. Utilise --data-urlencode ou mets la requête dans un fichier. Et n'oublie pas -g si tu utilises curl avec des accolades — sinon curl les interprète comme des ranges et ça part en vrille. L'expérience de plusieurs heures de debug, je te l'offre.

23. Ajouter une fonctionnalité au serveur SPARQL ★★★★

★★★★ Délire

Dans le code de mini_fuseki.py, ajoute une fonctionnalité au choix :

💡 Indice : Regarde comment SELECT est implémenté dans le serveur. Tu peux copier la structure et modifier le parseur SPARQL pour supporter la nouvelle forme. C'est l'exercice le plus long du TD, mais aussi le plus gratifiant : après ça, tu pourras dire « j'ai contribué à un serveur SPARQL ». Sur LinkedIn, ça claque.

24. Déploiement et automatisation ★★★

★★★ Difficile

En t'inspirant du script publish.sh et du service systemd fournis avec les cours :

  1. Écris un script deploy.sh qui déploie le cours vers un serveur de ton choix (paramétrable : ./deploy.sh user@host).
  2. Le script doit :
    • Vérifier que les fichiers existent localement avant de les copier
    • Créer un backup automatique du dossier distant avant déploiement
    • Redémarrer le serveur web après déploiement
    • Envoyer une notification (email ou Discord) en cas d'échec
  3. Ajoute au Makefile une cible make deploy qui appelle ton script.
🚀 Culture : Le déploiement automatique, c'est le passage de l'artisanat à l'industrie. Avant, on copiait les fichiers à la main avec une disquette. Ensuite avec scp. Puis avec rsync. Puis avec des pipelines CI/CD. Aujourd'hui, tu es à l'étape scp, mais avec un script. C'est le début d'une longue et belle relation avec l'automatisation. Dans 5 ans, tu auras un pipeline Kubernetes qui déploie ton ontologie OWL sur 12 serveurs en haute disponibilité. Tout commence ici.

Annexe : Grille d'auto-évaluation

Utilise ce tableau pour suivre ta progression :

#ExerciceDifficultéConcept clé
1Triplets RDFsujet-verbe-objet
2Graphe de connaissancesnavigation, classes vs individus
3Unification★★substitution, MGU, occur check
4Chaînage avant★★moteur d'inférence
5Fichier Prologfaits, règles, récursion
6Moteur d'inférence★★★détection de cycles, trace
7Parseur Turtle★★préfixes, URIs, expansion
8RDF vs graphemétagraphe, réification
9Hiérarchie de classes⊑, sous-classe, héritage
10Héritage multiple★★ornithorynque, OWL vs héritage simple
11Propriétés et inférence★★domaine, range, déduction de types
12Restrictions OWL★★∀, ∃, cardinalités
13Constructeurs logiques★★★⊓, ⊔, ¬, ∀, ∃
14Cohérence d'ontologie★★★contradiction, ⊥
15Classification★★chemin de classification
16Owlready2API Python, création d'ontologie
17Pizza Ontology★★Owlready2, restrictions
18Détection de contradiction★★★★raisonneur maison
19Premières requêtes SPARQLSELECT, WHERE, triplets
20Jointures et FILTER★★property paths, FILTER
21CONSTRUCT★★création de graphe
22API REST SPARQL★★★curl, JSON, parsing
23Nouvelle fonctionnalité Fuseki★★★★DESCRIBE, ASK, export
24Déploiement automatique★★★CI/CD, backup, notification
« Un problème sans solution est un problème mal posé. » — Albert Einstein (qui aurait aussi excellé en SPARQL)
🏆 Barème de progression :
0-8 exercices : Tu es au niveau « j'ai survolé le cours ». Revois les bases.
9-16 exercices : Tu es au niveau « je commence à comprendre ». Bonne maîtrise.
17-22 exercices : Tu es au niveau « je peux enseigner ce cours ». Chapeau.
23-24 exercices : Tu es au niveau « Tim Berners-Lee te propose un stage au W3C ».

Et si tu as fait les ★★★★ : tu es au niveau « les ornithorynques te craignent ».

⊓ ⊔ ¬ ∃ ∀ ⸎ ☐