- From: Martynas Jusevičius <martynas@graphity.org>
- Date: Tue, 11 Sep 2012 23:14:59 +0300
- To: Timothy Armstrong <tim.armstrong@gmx.com>
- Cc: semantic-web@w3.org
Hey Timothy, RDF is metadata that can be easily managed: it has standard transport, serializations, query language etc. The object model has none of that. By coupling the application domain model with the data model (e.g. by naming classes/methods after ontology terms) you prevent the application from being generic. You need to keep the objects mirroring the RDF -- this is similar to what ORM was supposed to deliver but haven't really succeeded. I think generic applications are inevitable given how fast the data volumes grow. If we want achieve that we should be doing the opposite -- pushing the application domain logic into a generic model such as RDF, so that it can be managed. I agree your approach is useful when semantifying the OO world. But if I can achieve the same end result in plain Java (using Jena and our own platform), why should I use an extra layer of software (given the above points)? Martynas graphity.org On Tue, Sep 11, 2012 at 10:07 PM, Timothy Armstrong <tim.armstrong@gmx.com> wrote: > Hi, > > Martynas, I'm not sure what you mean by “huge abstraction level.” If you > look at my example program, http://www.semanticoop.org/example.html, you'll > see that all the code is the OWL semantics for the attributes/properties, a > single line at the beginning of the program, and then regular Java code. If > we add OWL to Java, all OWL data are just object-oriented data, so we just > use object-oriented code to manipulate the OWL data instead of some special > sort of code as in Jena, Sesame, RDFLib, etc. (This software is very > valuable; I'll probably want to combine my software with both Jena and > Sesame.) > > My motivation is mainly to allow people to use the Semantic Web in any of > their object-oriented code, which I'm sure no one else has ever done before. > Really, I think people will love it. However, I think my software also has > some advantages over Semantic Web software that stores its data as whole > triples, and I believe it is very much worth investigating them. I ran some > benchmarks comparing my software with Jena for creating resources / Java > objects and making triple statements. If you look at them, > http://www.semanticoop.org/benchmarks.html, you'll see that my software > compares very favorably. Please feel free to try them yourself! (And email > me if you have problems running the code.) I'll gladly run any more > benchmarks anyone suggests, given that I don't have SPARQL working yet > (though it should be close to working). At least, they should be good > benchmarks to run. > > Well I'm glad people are talking to me, but I'm just surprised I'm really > not getting people to say much positive. Shouldn't we just go ahead and try > to convince people to post their object-oriented data on the Semantic Web so > that people have access to the data, as in my last post? Once the code is > written, that is. > > Tim > > > > On 09/07/2012 09:15 AM, Martynas Jusevičius wrote: >> >> Tim, >> >> let me be so bold as to argue that you do not need the object model >> *at all* to build Semantic Web apps. Above RDF/SPARQL API level, that >> is. >> >> So your idea might be interesting as a computer science experiment, >> but to those building practical applications, it might be just another >> huge abstraction level without real added value. >> It might be helpful in order to integrate legacy Java apps or lower >> the SW learning curve for developers coming from that world, but >> that's pretty much it. Are you sure it's worth the effort? >> >> Martynas >> >> On Fri, Sep 7, 2012 at 2:48 AM, Timothy Armstrong <tim.armstrong@gmx.com> >> wrote: >>> >>> Hi, >>> >>> Well, we need a new reasoner. I explain my approach a bit below for the >>> reasoner I wrote. I believe it is new, but I could be entirely mistaken >>> that it's new. At no time does all of memory have to be in a reasoned >>> state, only a small part of it. We need a new reasoner because all the >>> existing ones run on a set of whole triples, and we need one that just >>> runs >>> on Java. >>> >>> I believe it is eminently worthwhile to write a new reasoner. I'm sure >>> there is a lot we can take from existing reasoners. We would have to >>> work >>> on it. I'm always surprised that more people don't know about the >>> Semantic >>> Web. It is a very powerful set of technologies, and I think making the >>> Internet into a giant database is just a great practical development in >>> computers. I have in mind for all programmers to use the Semantic Web >>> every >>> day in all their object-oriented code: OWL, SPARQL, rules, and Semantic >>> Web >>> Services. I have in mind for everyone to know about the Semantic Web. >>> Likely people will want a lot more Semantic Web software if that happens. >>> >>> People didn't seem impressed when I said we could post all >>> object-oriented >>> data on the Semantic Web. We can. The Semantic Web will just be giant >>> with >>> all that data on it. I'd like to explain in more detail. People have >>> commented on the difference between attributes and properties, and I've >>> read >>> some of the links. My view is still that an attribute is just a binary >>> predicate, nothing more, nothing less. It just relates two entities. >>> Translating Java data into RDF is on my to do list to code, but it's >>> straightforward to explain. Each Java package is an ontology. The >>> classes >>> in the package are members of the ontology. We make each attribute into >>> a >>> property. In my software, properties are defined in their own files >>> alongside the classes. We could put all the properties in the main >>> ontology >>> if the properties from different classes don't conflict, or we could >>> create >>> a separate ontology for each class that just contains the class's >>> attributes. Then for the data, we just take each Java Collection or >>> array >>> that is an attribute and make each element of it into a triple. When it >>> is >>> a list or an array, we will have to differentiate whether the programmer >>> really means a set of triples or a list like rdf:List. Sometimes when >>> programmers use lists, they really mean sets. The value of each >>> attribute >>> that is not a Java Collection or an array is just a single triple. There >>> are rdf:type triples for class membership. So all object-oriented data >>> are >>> triples. Then we can post all object-oriented data on the Semantic Web. >>> We >>> should just go ahead and do that so that people have access to the data. >>> >>> My approach to reasoning is a little difficult to explain, but I did my >>> best >>> to explain it in my article, which I quote here. It might make better >>> sense >>> in the context of the article, but you should be able to follow it. As I >>> mentioned, for each read operation, it is as if Protege reasoned only the >>> part of the data set relevant to the screen the user is currently viewing >>> and did not do any more reasoning. When we call a read method on a Java >>> Collection that is an attribute, we do only the reasoning that could >>> potentially cause objects to be added to the set of objects. >>> >>> Property reasoning consists of trying to add objects to a certain >>> subject-predicate pair. When we call a read method on a Java Collection >>> that is an attribute for a certain subject and predicate, we want all the >>> objects to be in it. The goal is to reason this object set, i.e. add as >>> many members to it as we can according to the reasoning. For each type >>> of >>> property reasoning, there is a certain manner in which objects may be >>> added >>> to the object set. We need to try to add objects by each type of >>> reasoning. >>> Depending on the semantics of the property, we need to try to add objects >>> by >>> zero or more of rdfs:subPropertyOf (including owl:equivalentProperty), >>> owl:inverseOf, owl:ReflexiveProperty, owl:SymmetricProperty, and >>> owl:TransitiveProperty. So let us look at each type of reasoning. For a >>> subject s and a predicate p, let us call the set of objects O_s,p. >>> >>> First, let us look at rdfs:subPropertyOf reasoning. Let us have a >>> property >>> hasChild with two subproperties, hasDaughter and hasSon, representing the >>> sets of a person's children, daughters, and sons, respectively. The >>> domains >>> are all Person, a class representing a person. The ranges are Person, >>> Female, and Male, respectively, where Female is a female person and Male >>> is >>> a male person. We are trying to find all of a person x's children. >>> I.e., >>> we are trying to reason the object set O_x,hasChild, with person x as >>> subject and hasChild as predicate. To find all of x's children, we need >>> to >>> find all of x's daughters and sons. I.e., we need to reason the object >>> sets >>> O_x,hasDaughter and O_x,hasSon. However, if the only form of reasoning >>> we >>> are using for hasChild is rdfs:subPropertyOf, i.e. if no other form of >>> reasoning can add objects to O_x,hasChild, then we reason O_x,hasDaughter >>> and O_x,hasSon, and then we are done reasoning. We reason those two >>> object >>> sets and add them to O_x,hasChild along with any objects that were in it >>> before the reasoning. We have found all of x's children and have likely >>> reasoned only a small part of the whole data set. None of the rest of >>> the >>> data matters, so we do not have to reason it. In general, when we are >>> trying to reason an object set O_s,p, we need to reason O_s,q for each >>> subproperty q of p. >>> >>> Let us say that hasChild has further semantics beyond having >>> subproperties. >>> In particular, let us say it has an inverse property by owl:inverseOf, >>> hasParent, the set of a person's parents. The domain and range of each >>> is >>> Person. We have found the object sets we need to reason for adding >>> objects >>> to O_x,hasChild by rdfs:subPropertyOf reasoning. Now let us find the >>> object >>> sets we need to reason for adding objects to it by owl:inverseOf >>> reasoning. >>> For each member y of the Person class, we reason the object set >>> O_y,hasParent. If x is in O_y,hasParent, i.e. if y hasParent x, then x >>> hasChild y. However, those object sets are the only ones we need to >>> reason >>> for the owl:inverseOf reasoning. We do not need to do any more >>> reasoning. >>> We are not having our particular hasChild example be reflexive, >>> symmetric, >>> or transitive. So for our particular hasChild example, we reason the >>> object >>> sets in this paragraph and the previous one. Then if those forms of >>> reasoning are the only ones our system does, nothing else can possibly >>> add >>> objects to O_x,hasChild. >>> >>> >>> (I use AspectJ to get all instantiated members of a class, which normally >>> we >>> cannot do in Java.) The other property reasoning is exactly the same >>> (it's >>> on page 8 in the article on my web page, but I'll gladly explain here if >>> anyone asks): when we are trying to reason an object set, for each type >>> of >>> reasoning there is only a certain number of other object sets we need to >>> reason to complete the reasoning. So when we call a read method on a >>> Java >>> Collection that is an attribute, we reason only a small part of memory. >>> Well, someone can tell me if that approach isn't new, but it seems very >>> efficient computationally. >>> >>> Oh, I really think I've done something new. I have the basis for a whole >>> Semantic Web system that just runs on Java instead of on a set of whole >>> triples. >>> >>> Tim >>> http://www.semanticoop.org >>> >>> >>> >>> >>> On 09/01/2012 08:02 PM, adasal wrote: >>> >>> Hi, >>> I don't think you answered the question of how what you propose would be >>> optimised. How would it deal with reasoning, for instance, bearing in >>> mind >>> that Pellet and many others have been subject to many years of >>> development >>> and probably the subject of many Phds too! >>> >>> You might want to look at this project which Henry Story tipped me off >>> to:- >>> https://github.com/w3c/banana-rdf >>> >>> This is from the test suit:- >>> ObjectExamples.scala >>> >>> package org.w3.banana >>> >>> import scalaz.{ Validation, Failure, Success } >>> import java.util.UUID >>> >>> class ObjectExamples[Rdf <: RDF]()(implicit diesel: Diesel[Rdf]) { >>> >>> import diesel._ >>> import ops._ >>> >>> case class Person(name: String, nickname: Option[String] = None) >>> >>> object Person { >>> >>> val clazz = uri("http://example.com/Person#class") >>> implicit val classUris = classUrisFor[Person](clazz) >>> >>> val name = property[String](foaf.name) >>> val nickname = optional[String](foaf("nickname")) >>> val address = property[Address](foaf("address")) >>> >>> implicit val container = uri("http://example.com/persons/") >>> implicit val binder = pgb[Person](name, nickname)(Person.apply, >>> Person.unapply) >>> >>> } >>> >>> sealed trait Address >>> >>> object Address { >>> >>> val clazz = uri("http://example.com/Address#class") >>> implicit val classUris = classUrisFor[Address](clazz) >>> >>> // not sure if this could be made more general, nor if we actually >>> want >>> to do that >>> implicit val binder: PointedGraphBinder[Rdf, Address] = new >>> PointedGraphBinder[Rdf, Address] { >>> def fromPointedGraph(pointed: PointedGraph[Rdf]): >>> Validation[BananaException, Address] = >>> Unknown.binder.fromPointedGraph(pointed) orElse >>> VerifiedAddress.binder.fromPointedGraph(pointed) >>> >>> def toPointedGraph(address: Address): PointedGraph[Rdf] = address >>> match { >>> case va: VerifiedAddress => >>> VerifiedAddress.binder.toPointedGraph(va) >>> case Unknown => Unknown.binder.toPointedGraph(Unknown) >>> } >>> } >>> >>> } >>> >>> case object Unknown extends Address { >>> >>> val clazz = uri("http://example.com/Unknown#class") >>> implicit val classUris = classUrisFor[Unknown.type](clazz, >>> Address.clazz) >>> >>> // there is a question about constants and the classes they live in >>> implicit val binder: PointedGraphBinder[Rdf, Unknown.type] = >>> constant(this, uri("http://example.com/Unknown#thing")) withClasses >>> classUris >>> >>> } >>> >>> case class VerifiedAddress(label: String, city: City) extends Address >>> >>> object VerifiedAddress { >>> >>> val clazz = uri("http://example.com/VerifiedAddress#class") >>> implicit val classUris = classUrisFor[VerifiedAddress](clazz, >>> Address.clazz) >>> >>> val label = property[String](foaf("label")) >>> val city = property[City](foaf("city")) >>> >>> implicit val ci = classUrisFor[VerifiedAddress](clazz) >>> >>> implicit val binder = pgb[VerifiedAddress](label, >>> city)(VerifiedAddress.apply, VerifiedAddress.unapply) withClasses >>> classUris >>> >>> } >>> >>> case class City(cityName: String, otherNames: Set[String] = Set.empty) >>> >>> object City { >>> >>> val clazz = uri("http://example.com/City#class") >>> implicit val classUris = classUrisFor[City](clazz) >>> >>> val cityName = property[String](foaf("cityName")) >>> val otherNames = set[String](foaf("otherNames")) >>> >>> implicit val binder: PointedGraphBinder[Rdf, City] = >>> pgb[City](cityName, otherNames)(City.apply, City.unapply) >>> withClasses >>> classUris >>> >>> } >>> >>> } >>> >>> The stated aim of the developers is to follow the RDF spec 'carefully' >>> and >>> to work with Jena and Sesame, so perhaps not the same as yours? >>> >>> >>> Adam >>> >>> >>> On 30 August 2012 17:03, Timothy Armstrong <tim.armstrong@gmx.com> wrote: >>>> >>>> Hi, >>>> >>>> Sorry for taking so long to respond, and thank you for talking to me. >>>> >>>> As far as I can tell, it is entirely possible to build Semantic Web >>>> software on top of object-oriented programming languages, and presumably >>>> database technologies, instead of starting Semantic Web software from >>>> scratch. Object-oriented languages already have a lot of the OWL data >>>> model >>>> implemented. Well, all they have are classes, properties, and >>>> rdfs:subClassOf, but they do those very well. So we want to add the >>>> rest of >>>> OWL to them. >>>> >>>> All the property reasoning just works directly for attributes. >>>> Attributes >>>> can have subattributes, inverse attributes, be transitive, etc., and it >>>> all >>>> makes perfect sense. We just let people use property reasoning for any >>>> of >>>> their object-oriented attributes. I tried to show how useful it would >>>> be in >>>> the example program on my web page: >>>> http://www.semanticoop.org/example.html. >>>> There is a Person Java class with attributes for the person's mother, >>>> father, parents, children, ancestors, descendants, an attribute for all >>>> the >>>> person's relatives, etc. You can imagine how messy the Java program >>>> would >>>> be without the property reasoning. The reasoning really helps. Well, >>>> maybe >>>> there are better ways of doing it than with my software, but I think >>>> that if >>>> we can add OWL to OOP, people will really like it. >>>> >>>> Well, I really don't know what to do with the software. Thank you for >>>> talking to me about it. >>>> >>>> Tim Armstrong >>>> >>>> >>>> >>>> On 08/20/2012 05:21 PM, adasal wrote: >>>> >>>> OK, there is something like multiple inheritance in Scala with Scala >>>> traits and there are a few implementations of mixin frameworks in Java >>>> which >>>> is really IoC using DI. Tapestry was my example, but Spring allows >>>> similar >>>> to enable separation of concerns. >>>> However I believe that Sesame/AliBaba also allows such hooks. >>>> When it comes to reasoning there are existing Java reasoners. It seems >>>> more than a tall order to build your own! >>>> For instance http://clarkparsia.com/pellet/ >>>> The problem that you will have if you build your own is that you will >>>> both >>>> have to optimise and verify it. >>>> >>>> The mixin pattern is also available in Python, there are some advantages >>>> against inheritance as run time behaviour can be determined. >>>> >>>> Are you able to explain better the difference and implication of your >>>> approach to existing approaches? >>>> It has been said in this thread that code up to the RDF level is the >>>> better approach, that is the RDF is not fully modelled in the code but >>>> translated through e.g. SPARQL I suppose. >>>> How do you understand this? >>>> >>>> Best, >>>> >>>> Adam >>>> >>>> On 20 August 2012 16:39, Timothy Armstrong <tim.armstrong@gmx.com> >>>> wrote: >>>>> >>>>> Hi, >>>>> >>>>> Well, if there would be some way to do multiple inheritance in Java, >>>>> that >>>>> could be very useful. I was thinking it would probably be possible to >>>>> do >>>>> some of the class reasoning in Java with its limited support for >>>>> multiple >>>>> inheritance with interfaces, just we would be partially limited in what >>>>> we >>>>> can do with classes in Java. There shouldn't be a problem with the >>>>> property >>>>> reasoning, SPARQL, or rules in Java though (well I have methods to >>>>> compute >>>>> all the triplestore indexes). Semantic Web Services written as Java >>>>> annotations on methods should work if annotations are extended to >>>>> support >>>>> arbitrary datatypes. >>>>> >>>>> I could have written the code in a language that has multiple >>>>> inheritance, but we can do a lot in Java, and Java is just my best >>>>> language. >>>>> It might be straightforward to copy the code to any other >>>>> object-oriented >>>>> language. I just looked at Python decorators this morning, since >>>>> Python has >>>>> multiple-inheritance. It doesn't look straightforward to use them just >>>>> for >>>>> metadata on code elements like Java annotations, but maybe it can be >>>>> done. >>>>> If it can, it looks like they would support arbitrary datatypes. And >>>>> then >>>>> maybe we could add all of OWL, SPARQL, rules, and Semantic Web Services >>>>> to >>>>> Python without modifying Python... Well, there would need to be >>>>> something >>>>> like AspectJ for Python as I'm doing it. >>>>> >>>>> Truthfully, I haven't spent much thought about how best to do the class >>>>> reasoning. I focused on the property reasoning and indexes and was >>>>> waiting >>>>> to talk to people about the class reasoning. I'll have to look into >>>>> the >>>>> technologies you mention. >>>>> >>>>> Tim >>>>> >>>>> >>>>> >>>>> On 08/18/2012 04:55 PM, adasal wrote: >>>>>> >>>>>> We would need to modify a compiler to determine to which classes an >>>>>> object belongs so we would know what methods can be used with it. >>>>>> There >>>>>> could be methods in defined classes. >>>>> >>>>> >>>>> You must be thinking about a multiple class inheritance hierarchy. >>>>> >>>>> There is this project >>>>> http://insightfullogic.com/blog/2011/sep/16/multiple-inheritance/ >>>>> but I think there must be other implementations. >>>>> Further containers for IoC such as Tapestry have a mature mixin >>>>> implementation for class transformation, or Scala (and Java 8 to be) >>>>> supports traits. >>>>> Wouldn't this cover it instead of messing around with the compiler? >>>>> >>>>> I would have thought the real problem is how to define precedence in >>>>> the >>>>> multiple hierarchy. How does OWL deal with contradictory definitions in >>>>> the >>>>> hierarchy? >>>>> >>>>> Adam >>>>> >>>>> On 18 August 2012 16:10, Timothy Armstrong <tim.armstrong@gmx.com> >>>>> wrote: >>>>>> >>>>>> Hi Adam, >>>>>> >>>>>> What I have in mind is fitting my software together with Sesame or >>>>>> Jena >>>>>> and just having the back-end store sets of objects instead of whole >>>>>> triples >>>>>> and see how that works. For benchmarks, I think it won't be very >>>>>> difficult >>>>>> to get SPARQL running on my software, since I have methods to compute >>>>>> all >>>>>> the triplestore indexes (permutations of subject-predicate-object) >>>>>> from all >>>>>> of main memory, but SPARQL isn't running yet. >>>>>> >>>>>> I just meant that my understanding was that OWL can express anything >>>>>> about data OOP can express, and more, but I'm sure Alan is right that >>>>>> there >>>>>> is more than abstract classes. By "disparity" I meant that even if >>>>>> there are >>>>>> differences between OOP and OWL of which I'm not aware, I still don't >>>>>> see a >>>>>> problem with adding OWL to OOP. >>>>>> >>>>>> We would need to modify a compiler to determine to which classes an >>>>>> object belongs so we would know what methods can be used with it. >>>>>> There >>>>>> could be methods in defined classes. >>>>>> >>>>>> Tim >>>>>> >>>>>> >>>>>> >>>>>> On 08/18/2012 07:35 AM, adasal wrote: >>>>>> >>>>>> >>>>>> >>>>>> On 17 August 2012 23:08, Timothy Armstrong <tim.armstrong@gmx.com> >>>>>> wrote: >>>>>>> >>>>>>> Certainly, object-oriented classes and OWL classes are different, but >>>>>>> my understanding is that the main difference is just that OWL is >>>>>>> strictly >>>>>>> better. >>>>>> >>>>>> >>>>>> What do you mean by 'strictly', 'better' and 'strictly better'? >>>>>> >>>>>>> I'm not aware of anything OOP can do that OWL cannot do, but OWL >>>>>>> can >>>>>>> do a lot more. >>>>>> >>>>>> >>>>>> What do you mean by 'do'? Do you mean it is more expressive such that >>>>>> it >>>>>> is possible to define in OWL what cannot be defined in OOP? Isn't that >>>>>> axiomatic in that they are different languages with different >>>>>> semantics? >>>>>> What you are really saying is that you want to extend the syntax of >>>>>> OOP >>>>>> in a form you think is convenient to use such that it will be able to >>>>>> express OWL semantics. >>>>>> >>>>>>> Well, abstract classes, but that's all I can think of. >>>>>> >>>>>> So is this relevant? >>>>>> >>>>>>> Or if there is still going to be a disparity, >>>>>> >>>>>> What does this mean? >>>>>> >>>>>>> we should still just be able to add all the OWL class constructs and >>>>>>> everything else about OWL and let people use them in OOP. >>>>>> >>>>>> You mean with your annotations - but the issue really is whether this >>>>>> is >>>>>> more convenient than existing approaches. >>>>>> >>>>>>> We'd need to get into a compiler to do some of it, but I think it >>>>>>> would >>>>>>> be worth it. >>>>>> >>>>>> Why would it be necessary to get into the compiler, what are you >>>>>> talking >>>>>> about? >>>>>> Do you mean to pick up annotations - that is not necessary as new >>>>>> annotations can be defined as things stand - or to optimise such as in >>>>>> the >>>>>> way you mention where reasoning is selective. I can't see that this >>>>>> needs >>>>>> access to the compiler so much as an understanding of the logic of >>>>>> whether >>>>>> and when selective reasoning is a proper optimisation. >>>>>> >>>>>> You would have to show that your approach is better than the existing >>>>>> approaches to optimisation that sit on top of triple and quad stores. >>>>>> Can you do this? >>>>>> >>>>>> Adam >>>>>> >>>>>> >>>>> >>>> >>> > >
Received on Tuesday, 11 September 2012 20:15:28 UTC