summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-02-07 22:53:58 +0100
committerDavid Robillard <d@drobilla.net>2017-02-07 22:53:58 +0100
commit99458ff38158e80b58663df5b6ff2e7a91a7fd0f (patch)
treeefd3052cfb51f76d4f331543f4b41ed9c33ab416
parentf5e6b2cded8fd778171213fbfecd4901cdf52e9f (diff)
downloadsord-99458ff38158e80b58663df5b6ff2e7a91a7fd0f.tar.gz
sord-99458ff38158e80b58663df5b6ff2e7a91a7fd0f.tar.bz2
sord-99458ff38158e80b58663df5b6ff2e7a91a7fd0f.zip
Fix functional properties with blank nodes
-rw-r--r--NEWS4
-rw-r--r--src/sord_validate.c34
2 files changed, 31 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 9a09e09..50e6051 100644
--- a/NEWS
+++ b/NEWS
@@ -3,8 +3,10 @@ sord (0.16.1) unstable;
* sord_validate: Fix restriction count reporting
* sord_validate: Use consistent error format
* sord_validate: Add support for maximum cardinality
+ * sord_validate: Only report functional / inverse functional property
+ errors if the subjects / objects are not blank
- -- David Robillard <d@drobilla.net> Tue, 07 Feb 2017 22:21:10 +0100
+ -- David Robillard <d@drobilla.net> Tue, 07 Feb 2017 22:52:31 +0100
sord (0.16.0) stable;
diff --git a/src/sord_validate.c b/src/sord_validate.c
index 8856d2f..e30bbc0 100644
--- a/src/sord_validate.c
+++ b/src/sord_validate.c
@@ -420,6 +420,19 @@ check_type(SordModel* model,
return false;
}
+static uint64_t
+count_non_blanks(SordIter* i, SordQuadIndex field)
+{
+ uint64_t n = 0;
+ for (; !sord_iter_end(i); sord_iter_next(i)) {
+ const SordNode* node = sord_iter_get_node(i, field);
+ if (sord_node_get_type(node) != SORD_BLANK) {
+ ++n;
+ }
+ }
+ return n;
+}
+
static int
check_properties(SordModel* model, URIs* uris)
{
@@ -474,14 +487,23 @@ check_properties(SordModel* model, URIs* uris)
st = errorf(quad, "Object property with literal value");
}
- if (is_FunctionalProperty &&
- sord_count(model, subj, pred, NULL, NULL) > 1) {
- st = errorf(quad, "Functional property with many objects");
+ if (is_FunctionalProperty) {
+ SordIter* o = sord_search(model, subj, pred, NULL, NULL);
+ const uint64_t n = count_non_blanks(o, SORD_OBJECT);
+ if (n > 1) {
+ st = errorf(quad, "Functional property with %u objects", n);
+ }
+ sord_iter_free(o);
}
- if (is_InverseFunctionalProperty &&
- sord_count(model, NULL, pred, obj, NULL) > 1) {
- st = errorf(quad, "Inverse functional property with many subjects");
+ if (is_InverseFunctionalProperty) {
+ SordIter* s = sord_search(model, NULL, pred, obj, NULL);
+ const unsigned n = count_non_blanks(s, SORD_SUBJECT);
+ if (n > 1) {
+ st = errorf(
+ quad, "Inverse functional property with %u subjects", n);
+ }
+ sord_iter_free(s);
}
if (sord_node_equals(pred, uris->rdf_type) &&