2

I'm trying to figure out a way of implementing a SWRL rule that would need to make use of an OR type statement. Here is the scenario: The ontology has a class "MachineTool" which has an object property of "hasProcess" and a number of classes of processes. We want to be able to get a list of individuals of MachineTool which has a hasProcess value of either "EndMilling" or "Drilling".

If 'or' statements were allowed the SWRL rule would look something like:

MachineTool(?mt) ^ hasProcess(?mt, ?p) ^ (EndMilling OR Drilling)(?p) -> MyMachineTools(?mt)

But that rule isn't legal. Does someone know of a rule (or set of rules) that can accomplish what we are looking for? I had thought one alternative could be (but haven't tested it, Protege is being weird at the moment):

EndMilling(?p) -> MyProcesses(?p)
Drilling(?p) -> MyProcesses(?p)
MachineTool(?mt) ^ hasProcess(?mt, ?p) ^ MyProcesses(?p) -> MyMachineTools(?mt)

I welcome all thoughts on this problem.

Christian
  • 63
  • 1
  • 7
  • Specify which version of Protege are you using. – Kaarel Jul 06 '11 at 18:22
  • I guess I should have clarified that part. Ultimately I need to create and run the rule programatically with the OWL API. Protege (both 3.x and 4.1) is used for playing around with more complex rules until I figure out what the rule should look like. – Christian Jul 06 '11 at 19:19
  • I've edited my answer a bit, maybe it's more helpful now. In general it is unclear which SWRL surface syntaxes are "official" and which tools support which syntaxes. I think your examples should or could work. So maybe file a bug report with the Protege and OWL-API developers. – Kaarel Jul 06 '11 at 22:25

1 Answers1

4

OR is legal in SWRL rules if expressed using OWL's ObjectUnionOf.

I think the problem is with the tool support for the SWRL surface syntax like featured in your code samples. Protege 3.x does not support this OR-construct syntactically (at least it didn't last time I checked), and while Protege 4.1 can render it, it fails to reparse it (just checked with rc5). But if you are using a recent OWL-API (v3.2.x) and are using syntaxes like XML or the functional-style syntax everything should work. (Note that Protege 3.x and 4.x use wildly different OWL APIs, I'd recommend you to work only with Protege 4.x and OWL-API 3.x.)

If you cannot get OR working in SWRL, then you could use a named class that is equivalent to the ObjectUnionOf, e.g.

EquivalentClasses(my-processes, ObjectUnionOf(end-milling, drilling))

machine-tool(?mt) ^ has-process(?mt, ?p) ^ my-processes(?p)
                                                        -> my-machine-tool(?mt)

Note that your work-around (2nd code sample) does not give a semantically equivalent statement, because you are only stating:

SubClassOf(end-milling, my-processes)
SubClassOf(drilling, my-processes)

which is the same as stating:

SubClassOf(ObjectUnionOf(end-milling, drilling), my-processes)

i.e. to state an equivalence, you need the other implication as well:

SubClassOf(my-processes, ObjectUnionOf(end-milling, drilling))

Note also that your rule can be easily expressed in OWL, i.e. you don't need SWRL at all for this rule:

SubClassOf(
   ObjectIntersectionOf(
      :machine-tool
      ObjectSomeValuesFrom(
         :has-process
         ObjectUnionOf(
            :end-milling
            :drilling
         )
      )
   )
   :my-machine-tool
)

Stating everything in OWL (if possible) has some benefits, e.g. you get better tool support (there are more OWL reasoners than SWRL reasoners), and you get more powerful reasoning (SWRL reasoners apply the rule only to known individuals).

Kaarel
  • 10,554
  • 4
  • 56
  • 78
  • I did manage to get my work-around to get the desired results. I'm still interested in your suggestion. Your comment about missing the SubClassOf implication, would that only happen when not using a reasoner (such as Pellet)? I've been using SWRL for a number of different queries on this and related programs and using a reasoner to get the results. I think the reasoner is pulling the SubClasses of the processes specified (at least it appears to do so). In your lower example, is it possible to get the instances of the "my-machine-tool" class without using a reasoner? – Christian Jul 06 '11 at 23:13
  • I don't really understand your questions, but I edited my answer a bit... If you managed to get something working then post an answer here (it's OK to answer your own question). Regarding "getting the instances": you always need some tool to do this "getting". Reasoner is a tool that fetches things in a semantically correct and complete way. So always use a reasoner (unless, of course, it takes it too long to compute things, which it often does...). – Kaarel Jul 07 '11 at 06:54