Ontologi for Grep_eng - Utdanningsdirektoratet/Grep_SPARQL GitHub Wiki

Experiment: Ontology for Grep

We have created a draft ontology for Grep and placed this in a separate SPARQL repo in Beta. Go to https://sparql-beta-data.udir.no/sparql and select the repository, called "Ontologi".

You can also view the ontology as a file, and then in Turtle serialization: owl-eksperiment_kl06_20230324.ttl.

The ontology contains

  • Classes
    • all grep types are defined as owl:Class (in addition to rdf:type)
  • Object Properties (owl:ObjectProperty)
    • properties that refer to one or more other objects where "range" is a URI in Grep
  • Data properties (owl:DatatypeProperty)
    • properties that have "range" a given data type (eg rdfs:range rdf:langString (language versioned literal)

All the classes and properties (both object and data type properties) are described in prose via each objets rdfs:label and rdfs:comment. E.g. such:

@prefix : <http://psi.udir.no/ontologi/kl06/> .
@prefix d: <http://psi.udir.no/kl06/> .
@prefix u: <http://psi.udir.no/ontologi/kl06/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix udir: <http://psi.udir.no/ontologi/> .
@base <http://psi.udir.no/ontologi/kl06/> .

u:laereplan_lk20 rdf:type owl:Class ;
                 rdfs:subClassOf udir:Laereplan ;
                 rdfs:comment "Element som uttrykker den samlede kompetansen en elev, lærling,  lærekandidat eller deltaker skal ha etter endt opplæring på et gitt nivå/trinn i ett eller flere fag etter Kunnskapsløftet LK20, fagfornyelsen"@nb ,
                              "Element that indicates the overall competence a student, apprentice, training candidate or participant must have after completing training at a specified level/year-level in one or more subjects according to the Knowledge promotion (LK20)"@en ;
                 rdfs:label "Curriculum (LK20)"@en ,
                            "Læreplan (LK20)"@nb .

In this way, the ontology functions as an encyclopedia for what is meant by the various objects.

Note in particular that both u:laereplan_lk20 and u:laereplan are subclasses of Laereplan (with a capital L) which are located in a different namespace than elsewhere in Grep, namely http://psi.udir.no/ontologi/ and not as otherwise , http://psi.udir.no/ontologi/kl06/. See u:laereplan_lk20 rdfs:subClassOf udir:Laereplan in the code above, and also see the prefix "udir:" at the top of the document. In that way (and that is a part of our experiment) we have enriched the model with hierarchy where this is natural. We have done the same with

  • udir:Kompetansemaal (eng: udir:Competence aim)
    • u:kompetansemaal (eng: u:competence aim)
    • u:kompetansemaal_lk20 (eng: u:competence aim_lk20)
  • udir:Kompetansemaalsett (eng: u:Competence aim set)
    • u:kompetansemaalsett (eng: u:competence aim set)
    • u:kompetansemaalsett_lk20 (eng: u:competence aim set_lk20)

If we had baked this ontology into the main repo (201906), we could query instances of udir:Laereplan and get a list of all curricula (both lk06 and lk20 curricula). However, since this is currently an experiment, we have not mixed the ontology with the data. But in the sandbox environment, we have. See http://sandkasse-data.udir.no:7200/sparql and the "Grep_owl-eksperiment" repo. There you can query directly:

PREFIX udir: <http://psi.udir.no/ontologi/>
select * where { 
	?lp a udir:Laereplan .
} ORDER BY ?lp

and you'll get 998 curricula in return (ie both curriculum types).

But back to Beta and the "Ontologi" repo:
Since ontology and data are separate, we can still get the same result, but we have to do some tricks: Be in the "Ontologi" repo, and run the following query:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?lp  where { 
  ?laereplan rdfs:subClassOf <http://psi.udir.no/ontologi/Laereplan>
    
    SERVICE <repository:201906> {
    ?lp a ?laereplan
    }   
} order by ?lp

and you'll get the same 998 curricula as in the previous query.

The trick is just a so-called federated search against a different repo than the one we are in (SERVICE <repository:201906>). Note that it does not matter where you stand and which way you "federate". The query above, only reversed, is a much heavier query:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?lp where { 
  ?lp a ?laereplan
    
    SERVICE <repository:Ontologi> {
    ?laereplan rdfs:subClassOf <http://psi.udir.no/ontologi/Laereplan>
    }   
} order by ?laereplan

This query took 34 seconds when we last checked, while the previous one took just 0.1 second. The reason is that in this query we have in principle an s-p-o query (?s ?p ?o), i.e. that we start from three variables, which in practice means all triples in the entire database. The query then runs through all triples, and checks against what we have written under `repository:Ontology' for each triple. This is quite heavy.

Two queries to get a full overview of types and properties:

Query that gives a full overview of all owl:Class

# Query that returns all classes in Grep with labels and definitions
# Go to https://sparql-beta-data.udir.no/sparql
# Select the "Ontologi" repo at the top right of the page
# Paste the query below into the query window and click "Run
PREFIX u: <http://psi.udir.no/ontologi/kl06/>
PREFIX udir: <http://psi.udir.no/ontologi/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://psi.udir.no/ontologi/kl06/>
select * where { 
	?type rdf:type owl:Class ;
       rdfs:label ?labelEN ;
       rdfs:label ?labelNB ;
       rdfs:comment ?commentEN ;
       rdfs:comment ?commentNB .
    OPTIONAL {?type rdf:type owl:Class ; rdfs:subClassOf ?subClassOf}
    FILTER (lang(?commentEN)="en" && (lang(?commentNB)="nb" && (lang(?labelEN)="en" && (lang(?labelNB)="nb"))))
} ORDER BY ?type

Query that gives a full overview of all owl:ObjectProperty or owl:DatatypeProperty

The page "List of all properties"@norwegian in our REST wiki is built on the ontology described above. The same overview can be reached via the query below. Go to https://sparql-beta-data.udir.no/sparql and select the "Ontologi" repo in the top right corner, then click on "SPARQL" in the left menu and run the following query:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT 
?property ?tittel ?definisjon ?label ?definition 
(concat(group_concat(distinct ?dom;separator=', ')) as ?domain)
(concat(group_concat(distinct ?rng;separator=', ')) as ?range)
WHERE {
    ?property a owl:DatatypeProperty ; # evt owl:ObjectProperty
              rdfs:label ?label ;
              rdfs:label ?tittel ;
              rdfs:comment ?definisjon ;
              rdfs:comment ?definition ;
              rdfs:domain ?dm ;
              rdfs:range ?rg .
    FILTER(lang(?tittel)="nb")
    FILTER(lang(?definisjon)="nb")
    FILTER(lang(?label)="en")
    FILTER(lang(?definition)="en")
    BIND(REPLACE(STR(?dm), ".*/", "") AS ?dom)
    # enten
    #BIND(REPLACE(STR(?rg), ".*/", "") AS ?rng)
    # eller: 
    BIND(REPLACE(STR(?rg), ".*[/#]", "") AS ?rng)
}
GROUP BY ?property ?tittel ?definisjon ?label ?definition 
ORDER BY ?property

Change from owl:DatatypeProperty to owl:ObjectProperty in the first line after the WHERE clause to switch to show all owl:ObjectProperty.




Contact us if you have questions about this, have ideas or suggestions for changes.

⚠️ **GitHub.com Fallback** ⚠️