OWL Ontology: Represent increasing number, like first, second, third - ontology

I have a question about an OWL ontology that I am making. I have a class that is actually an ID class and I would like to have instances: first, second, third etc.
The first solution that I have figured is creating individuals {first, second, third etc} for this class, but then I have to write a huge number of individuals.
The other solution is to create a data property that will be connected with my class that has type "integer".
The second solution looks more appropriate but the thing is that I can't represent the word "first", just the number 1.
Do you know how I can do that?

You could create a class of ordinals that are uniquely identified by an integer, like so (in Turtle syntax):
:hasPosition a owl:DatatypeProperty, owl:FunctionalProperty ;
rdfs:range xsd:integer .
:Ordinal a owl:Class ;
rdfs:subClassOf [
a owl:Restriction ;
owl:onProperty :hasPosition ;
owl:someValuesFrom :integer
] ;
owl:hasKey ( :hasPosition ) .
Note the use of owl:hasKey (introduced in OWL 2) which means that the value of :hasPosition identifies a unique instance. The property is functional so that an instance cannot have two distinct positions.

Related

OWL Infer Class Restrictions on Instances

I have an ontology where instance types are described with class restrictions. My goal is to use a reasoner to generate all other class restrictions which are valid for an instance. Consider this toy ontology example below:
#Class Hierarchy
:Highest_Class rdf:type owl:Class .
:Lower_Class rdf:type owl:Class ;
rdfs:subClassOf :Highest_Class .
:Lowest_Class rdf:type owl:Class ;
rdfs:subClassOf :Lower_Class .
#The class of named individuals
:ThingClass rdf:type owl:Class .
#Object property relationship
:related_to rdf:type owl:ObjectProperty ,
owl:TransitiveProperty .
#Instances in ontology
:thing_1 rdf:type owl:NamedIndividual ,
:ThingClass ,
[ rdf:type owl:Restriction ;
owl:onProperty :related_to ;
owl:someValuesFrom :Lowest_Class
] .
:thing_2 rdf:type owl:NamedIndividual ,
:ThingClass ,
[ rdf:type owl:Restriction ;
owl:onProperty :related_to ;
owl:someValuesFrom :Lower_Class
] .
This is what I would expect the reasoner to infer:
Since thing_1 is something that is related_to some Lowest_Class, and Lowest_Class is a subclass of Lower_Class and Highest_Class, then thing_1 is something that is related_to some Lower_Class and is related_to some Highest_Class.
Since thing_2 is something that is related_to some Lower_Class, and Lower_Class is a subclass of Highest_Class , then thing_2 is something that is "related_to some Highest_Class".
If I run a reasoner in Protege on this ontology and use the DL query tab to find individuals which are related_to some Highest_Class or related_to some Lower_Class, I see thing_1 and thing_2 listed, as expected. However, when I try to run a reasoner using the ROBOT tool or ELK command line tool, these class restriction axioms do not appear in the reasoned ontology.
Is there a way to produce such axioms into a reasoned ontology after running inference or is this not possible? Also, an explanation on how DL query is able to correctly associate individuals with the class restriction query would be very helpful.

Validating unique names for strings and optional reference

New to XText, I am struggling with two issues with the following MWE grammar.
Metamodel:
(classes += Type)*
;
Type:
Enumeration | Class
;
Enumeration:
'enumeration' name = ValidID '{' (literals += EnumLiteral ';')+ '}'
;
EnumLiteral:
ValidID
;
Class:
'class' name = ValidID '{'
(references += Reference)*
'}'
;
Reference:
'reference' name = ValidID ':' type = Class ('#' opposite = [Reference])?
;
So my questions are:
Since the enumeration literals list is ValidID, it seems to be represented by EStrings. The documentation does not seem to deal with the case of primitive types in ECore. How is it possible to check for non-duplicates in literals, and report it adequately in the editor (i.e., the error should be at the first occurence of a repeated literal)?
Despite my best efforts, I was unable to write a custom scope for the opposite reference. Since XText uses reflection for retrieving the scoping methods, I suspect I don't have the correct one: I tried def scope_Reference_opposite(Reference context, EReference r), is it correct? An example would be really appreciated, from which I am confident I can easily adapt to my "real" DSL.
Thanks a lot for the help, you will save me a lot of time looking again and again for a solution in documentation...
Errors can be attached to a certain index of a many-values feature. Write a validation for the type Enumeration and check the the list of literals for duplicates. Attach the error to the index in the list.
The signature is correct. Did you import the correct 'Reference' or did you use some other class with the same simple name by accident. Also please not that your grammar appears to be wrong for the type of the reference. This should be type=[Class] or more likely type=[Class|ValidID].
If you plan to use or do already use Xbase, things may look different. Xbase doesn't use the reflective scope provider.

Does anyone have an efficient R3 function that mimics the behaviour of find/any in R2?

Rebol2 has an /ANY refinement on the FIND function that can do wildcard searches:
>> find/any "here is a string" "s?r"
== "string"
I use this extensively in tight loops that need to perform well. But the refinement was removed in Rebol3.
What's the most efficient way of doing this in Rebol3? (I'm guessing a parse solution of some sort.)
Here's a stab at handling the "*" case:
like: funct [
series [series!]
search [series!]
][
rule: copy []
remove-each s b: parse/all search "*" [empty? s]
foreach s b [
append rule reduce ['to s]
]
append rule [to end]
all [
parse series rule
find series first b
]
]
used as follows:
>> like "abcde" "b*d"
== "bcde"
I had edited your question for "clarity" and changed it to say 'was removed'. That made it sound like it was a deliberate decision. Yet it actually turns out it may just not have been implemented.
BUT if anyone asks me, I don't think it should be in the box...and not just because it's a lousy use of the word "ALL". Here's why:
You're looking for patterns in strings...so if you're constrained to using a string to specify that pattern you get into "meta" problems. Let's say I want to extract the word *Rebol* or ?Red?, now there has to be escaping and things get ugly all over again. Back to RegEx. :-/
So what you might actually want isn't a STRING! pattern like s?r but a BLOCK! pattern like ["s" ? "r"]. This would permit constructs like ["?" ? "?"] or [{?} ? {?}]. That's better than rehashing the string hackery that every other language uses.
And that's what PARSE does, albeit in a slightly-less-declarative way. It also uses words instead of symbols, as Rebol likes to do. [{?} skip {?}] is a match rule where skip is an instruction that moves the parse position past any single element of the parse series between the question marks. It could also do so if it were parsing a block as input, and would match [{?} 12-Dec-2012 {?}].
I don't know entirely what the behavior of /ALL would-or-should be with something like "ab??cd e?*f"... if it provided alternate pattern logic or what. I'm assuming the Rebol2 implementation is brief? So likely it only matches one pattern.
To set a baseline, here's a possibly-lame PARSE solution for the s?r intent:
>> parse "here is a string" [
some [ ; match rule repeatedly
to "s" ; advance to *before* "s"
pos: ; save position as potential match
skip ; now skip the "s"
[ ; [sub-rule]
skip ; ignore any single character (the "?")
"r" ; match the "r", and if we do...
return pos ; return the position we saved
| ; | (otherwise)
none ; no-op, keep trying to match
]
]
fail ; have PARSE return NONE
]
== "string"
If you wanted it to be s*r you would change the skip "r" return pos into a to "r" return pos.
On an efficiency note, I'll mention that it is indeed the case that characters are matched against characters faster than strings. So to #"s" and #"r" to end make a measurable difference in the speed when parsing strings in general. Beyond that, I'm sure others can do better.
The rule is certainly longer than "s?r". But it's not that long when comments are taken out:
[some [to #"s" pos: skip [skip #"r" return pos | none]] fail]
(Note: It does leak pos: as written. Is there a USE in PARSE, implemented or planned?)
Yet a nice thing about it is that it offers hook points at all the moments of decision, and without the escaping defects a naive string solution has. (I'm tempted to give my usual "Bad LEGO alligator vs. Good LEGO alligator" speech.)
But if you don't want to code in PARSE directly, it seems the real answer would be some kind of "Glob Expression"-to-PARSE compiler. It might be the best interpretation of glob Rebol would have, because you could do a one-off:
>> parse "here is a string" glob "s?r"
== "string"
Or if you are going to be doing the match often, cache the compiled expression. Also, let's imagine our block form uses words for literacy:
s?r-rule: glob ["s" one "r"]
pos-1: parse "here is a string" s?r-rule
pos-2: parse "reuse compiled RegEx string" s?r-rule
It might be interesting to see such a compiler for regex as well. These also might accept not only string input but also block input, so that both "s.r" and ["s" . "r"] were legal...and if you used the block form you wouldn't need escaping and could write ["." . "."] to match ".A."
Fairly interesting things would be possible. Given that in RegEx:
(abc|def)=\g{1}
matches abc=abc or def=def
but not abc=def or def=abc
Rebol could be modified to take either the string form or compile into a PARSE rule with a form like:
regex [("abc" | "def") "=" (1)]
Then you get a dialect variation that doesn't need escaping. Designing and writing such compilers is left as an exercise for the reader. :-)
I've broken this into two functions: one that creates a rule to match the given search value, and the other to perform the search. Separating the two allows you to reuse the same generated parse block where one search value is applied over multiple iterations:
expand-wildcards: use [literal][
literal: complement charset "*?"
func [
{Creates a PARSE rule matching VALUE expanding * (any characters) and ? (any one character)}
value [any-string!] "Value to expand"
/local part
][
collect [
parse value [
; empty search string FAIL
end (keep [return (none)])
|
; only wildcard return HEAD
some #"*" end (keep [to end])
|
; everything else...
some [
; single char matches
#"?" (keep 'skip)
|
; textual match
copy part some literal (keep part)
|
; indicates the use of THRU for the next string
some #"*"
; but first we're going to match single chars
any [#"?" (keep 'skip)]
; it's optional in case there's a "*?*" sequence
; in which case, we're going to ignore the first "*"
opt [
copy part some literal (
keep 'thru keep part
)
]
]
]
]
]
]
like: func [
{Finds a value in a series and returns the series at the start of it.}
series [any-string!] "Series to search"
value [any-string! block!] "Value to find"
/local skips result
][
; shortens the search a little where the search starts with a regular char
skips: switch/default first value [
#[none] #"*" #"?" ['skip]
][
reduce ['skip 'to first value]
]
any [
block? value
value: expand-wildcards value
]
parse series [
some [
; we have our match
result: value
; and return it
return (result)
|
; step through the string until we get a match
skips
]
; at the end of the string, no matches
fail
]
]
Splitting the function also gives you a base to optimize the two different concerns: finding the start and matching the value.
I went with PARSE as even though *? are seemingly simple rules, there is nothing quite as expressive and quick as PARSE to effectively implementing such a search.
It might yet as per #HostileFork to consider a dialect instead of strings with wildcards—indeed to the point where Regex is replaced by a compile-to-parse dialect, but is perhaps beyond the scope of the question.

how to relate an individual with a combination of individuals?

I have an ontology that contains plants and diseases and a property treat (a plant treats diseases). I have a lot of plants and diseases, but now I want to add a disease that is treatable by a combination of two or more plants. For instance, how can I represent the following sentence?
Disease X is treatable by the combination of plant A and plant B, but not by plant A or plant B alone.
I've been thinking to obtain this using a reasoner, but I have no idea how.
It sounds like you have, at the moment, an ontology with a classes Disease and Plant, and a property treats with domain Plant and range Disease. As I understand it, the problem is that what should treat some Diseases are not individual Plants, but rather combinations of them. In these cases, we might say that a plant is used in the treatment of a disease, but does not, itself, treat the disease. It is probably reasonable to say, too, that if a plant, by itself, treats a disease, then it also is used in the treatment of a disease.
So, you have a class of individuals that you haven't considered before, that is combinations of plants, so why not introduce a class PlantCombination and a property hasComponent that relates PlantCombinations to the plants in the combination? You can also add a restriction that says that each plant combination has at least two plants, if you like, by saying PlantCombination SubClassOf hasComponent min 2 Plant. Since both Plants and PlantCombinations can treat Diseases, you'll want to change the domain of treats to be Plant or PlantCombination. To ensure that a reasoner can infer that if plant82 treats disease92 then plant82 isUsedToTreat disease92, you can assert that treats SubPropertyOf isUsedToTreat. (This will also mean that a plant combination that treats a disease is also used to treat that disease.) To ensure that when a combination with a component plant23 treats a disease, that plant23 is used to treat the disease, you can add the assertion that inverse(hasComponent) o treats SubPropertyOf isUsedToTreat. Here's an ontology that does just that:
N3 Format
#prefix : <http://www.example.org/plantsAndDiseases#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<http://www.example.org/plantsAndDiseases>
a owl:Ontology .
:Plant
a owl:Class .
:Disease
a owl:Class .
:PlantCombination
a owl:Class ;
rdfs:subClassOf
[ a owl:Restriction ;
owl:minQualifiedCardinality
"2"^^xsd:nonNegativeInteger ;
owl:onClass :Plant ;
owl:onProperty :hasComponent
] .
:hasComponent
a owl:ObjectProperty ;
rdfs:domain :PlantCombination ;
rdfs:range :Plant .
:isUsedToTreat
a owl:ObjectProperty ;
rdfs:comment "X isUsedToTreat Y means that X is used in the treatment of Y. X may either treat Y, or may be a component of a combination that treats Y." ;
rdfs:domain
[ a owl:Class ;
owl:unionOf (:Plant :PlantCombination)
] ;
rdfs:range :Disease ;
owl:propertyChainAxiom
([ owl:inverseOf :hasComponent
] :treats) .
:treats
a owl:ObjectProperty ;
rdfs:comment "X treats Y means that X is a sufficient treatment for Y." ;
rdfs:domain
[ a owl:Class ;
owl:unionOf (:Plant :PlantCombination)
] ;
rdfs:range :Disease ;
rdfs:subPropertyOf :isUsedToTreat .
OWL Functional Syntax
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(xml:=<http://www.w3.org/XML/1998/namespace>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Ontology(<http://www.example.org/plantsAndDiseases>
Declaration(Class(<http://www.example.org/plantsAndDiseases#Disease>))
Declaration(Class(<http://www.example.org/plantsAndDiseases#Plant>))
Declaration(Class(<http://www.example.org/plantsAndDiseases#PlantCombination>))
SubClassOf(<http://www.example.org/plantsAndDiseases#PlantCombination> ObjectMinCardinality(2 <http://www.example.org/plantsAndDiseases#hasComponent> <http://www.example.org/plantsAndDiseases#Plant>))
Declaration(ObjectProperty(<http://www.example.org/plantsAndDiseases#hasComponent>))
ObjectPropertyDomain(<http://www.example.org/plantsAndDiseases#hasComponent> <http://www.example.org/plantsAndDiseases#PlantCombination>)
ObjectPropertyRange(<http://www.example.org/plantsAndDiseases#hasComponent> <http://www.example.org/plantsAndDiseases#Plant>)
Declaration(ObjectProperty(<http://www.example.org/plantsAndDiseases#isUsedToTreat>))
AnnotationAssertion(rdfs:comment <http://www.example.org/plantsAndDiseases#isUsedToTreat> "X isUsedToTreat Y means that X is used in the treatment of Y. X may either treat Y, or may be a component of a combination that treats Y.")
ObjectPropertyDomain(<http://www.example.org/plantsAndDiseases#isUsedToTreat> ObjectUnionOf(<http://www.example.org/plantsAndDiseases#PlantCombination> <http://www.example.org/plantsAndDiseases#Plant>))
ObjectPropertyRange(<http://www.example.org/plantsAndDiseases#isUsedToTreat> <http://www.example.org/plantsAndDiseases#Disease>)
Declaration(ObjectProperty(<http://www.example.org/plantsAndDiseases#treats>))
AnnotationAssertion(rdfs:comment <http://www.example.org/plantsAndDiseases#treats> "X treats Y means that X is a sufficient treatment for Y.")
SubObjectPropertyOf(<http://www.example.org/plantsAndDiseases#treats> <http://www.example.org/plantsAndDiseases#isUsedToTreat>)
ObjectPropertyDomain(<http://www.example.org/plantsAndDiseases#treats> ObjectUnionOf(<http://www.example.org/plantsAndDiseases#PlantCombination> <http://www.example.org/plantsAndDiseases#Plant>))
ObjectPropertyRange(<http://www.example.org/plantsAndDiseases#treats> <http://www.example.org/plantsAndDiseases#Disease>)
SubObjectPropertyOf(ObjectPropertyChain(ObjectInverseOf(<http://www.example.org/plantsAndDiseases#hasComponent>) <http://www.example.org/plantsAndDiseases#treats>) <http://www.example.org/plantsAndDiseases#isUsedToTreat>)
)
Alternative to Joshua's answer: You can represent diseases and plants as OWL classes, as here you refer to sets of plants (not particular instances, which you would find in the nature). You can then link classes with existential restrictions (some - common pattern in biology).
You need also to introduce a supplementary step in your modelling, as mentioned: Plants can be for example ingredients of treatments, diseases being treatable by treatments.
Then if you consider the following commented (#) ontology (Manchester syntax), I describe the axioms for the modelling. You can save the file and open it with Protege.
Prefix: xsd: <http://www.w3.org/2001/XMLSchema#>
Prefix: owl: <http://www.w3.org/2002/07/owl#>
Prefix: : <http://www.example.org/demo.owl#>
Prefix: xml: <http://www.w3.org/XML/1998/namespace>
Prefix: rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
Prefix: rdfs: <http://www.w3.org/2000/01/rdf-schema#>
Ontology: <http://www.example.org/demo.owl>
ObjectProperty: has-ingredient
ObjectProperty: treatableBy
Class: owl:Thing
Class: PlantA
SubClassOf:
Plant
Class: Treatment
#Your treatment obtained by mixing some
#of the plant B and some of the plant A
Class: TreatmentAB
SubClassOf:
Treatment,
(has-ingredient some PlantA)
and (has-ingredient some PlantB)
Class: PlantB
SubClassOf:
Plant
#This treatment has ingredient the plant A
Class: TreatmentA
SubClassOf:
has-ingredient some PlantA,
Treatment
#This treatment is made from plant B (among other things)
Class: TreatmentB
SubClassOf:
Treatment,
has-ingredient some PlantB
Class: Disease
Class: Plant
# This disease is treatable by the TreatmentAB
Class: DiseaseA
SubClassOf:
treatableBy some TreatmentAB,
Disease
Class: DiseaseB
SubClassOf:
treatableBy some TreatmentB,
Disease
Now if we were reasoning over the ontology and ask for the subclasses of treatableBy some TreatmentA we wouldn't get any class. The expression treatableBy some TreatmentAB returns DiseaseA as expected.

Jena Custom Rules using Built-ins

I am currently messing around with Jena trying to create rules to add to my generic reasoner. I created the following simple rule:
[rule1: (?x ?rdf:type ?y),(?y rdfs:subClassOf ?z)-> (?x rdfs:type ?z)]
This works fine, and fires correctly, giving me everything I expect. After I did this I wanted to assign a timestamp to ?x, so that I'd know when the conclusion was come to, I wanted to used the Now builtin as follows.
[rule1: (?x ?rdf:type ?y),(?y rdfs:subClassOf ?z),now(?x)-> (?x rdfs:type ?z)]
This unfortunately does not work, it does nor throw an error, it just does not seem to bind any time value to ?x and also it seems to prevent the rule from being fired correctly as in the first case. The ontology I am using is below. Any ideas?
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#">
<owl:Class rdf:about="livingthing"></owl:Class>
<owl:Class rdf:about="Human">
<rdfs:subClassOf rdf:resource="livingthing"/>
</owl:Class>
<rdf:Description rdf:about="john">
<rdf:type rdf:resource="Human"/>
</rdf:Description>
</rdf:RDF>
According to the javadoc, Now will “Bind the first arg to the current date time in the current locale and timezone.” I haven't tried using Now, but I'd expect that "the current date time in the current locale and timezone" is a some sort of RDF literal (perhaps a date or datetime)? Literals cannot be the subjects of triples in RDF. For the rule
[rule1: (?x ?rdf:type ?y),(?y rdfs:subClassOf ?z),now(?x) -> (?x rdfs:type ?z)]
to match in the graph, the variable ?x will be bound to the date literal, say, "2013-05-24" (but as I mentioned, I don't know exactly what Now will produce) but there cannot be any matches for (?x rdf:type ?y) because these would have the form "2013-05-24" rdf:type ?y and there cannot be triples of that form. This means that the rule cannot fire.
If you want to add a timestamp to something, you probably want an n-ary relation, so that you're actually representing (or representing, in addition to ?x rdf:type ?z) a relation inferredSubclassRule(?super,?sub,?time ), which can be represented in RDF by a blank node like:
[] a :inferredSubclassRule ;
:hasSuperClass ?super ;
:hasSubClass ?sub ;
:hasTimestamp ?time .

Resources