buda-base / editserv

Editing services of the buda platform
Apache License 2.0
0 stars 0 forks source link

Second Order Logic and updating neighbor entities #14

Open eroux opened 4 years ago

eroux commented 4 years ago

When we receive an update from one entity, we need to sometimes update the links to this entity in other graphs. For instance if we have:

bdg:A {
   bdr:A bdo:hasSon bdr:B .
}
bdg:B {
   bdr:B bdo:hasFather bdr:A .
}

and we receive an update to bdg:A where the hasSon triple is removed, we need to remove the hasFather triple in bdg:B. This issue is about the logics involved in what triple to remove.

As a preliminary, it would be good to define a minimal graph which could be defined as the minimal number of triples necessary to obtain an inferred model. It will be discussed in a separate issue. This issue assumes that all the graphs we're dealing with are minimal.

In our use cases, we can know what properties will be encountered in other graphs through different second order logic properties:

If we have in the ontology

bdo:PA  a owl:SymmetricProperty .
bdo:PB owl:inverseOf bdo:PC .
bdo:PC owl:inverseOf bdo:PB .

and

bdg:GA {
   bdr:IA bdo:PA bdr:IB .
   bdr:IA bdo:PB bdr:IB .
}
bdg:GB {
   bdr:IB bdo:PA bdr:IA .
   bdr:IB bdo:PC bdr:IA .
}

which is a coherent state, then:

There's actually no difficulty...

MarcAgate commented 4 years ago

Exactly, and I believe this is what is already implemented. The question (or potential issue or difficulty) regarding this is really about identifying SymmetricProperties and properties being the inverse of other properties. hasSon is really a good example since it inherits from hasChild which has an inverse property, while being at the same time a sub property of a owl:SymmetricProperty (since kinWith is a superProp of hasChild which is a superProp of hasSon).

So when hasSon is encountered and analyzed, we consider it as a property having an inverse because it's parent prop has an inverse (i.e hasChild has an inverse: hasParent), while we ignore it or do not consider it has a SymetricProperty since we assume that there is no type inheritance for Properties. If the rule is really "no type inheritance for Properties" then there is no issue at all and we consider as a owl:SymmetricProperty only properties having that type explicitly defined in the ontology (ad for kinWith). This discussion https://stackoverflow.com/questions/37854557/owl-class-and-subclass-property-inheritance might help to clarify what this discussion is all about even though it doesn't clearly address this:

PropA rdf:type owl:SymmetricProperty PropB rdf;type owl:ObjectProperty PropB rdf:subPropertyOf PropA

But

owl:SymmetricProperty a rdfs:Class ; rdfs:label "SymmetricProperty" ; rdfs:comment "The class of symmetric properties." ; rdfs:isDefinedBy http://www.w3.org/2002/07/owl# ; rdfs:subClassOf owl:ObjectProperty .

so the type of PropB is a superClass of the type of PropA with propB a subProp of PropA

eroux commented 4 years ago

yes, the baseline is that there's no inheritance. Looking at RDF as if it was a programming language often leads to many confusion... (which I think is one of the reasons why RDF is not very adopted by programmers, it's counter-intuitive). So, no inheritance no problem!

MarcAgate commented 4 years ago

Trying to clarify this a little bit more, I would say that in our case :

"we take inheritance into account when searching for inverse prop" "we ignore inheritance when searching for SymmetricProperties"

which might be translated as :

"inheritance is ok with a rdf:Property (owl:inverseOf a rdf:Property ;) " "inheritance is ignored for rdfs:class (owl:ObjectProperty a rdfs:Class ;)"

this is the only generic and rational way of thinking I found about this issue.

eroux commented 4 years ago

no, we never take inheritance into account, not even for inverse props

MarcAgate commented 4 years ago

Right, we really don't care about inheritance when a reasoner already produced an inferred model containing "missing triples". i.e when we have:

resA hasSon resB 
and 
hasSon rdfs:subPropertyOf hasChild 
it infers resA hasChild resB 

or when having:

hasChild inverseOf hasparent 
and  
hasSon rdfs:subPropertyOf hasChild 
it inferes hasSon inverseOf HasParent   

Since I am not sure we approach this discussion using the same perspective, I describe below when this problem occurs in the actual process and what it might take to solve it:

1) We receive an edited graph bdg:ResA from the client 2) We look for triples that were added or removed from the model 3) We find out that ResA hasSon ResB has been added (or removed) 4) We analyse this triple and look up the ontology to learn something about hasSon: is it a owl:SymetricProp ? Does it have an inverse prop?

This is where some inference or logic must be used so we have the means to figure out that hasSon actually has an inverseProp which is hasParent even though the triple hasSon inverseOf HasParent doesn't exist in the ontology.

There are at least two ways to do this (as shown above):

A) keep the ontology as is and apply a reasoner on bdg:Resa, so we infer ReasA hasChild ResB (and then we can figure out the inverse prop since hasChild inverseOf hasParent is in the ontology)

or

B) apply a reasoner to the ontolgoy so it infers hasSon inverseOf HasParent.

Does it make sense or am I completely off track ?

eroux commented 4 years ago

well, in that case it's actually even more complex... because what we really want is hasFather or hasMother instead of hasParent... here what should actually happen is something like the following:

The reason is that for the hasFather to be inferred in the graph of ResB, you need the triple ResA bdo:gender bdr:GenderMale which is in the graph of ResA... I think this algorithm works...

MarcAgate commented 4 years ago

I have noticed that most of the time, the inverse triples we need are already in ResB For instance, when processing that triple in (bdg:P705)

T1 = new Triple(NodeFactory.createURI("http://purl.bdrc.io/resource/P705"),
                NodeFactory.createURI("http://purl.bdrc.io/ontology/core/hasFather"), NodeFactory.createURI("http://purl.bdrc.io/resource/P2MS9526"));

We merge P705 and P2MS9526 and the resulting graph already contains (without inference) the following:

bdr:P2MS9526  a         bdo:Person ;
        bdo:hasChild    bdr:P705 ;
        bdo:hasSon      bdr:P705 ;

But at this point, we don't know a thing about bdo:hasChild or bdo:hasSon (i.e we don't know if they are inverseProps and nor if any of them (or both) correspond to the inverse of hasFather.
Wether we get these triples from inference or directly from the union graph, there is a need to refer to the ontology to find out about the inverse of hasParent.

So at this point we could solve the issue this way :

1) Lookup the ontology to get the inverse of hasParent -> then we find that hasChild is the inverse 2) Then we would know that bdr:P2MS9526 bdo:hasChild bdr:P705 ; is a possible inverse triple 3) Still we need to go further and check for subProperties of hasChild -> we find hasDaughter and hasSon 4) Then we could assert that bdr:P2MS9526 bdo:hasSon bdr:P705 ;is the inverse triple we look for and just keep this one.

WDYT

eroux commented 4 years ago

These triples are in bdg:P2MS9526 on Fuseki, but not in the git version, see

https://gitlab.com/bdrc-data/persons/-/blob/master/3b/P2MS9526.trig

The way it goes would be as follows:

Initial state (on git)
bdg:P2MS9526 {
   bdr:P2MS9526  bdo:hasSon      bdr:P705 ;
                             bdo:gender bdr:GenderMale .
}
bdg:P705 {
   bdr:P705  bdo:hasFather      bdr:P2MS9526 ;
                             bdo:gender bdr:GenderMale .
}
Change received by the editor

we remove the triple

- bdr:P2MS9526  bdo:hasSon      bdr:P705 .
Inference stage for added triples

What we need to do here is something along the lines of:

bdr:P2MS9526  bdo:hasSon      bdr:P705 .

plus

bdr:P2MS9526 bdo:gender bdr:GenderMale .

plus the rule

(?a :hasSon ?b), (?a :personGender bdr:GenderMale) -> (?b :hasFather ?a)

gives 

bdr:P2MS9526  bdo:hasSon      bdr:P705 .

(the rule with the funny syntax is there and is integrated in the reasoner). This algorithm is slightly simpler than the one I initially described but that should give you the idea.

Inference stage for removed triples

For removed triples things are a bit different. The initial graph has

bdr:P2MS9526 bdo:hasSon bdr:P705 .

the final graph doesn't have this triple. We run the inference on both the initial and the final graph.

With the same algorithm as before, the initial graph will give

bdr:P2MS9526 bdo:hasSon bdr:P705 .

but the second graph will not. So by diffing the inference on the final graph and the inference on the initial graph, we can have the diff to apply to other graphs. Actually this is a generalization of the more simple case which could be handled in the exact same way...

Do you see what I mean?

MarcAgate commented 4 years ago

Yes. But I suspect the two triples resulting from inference are bdr:P705 bdo:hasParent bdr:P2MS9526 . instead of bdr:P2MS9526 bdo:hasSon bdr:P705 . .

eroux commented 4 years ago

you can try the BDRCReasoner and see, it should give both

MarcAgate commented 4 years ago

Fixed as of commit ee7cb0e