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 | 12x 23x 23x 23x 23x 23x 44995x 13483x 31512x 14527x 72x 30557x 72x 2613x 72x 72x 72x 72x 466372x 466372x 44995x 31512x 44995x 54x 466372x 466372x 75586x 75586x 466372x 466372x 466372x 466372x 211283x 255089x 58147x 5005x 53142x 13249x 39893x 2939x 58147x 24476x 24476x 24111x 365x 82x 283x 21x 21x 262x 6x 6x 256x 10x 10x 24476x 5129x 3286x 5129x 18112x 18112x 466372x 466372x 466372x 466372x 211283x 255089x 58147x 8808x 58147x 5129x 5129x | 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;
}
}
}
} |