Hello,
I'm currently using owlready2 to communicate between Python and OWL, and it is a great API! Thanks a lot :) I have a question regarding accessing inferred facts: how can I access inferred facts in individuals? For example: - Entities: Component, Material, Method - Individuals: Component1, Metal, Drilling - Object Properties: hasMaterial, hasProductionMethod - Rule: Component(?c) ^ hasMaterial(?c, Metal) -> hasProductionMethod(?c, Drilling) I defined that Component1 hasMaterial Metal. Then in Protégé I use the Hermit reasoner and it infers that Component1 hasProductionMethod Drilling. However, when I do this in owlready (with sync_reasoner) I cannot access this information. Is there a way to do this? Many thanks, Oli |
Administrator
|
Hello,
There is still no rule support in Olwready, sorry :-( As far as I know, rules can be used be reasoner for checking consistency, but in Protégé I do not see the inferred property values (where/how do you obtained them ?). Best regards, Jean-Baptiste Lamy MCF HDR, Laboratoire LIMICS, Université Paris 13 |
Hi Jean-Baptiste,
Thanks for the fast reply :) After defining the rule in SWRL Tab, I start the reasoner and in the Property assertions of the individual Component1 I get a object property assertion hasProductionMethod Drilling. This assertion, however, is not saved in the ontology after the reasoner is stopped. But I thought that maybe I could access this information from Python while the reasoner was running, with something like this: import owlready2 as owl onto_path = "my/path/to/onto.owl" onto = owl.get_ontology("file://" + onto_path).load() with onto: owl.sync_reasoner() print(onto["Component1"].hasProductionMethod) Is this possible? If not, could I change something in the sync_reasoner function to get a result? I don't need this value in the ontology I just need to extract it to Python. Thanks again! Cheers, Oli |
Administrator
|
Hello,
> Is this possible? If not, could I change something in the sync_reasoner > function to get a result? I don't need this value in the ontology I just > need to extract it to Python. The problem is that Hermit does not show those inferrences on the command line. So you need to modify Hermit in order to get them on command line, and then to modify Owlready to apply the inferrences. I already did a similar modification for individual classification, so it is possible, but not easy :-( Best regards, Jean-Baptiste Lamy MCF HDR, Laboratoire LIMICS, Université Paris 13 |
Hi Jean-Baptiste,
Thanks for the comment and sorry for the late response! I managed to access the inferred facts using the java based SWRLapi. I've created a java program that I can run using the command line (similarly to what sync_reasoner does). It is not a really elegant solution but I get the results that I wanted. Cheers, Oli |
Hi Oli,
I wonder if you could share the program you created? I'm looking for a similar solution. Thanks |
Hi!
Sure :) Here is my InferenceEngine class: from pathlib import Path import subprocess from global_settings import INFERENCE_PATH, GLOBAL_LOGGER class InferenceEngine(object): """ InferenceEngine class :param input_file: path to the txt file :type input_file: str, Path :param ontology_list: list with paths to the owl files to be written in :attr:`file_path` :type ontology_list: list :param inference_path: path to the directory where the reasoner.jar is located :type inference_path: Path """ def __init__(self, input_file, ontology_list, inference_path=INFERENCE_PATH): self.input_file = input_file self.ontology_list = ontology_list self.inference_path = inference_path def write_reasoner_input_file(self): """ Given a list with paths to owl files (ontology_list) and a txt file (file_path), this method writes the owl file paths to the txt file. The resulting txt file is the input for the :func:`run_rule_engine`. :return: written input_file """ if isinstance(self.input_file, Path): self.input_file = str(self.input_file) with open(self.input_file, 'w') as f: for ontology_path in self.ontology_list: f.write(ontology_path + '\n') def run_rule_engine(self): """ Function that runs the rule engine (using Drools). It uses self.input_file, which is the path to txt file, which contains a list with the path of the ontology that uses the rule engine and the dependencies of that ontology (imported ontologies). It does not return anything but it updates the inferred facts to the input ontology. :Note: The order in which the ontologies paths are written into the txt file matters. The dependencies should be always above the main ontology, in order to avoid import errors. For example, imagine that the rule engine is going to be applied to the ontology onto, which depends on the ontology onto. Then, the input_file.txt will look like this: global/path/to/onto1.owl global/path/to/onto.owl This is achieved using the method :func:`write_reasoner_input_file` """ if isinstance(self.inference_path, str): self.inference_path = Path(self.inference_path) GLOBAL_LOGGER.info('The input inference_path ({}) should be of type Path and it has been converted.'.format( self.inference_path)) jar_path = self.inference_path / "reasoner.jar" self.write_reasoner_input_file() command = ["java", "-jar", str(jar_path), str(self.input_file)] subprocess.check_output(command) For it to work, you will need the reasoner.jar file that I've created. Do you know how can I attach a file? It is not the prettiest solution, but it is something :P Cheers, Oli |
Hi Oli,
Great thanks! I'm using the nabble site to browse this forum and in the reply page there is a "More" button with a drop down that lets you upload files. Otherwise perhaps you could upload to Dropbox or Google Drive or something similar and share the link so I can get your jar file? Thanks! |
Hi :)
I realized that I have to register to be able to add files, but it doesn't seem to upload. I have uploaded the jar file to WeTransfer (https://we.tl/t-6TXF0ABLjf). Hope it works! Let me know if it doesn't work (the download or the code). Good luck! |
Hi Oli,
The download works, thanks so much! Can you give a quick overview of how your code works? What are "input_file" and "ontology_list"? I have an ontology file with some SWRL rules defined and it also contains some individuals, I want to run a reasoner to apply the rules to the individuals. Thanks |
In reply to this post by Oli
Hi Oli,
Actually no problem I managed to figure it out and got it working! This is great it is exactly what I needed and should let me get further with my project. Thanks a lot for the time spent developing your code. I wonder if you would be able to share the source? And if you are able to give permission to use the code in my research project if you don't mind? Thanks :) |
In reply to this post by Oli
You could also force a reclassification step by creating a new class that matches the condition of having the property. Then HermiT will report it in the output. It's not the cleanest solution, but it doesn't require any extra libraries and a little extra work in the ontology.
|
In reply to this post by martingrant
Heyhey,
Happy to hear it works :) Here you have the java code (finally managed to upload a file!): InferenceEngine.java It was the first time I used java so I hope it is not too messy. But since you have it now, you can expand it or make it nicer :) Of course you can use it! I'm happy to hear that it is useful for someone else! Cheers, Oli |
In reply to this post by Jiba
Hi Jean-Baptiste,
when will owelready2 support the access of inferred facts (properties) of individuals? Best regards, Walter Zimmer |
In reply to this post by liam
Hi Liam,
Thank you for providing another solution to this problem. Could you please elaborate a bit more on this? I am also working on implementing a solution to access inferred facts (properties) in python. The way I am doing it is the following. I modified the HermiT jar (CommandLine.java, Reasoner,java and HierarchyDumperFSS.java) to also print the inferred properties. Then I call the the reasoner from Python: reasoner.py command = "java -Xmx2000M -cp /usr/local/lib/python3.6/dist-packages/owlready2/hermit:/usr/local/lib/python3.6/dist-packages/owlready2/hermit/HermiT_modified.jar org.semanticweb.HermiT.cli.CommandLine -c -O -D -o pizza_onto_inference.owl pizza.owl" The next step is to parse the inferred results within reasoner.py. I have created three individuals (pizza1, pizza2, meatTopping1) and assigned the property has_topping(meatTopping1) to pizza1. For pizza2 I set the SameIndividualAs(pizza1) property. After running the HermiT reasoner I can see that pizza2 has also the property has_topping(meatTopping1). Has someone written already a parser to parse inferred properties and can share the file? Thanks, Walter |
Administrator
|
Hi Walter,
Modifying the Python parser is the easy part of the job (at least for me). If you send me the modified version of HermiT (that prints the inferred properties), I should be able to write the parser quickly. Best regards, Jiba |
Hi Jiba,
Thank you for your answer. I started already to write the parser, but still need to rewrite two methods. You can see my changes in the reasoner.py (annotated with 'CHANGED BY W. ZIMMER'). Here is a link to the modified HermiT version 1.3.8 and the modified owlready2 (version 0.13) python lib. https://we.tl/t-7R0Yv7OuNA I have modified CommandLine.java to do inference on all types (incl. properties): hermit.precomputeInferences(InferenceType.CLASS_HIERARCHY, InferenceType.OBJECT_PROPERTY_HIERARCHY, InferenceType.DATA_PROPERTY_HIERARCHY,InferenceType.CLASS_ASSERTIONS,InferenceType.OBJECT_PROPERTY_ASSERTIONS,InferenceType.SAME_INDIVIDUAL,InferenceType.DISJOINT_CLASSES,InferenceType.DATA_PROPERTY_ASSERTIONS,InferenceType.DIFFERENT_INDIVIDUALS); In Reasoner.java I have added the method to print also the properties: printer.printInferredProperties(m_instanceManager.getCurrentRoleHierarchy()); I perform the inference with the following command which writes the inferred properties into a file (pizza_onto_inference.owl): java -Xmx2000M -cp /usr/local/lib/python3.6/dist-packages/owlready2/hermit:/usr/local/lib/python3.6/dist-packages/owlready2/hermit/HermiT_modified.jar org.semanticweb.HermiT.cli.CommandLine -c -O -D -o pizza_onto_inference.owl pizza_onto.owl Here is the content of pizza_onto_inference.owl: SubClassOf( <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#TomatoTopping> <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#Topping> ) SubClassOf( <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#CheeseTopping> <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#Topping> ) SubClassOf( <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#MeatTopping> <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#Topping> ) SubClassOf( <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#FishTopping> <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#Topping> ) owl:bottomObjectProperty (known instances: | possible instances: ) <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#has_topping> (known instances: (<http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#pizza1>, <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#meatTopping1>) (<http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#pizza2>, <http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#meatTopping1>) | possible instances: ) owl:topObjectProperty (known instances: | possible instances: ) I need to parse the bottom part and assign the property has_topping to the pizza2 individual. Here you can find the modifiedd pizza_onto.owl file. I have created the individuals pizza1, pizza2 and meatTopping1 and assigned the property has_topping to pizza1 and the attribute pizza1.sameAs(pizza2). pizza_onto.owl Best regards, Walter |
Administrator
|
Hi Walter,
I integrated this in the development version on Bitbucket. It works well for inferring Object property values (but not yet for data properties) ! Best regards, Jiba |
Administrator
|
Hi again,
I forget to mention that inferring property values is disabled by default. You need to activate it with the infer_property_values parameter as follows: sync_reasoner(infer_property_values = True) Jiba |
Test.owl
Hi Jiba, I have uploaded an owl file,in which I have created a Person class. hasfather and isfatherof are two object properties which are inverse of each other. (I am using release 0.14) Following are the relationships defined in the owl file. a) A isfatherof B b)B hasfather A c)C hasfather B. On running reasoner,it should infer 'B isfatherof C',but i am not getting the inferred value. code which I used after loading the ontology is: with onto: sync_reasoner(infer_property_values = True,keep_tmp_file = 1) |
Free forum by Nabble | Edit this page |