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 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | 13x 5537x 5537x 10x 10x 24x 24x 24x 24x 146x 145x 1x 73160x 1929x 1929x 4965x 4965x 4965x 4965x 4965x 4965x 4965x 1929x 3036x 3036x 9930x 9930x 73x 73x 73x 73x 73x 73x 399x 73x 73x 466394x 73x 73x 73x | import * as rdfjs from "@rdfjs/types";
import { RdfStore } from 'rdf-stores';
import { rdf, RDF } from '../../ontologies';
import { dataFactory } from '../data-factory';
const { namedNode, blankNode } = dataFactory;
/**
* A handler to generate graph URIs from any given URI.
*/
export interface GraphUriGenerator {
/**
* Generate a graph URI from a given URI.
* @param uri A URI.
*/
getGraphUri(uri: string | rdfjs.Quad_Graph): string;
}
/**
* Default implementation of the InferenceGraphHandler interface. It generates URIs
* for inference graphs using a Mentor specific URN scheme.
*/
export class DefaultInferenceGraphHandler implements GraphUriGenerator {
getGraphUri(uri: string | rdfjs.Quad_Graph): string {
const u = typeof uri === "string" ? uri : uri.value;
return `urn:mentor:inference:${u}`;
}
/**
* Check if a given URI is an inference graph URI.
* @param uri A URI.
* @returns `true` if the URI is an inference graph URI, `false` otherwise.
*/
isInferenceGraphUri(uri: string | rdfjs.Quad_Graph): boolean {
const u = typeof uri === "string" ? uri : uri.value;
return u.startsWith("urn:mentor:inference:");
}
}
/**
* An interface for reasoners that operate on existing graphs in the RDF store and
* materialise the inferred triples in an inference graph.
*/
export interface Reasoner {
/**
* A handler to generate inference graph URIs from any given graph URI if no explicit target graph is provided.
*/
targetUriGenerator: GraphUriGenerator;
/**
* Apply inference on the source graph and store the inferred triples in the target graph.
* @param store The store to be inferenced.
* @param sourceGraph The source graph where to find the triples to be inferenced.
* @param targetGraph The optional target graph where to store the inferred triples. If none is provided, the graph from getGraphUri will be used.
*/
expand(store: rdfjs.DatasetCore, sourceGraph: string | rdfjs.Quad_Graph, targetGraph?: string | rdfjs.Quad_Graph): rdfjs.DatasetCore;
}
/**
* A base class for reasoners that expand graphs with inferred triples.
*/
export abstract class ReasonerBase implements Reasoner {
protected store: rdfjs.DatasetCore = RdfStore.createDefault().asDataset();
public sourceGraph?: rdfjs.Quad_Graph;
public targetGraph?: rdfjs.Quad_Graph;
public readonly errors: { message: string, quad: rdfjs.Quad }[] = [];
readonly targetUriGenerator: GraphUriGenerator;
constructor(targetUriGenerator: GraphUriGenerator) {
if (targetUriGenerator) {
this.targetUriGenerator = targetUriGenerator;
} else E{
throw new Error(`Invalid value for targetUriGenerator: ${targetUriGenerator}`);
}
}
protected getGraphNode(graph: string | rdfjs.Quad_Graph): rdfjs.Quad_Graph {
if (typeof graph === "string") {
return namedNode(graph);
} else {
return graph;
}
}
protected isW3CNode(term: rdfjs.Quad_Subject | rdfjs.Quad_Object): boolean {
return term.value.startsWith("http://www.w3.org");
}
/**
* Get the URIs of ordered list members in the store.
* @param graphUris Optional graph URI or array of graph URIs to query.
* @param listUri URI of the list to get the items from.
* @returns An array of URIs of the items in the list.
*/
getListItems(listUri: string): rdfjs.Quad_Object[] {
// To do: Fix #10
const list = listUri.includes(':') ? namedNode(listUri) : blankNode(listUri);
return this._getListItems(list);
}
private _getListItems(subject: rdfjs.Quad_Subject): rdfjs.Quad_Object[] {
Iif (!this.sourceGraph) {
return [];
}
let first = Array.from(this.match(this.sourceGraph, subject, rdf.first, null));
Iif (!first.length) {
return [];
}
const rest = Array.from(this.match(this.sourceGraph, subject, rdf.rest, null));
const firstItem = first[0].object;
const restList = rest[0]?.object;
if (restList.value === RDF.nil) {
return [firstItem];
} else {
const restItems = this._getListItems(restList as rdfjs.Quad_Subject);
return [firstItem, ...restItems];
}
}
/**
* Query the store for triples matching the given pattern supporting multiple graphs.
* @param graphUris Optional graph URI or array of graph URIs to query.
* @param subject A subject URI or null to match any subject.
* @param predicate A predicate URI or null to match any predicate.
* @param object An object URI or null to match any object.
* @todo Refactor and merge with the same method in the Mentor RDF Store class.
*/
*match(graph: rdfjs.Quad_Graph, subject: rdfjs.Quad_Subject | null, predicate: rdfjs.Quad_Predicate | null, object: rdfjs.Quad_Object | null) {
if (graph !== undefined) {
yield* this.store.match(subject, predicate, object, graph);
} else E{
yield* this.store.match(subject, predicate, object);
}
}
public expand(store: rdfjs.DatasetCore, sourceGraph: string | rdfjs.Quad_Graph, targetGraph?: string | rdfjs.Quad_Graph): rdfjs.DatasetCore {
Eif (!targetGraph) {
targetGraph = this.targetUriGenerator.getGraphUri(sourceGraph);
}
this.store = store;
this.sourceGraph = this.getGraphNode(sourceGraph);
this.targetGraph = this.getGraphNode(targetGraph);
// Ensure the target graph is empty so this function is idempotent and consistent.
for (let quad of store.match(null, null, null, this.targetGraph)) {
store.delete(quad);
}
this.beforeInference();
for (let quad of store.match(null, null, null, this.sourceGraph)) {
this.applyInference(quad)
}
this.afterInference();
this.resetState();
return store;
}
protected beforeInference() { }
protected afterInference() { }
protected resetState() { }
abstract applyInference(quad: rdfjs.Quad): void;
/**
* Indicate if a given resource should *not* be inferred to be a owl:NamedIndividual.
* @param id A resource URI or blank node identifier.
*/
protected abstract isClass(id: string): boolean;
} |