Protege min cardinality not adding member to defined class - owl

I'm new to Protege and ontology.
I have a defined class UniqueScreening that is
equivalent to -> FilmScreening and (hasTrack min 2 Track)
then i create some members of Track that is tr001 and tr002
and then I create a member of FilmScreening which is fs001 that has Types
Film Screening
hasTrack some {tr001}
hasTrack some {tr002}
and the hasTrack object property has domain Track
my question is, why fs001 member is not inferred to UniqueScreening class?
does my class definition wrong?

As commented by Ignazio:
Declare tr001 and tr002 to be different individuals. By default they could be the same individual, so the cardinality would not be matched.

Related

Inverse property with range restriction

In Protege, I have defined a class :Person, and an object property :likes (with domain :Person and range :Person).
I have defined an inverse property of :likes called :isLikedBy.
Then I define an additional class :Rich.
I wish I could define a property :likesBackForBadReasons in this way: an equivalent property (or is it a subproperty?) of :isLikedBy, but only when the range of that relationship is an instance of :Rich.
So my inference engines infers that any :Rich :Person "A" who :likes a :Person "B", then this "B" :likesBackForBadReasons "A".
How to define that :likesBackForBadReasons object property in Protege?
TL;TDR: This specific requirement can only be dealt with using rules and not by typical Description Logic (DL) inferences. You can use either of the following rules:
Person(?x) ^ PersonThatIsNotRich(?x) ^ RichPerson(?y) ^ likes(?y, ?x) ^ likes(?x, ?y) -> BadPerson(?x)
Person(?x) ^ PersonThatIsNotRich(?x) ^ RichPerson(?y) ^ likes(?y, ?x) ^ likes(?x, ?y) -> likesForBadReason(?x, ?y)
where PersonThatIsNotRich is disjoint with RichPerson. These rules also ensure that a rich person liking another rich person will not be considered a bad person.
How to use SWRL to do this inference:
The ontology using this rule in Manchester syntax is as follows:
ObjectProperty: isLikedBy
InverseOf: likes
ObjectProperty: likes
InverseOf: isLikedBy
ObjectProperty: likesForBadReason
SubPropertyOf: likes
Class: BadPerson
SubClassOf: Person
Class: Person
Class: PersonThatIsNotRich
SubClassOf: Person
DisjointWith: RichPerson
Class: RichPerson
SubClassOf: Person
DisjointWith: PersonThatIsNotRich
Individual: badPerson
Types: Person
Facts: likes richPerson
Individual: otherBadPerson
Types: Person
Facts: likes otherRichPerson
Individual: otherRichPerson
Types: RichPerson
Facts: likes badPerson, likes richPerson
Individual: richPerson
Types: RichPerson
Facts: likes badPerson, likes otherRichPerson
Rule:
Person(?x), PersonThatIsNotRich(?x), RichPerson(?y), likes(?y, ?x), likes(?x, ?y) - BadPerson(?x)
Notes:
You will note that badPerson is inferred to be a BadPerson while otherBadPerson is not inferred to be a BadPerson. This is because otherBadPerson likes otherRichPerson, but otherRichPerson likes badPerson, not otherBadPerson. It is because the same rich person is not liked-back. It is the involvement of the same individual that causes a typical Description Logic reasoner to not be able to infer this correctly (or at least that is my understanding - someone who understands the difference between DL reasoners and rules better is welcome to correct me).
You will also note that a rich person liking another rich person and being liked back by that rich person, does not cause the rich person to be inferred to be a BadPerson.
Why intuitive solution using DL axiom does not work:
Intuitively one may think that defining BadPerson as follows will give the desired inference, but it does not:
Class: BadPerson
EquivalentTo:
(isLikedBy some RichPerson)
and (likes some Person) and (not RichPerson)
SubClassOf: Person
This will merely ensure that a BadPerson is liked by some rich person and that BadPerson likes some rich person, but the rich person is not necessarily the same rich person.
Why define a BadPerson class rather than a likesForBadReasons property in DL?
Reasoning in DL is defined in terms of classes and not in terms of relations. The basic reasoning in DL is classification and this aims to classify classes form the most general to the most specific. There is no such reasoning procedure for classification of relations.

Check OWL Class

Suppose the range of an object property is defined through a class expression. I want to know whether a particular instance of the class can be used in the range of the object property. Is it possible to use the OWL API and check if a particular class is subsumed by this class expression ?
OWLAPI cannot provide a complete answer for this - an OWLReasoner implementation is necessary for complete results.
Given an implementation of OWLReasoner, to check entailment you can either list all the subclasses of a class expression and check if the class you're interested in appears in the response, or ask the reasoner if your class of interest is a subclass, i.e.,
OWLDataFactory df = ...
OWLClassExpression ce = ...
OWLClass c = ...
OWLReasoner r = ...
OWLAxiom ax = df.getOWLObjectSubClassOf(c, ce);
boolean cIsSubclassOfCE = r.isEntailed(ax);

How to analyze a complex class axiom using OWL API

I read the OWL API documentation, most of the examples are about create class axioms and add them to the ontology. Now, I need to retrieve the restriction of a class, and extract the elements in the restriction.
For example, in the pizza.owl, ChessePizza class is defined by the restriction: "Pizza and (hasTopping some CheeseTopping)". I can use the "getEquivalentClassesAxioms" function to get the whole axiom. But I want to know the details of this axiom, such as the object properties (hasTopping) and classes (CheeseTopping) used in this axiom. Is there any method to extract the elements of a axiom?
The best approach to, for example, extract the property for all existential restrictions, is to write an OWLObjectVisitor.
In a visitor, you implement a visit(OWL... o) for each class that the visitor knows about. For an axiom that defines A equivalentTo p some Q, the visitor would look something like:
OWLObjectVisitor v = new OWLObjectVisitor() {
public void visit(OWLEquivalentClassesAxiom ax) {
// this is an example of recursive visit
ax.classExpressions().forEach(c->c.accept(v));
}
public void visit(OWLObjectSomeValuesFrom ce) {
OWLObjectPropertyExpression p = ce.getProperty();
// here you can do what you need with the property.
}
};
axiom.accept(v);

Objectify: How does one use the #Container annotation?

The following (abstracted) code gives a StackOverflow error, I assume due to recursive referencing between Team and Member (Team contains Member, which contains Team, etc).
#Entity public class Team {
#Id public String id;
public List<Member> members;
public Team() {
this.id = UUID.randomUUID().toString();
}
}
public class Member {
#Container Team team; //removing this line prevents error, but then how to reference this member's team?
public Member() {}
}
How does one set up the annotations for this relationship properly, so that a team has references to its members, and each member has a reference to its team?
#Container causes an embedded entity to be populated with the referenced entity. If you do what you have above, when you load one of Team or Member, it will load the other as an embedded entity in it, which then load the former again inside it -> Obviously this is an infinite recursion of Teams and Members all the way to an overflow.
Assuming a Member can only be on one team. perhaps you are better setting Team to be a #Parent (Teams contain members, a member is part of a team). Keep in mind this means you'll have a sustained 1 write per second limit, although you can burst higher for short durations.

How to ignore an unknown subclass with single collection inheritance in Mongoid?

The default inheritance method for Mongoid is creating a single collection for all subclasses. For instance:
class User
include Mongoid::Document
end
class Admin < User
end
class Guest < User
end
Internally, Mongoid adds a _type field to each document with the class name, which is used to automatically map each instance to the right class.
The problem is, if I have a document in this collection with an unknown _type value, I get an exception:
NameError: uninitialized constant UnknownClass
This can happen if you create a new subclass of User, in the example above, and a migration that creates a new instance of this new subclass. Until you restart your servers, every query to this collection (like User.all.to_a). Is there a safe way to avoid this error?
The only solution I came up is rescuing NameError exception and querying by all known subclasses:
class User
def self.some_query(params)
self.where(params).to_a
rescue NameError => e
Rails.logger.error "Unknown subclass: #{e.message}"
subtypes = self.descendants.map(&:to_s)
self.where(params.merge(:_type.in => subtypes)).to_a
end
end

Resources