In following example (written in OWLready2):
class A(Thing): pass
class p(ObjectProperty, FunctionalProperty): pass
class B(Thing): pass
class B1(B): equivalent_to = [B & p.some(A)]
class B2(B): equivalent_to = [B & Not(p.some(A))]
b1 = B(p=A())
b2 = B()
object b1 is reparented to B1, while b2 is not to B2. What's the reason for that? Did I use the wrong design pattern?
Because of Open World principle its considered unknown whether the defined individual b2 actually has a p=A(). OWLready2 has the means to use close world approach for the individual:
close_world(b2)
This will add a p.only(Nothing) restriction to b2, which is sufficient to infer b2 as being of class B2.