IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SPARQL Discussion :

Récupérer concepts associés à un mot (SPARQL & Jena & Ontologie exemple Pizza)


Sujet :

SPARQL

  1. #1
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut Récupérer concepts associés à un mot (SPARQL & Jena & Ontologie exemple Pizza)
    Bonjour,

    Je suis toujours à la recherche d'une ontologie sur les BPM, mais en attendant j'essaye de faire un bout de mon projet avec l'ontologie exemple qu'est celle avec les pizzas et leurs ingrédient.

    Je travaille sur Eclipse, avec Jena (import : org.apache.jena.query.*; ), et j'ai modifié un projet exemple basé sur les pizzas : (public static final String PIZZA_NS = "http://www.co-ode.org/ontologies/pizza/pizza.owl#";).

    Bref, je voudrais actuellement envoyer le nom d'un ingrédient dans une requête, et extraire de l'ontologie tous les "concepts" associés/liés.
    En fouinant sur le net, je suis tombé sur un exemple lié à DBpedia, et j'ai essayé de l'adapter à mon cas :

    Exemple de DBpedia :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * WHERE {
      dbpedia:Nokia a ?c1 ; a ?c2 .
      ?c1 rdfs:subClassOf ?c2 .
    }
    J'ai essayé de l'adapter à mon cas, mais ça n'a pas l'air de fonctionner du tout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		showQuery(m, prefix
    				+ "SELECT * "
    				+ "WHERE { "
    				+ "  MozzarellaTopping a ?c1 ; a ?c2 . "
    				+ "  ?c1 rdfs:subClassOf ?c2 . "
    				+ "} "
    Je voudrais extraire tout ce qui est lié à "MozzarellaTopping", mais visiblement, je fais planter l'API :
    Exception in thread "main" org.apache.jena.query.QueryParseException: Lexical error at line 4, column 37. Encountered: " " (32), after : "MozzarellaTopping"

    Auriez-vous des idées sur comment interroger l'ontologie avec Jena et SPARQL ?

    Merci



    EDIT :
    Ok, j'ai trouvé une première erreur, il me manquait aussi le préfixe à mon ingrédient.
    Dans mon code, j'ai un peu avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		String prefix = "prefix pizza: <" + PIZZA_NS + ">\n" + "prefix rdfs: <"
    				+ RDFS.getURI() + ">\n" + "prefix owl: <" + OWL.getURI() + ">\n";
    On remarque le "prefix pizza: <" qui précise le préfixe à associer aux ingrédients... j'ai donc maintenant une requête qui ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		// Test for obtaining upper concepts from Pizza Ontology
    		showQuery(m, prefix
    				+ "SELECT * "
    				+ "WHERE { "
    				+ "  pizza:MozzarellaTopping a ?x ; a ?y . "
    				+ "  ?x rdfs:subClassOf ?y . "
    				+ "} "
    				);
    Malheureusement, cela me renvoie un tableau vide
    Je ne sais toujours pas comment récupérer toutes les classes OU individus qui utilisent de la mozzarella...



    EDIT 2 :

    Je pense avoir réussi à extraire des données "connexes" avec une requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		// ?s = subject   ?p = predicate   ?o = object
    		showQuery(m, prefix
    				+ "SELECT ?p ?o "
    				+ "WHERE { "
    				+ " pizza:MozzarellaTopping ?p ?o "
    				+ "} "
    				);
    Dans le résultat j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -------------------------------------------------
    | p                | o                          |
    =================================================
    | owl:disjointWith | :GorgonzolaTopping         |
    | owl:disjointWith | :GoatsCheeseTopping        |
    | owl:disjointWith | :FourCheesesTopping        |
    | owl:disjointWith | :ParmesanTopping           |
    | rdfs:subClassOf  | _:b0                       |
    | rdfs:subClassOf  | :CheeseTopping             |
    | rdfs:subClassOf  | _:b1                       |
    | rdfs:label       | "CoberturaDeMozzarella"@pt |
    | rdf:type         | owl:Class                  |
    -------------------------------------------------
    Du coup je vais vouloir filtrer les "owl:disjointWith" vu qu'ils ne sont pas des concepts "positifs".

    Je pense que je cherche quelque chose dans ce genre-là... mais je suis moi-même un peu perdu.
    J'ai bien obtenu le "CheeseTopping", mais j'espérais plus de choses. (le topic n'est pas clôt)
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  2. #2
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Bonjour,

    J'ai avancé par rapport à la semaine dernière
    J'arrive à extraire les classes "supérieures"/globales pour un mot, tout en filtrant les réponses peu utiles.
    Typiquement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		String MyQuery = prefix
    				+ "SELECT ?o "
    				+ "WHERE { "
    				+ " pizza:MozzarellaTopping rdfs:subClassOf ?o . "
    				+ " filter( ! isBlank(?o) ) "
    				+ "} ";
    Cette requête me renvoie uniquement CheeseTopping !
    Ce qui est effectivement ce que je cherche. (et le isBlank permet de filtrer les _:b1 et autres)

    Actuellement, j'ai un but de code me permettant de faire une requête, et d'utiliser le résultat pour tester les classes du niveau supérieur.
    Cependant un "problème" subsiste : je suis actuellement obligé d'ajouter le préfixe pizza: à toutes mes requêtes.

    Existe-t-il un moyen de se passer du préfixe pour obtenir des réponses ?

    En gros je cherche à faire une requête générique similaire à cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT ?o
    WHERE {
    MozzarellaTopping rdfs:subClassOf ?o .
    filter( ! isBlank(?o) )
    Où le pizza:MozzarellaTopping ne nécessite pas le préfixe pizza:... est-ce possible ?
    Comment demander en SPARQL d'extraire tous les concepts qui s'appellent exactement "MozzarellaTopping", mais avec n'importe quel préfixe ?

    Merci


    EDIT :
    Question débile... le pizza: est le préfixe de mon ontologie....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    prefix pizza: <http://www.co-ode.org/ontologies/pizza/pizza.owl#>
    prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix owl: <http://www.w3.org/2002/07/owl#>
    Bref... je ne sais pas trop s'il me reste des questions...

    Peut être : est-il possible en une requête d'obtenir une union de concepts/classes mères qui contiennent plusieurs mots ?
    Par exemple si je mets MozzarellaTopping et DeepPanBase, y a-t-il moyen d'obtenir l'union des concepts au dessus d'eux ? (ou je dois construire plusieurs requêtes en Java, et les exécuter à la chaîne et traiter à la main les list de string ?)
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Bonjour,

    Je ne sais pas si ça servira à quelqu'un, mais j'ai avancé.
    Au début j'ai codé tout un algorithme en Java pour faire des appels récursifs jusqu'à owl:Thing, mais visiblement c'est inutile, il suffit simplement d'utiliser rdfs:subClassOf*.

    Le code pour extraire les ancêtres de façon récursive en SPARQL s'écrit donc simplement (dans le cas où je veux récupérer les ancêtres de pizza:MozzarellaTopping) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		showQuery(m, prefix
    				+ "SELECT ?o "
    				+ "WHERE { "
    				+ " pizza:MozzarellaTopping rdfs:subClassOf* ?o ."
    				+ " FILTER ( ! isBlank(?o) ) "
    				+ "} "
    				);
    Et évidemment, pour récupérer les ancêtres "communs" à plusieurs entités (pizza:MozzarellaTopping et pizza:DeepPanBase ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		showQuery(m, prefix
    				+ "SELECT ?o "
    				+ "WHERE { "
    				+ " pizza:MozzarellaTopping rdfs:subClassOf* ?o ."
    				+ " pizza:DeepPanBase rdfs:subClassOf* ?o ."
    				+ " FILTER ( ! isBlank(?o) ) "
    				+ "} "
    				);

    Bref, en avançant j'ai réfléchi, et je cherche maintenant à obtenir les concepts/entités inférées par plusieurs mots.
    Typiquement, pizza:MozzarellaTopping et pizza:DeepPanBase peuvent générer une pizza:CheeseyPizza (selon les règles et inférences vues dans Protégé).
    Comment faire pour récupérer ce concept/cette déduction/cette inférence ?
    SPARQL peut le faire ? Ou je dois ajouter un raisonneur dans mon code ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  4. #4
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Bonjour !

    J'ai résolu mon problème, et je vais partager mon code ! (je vais l'uploader aussi, et mettre un lien vers ce post )

    Tout d'abord, il n'est pas "toujours" possible de récupérer les concepts associés à un/des mots, cela dépend de l'ontologie que l'on a, et des individus que l'on y ajoute.
    Je me suis concentré pour le moment sur l'exemple "Pizza".
    Voici le cadre exact de mon test : comment peut-on obtenir les notions en rapport avec un/des mots ?
    Et particulièrement, comment obtenir une réponse "CheeseyPizza" depuis les termes "MozzarellaTopping" et "DeepPanBase" ? (CheeseyPizza étant une sous-classe de "Pizza" contenant des règles au sujet de "PizzaBase" et "PizzaTopping"/"CheeseTopping")

    J'ai fait deux bouts de code pour récupérer deux choses différentes.
    Tout d'abord, comment faire une requête SPARQL qui extrait les concepts ancêtres d'une classe, et les concepts ancêtres communs à deux classes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    public static final String	SOURCE		= "./resources/";
    public static final String	PIZZA_NS	= "http://www.co-ode.org/ontologies/pizza/pizza.owl#";
     
    public void run()
    {
    	OntModel m = getModel();
    	loadData(m);
     
    	String prefix = "prefix pizza: <" + PIZZA_NS + ">\n" + "prefix rdfs: <"
    				+ RDFS.getURI() + ">\n" + "prefix owl: <" + OWL.getURI() + ">\n";
     
    	// Research of all ancestors of pizza:MozzarellaTopping
    	showQuery(m, prefix
    			+ "SELECT ?o " + "WHERE { "
    			+ " pizza:MozzarellaTopping rdfs:subClassOf* ?o . "
    			+ " FILTER ( ! isBlank(?o) ) " + "} ");
     
    	// Research of common ancestors between Mozzarella and DeepPanBase
    	showQuery(m, prefix
    			+ "SELECT ?o " + "WHERE { "
    			+ " pizza:MozzarellaTopping rdfs:subClassOf* ?o . "
    			+ " pizza:DeepPanBase rdfs:subClassOf* ?o . "
    			+ " FILTER ( ! isBlank(?o) ) " + "} ");
    }
     
    protected OntModel getModel()
    {
    	// OWL_MEM
    	return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
    }
     
    protected void loadData(Model m)
    {
    	FileManager.get().readModel(m, SOURCE + "pizza.owl.rdf");
    }
     
    protected void showQuery(Model m, String q)
    {
    	Query query = QueryFactory.create(q);
    	QueryExecution qexec = QueryExecutionFactory.create(query, m);
    	try
    	{
    		ResultSet results = qexec.execSelect();
    		ResultSetFormatter.out(results, m);
    	}
    	finally
    	{
    		qexec.close();
    	}
     
    }

    Pour pouvoir exploiter au niveau du code tout cela, il est possible également de construire une liste de mots.
    La requête est exécutée à la main par "getResultQuery", la requête est construite par "subClassQueryBuilder" (qui construit une requête similaire à ce qui a été vu au dessus... mais elle est plus générique et accepte d'autres mots que "MozzarellaTopping").
    Beaucoup de paramètre se baladent, il s'agit le plus souvent du préfixe "pizza:" ou du header/URI.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    	// Function calling multiple others functions... that prints the ancestors
    	public void listAncestors()
    	{
    		List<String> ConceptsList = new ArrayList<String>();
     
    		// ConceptsList = getUpperClasses("pizza:MozzarellaTopping");
    		ConceptsList = getUpperClasses("pizza", "MozzarellaTopping");
    		for (Iterator<String> iter = ConceptsList.iterator(); iter.hasNext();)
    		{
    			String str = iter.next();
     
    			System.out.println(str);
    		}
    	}
     
    	/**
             * Create a list of words which are the "ancestors" (in the ontology entities'
             * tree) of a given word. Multiple words are extracted following a recursive
             * method. The stop case is achieved when the extracted ancestor entity is
             * named "owl:Thing".
             * 
             * @param ontologyPrefix
             *          : the name of the prefix/IRI for searching the word in (ex:
             *          "pizza":word)
             * @param subClass
             *          : the word to search for in the ontology (ex:
             *          class:"MozzarellaTopping")
             * @return a list of strings containing all of the ancestors
             */
    	public List<String> getUpperClasses(String ontologyPrefix, String subClass)
    	{
    		List<String> ListUpperClasses;
    		OntModel m = getModel();
    		loadData(m);
    		String prefix = getPrefix(ontologyPrefix);
     
     
    		String MyQuery = subClassQueryBuilder(ontologyPrefix + ":" + subClass, "o", prefix);
     
    		ListUpperClasses = getResultQuery(m, MyQuery, "o");
     
    		if (!ListUpperClasses.isEmpty())
    		{
    			for (Iterator<String> iter = ListUpperClasses.iterator(); iter.hasNext();)
    			{
    				String str = iter.next();
     
    				// System.out.println(str);
    			}
    		}
    		else
    		{
    			System.out.println("List is empty -- No ancestors");
    		}
     
    		return (ListUpperClasses);
    	}
     
    	/**
             * Build a predefined SPARQL query with the IRI. Let you choose the name of
             * the variable to extract.
             * 
             * @param objectName
             *          : the class/entity to search for in the ontology
             * @param qualif
             *          : the name of the variable in the query/the col name in the result
             *          table
             * @param prefix
             *          : the full URI/IRI to be included before the query
             * @return a string containing the URI/IRI and the query
             */
    	protected String subClassQueryBuilder(String objectName, String qualif, String prefix)
    	{
    		// ?s = subject ?p = predicate ?o = object
    		String MyQuery = prefix + "SELECT " + "?" + qualif + " " + "WHERE { "
    				+ objectName + " rdfs:subClassOf* " + "?" + qualif + " . "
    				+ " FILTER ( ! isBlank(" + "?" + qualif + ") ) " + "} ";
     
    		return (MyQuery);
    	}
     
    	/**
             * Build the URI/IRI prefix used in the queries.
             * 
             * @param ontologyPrefix
             *          : the precise prefix of the IRI (ex: "pizza" in
             *          pizza:MozzarellaTopping)
             * @return a string containing the URI/IRI prefix
             */
    	protected String getPrefix(String ontologyPrefix)
    	{
    		String prefix;
     
    		prefix = "prefix " + ontologyPrefix + ": <" + PIZZA_NS + ">\n"
    				+ "prefix rdfs: <" + RDFS.getURI() + ">\n" + "prefix owl: <"
    				+ OWL.getURI() + ">\n";
     
    		return (prefix);
    	}
     
    	protected OntModel getModel()
    	{
    		// OWL_MEM
    		return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
    	}
     
    	protected void loadData(Model m)
    	{
    		FileManager.get().readModel(m, SOURCE + "pizza.owl.rdf");
    	}
     
     
    	/**
             * Execute the query
             * 
             * @param m
             *          : The OWL model
             * @param q
             *          : The query to execute
             * @param bindingName
             *          : The name of the column to read
             * @throws Error
             *           if query execution fails
             * @return List of each ancestor
             */
    	protected List<String> getResultQuery(Model m, String q, String bindingName)
    	{
    		Query query;
    		QueryExecution qexec;
    		ResultSet results; // Iterator<QuerySolution>
    		List<String> ResultList = new ArrayList<String>();
     
    		query = QueryFactory.create(q);
    		qexec = QueryExecutionFactory.create(query, m);
    		try
    		{
    			results = qexec.execSelect();
     
    			while (results.hasNext())
    			{
    				QuerySolution binding = results.nextSolution();
    				Resource subj = (Resource) binding.get(bindingName);
     
    				ResultList.add(subj.getLocalName());
    			}
     
    		}
    		finally
    		{
    			qexec.close();
    		}
     
    		return (ResultList);
    	}


    Tout cela présentait la partie SPARQL.
    Passons à la partie raisonneur pure.
    La partie raisonneur va essayer de plusieurs façons différentes d'obtenir la "CheeseyPizza" en instanciant plusieurs individus de type "MozzarellaTopping" et/ou "DeepPanBase" (rappelons : une CheeseyPizza est une pizza (donc une base et des ingrédients) contenant au moins un ingrédient, mais uniquement de type fromage).

    Pour faire les inférences, on met d'abord en mémoire le modèle de base.
    Puis on demande à créer un modèle gérant les inférences, que l'on apposera par dessus le modèle de base.
    On instancie ensuite dans le programme java les références vers les différentes classes et relations que l'on va utiliser (OntClass et OntProperty), puis on ajoute au modèle de base (en mémoire) des "individus" issus des propriétés qui nous intéressent. (l'ordre et les résultats sont expliqués après le code)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    	public static final String	SOURCE		= "./resources/";
    	public static final String	PIZZA_NS	= "http://www.co-ode.org/ontologies/pizza/pizza.owl#";
     
    	public void run()
    	{
    		// Prefix/Header for SPARQL requests
    		final String prefix = "prefix pizza: <" + PIZZA_NS + ">\n"
    				+ "prefix rdfs: <" + RDFS.getURI() + ">\n" + "prefix owl: <"
    				+ OWL.getURI() + ">\n";
    		// Prefix for classes, individuals, ... for every object
    		final String NS = PIZZA_NS;
     
    		System.out.println("CREATE THE BASE MODEL\n");
    		// CREATE THE BASE MODEL
    		OntModel base = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
    		base.read(SOURCE + "pizza.owl.rdf", "RDF/XML");
     
    		System.out.println("CREATE THE REASONING MODEL USING THE BASE\n");
    		// CREATE THE REASONING MODEL USING THE BASE
    		OntModel inf = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF, base);
    		// OWL_MEM_MICRO_RULE_INF // It works + Very quick
    		// OWL_MEM_MINI_RULE_INF // It works + Slow (40Mins) + 1,1Go RAM (Validity is slow)
    		// OWL_MEM_RULE_INF // It works (mights loop if error) + VERY SLOW + 2,1 GO RAM (unfinished)
    		// OWL_MEM_TRANS_INF // It works (SPARQL mights not work) + Ultra Speed / No inference
     
    		System.out.println("CREATE INDIVIDUALS FOR TESTING PURPOSE\n");
    		// CREATE A DUMMY INDIVIDUAL FOR TESTING PURPOSE
     
    		// Instantiate each useful Class
    		OntClass ThingClass = base.getOntClass(NS + "owl:Thing");
    		OntClass FoodClass = base.getOntClass(NS + "Food");
    		OntClass IceCreamClass = base.getOntClass(NS + "IceCream");
    		OntClass PizzaClass = base.getOntClass(NS + "Pizza");
    		OntClass MozzaToppingClass = base.getOntClass(NS + "MozzarellaTopping");
    		OntClass DeepPanBaseClass = base.getOntClass(NS + "DeepPanBase");
     
    		// Instantiate each useful Property (relation)
    		OntProperty hasIngredientProperty = base.createObjectProperty(NS + "hasIngredient");
    		OntProperty hasBaseProperty = base.createObjectProperty(NS + "hasBase");
    		OntProperty hasToppingProperty = base.createObjectProperty(NS + "hasTopping");
     
    		// Instantiate each useful individual
    		Individual MozzaTopping = base.createIndividual(NS + "MyMozzaTopping", MozzaToppingClass);
    		Individual DeepPanBase = base.createIndividual(NS + "MyDeepPanBase",
    				DeepPanBaseClass);
     
    		/*
    		 * BEGINNING OF THE TESTS HERE
    		 */
    		System.out.println("\nTEST VALIDITY BEFORE ADDING INDIVIDUALS\n");
    		checkValidity(inf);
     
    		// Instantiate testing individuals
    		// MyPizza1 : individual with 2 classes simultaneously (Mozza & DeepPan)
    		Individual MyPizza1 = base.createIndividual(NS + "MyPizza1", ThingClass);
    		MyPizza1.setOntClass(MozzaToppingClass);
    		MyPizza1.addOntClass(DeepPanBaseClass);
     
    		System.out.println("\nTest MyPizza1\n");
    		showAsserted(base, NS + "MyPizza1");
    		showInferred(inf, NS + "MyPizza1");
    		System.out.println("\nTest Validity of MyPizza1 : ");
    		checkValidity(inf); // ERROR
     
    		MyPizza1.remove();
    		System.out.println("\nRemove MyPizza1, Validity should be OK now : ");
    		checkValidity(inf); // OK
     
    		// MyPizza2 : individual of class "Food", linked with Mozza & DeepPan
    		Individual MyPizza2 = base.createIndividual(NS + "MyPizza2", FoodClass);
    		MyPizza2.addProperty(hasBaseProperty, DeepPanBase);
    		MyPizza2.addProperty(hasToppingProperty, MozzaTopping);
     
    		System.out.println("\nTest MyPizza2\n");
    		showAsserted(base, NS + "MyPizza2");
    		showInferred(inf, NS + "MyPizza2");
    		System.out.println("\nTest Validity of MyPizza2 : ");
    		checkValidity(inf); // OK
     
    		MyPizza2.remove();
    		System.out.println("\nRemove MyPizza2, Validity should be OK now : ");
    		checkValidity(inf); // OK
     
    		// MyPizza3 : individual of class "DeepPanBase", linked with Mozza
    		Individual MyPizza3 = base.createIndividual(NS + "MyPizza3", DeepPanBaseClass);
    		MyPizza3.addProperty(hasToppingProperty, MozzaTopping);
     
    		System.out.println("\nTest MyPizza3\n");
    		showAsserted(base, NS + "MyPizza3");
    		showInferred(inf, NS + "MyPizza3");
    		System.out.println("\nTest Validity of MyPizza3 : ");
    		checkValidity(inf); // ERROR
     
    		MyPizza3.remove();
    		System.out.println("\nRemove MyPizza3, Validity should be OK now : ");
    		checkValidity(inf); // OK
     
    		// IceCream : individual of class "IceCream", linked with Moza & DeePan
    		Individual MyIceCream = base.createIndividual(NS + "MyIceCream", IceCreamClass);
    		MyIceCream.addProperty(hasBaseProperty, DeepPanBase);
    		MyIceCream.addProperty(hasToppingProperty, MozzaTopping);
     
    		System.out.println("\nTest IceCream\n");
    		showAsserted(base, NS + "MyIceCream");
    		showInferred(inf, NS + "MyIceCream");
    		System.out.println("\nTest Validity of IceCream : ");
    		checkValidity(inf);
     
    		/*
    		 * END OF THE TESTS HERE
    		 */
     
    		System.out.println("End Tests\n");
    	}
     
    	protected void showAsserted(OntModel m, String individualURI)
    	{
    		// list the asserted types
    		Individual instance = m.getIndividual(individualURI); // BASE
    		for (Iterator<Resource> i = instance.listRDFTypes(false); i.hasNext();)
    		{
    			System.out
    					.println(instance.getURI() + " is asserted in class " + i.next());
    		}
    	}
     
    	protected void showInferred(OntModel m, String individualURI)
    	{
    		// list the inferred types
    		Individual instance = m.getIndividual(individualURI); // INFERED
    		for (Iterator<Resource> i = instance.listRDFTypes(false); i.hasNext();)
    		{
    			System.out.println(
    					instance.getURI() + " is inferred to be in class " + i.next());
    		}
    	}
     
    	protected void checkValidity(OntModel inf)
    	{
    		ValidityReport validity = inf.validate();
    		if (validity.isValid())
    		{
    			System.out.println("OK");
    		}
    		else
    		{
    			System.out.println("Conflicts");
    			for (Iterator i = validity.getReports(); i.hasNext();)
    			{
    				System.out.println(" - " + i.next());
    			}
    		}
    	}
    • On va d'abord créer deux individus : une MozzarellaTopping et une DeepPanBase (chacun n'appartenant qu'à une seule classe), puis on vérifie l'intégrité du modèle avec checkValidity(inf); (normalement tout est bon).
    • L'individu MyPizza1 va être créé et sera une "owl:Thing" (une chose ! LA CHOSE ! ) que l'on va immédiatement transformer en MozzarellaToppingClass et lui ajouter une seconde classe d'appartenance : DeepPanBaseClass.
      En faisant une vérification du modèle, des erreurs vont apparaitre, mais il est possible de voir "CheeseyPizza" apparaitre dans les inférences ! (on nettoie l'individu après chaque test... donc le modèle redevient intègre)
    • MyPizza2 sera de type "Food", et on lui ajoute deux relations avec deux autres individus... MyPizza2 contient maintenant une relation "hasBase" avec un individu "DeepPanBase", et une relation "hasTopping" avec un individu "MozzarellaTopping" (créés au début). L'intégrité fonctionne, et l'inférence comprend effectivement qu'il s'agit d'une Pizza et d'une CheeseyPizza (et beaucoup d'autres choses).
    • MyPizza3 est de type "DeepPanBase", et on va lui ajouter une relation "hasTopping" avec l'individu "MozzarellaTopping"... l'inférence va effectivement comprend qu'il s'agit d'une CheeseyPizza, mais cela va créer des erreur d'intégrité. (on supprime MyPizza3, et on revérifie le modèle : tout marche)
    • IceCream est de type "IceCream" (donc pas une Pizza, mais de la Food), mais on va lui associer une relation "hasBase" avec "DeepPanBase" et une relation "hasTopping" avec "MozzarellaTopping"... ce qui fera dire au raisonneur qu'il s'agit d'une CheeseyPizza, mais l'intégrité va remonter des erreurs.


    Les "erreurs" d'intégrité sont dûes à la définition de l'ontologie qui décrit qu'une "Pizza" n'est ni une IceCream, ni une PizzaBase, ni une PizzaTopping... mais bel et bien un objet "seul" qui dispose d'au moins une propriété/relation "PizzaBase", et de un ou plus "PizzaIngredient".


    Il est possible de changer le moteur d'inférence en changeant cette ligne :
    OntModel inf = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF, base);Le OWL_MEM_MICRO_RULE_INF peut être changé en OWL_MEM_MINI_RULE_INF, ou en OWL_MEM_RULE_INF, ou en OWL_MEM_TRANS_INF.
    Attention, le Micro est très rapide (quelques secondes), mais le Mini prend plus de 40 mins sur ma machine... MEM_RULE met plus d'1h à seulement vérifier la base... et MEM_TRANS ne fait quasiment aucune inférence.

    Je précise : plusieurs parties du code proviennent des exemples fournis par Apache Jena.



    EDIT : Le projet Java se trouve attaché à ce post plus bas.
    Comme la pièce jointe ne peut PAS faire plus de 2 Mo, j'ai retiré les .JAR supplémentaires.
    Pour faire fonctionner ce projet sous Eclipse, vous devrez extraire le dossier contenu dans l'archive, et aller chercher sur internet tous les .JAR manquants, et les placer dans le dossier "lib/".
    Voici la liste des JAR à placer dans "lib/" et à ajouter au projet (Build Path -> Configure Build Path -> Add JARs) :
    commons-cli-1.3.jar
    commons-lang3-3.4.jar
    httpclient-4.5.2.jar
    httpclient-cache-4.5.2.jar
    httpcore-4.4.4.jar
    jackson-annotations-2.7.0.jar
    jackson-core-2.7.4.jar
    jackson-databind-2.7.4.jar
    jena-arq-3.3.0.jar
    jena-base-3.3.0.jar
    jena-core-3.3.0.jar
    jena-iri-3.3.0.jar
    jena-rdfconnection-3.3.0.jar
    jena-shaded-guava-3.3.0.jar
    jsonld-java-0.9.0.jar
    libthrift-0.9.3.jar
    log4j-1.2.17.jar
    slf4j-api-1.7.21.jar
    slf4j-log4j12-1.7.21.jar
    xercesImpl-2.11.0.jar
    xml-apis-1.4.01.jar


    EDIT 2 : afin d'offrir un code propre qui fait à la fois du SPARQL "et" du raisonnement sur les individus, je joins une source utile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    package Jena_Reasoner_SPARQL;
     
    import java.util.Date;
    import java.util.Iterator;
     
    import org.apache.jena.ontology.Individual;
    import org.apache.jena.ontology.OntClass;
    import org.apache.jena.ontology.OntModel;
    import org.apache.jena.ontology.OntModelSpec;
    import org.apache.jena.ontology.OntProperty;
    import org.apache.jena.query.Query;
    import org.apache.jena.query.QueryExecution;
    import org.apache.jena.query.QueryExecutionFactory;
    import org.apache.jena.query.QueryFactory;
    import org.apache.jena.query.ResultSet;
    import org.apache.jena.query.ResultSetFormatter;
    import org.apache.jena.rdf.model.Model;
    import org.apache.jena.rdf.model.ModelFactory;
    import org.apache.jena.rdf.model.Resource;
    import org.apache.jena.reasoner.ValidityReport;
    import org.apache.jena.vocabulary.OWL;
    import org.apache.jena.vocabulary.RDFS;
     
    public class Simple_Reasoner_and_SPARQL_Request
    {
    	public static final String	SOURCE		= "./resources/";
    	public static final String	PIZZA_NS	= "http://www.co-ode.org/ontologies/pizza/pizza.owl#";
    	public static final String	prefix		= "prefix pizza: <" + PIZZA_NS + ">\n"
    																				+ "prefix rdfs: <" + RDFS.getURI() + ">\n"
    																				+ "prefix owl: <" + OWL.getURI() + ">\n";
     
    	public static void main(String[] args)
    	{
    		System.out.println("BEGIN " + new Date());
     
    		new Simple_Reasoner_and_SPARQL_Request().run();
     
    		System.out.println("END " + new Date());
    	}
     
    	public void run()
    	{
    		String NS = PIZZA_NS;
     
    		System.out.println("CREATE AND LOAD THE BASE MODEL");
    		// CREATE AND LOAD THE BASE MODEL
    		OntModel base = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
    		base.read(SOURCE + "pizza.owl.rdf", "RDF/XML");
     
    		System.out.println("CREATE THE REASONING MODEL USING THE BASE\n");
    		// CREATE THE REASONING MODEL USING THE BASE
    		OntModel inf = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF, base);
    		// OWL_MEM_MICRO_RULE_INF // It works + Very quick
    		// OWL_MEM_MINI_RULE_INF // It works + Slow (40Mins) + 1,1Go RAM (Validity is slow)
    		// OWL_MEM_RULE_INF // It works (mights loop if error) + VERY SLOW + 2,1Go RAM (unfinished)
    		// OWL_MEM_TRANS_INF // It works (SPARQL mights not work) + Ultra Speed / No inference
     
    		System.out.println("CREATE INDIVIDUALS FOR TESTING PURPOSE\n");
    		// CREATE INDIVIDUALS FOR TESTING PURPOSE
     
    		// Instantiate each useful Class
    		OntClass ThingClass = base.getOntClass(NS + "owl:Thing");
    		OntClass FoodClass = base.getOntClass(NS + "Food");
    		OntClass IceCreamClass = base.getOntClass(NS + "IceCream");
    		OntClass PizzaClass = base.getOntClass(NS + "Pizza");
    		OntClass MozzaToppingClass = base.getOntClass(NS + "MozzarellaTopping");
    		OntClass DeepPanBaseClass = base.getOntClass(NS + "DeepPanBase");
     
    		// Instantiate each useful Property (relation)
    		OntProperty hasIngredientProperty = base.createObjectProperty(NS + "hasIngredient");
    		OntProperty hasBaseProperty = base.createObjectProperty(NS + "hasBase");
    		OntProperty hasToppingProperty = base.createObjectProperty(NS + "hasTopping");
     
    		// Instantiate each useful individual
    		Individual MozzaTopping = base.createIndividual(NS + "MyMozzaTopping", MozzaToppingClass);
    		Individual DeepPanBase = base.createIndividual(NS + "MyDeepPanBase", DeepPanBaseClass);
     
    		/*
    		 * BEGINNING OF THE TESTS HERE
    		 */
    		System.out.println("\nTEST VALIDITY BEFORE ADDING INDIVIDUALS " + new Date() + "\n");
    		checkValidity(inf);
     
    		// Instantiate testing individuals
    		// MyPizza1 : individual of class "Food", linked with Mozza & DeepPan
    		Individual MyPizza1 = base.createIndividual(NS + "MyPizza1", FoodClass);
    		MyPizza1.addProperty(hasBaseProperty, DeepPanBase);
    		MyPizza1.addProperty(hasToppingProperty, MozzaTopping);
     
    		System.out.println("\nTest MyPizza1 " + new Date() + "\n");
    		showAsserted(base, NS + "MyPizza1");
    		showInferred(inf, NS + "MyPizza1");
    		System.out.println("\nTest Validity of MyPizza1 : " + new Date());
    		checkValidity(inf); // OK
     
    		// SPARQL Tests now
    		System.out.println("\nSPARQL TESTS\n");
    		printPrefix();
     
    		// Research every Food
    		System.out.println("\nResearch Food in Base model");
    		showQuery(base,
    				prefix + "SELECT ?individual " + "WHERE { "
    						+ " ?individual a pizza:Food . "
    						+ " FILTER ( ! isBlank(?individual) ) " + "} ");
     
    		System.out.println("\nResearch Food in Inference model");
    		showQuery(inf,
    				prefix + "SELECT ?individual " + "WHERE { "
    						+ " ?individual a pizza:Food . "
    						+ " FILTER ( ! isBlank(?individual) ) " + "} ");
     
    		// Research every CheeseyPizza
    		System.out.println("\nResearch CheeseyPizza in Base model");
    		showQuery(base,
    				prefix + "SELECT ?individual " + "WHERE { "
    						+ " ?individual a pizza:CheeseyPizza . "
    						+ " FILTER ( ! isBlank(?individual) ) " + "} ");
     
    		System.out.println("\nResearch CheeseyPizza in Inference model");
    		showQuery(inf,
    				prefix + "SELECT ?individual " + "WHERE { "
    						+ " ?individual a pizza:CheeseyPizza . "
    						+ " FILTER ( ! isBlank(?individual) ) " + "} ");
     
    		/*
    		 * END OF THE TESTS HERE
    		 */
     
    		System.out.println("End Tests\n");
    	}
     
    	protected void showAsserted(OntModel m, String individualURI)
    	{
    		// list the asserted types
    		Individual instance = m.getIndividual(individualURI); // BASE
    		for (Iterator<Resource> i = instance.listRDFTypes(false); i.hasNext();)
    		{
    			System.out
    					.println(instance.getURI() + " is asserted in class " + i.next());
    		}
    	}
     
    	protected void showInferred(OntModel m, String individualURI)
    	{
    		// list the inferred types
    		Individual instance = m.getIndividual(individualURI); // INFERED
    		for (Iterator<Resource> i = instance.listRDFTypes(false); i.hasNext();)
    		{
    			System.out.println(
    					instance.getURI() + " is inferred to be in class " + i.next());
    		}
    	}
     
    	protected void checkValidity(OntModel inf)
    	{
    		ValidityReport validity = inf.validate();
    		if (validity.isValid())
    		{
    			System.out.println("OK");
    		}
    		else
    		{
    			System.out.println("Conflicts");
    			for (Iterator i = validity.getReports(); i.hasNext();)
    			{
    				System.out.println(" - " + i.next());
    			}
    		}
    	}
     
    	protected void printPrefix()
    	{
    		System.out.println(prefix);
    	}
     
    	protected void showQuery(Model m, String q)
    	{
    		Query query = QueryFactory.create(q);
    		QueryExecution qexec = QueryExecutionFactory.create(query, m);
    		try
    		{
    			ResultSet results = qexec.execSelect();
    			ResultSetFormatter.out(results, m);
    		}
    		finally
    		{
    			qexec.close();
    		}
     
    	}
    }
    Fichiers attachés Fichiers attachés
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/12/2013, 11h18
  2. Réponses: 2
    Dernier message: 15/02/2007, 22h00
  3. Réponses: 1
    Dernier message: 12/10/2006, 16h48
  4. récupérer login connexion et mot de passe
    Par zut94 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 13/01/2006, 15h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo