Ari Wijayanti
Ari Wijayanti

Reputation: 89

How to CONSTRUCT new triples combining two TRANSITIVE CLOSURE in SPARQL?

I have an RDF file with several relations on it. Some of relations have transitive closure. I posted a question before about how to construct a property's transitive closure in Sparql in this link . Now I am able to construct new triples with property's transitive closure which means extracted all over the path. For example, there is a part_of relation, if ?a is part_of ?b , and ?b is part_of ?c, so we can infer that a is part_of ?c. Then I made my query like this:

construct {?a :part_of ?b} where {?a :part_of+ ?b . filter(?a != ?b) }

Then I have another transitive closure. For example, there is an is_a relation, if ?a is_a ?b , and ?b is_a ?c, so we can infer that ?a is_a ?c. Then I made my query like this:

construct {?a :is_a ?b} where {?a :is_a+ ?b . filter(?a != ?b)}

And then I have another condition which is including these two transitive closure: For example, if ?a part_of ?b , and ?b is_a ?c, so we can infer that ?a part_of ?c. Then could I make my query like this?

construct {?a :part_of ?c}
where {
      ?a :part_of+ ?b . 
      ?b :is_a+ ?c .
      filter(?a != ?c)
}

Upvotes: 2

Views: 485

Answers (1)

Joshua Taylor
Joshua Taylor

Reputation: 85883

And then I have another condition which is including these two transitive closure: For example, if ?a part_of ?b , and ?b is_a ?c, so we can infer that ?a part_of ?c. Then could I make my query like this?

To write that alone, it's simply:

construct { ?a :part_of ?c }
where {
  ?a :part_of ?b .
  ?b :is_a ?c
}

(I'm not sure whether that actually makes sense, though. After all, ?c is a type, not an instance. My finger is a part of me, and I am a human, but my finger is not a part of human, even though fingers can be parts of things that are humans.)

Since you don't use ?b in the construct part, you can even turn this into a property path:

construct { ?a :part_of ?c }
where { ?a :part_of/:is_a ?c }

But, none of this handles the transitive part of the problem. Let's look at that. You're saying that whenever you can follow a chain of :part_of, there should be a :part_of link, and whenever there's a :part_of followed by a :is_a, there should be a :part_of link. You can combine those with:

construct { ?a :part_of ?c }
where { ?a (:part_of+/:is_a?)+ ?c }

The path (:part_of+/:is_a?)+ means:

  • (1) one or more occurrences of:
    • (2) one or more occurrences of :part_of
    • (3) optionally followed by
    • (4) zero or one occurrences of :is_a

If you look at each place where you want to infer a :part_of relationship, you'll see that this pattern matches.

Upvotes: 1

Related Questions