Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 11x 24x 24x 24x 24x 24x 45490x 13483x 32007x 14735x 73x 31011x 73x 2643x 73x 73x 73x 73x 472034x 472034x 45490x 32007x 45490x 55x 472034x 472034x 77149x 77149x 472034x 472034x 472034x 472034x 212688x 259346x 59176x 4981x 54195x 13759x 40436x 2967x 59176x 24555x 24555x 24215x 340x 75x 265x 19x 19x 246x 5x 5x 241x 9x 9x 24555x 5199x 3388x 5199x 18710x 18710x 472034x 472034x 472034x 472034x 212688x 259346x 59176x 8768x 59176x 5199x 5199x | import * as rdfjs from "@rdfjs/types";
import { owl, rdf, rdfs, skos, sh } from "../../ontologies";
import { SkosReasoner } from "./skos-reasoner";
import { GraphUriGenerator, DefaultInferenceGraphHandler } from "./reasoner";
import { dataFactory } from "../data-factory";
const { quad } = dataFactory;
/**
* A simple RDFS reasoner that expands the graph with inferred triples.
*/
export class RdfsReasoner extends SkosReasoner {
protected ontologies: Set<string> = new Set();
protected classes: Set<string> = new Set();
protected properties: Set<string> = new Set();
protected individuals: Set<rdfjs.Quad_Subject> = new Set();
constructor(targetUriGenerator: GraphUriGenerator = new DefaultInferenceGraphHandler()) {
super(targetUriGenerator);
}
protected isIgnoredNode(term: rdfjs.Quad_Subject | rdfjs.Quad_Object): boolean {
switch (term.value) {
case skos.Concept.value:
case skos.ConceptScheme.value:
case skos.Collection.value:
case skos.OrderedCollection.value:
case sh.Shape.value:
case sh.NodeShape.value:
case sh.PropertyShape.value:
return true;
default:
return false;
}
}
protected isClass(id: string): boolean {
return super.isClass(id) ||
this.classes.has(id) ||
this.properties.has(id) ||
this.ontologies.has(id);
}
protected afterInference() {
super.afterInference();
// After all axioms have been inferred, add the inferred individuals to the graph.
const individuals = [...this.individuals].filter(x => !this.isClass(x.value));
for (let individual of individuals) {
this.store.add(quad(individual, rdf.type, owl.NamedIndividual, this.targetGraph));
}
}
protected override resetState(): void {
this.ontologies.clear();
this.classes.clear();
this.properties.clear();
this.individuals.clear();
}
override applyInference(quad: rdfjs.Quad) {
super.applyInference(quad);
// Treat all named nodes with rdf:type definitions as potential individuals.
if (quad.subject.termType == "NamedNode" && quad.predicate.equals(rdf.type)) {
// Only consider individuals that are not of a type that is ignored such as skos:Concept.
if (!this.isIgnoredNode(quad.object)) {
this.individuals.add(quad.subject);
}
if (quad.object.value == owl.Ontology.value) {
this.ontologies.add(quad.subject.value);
}
}
this.inferClassAxioms(quad as rdfjs.Quad);
this.inferPropertyAxioms(quad as rdfjs.Quad);
}
protected assertClass(subject: rdfjs.Quad_Subject) {
this.store.add(quad(subject, rdf.type, rdfs.Class, this.targetGraph));
this.classes.add(subject.value);
}
protected inferClassAxioms(q: rdfjs.Quad) {
let s = q.subject;
let p = q.predicate;
let o = q.object.termType != "Literal" ? q.object : undefined;
if (!o) {
return;
}
switch (p.value) {
case rdf.type.value: {
if (o.equals(rdfs.Class)) {
// No need to infer the class type, as it is already asserted.
this.classes.add(s.value);
} else if (o.equals(owl.Class)) {
this.assertClass(s);
} else if (!this.isW3CNode(o)) {
this.assertClass(o);
}
return;
}
case rdfs.subClassOf.value: {
this.assertClass(s);
if (!this.isW3CNode(o)) {
this.assertClass(o);
} else if (o.equals(rdfs.Resource)) {
this.store.add(quad(rdfs.Resource, rdf.type, rdfs.Class, this.targetGraph));
} else if (o.equals(rdfs.Class)) {
this.store.add(quad(rdfs.Class, rdf.type, rdfs.Class, this.targetGraph));
this.store.add(quad(rdfs.Class, rdfs.subClassOf, rdfs.Resource, this.targetGraph));
} else if (o.equals(rdfs.Datatype)) {
this.store.add(quad(rdfs.Datatype, rdf.type, rdfs.Class, this.targetGraph));
this.store.add(quad(rdfs.Datatype, rdfs.subClassOf, rdfs.Class, this.targetGraph));
} else if (o.equals(owl.Class)) {
this.store.add(quad(owl.Class, rdf.type, rdfs.Class, this.targetGraph));
this.store.add(quad(owl.Class, rdfs.subClassOf, rdfs.Class, this.targetGraph));
}
return;
}
case rdfs.range.value:
case rdfs.domain.value: {
if (!this.isW3CNode(o)) {
this.assertClass(o);
}
return;
}
}
}
protected assertProperty(subject: rdfjs.Quad_Subject) {
this.store.add(quad(subject, rdf.type, rdf.Property, this.targetGraph));
this.properties.add(subject.value);
}
protected inferPropertyAxioms(quad: rdfjs.Quad) {
let s = quad.subject;
let p = quad.predicate;
let o = quad.object.termType != "Literal" ? quad.object : undefined;
if (!o) {
return;
}
switch (p.value) {
case rdf.type.value: {
if (o.equals(rdf.Property)) {
// No need to infer the property type, as it is already asserted.
this.properties.add(s.value);
}
return;
}
case rdfs.range.value:
case rdfs.domain.value: {
this.assertProperty(s);
return;
}
}
}
} |