Skip to content

Commit

Permalink
Fixed problems with owl:equivalentClass handling
Browse files Browse the repository at this point in the history
* As there is no simple and right way to deal with the
  owl:equivalentClass and the way it's used in the ARCHE ontology makes
  it completely non-important, support for it was just dropped
* Similarly owl_equivalentProperty support was dropped but it was not
  even used in the ARCHE ontology
* Tests extended to the ARCHE production instance
  • Loading branch information
zozlak committed Oct 11, 2023
1 parent 2624b89 commit df2d9d7
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 46 deletions.
10 changes: 6 additions & 4 deletions src/acdhOeaw/arche/lib/schema/BaseDesc.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ class BaseDesc {
*
* @param object $d
* @param array<string> $ids
* @param string $nmsp
* @param ?string $nmsp
* @param ?string $skipNmsp
*/
public function __construct(object $d = null, array $ids = [],
string $nmsp = null) {
$nmspL = strlen((string) $nmsp);
?string $nmsp = null, ?string $skipNmsp = null) {
foreach ($ids as $i) {
if ($nmspL > 0 && substr($i, 0, $nmspL) === $nmsp) {
if (str_starts_with($i, $nmsp)) {
$this->uri = $i;
break;
} elseif (empty($this->uri) && !str_starts_with($i, $skipNmsp)) {
$this->uri = $i;
}
}
if (empty($this->uri)) {
Expand Down
74 changes: 36 additions & 38 deletions src/acdhOeaw/arche/lib/schema/Ontology.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,22 +448,22 @@ private function checkVocabularyValueRest(string $vocabularyUrl,

private function loadClassesDb(): void {
$query = "
WITH RECURSIVE t(pid, id, n) AS (
SELECT DISTINCT id, id, 0
WITH RECURSIVE t(pid, id) AS (
SELECT DISTINCT id, id
FROM
identifiers
JOIN metadata USING (id)
WHERE
property = ?
AND substring(value, 1, 1000) = ?
UNION
SELECT r.target_id, t.id, t.n + 1
SELECT r.target_id, t.id
FROM
relations r
JOIN t ON t.pid = r.id AND (property = ? OR property = ?)
JOIN t ON t.pid = r.id AND property = ?
),
tt AS (
SELECT id, json_agg(pid ORDER BY n DESC) AS pids
SELECT id, jsonb_agg(pid ORDER BY pid) AS pids
FROM t
GROUP BY 1
)
Expand Down Expand Up @@ -495,7 +495,7 @@ private function loadClassesDb(): void {
";
$param = [
RDF::RDF_TYPE, RDF::OWL_CLASS, // with non-recursive
RDF::RDFS_SUB_CLASS_OF, RDF::OWL_EQUIVALENT_CLASS, // with recursive
RDF::RDFS_SUB_CLASS_OF, // with recursive
RDF::SKOS_ALT_LABEL, RDF::RDFS_COMMENT, // c3 (label), c4 (comment)
];
//exit("\n".(new \zozlak\queryPart\QueryPart($query, $param))."\n");
Expand Down Expand Up @@ -533,22 +533,22 @@ private function loadPropertiesDb(): void {
$anPropSql = substr(str_repeat('?, ', count($anPropParam)), 0, -2);

$query = "
WITH RECURSIVE t(pid, id, type, n) AS (
SELECT DISTINCT id, id, value, 0
WITH RECURSIVE t(pid, id, type) AS (
SELECT DISTINCT id, id, value
FROM
identifiers
JOIN metadata USING (id)
WHERE
property = ?
AND substring(value, 1, 1000) IN (?, ?)
UNION
SELECT r.target_id, t.id, t.type, t.n + 1
SELECT r.target_id, t.id, t.type
FROM
relations r
JOIN t ON t.pid = r.id AND (property = ? OR property = ?) AND n < 30
JOIN t ON t.pid = r.id AND property = ?
),
tt AS (
SELECT id, type, json_agg(pid ORDER BY n DESC) AS pids
SELECT id, type, jsonb_agg(pid ORDER BY pid) AS pids
FROM t
GROUP BY 1, 2
)
Expand All @@ -561,17 +561,17 @@ private function loadPropertiesDb(): void {
GROUP BY 1
) c1 USING (id)
JOIN (
SELECT t.id, json_agg(ids ORDER BY n DESC, ids) AS properties
SELECT t.id, jsonb_agg(ids ORDER BY ids) AS properties
FROM t JOIN identifiers i ON t.pid = i.id
GROUP BY 1
) c2 USING (id)
LEFT JOIN (
SELECT r.id, json_agg(ids) AS range
SELECT r.id, jsonb_agg(ids) AS range
FROM relations r JOIN identifiers i ON r.target_id = i.id AND r.property = ?
GROUP BY 1
) c3 USING (id)
LEFT JOIN (
SELECT r.id, json_agg(ids) AS domain
SELECT r.id, jsonb_agg(ids) AS domain
FROM relations r JOIN identifiers i ON r.target_id = i.id AND r.property = ?
GROUP BY 1
) c4 USING (id)
Expand Down Expand Up @@ -603,7 +603,7 @@ private function loadPropertiesDb(): void {
";
$param = [
RDF::RDF_TYPE, RDF::OWL_DATATYPE_PROPERTY, RDF::OWL_OBJECT_PROPERTY, // with non-recursive term
RDF::RDFS_SUB_PROPERTY_OF, RDF::OWL_EQUIVALENT_PROPERTY, // with recursive term
RDF::RDFS_SUB_PROPERTY_OF, // with recursive term
RDF::RDFS_RANGE, RDF::RDFS_DOMAIN, // c3, c4
RDF::SKOS_ALT_LABEL, RDF::RDFS_COMMENT, // c5, c6
];
Expand Down Expand Up @@ -660,26 +660,24 @@ private function loadRest(): void {
$baseUrl = $this->repo->getBaseUrl();
$baseUrlL = strlen($baseUrl);
$mapping = [
RDF::SKOS_ALT_LABEL => 'label',
RDF::RDFS_COMMENT => 'comment',
RDF::OWL_EQUIVALENT_CLASS => 'ids',
RDF::RDFS_SUB_CLASS_OF => 'parent',
RDF::OWL_EQUIVALENT_PROPERTY => 'ids',
RDF::RDFS_SUB_PROPERTY_OF => 'parent',
RDF::RDFS_RANGE => 'range',
RDF::RDFS_DOMAIN => 'domain',
RDF::OWL_ON_PROPERTY => 'onProperty',
RDF::OWL_CARDINALITY => 'cardinality',
RDF::OWL_MIN_CARDINALITY => 'min',
RDF::OWL_MAX_CARDINALITY => 'max',
$idPred => 'ids',
RDF::RDF_TYPE => 'type',
$nmsp . 'automatedFill' => 'automatedFill',
$nmsp . 'defaultValue' => 'defaultValue',
$nmsp . 'langTag' => 'langTag',
$nmsp . 'ordering' => 'ordering',
$nmsp . 'recommendedClass' => 'recommendedClass',
$nmsp . 'vocabs' => 'vocabs',
RDF::SKOS_ALT_LABEL => 'label',
RDF::RDFS_COMMENT => 'comment',
RDF::RDFS_SUB_CLASS_OF => 'parent',
RDF::RDFS_SUB_PROPERTY_OF => 'parent',
RDF::RDFS_RANGE => 'range',
RDF::RDFS_DOMAIN => 'domain',
RDF::OWL_ON_PROPERTY => 'onProperty',
RDF::OWL_CARDINALITY => 'cardinality',
RDF::OWL_MIN_CARDINALITY => 'min',
RDF::OWL_MAX_CARDINALITY => 'max',
$idPred => 'ids',
RDF::RDF_TYPE => 'type',
$nmsp . 'automatedFill' => 'automatedFill',
$nmsp . 'defaultValue' => 'defaultValue',
$nmsp . 'langTag' => 'langTag',
$nmsp . 'ordering' => 'ordering',
$nmsp . 'recommendedClass' => 'recommendedClass',
$nmsp . 'vocabs' => 'vocabs',
];
$term = new SearchTerm(
RDF::RDF_TYPE,
Expand Down Expand Up @@ -725,7 +723,7 @@ private function loadRest(): void {
}
$loaded->attach($obj);
match ($obj->type ?? null) {
RDF::OWL_CLASS => $this->loadClassRest($obj, $nmsp),
RDF::OWL_CLASS => $this->loadClassRest($obj, $nmsp, $baseUrl),
RDF::OWL_DATATYPE_PROPERTY, RDF::OWL_OBJECT_PROPERTY => $this->loadPropertyRest($obj, $nmsp),
RDF::OWL_RESTRICTION => $this->loadRestrictionRest($obj, $nmsp),
default => null
Expand All @@ -734,10 +732,10 @@ private function loadRest(): void {
$this->buildClassesRevIndex();
}

private function loadClassRest(object $data, string $nmsp): void {
private function loadClassRest(object $data, string $nmsp, string $baseUrl): void {
$data->class = $data->ids;
$data->classes = $data->ids;
$class = new ClassDesc($data, $data->ids, $nmsp);
$class = new ClassDesc($data, $data->ids, $nmsp, $baseUrl);
$visited = new SplObjectStorage();
$visited->attach($data);
$this->resolveParents($class, 'classes', $data->parent ?? [], $visited);
Expand Down
32 changes: 28 additions & 4 deletions tests/OntologyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ public function tearDown(): void {
*/
private function getOntologies(): array {
return [
'db' => Ontology::factoryDb(self::$pdo, self::$schema),
'rest' => Ontology::factoryRest('http://127.0.0.1/api'),
'db' => Ontology::factoryDb(self::$pdo, self::$schema),
'rest' => Ontology::factoryRest('http://127.0.0.1/api'),
'arche' => Ontology::factoryRest('https://arche.acdh.oeaw.ac.at/api'),
];
}

Expand Down Expand Up @@ -125,11 +126,34 @@ public function testClassInheritance(): void {
}

public function testClassGetProperties(): void {
$n1 = $n2 = $n3 = null;
foreach ($this->getOntologies() as $k => $o) {
$c = $o->getClass('https://vocabs.acdh.oeaw.ac.at/schema#Collection');
$p = $c->getProperties();
$c = $o->getClass('https://vocabs.acdh.oeaw.ac.at/schema#Collection');
$p = $c->getProperties();
$n1 ??= count($p);
$this->assertGreaterThan(0, count($p), $k);
$this->assertEquals($n1, count($p), $k);
$this->assertEquals(count(array_unique(array_map('spl_object_id', $p))), count($p), $k);
$this->assertEquals(count(array_unique(array_map('spl_object_id', $c->properties))), count($p), $k);

// https://vocabs.acdh.oeaw.ac.at/schema#Project and http://xmlns.com/foaf/0.1/Project are owl:equivalentClass
// which caused a lot of trouble in the past
$c = $o->getClass('https://vocabs.acdh.oeaw.ac.at/schema#Project');
$p = $c->getProperties();
$n2 ??= count($p);
$this->assertGreaterThan(0, count($p), $k);
$this->assertEquals($n2, count($p), $k);
$this->assertEquals(count(array_unique(array_map('spl_object_id', $p))), count($p), $k);
$this->assertEquals(count(array_unique(array_map('spl_object_id', $c->properties))), count($p), $k);

$c2 = $o->getClass('http://xmlns.com/foaf/0.1/Project');
$this->assertEmpty(array_intersect($c->class, $c2->class));
$p = $c2->getProperties();
$n3 ??= count($p);
$this->assertGreaterThan(0, count($p), $k);
$this->assertEquals($n3, count($p), $k);
$this->assertEquals(count(array_unique(array_map('spl_object_id', $p))), count($p), $k);
$this->assertEquals(count(array_unique(array_map('spl_object_id', $c2->properties))), count($p), $k);
}
}

Expand Down

0 comments on commit df2d9d7

Please sign in to comment.