├── doc ├── _static │ └── empty.txt ├── _images │ ├── manual_installation.png │ ├── spyder_installation.png │ ├── terminal_installation.png │ └── protege_python_module_annotation.png ├── contact.rst ├── datatype.rst ├── index.rst ├── install.rst ├── rule.rst ├── intro.rst ├── porting1.rst ├── mixing_python_owl.rst ├── namespace.rst ├── world.rst └── disjoint.rst ├── test ├── Bench.class ├── Save.class ├── bench │ ├── dbtest_neo4j.class │ ├── dbtest_sqlobject.py │ ├── dbtest_mongodb.py │ ├── dbtest_sqlachemy.py │ ├── dbtest_neo4j.py │ ├── dbtest_owlready2.py │ └── dbtest_neo4j.java ├── test_quadstore_slash.sqlite3 ├── test_mixed.py ├── test_id.owl ├── test_url.owl ├── test_multiple_base_prop.owl ├── test_annotated_axiom3.owl ├── test_ontoslash3_imported.owl ├── test_ontoslash3.owl ├── test_ontoslash.owl ├── test_propchain.ntriples ├── test_ontoslash2.owl ├── test_ns.owl ├── test_datetime.owl ├── test_breakline.owl ├── test_undeclared_entity.owl ├── test_ontoslash3_owlxml.owl ├── test_ontoslash3_imported_owlxml.owl ├── test_ontoslash2_owlxml.owl ├── test_ontoslash_owlxml.owl ├── test_annot_literal.owl ├── test_propchain_owlxml.owl ├── drug.py ├── Save.java ├── test_ntriples_bug.ntriples ├── test_owlxml_2.ntriples ├── test_mixed.owl ├── bench.py ├── test_propchain.owl ├── test_owlxml_2.owl ├── test_inverse.owl ├── test_datatype_one_of_owlxml.owl ├── test_annot_on_bn.owl ├── test_annotated_axiom1.owl ├── test_datatype.owl ├── test_annotated_axiom2.owl ├── pizza_onto.owl ├── test_annot_on_bn2.owl ├── onto2.owl ├── test_datatype_one_of.owl ├── crepes_et_galettes.owl ├── test_owlxml.owl ├── test_owlxml_bug.owl ├── Bench.java ├── test_parser.py └── catalog-v001.xml ├── hermit ├── HermiT.jar └── org │ └── semanticweb │ └── HermiT │ ├── Reasoner.class │ ├── cli │ ├── Arg.class │ ├── Option.class │ ├── Option$1.class │ ├── CommandLine.class │ ├── CommandLine$Action.class │ ├── CommandLine$StatusOutput.class │ ├── CommandLine$SubsAction.class │ ├── CommandLine$SupersAction.class │ ├── CommandLine$ClassifyAction.class │ ├── CommandLine$EntailsAction.class │ ├── CommandLine$UsageException.class │ ├── CommandLine$DumpClausesAction.class │ ├── CommandLine$EquivalentsAction.class │ ├── CommandLine$DumpPrefixesAction.class │ └── CommandLine$SatisfiabilityAction.class │ ├── Reasoner$1.class │ ├── Reasoner$2.class │ ├── Reasoner$3.class │ ├── Reasoner$4.class │ ├── Reasoner$5.class │ ├── Reasoner$6.class │ ├── Reasoner$7.class │ ├── Reasoner$8.class │ ├── Reasoner$9.class │ ├── Reasoner$10.class │ ├── Reasoner$11.class │ ├── Reasoner$ReasonerFactory.class │ ├── hierarchy │ ├── InstanceManager.class │ ├── HierarchyDumperFSS.class │ ├── InstanceManager$1.class │ ├── HierarchyDumperFSS$DataRoleComparator.class │ ├── HierarchyDumperFSS$ObjectRoleComparator.class │ └── HierarchyDumperFSS$AtomicConceptComparator.class │ └── Reasoner$OntologyChangeListener.class ├── pellet ├── antlr-3.2.jar ├── log4j-1.2.16.jar ├── pellet-2.3.1.jar ├── aterm-java-1.6.jar ├── httpcore-4.2.2.jar ├── jena-arq-2.10.0.jar ├── jena-iri-0.9.5.jar ├── jena-tdb-0.10.0.jar ├── jgrapht-jdk1.5.jar ├── slf4j-api-1.6.4.jar ├── xml-apis-1.4.01.jar ├── antlr-runtime-3.2.jar ├── commons-codec-1.6.jar ├── httpclient-4.2.3.jar ├── jena-core-2.10.0.jar ├── xercesImpl-2.10.0.jar ├── jcl-over-slf4j-1.6.4.jar ├── slf4j-log4j12-1.6.4.jar ├── owlapi-distribution-3.4.3-bin.jar ├── LICENSE.txt ├── pellet │ └── PelletRealize.java └── org │ └── mindswap │ └── pellet │ └── taxonomy │ └── printer │ └── ClassTreePrinter.java ├── setup.cfg ├── TODO.rst ├── .gitignore ├── pymedtermino2 ├── __init__.py └── icd10_french.py ├── MANIFEST.in ├── owlready_ontology.owl ├── instance_editor_qt.py ├── setup.py ├── close.py ├── disjoint.py └── __init__.py /doc/_static/empty.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/Bench.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/test/Bench.class -------------------------------------------------------------------------------- /test/Save.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/test/Save.class -------------------------------------------------------------------------------- /hermit/HermiT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/HermiT.jar -------------------------------------------------------------------------------- /pellet/antlr-3.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/antlr-3.2.jar -------------------------------------------------------------------------------- /pellet/log4j-1.2.16.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/log4j-1.2.16.jar -------------------------------------------------------------------------------- /pellet/pellet-2.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/pellet-2.3.1.jar -------------------------------------------------------------------------------- /pellet/aterm-java-1.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/aterm-java-1.6.jar -------------------------------------------------------------------------------- /pellet/httpcore-4.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/httpcore-4.2.2.jar -------------------------------------------------------------------------------- /pellet/jena-arq-2.10.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/jena-arq-2.10.0.jar -------------------------------------------------------------------------------- /pellet/jena-iri-0.9.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/jena-iri-0.9.5.jar -------------------------------------------------------------------------------- /pellet/jena-tdb-0.10.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/jena-tdb-0.10.0.jar -------------------------------------------------------------------------------- /pellet/jgrapht-jdk1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/jgrapht-jdk1.5.jar -------------------------------------------------------------------------------- /pellet/slf4j-api-1.6.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/slf4j-api-1.6.4.jar -------------------------------------------------------------------------------- /pellet/xml-apis-1.4.01.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/xml-apis-1.4.01.jar -------------------------------------------------------------------------------- /pellet/antlr-runtime-3.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/antlr-runtime-3.2.jar -------------------------------------------------------------------------------- /pellet/commons-codec-1.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/commons-codec-1.6.jar -------------------------------------------------------------------------------- /pellet/httpclient-4.2.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/httpclient-4.2.3.jar -------------------------------------------------------------------------------- /pellet/jena-core-2.10.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/jena-core-2.10.0.jar -------------------------------------------------------------------------------- /pellet/xercesImpl-2.10.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/xercesImpl-2.10.0.jar -------------------------------------------------------------------------------- /test/bench/dbtest_neo4j.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/test/bench/dbtest_neo4j.class -------------------------------------------------------------------------------- /pellet/jcl-over-slf4j-1.6.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/jcl-over-slf4j-1.6.4.jar -------------------------------------------------------------------------------- /pellet/slf4j-log4j12-1.6.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/slf4j-log4j12-1.6.4.jar -------------------------------------------------------------------------------- /test/test_quadstore_slash.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/test/test_quadstore_slash.sqlite3 -------------------------------------------------------------------------------- /doc/_images/manual_installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/doc/_images/manual_installation.png -------------------------------------------------------------------------------- /doc/_images/spyder_installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/doc/_images/spyder_installation.png -------------------------------------------------------------------------------- /doc/_images/terminal_installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/doc/_images/terminal_installation.png -------------------------------------------------------------------------------- /pellet/owlapi-distribution-3.4.3-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/pellet/owlapi-distribution-3.4.3-bin.jar -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/Arg.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/Arg.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$1.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$2.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$3.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$4.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$5.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$5.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$6.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$6.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$7.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$7.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$8.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$8.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$9.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$9.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/Option.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/Option.class -------------------------------------------------------------------------------- /doc/_images/protege_python_module_annotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/doc/_images/protege_python_module_annotation.png -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$10.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$10.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$11.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$11.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/Option$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/Option$1.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$Action.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$Action.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$ReasonerFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$ReasonerFactory.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/hierarchy/InstanceManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/hierarchy/InstanceManager.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$StatusOutput.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$StatusOutput.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$SubsAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$SubsAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$SupersAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$SupersAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/hierarchy/InstanceManager$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/hierarchy/InstanceManager$1.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$ClassifyAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$ClassifyAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$EntailsAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$EntailsAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$UsageException.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$UsageException.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/Reasoner$OntologyChangeListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/Reasoner$OntologyChangeListener.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$DumpClausesAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$DumpClausesAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$EquivalentsAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$EquivalentsAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$DumpPrefixesAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$DumpPrefixesAction.class -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [install_lib] 2 | compile = 1 3 | optimize = 1 4 | 5 | [sdist] 6 | force-manifest = 1 7 | dist-dir = /home/jiba/dist 8 | formats = gztar 9 | -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/cli/CommandLine$SatisfiabilityAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/cli/CommandLine$SatisfiabilityAction.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS$DataRoleComparator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS$DataRoleComparator.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS$ObjectRoleComparator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS$ObjectRoleComparator.class -------------------------------------------------------------------------------- /hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS$AtomicConceptComparator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwin/owlready2/HEAD/hermit/org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS$AtomicConceptComparator.class -------------------------------------------------------------------------------- /TODO.rst: -------------------------------------------------------------------------------- 1 | Owlready2 TODO list 2 | =================== 3 | 4 | * Add support for property chain in entity.property.indirect() 5 | * Add functions/methods for copying entities from an ontology to another 6 | * Obtain individual property value inferred by HermiT 7 | 8 | * Support additional file formats: 9 | * OWL/XML write 10 | * JSON 11 | * OBO 12 | -------------------------------------------------------------------------------- /test/test_mixed.py: -------------------------------------------------------------------------------- 1 | from owlready2 import * 2 | 3 | 4 | onto = get_ontology("http://www.semanticweb.org/jiba/ontologies/2017/2/test_mixed.owl") 5 | 6 | 7 | class Parent(Thing): 8 | namespace = onto 9 | def test(self): return "ok1" 10 | def test_inherited(self): return "ok" 11 | 12 | class Child(Thing): 13 | namespace = onto 14 | def test(self): return "ok2" 15 | 16 | -------------------------------------------------------------------------------- /test/test_id.owl: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # These are some examples of commonly ignored file patterns. 2 | # You should customize this list as applicable to your project. 3 | # Learn more about .gitignore: 4 | # https://www.atlassian.com/git/tutorials/saving-changes/gitignore 5 | 6 | # Compiled Python bytecode 7 | *.py[cod] 8 | __pycache__ 9 | 10 | # Log files 11 | *.log 12 | 13 | *.old 14 | *.save 15 | *.bug 16 | *.egg-info 17 | build 18 | doc/doctrees/ 19 | doc/html/ 20 | 21 | # Generated by MacOS 22 | .DS_Store 23 | 24 | # Generated by Windows 25 | Thumbs.db -------------------------------------------------------------------------------- /doc/contact.rst: -------------------------------------------------------------------------------- 1 | 2 | Contact and links 3 | ================= 4 | 5 | A forum/mailing list is available for Owlready on Nabble: http://owlready.8326.n8.nabble.com 6 | 7 | In case of trouble, please write to the forum or contact Jean-Baptiste Lamy 8 | 9 | :: 10 | 11 | LIMICS 12 | University Paris 13, Sorbonne Paris Cité 13 | Bureau 149 14 | 74 rue Marcel Cachin 15 | 93017 BOBIGNY 16 | FRANCE 17 | 18 | Owlready on BitBucket (Git development repository): https://bitbucket.org/jibalamy/owlready 19 | -------------------------------------------------------------------------------- /test/test_url.owl: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/test_multiple_base_prop.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /pymedtermino2/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Owlready2 3 | # Copyright (C) 2019 Jean-Baptiste LAMY 4 | # LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142 5 | # University Paris 13, Sorbonne paris-Cité, Bobigny, France 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/test_annotated_axiom3.owl: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | female 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | global-include *.py 2 | global-include *.pyx 3 | global-include *.txt 4 | global-include *.owl 5 | global-include *.rdf 6 | global-include *.ntriples 7 | global-include *.nt 8 | global-include *.rst 9 | global-include *.png 10 | global-include *.svg 11 | 12 | graft doc 13 | graft test 14 | graft hermit 15 | graft pellet 16 | graft locale 17 | 18 | include ./LICENSE.txt 19 | include ./README.rst 20 | 21 | exclude .hg 22 | exclude .hg/* 23 | exclude .git 24 | exclude .git/* 25 | exclude .gitignore 26 | 27 | exclude doc/examples/contraindications.py 28 | 29 | global-exclude *.pyc 30 | global-exclude *.pyo 31 | global-exclude *.save 32 | global-exclude catalog-v001.xml 33 | global-exclude __pycache__ 34 | global-exclude test*.py 35 | 36 | exclude test/* 37 | include test/regtest.py 38 | include test/bench.py 39 | include test/Bench.java 40 | include test/Save.java 41 | include test/Save.class 42 | include test/test_mixed.py 43 | include test/test_parser.py 44 | include test/test_quadstore_slash.sqlite3 45 | include test/*.ntriples 46 | include test/*.owl 47 | -------------------------------------------------------------------------------- /test/test_ontoslash3_imported.owl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | TEST imported 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/test_ontoslash3.owl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | TEST 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/test_ontoslash.owl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | TEST 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/test_propchain.ntriples: -------------------------------------------------------------------------------- 1 | . 2 | . 3 | . 4 | . 5 | _:genid1 . 6 | _:genid2 . 7 | _:genid1 _:genid2 . 8 | _:genid2 . 9 | _:genid1 . 10 | -------------------------------------------------------------------------------- /test/test_ontoslash2.owl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | TEST 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/test_ns.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |

test

29 | 30 | 31 | 32 |
33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test/test_datetime.owl: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 2017-09-17T13:52:24Z 23 | 2019-07-26T17:44:50.984100 24 | 2019-07-26T17:44:50.984100Z 25 | 2019-07-26T17:44:50 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/bench/dbtest_sqlobject.py: -------------------------------------------------------------------------------- 1 | import os, time 2 | import sqlobject 3 | 4 | """ 5 | 6 | Random write: 51.22364591545335 objects/second 7 | Random read: 11727.926239654573 objects/second 8 | 9 | """ 10 | 11 | NB = 10000 12 | 13 | db_filename = "/home/jiba/tmp/bench_sqlobject.sqlite3" 14 | if os.path.exists(db_filename): os.unlink(db_filename) 15 | connection = sqlobject.connectionForURI("sqlite://%s" % db_filename) 16 | sqlobject.sqlhub.processConnection = connection 17 | 18 | class Node(sqlobject.SQLObject): 19 | label = sqlobject.StringCol() 20 | next = sqlobject.ForeignKey("Node") 21 | next_index = sqlobject.DatabaseIndex("next") 22 | Node.createTable() 23 | 24 | t = time.time() 25 | previous = None 26 | for i in range(NB): 27 | node = Node(label = "node number %s" % i, next = None) 28 | if previous: 29 | previous.next = node 30 | previous = node 31 | dt = time.time() - t 32 | print("Random write:", 1/dt*NB, "objects/second") 33 | 34 | 35 | 36 | t = time.time() 37 | node = list(Node.select(Node.q.label == "node number 0"))[0] 38 | while True: 39 | label = node.label 40 | if node.next: 41 | node = node.next 42 | else: 43 | break 44 | dt = time.time() - t 45 | print("Random read:", 1/dt*NB, "objects/second") 46 | 47 | if os.path.exists(db_filename): os.unlink(db_filename) 48 | -------------------------------------------------------------------------------- /test/bench/dbtest_mongodb.py: -------------------------------------------------------------------------------- 1 | import time 2 | import pymongo 3 | from bson.objectid import * 4 | 5 | """ 6 | 7 | Random write: 2289.2182089579446 objects/second 8 | Bulk read: 291903.5688436056 objects/second 9 | Random read: 4723.250955702068 objects/second 10 | 11 | """ 12 | 13 | NB = 10000 14 | 15 | 16 | client = pymongo.MongoClient() 17 | client.drop_database("test_bench") 18 | db = client.test_bench 19 | db_nodes = db.nodes 20 | 21 | t = time.time() 22 | previous = None 23 | for i in range(NB): 24 | doc = { "label" : "node number %s" % i } 25 | node = db_nodes.insert_one(doc).inserted_id 26 | if previous: 27 | db_nodes.update_one({"_id": previous}, { "$set" : {"next": [node]} }) 28 | previous = node 29 | dt = time.time() - t 30 | print("Random write:", 1/dt*NB, "objects/second") 31 | 32 | 33 | t = time.time() 34 | for doc in db_nodes.find(): 35 | next = doc.get("next") or [] 36 | label = doc.get("label") or "" 37 | dt = time.time() - t 38 | print("Bulk read:", 1/dt*NB, "objects/second") 39 | 40 | 41 | t = time.time() 42 | node = db_nodes.find_one({ "label" : "node number 0" }) 43 | while True: 44 | label = node["label"] 45 | if not "next" in node: break 46 | next = node["next"][0] 47 | node = db_nodes.find_one({ "_id" : next }) 48 | dt = time.time() - t 49 | print("Random read:", 1/dt*NB, "objects/second") 50 | 51 | client.drop_database("test_bench") 52 | -------------------------------------------------------------------------------- /test/test_breakline.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | Comment long 37 | on 38 | multiple lines with " and ’ and \ and & and < and > and é. 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /test/test_undeclared_entity.owl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | trunk 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | body 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /test/bench/dbtest_sqlachemy.py: -------------------------------------------------------------------------------- 1 | import os, time 2 | from sqlalchemy.ext.declarative import declarative_base 3 | from sqlalchemy import * 4 | from sqlalchemy.orm import * 5 | 6 | """ 7 | 8 | Random write: 156.8178246156252 objects/second 9 | Random read: 5345.280200970007 objects/second 10 | 11 | """ 12 | 13 | NB = 10000 14 | 15 | db_filename = "/home/jiba/tmp/bench_sqlalchemy.sqlite3" 16 | if os.path.exists(db_filename): os.unlink(db_filename) 17 | engine = create_engine("sqlite:///%s" % db_filename) 18 | SQLObject = declarative_base() 19 | 20 | class Node(SQLObject): 21 | __tablename__ = "Node" 22 | id = Column(Integer, primary_key = True) 23 | label = Column(String, index = True) 24 | next_id = Column(Integer, ForeignKey('Node.id'), index = True) 25 | next = relationship("Node") 26 | 27 | SQLObject.metadata.create_all(engine) 28 | Session = sessionmaker(bind = engine) 29 | session = Session() 30 | 31 | 32 | t = time.time() 33 | previous = None 34 | for i in range(NB): 35 | node = Node(label = "node number %s" % i) 36 | session.add(node) 37 | if previous: 38 | previous.next.append(node) 39 | previous = node 40 | session.commit() 41 | dt = time.time() - t 42 | print("Random write:", 1/dt*NB, "objects/second") 43 | 44 | 45 | 46 | t = time.time() 47 | node = list(session.query(Node).filter(Node.label == "node number 0"))[0] 48 | while True: 49 | label = node.label 50 | if node.next: 51 | node = node.next[0] 52 | else: 53 | break 54 | dt = time.time() - t 55 | print("Random read:", 1/dt*NB, "objects/second") 56 | 57 | if os.path.exists(db_filename): os.unlink(db_filename) 58 | -------------------------------------------------------------------------------- /doc/datatype.rst: -------------------------------------------------------------------------------- 1 | Datatypes 2 | ========= 3 | 4 | Owlready automatically recognizes and translates basic datatypes to Python, such as string, int, float, etc. 5 | 6 | 7 | Creating custom datatypes 8 | ------------------------- 9 | 10 | The declare_datatype() global function allows to declare a new datatype. It takes 4 arguments: 11 | 12 | * datatype: the Python datatype (for example, a Python type or class) 13 | * iri: the IRI used to represent the datatype in ontologies 14 | * parser: a function that takes a serialized string and returns the corresponding datatype 15 | * unparser: a function that takes a datatype and returns its serialization in a string 16 | 17 | The function returns the storid associated to the datatype. 18 | 19 | **Warning:** The datatype must be declared **BEFORE** loading any ontology that uses it. 20 | 21 | Here is an example for adding support for the XSD "hexBinary" datatype: 22 | 23 | :: 24 | 25 | >>> class Hex(object): 26 | ... def __init__(self, value): 27 | ... self.value = value 28 | 29 | >>> def parser(s): 30 | ... return Hex(int(s, 16)) 31 | 32 | >>> def unparser(x): 33 | ... h = hex(x.value)[2:] 34 | ... if len(h) % 2 != 0: return "0%s" % h 35 | ... return h 36 | 37 | >>> declare_datatype(Hex, "http://www.w3.org/2001/XMLSchema#hexBinary", parser, unparser) 38 | 39 | 40 | The datatype can then be used as any others: 41 | 42 | :: 43 | 44 | >>> onto = world.get_ontology("http://www.test.org/t.owl") 45 | 46 | >>> with onto: 47 | ... class p(Thing >> Hex): pass 48 | 49 | ... class C(Thing): pass 50 | 51 | ... c1 = C() 52 | ... c1.p.append(Hex(14)) 53 | -------------------------------------------------------------------------------- /test/test_ontoslash3_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | http://test.org/test_ontoslash3/imported.owl 26 | 27 | 28 | TEST 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /test/test_ontoslash3_imported_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | TEST imported 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/test_ontoslash2_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | http://www.semanticweb.org/jiba/ontologies/2017/0/test 26 | 27 | 28 | TEST 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /test/test_ontoslash_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | http://www.semanticweb.org/jiba/ontologies/2017/0/test 26 | 27 | 28 | TEST 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /test/test_annot_literal.owl: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | #C 23 | 8 24 | 25 | 26 | 27 | #C 28 | Annotation value 29 | 30 | 31 | 32 | #C 33 | Annotation with lang 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/bench/dbtest_neo4j.py: -------------------------------------------------------------------------------- 1 | import time 2 | from neo4j import GraphDatabase 3 | 4 | """ 5 | 6 | Random write: 245.33559386034676 objects/second 7 | Bulk read: 52825.918844916654 objects/second 8 | Random read: 223.60659061924466 objects/second 9 | 10 | """ 11 | 12 | db = GraphDatabase.driver("bolt://localhost", auth = ("", "")) 13 | session = db.session() 14 | 15 | NB = 10000 16 | 17 | """ 18 | Supprime toute la base : 19 | 20 | MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r 21 | 22 | """ 23 | 24 | t = time.time() 25 | #tx = session.begin_transaction() 26 | #tx.run("""CREATE INDEX ON :Node(label)""") 27 | #tx.commit() 28 | tx = session.begin_transaction() 29 | previous = None 30 | for i in range(NB): 31 | label = "node number %s" % i 32 | node = tx.run("""CREATE (x:Node {label:"%s"}) RETURN id(x)""" % label).value()[0] 33 | if previous: 34 | tx.run("""MATCH (x:Node) WHERE id(x)=%s MATCH (y:Node) WHERE id(y)=%s CREATE (x)-[:NEXT]->(y)""" % (previous, node)) 35 | previous = node 36 | tx.commit() 37 | dt = time.time() - t 38 | print("Random write:", 1/dt*NB, "objects/second") 39 | 40 | 41 | t = time.time() 42 | tx = session.begin_transaction() 43 | labels = tx.run("""MATCH (x:Node) RETURN x.label""").value() 44 | nexts = tx.run("""MATCH (x:Node)-[:NEXT]->(y:Node) RETURN id(x), id(y)""").values() 45 | tx.commit() 46 | dt = time.time() - t 47 | print("Bulk read:", 1/dt*NB, "objects/second") 48 | 49 | t = time.time() 50 | tx = session.begin_transaction() 51 | node = tx.run("""MATCH (x:Node) WHERE x.label="node number 0" RETURN id(x)""").value()[0] 52 | while True: 53 | label = tx.run("""MATCH (x:Node) WHERE id(x)=%s RETURN x.label""" % node).value()[0] 54 | nexts = tx.run("""MATCH (x:Node)-[:NEXT]->(y:Node) WHERE id(x)=%s RETURN id(y)""" % node).value() 55 | if nexts: 56 | node = nexts[0] 57 | else: 58 | break 59 | dt = time.time() - t 60 | print("Random read:", 1/dt*NB, "objects/second") 61 | -------------------------------------------------------------------------------- /test/test_propchain_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/drug.py: -------------------------------------------------------------------------------- 1 | # Entire source code for the example of the use case, 2 | # including the creation of the ontology from scratch, 3 | # the five steps described in the paper, 4 | # the creation of the reasoning classes and the execution of the reasoner, 5 | # and the generation of a table similar to table 4 (bottom). 6 | 7 | # Import OwlReady 8 | 9 | from owlready2 import * 10 | 11 | 12 | # Create the ontology from scratch 13 | 14 | onto = get_ontology("http://test.org/onto.owl") 15 | 16 | with onto: 17 | class Drug(Thing): 18 | def take(self): print("I took a drug") 19 | 20 | class ActivePrinciple(Thing): 21 | pass 22 | 23 | class has_for_active_principle(Drug >> ActivePrinciple): 24 | python_name = "active_principles" 25 | 26 | class Placebo(Drug): 27 | equivalent_to = [Drug & Not(has_for_active_principle.some(ActivePrinciple))] 28 | def take(self): print("I took a placebo") 29 | 30 | class SingleActivePrincipleDrug(Drug): 31 | equivalent_to = [Drug & has_for_active_principle.exactly(1, ActivePrinciple)] 32 | def take(self): print("I took a drug with a single active principle") 33 | 34 | class DrugAssociation(Drug): 35 | equivalent_to = [Drug & has_for_active_principle.min(2, ActivePrinciple)] 36 | def take(self): print("I took a drug with %s active principles" % len(self.active_principles)) 37 | 38 | acetaminophen = ActivePrinciple("acetaminophen") 39 | amoxicillin = ActivePrinciple("amoxicillin") 40 | clavulanic_acid = ActivePrinciple("clavulanic_acid") 41 | 42 | AllDifferent([acetaminophen, amoxicillin, clavulanic_acid]) 43 | 44 | drug1 = Drug(active_principles = [acetaminophen]) 45 | drug2 = Drug(active_principles = [amoxicillin, clavulanic_acid]) 46 | drug3 = Drug(active_principles = []) 47 | 48 | close_world(Drug) 49 | 50 | sync_reasoner_pellet() 51 | 52 | print("drug2 new Classes:", drug2.__class__) 53 | 54 | drug1.take() 55 | 56 | drug2.take() 57 | 58 | drug3.take() 59 | 60 | -------------------------------------------------------------------------------- /test/Save.java: -------------------------------------------------------------------------------- 1 | /* 2 | javac -cp ./antibio_arcenciel/owlready_cas_dut_1/owlapi-3.4.3.jar ./owlready2/test/Save.java 3 | java -cp ./antibio_arcenciel/owlready_cas_dut_1/owlapi-3.4.3.jar:./owlready2/test Save > /dev/null 4 | 5 | */ 6 | 7 | import java.io.*; 8 | import java.util.*; 9 | 10 | import org.semanticweb.owlapi.model.*; 11 | import org.semanticweb.owlapi.util.*; 12 | import org.semanticweb.owlapi.io.*; 13 | import org.semanticweb.owlapi.apibinding.*; 14 | import org.semanticweb.owlapi.vocab.*; 15 | import org.coode.owlapi.turtle.*; 16 | 17 | class Save { 18 | public static void main(String[] args) throws Exception { 19 | 20 | long t; 21 | 22 | OWLOntologyManager m = OWLManager.createOWLOntologyManager(); 23 | OWLDataFactory df = OWLManager.getOWLDataFactory(); 24 | 25 | m.addIRIMapper(new AutoIRIMapper(new File("/home/jiba/telechargements/base_med"), false)); 26 | 27 | IRI iri = IRI.create("file://" + args[0]); 28 | OWLOntology o = m.loadOntologyFromOntologyDocument(iri); 29 | 30 | File saveas = new File(args[2]); 31 | OWLOntologyFormat format = m.getOntologyFormat(o); 32 | OWLXMLOntologyFormat owlformat = new OWLXMLOntologyFormat(); 33 | RDFXMLOntologyFormat rdfformat = new RDFXMLOntologyFormat(); 34 | TurtleOntologyFormat ntformat = new TurtleOntologyFormat(); 35 | if (format.isPrefixOWLOntologyFormat()) { 36 | owlformat.copyPrefixesFrom(format.asPrefixOWLOntologyFormat()); 37 | rdfformat.copyPrefixesFrom(format.asPrefixOWLOntologyFormat()); 38 | ntformat .copyPrefixesFrom(format.asPrefixOWLOntologyFormat()); 39 | } 40 | if (args[1].equals("nt")) { 41 | m.saveOntology(o, ntformat, IRI.create(saveas.toURI())); 42 | } 43 | else if(args[1].equals("rdf")) { 44 | m.saveOntology(o, rdfformat, IRI.create(saveas.toURI())); 45 | } 46 | else{ 47 | m.saveOntology(o, owlformat, IRI.create(saveas.toURI())); 48 | } 49 | 50 | 51 | System.err.println("saved"); 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/bench/dbtest_owlready2.py: -------------------------------------------------------------------------------- 1 | import os, time, tempfile 2 | from owlready2 import * 3 | 4 | """ 5 | 6 | Random write: 12892.586777357414 objects/second 7 | Random read: 19158.756753497568 objects/second 8 | 9 | """ 10 | 11 | tmp = "/home/jiba/tmp/tmp_bench.sqlite3" # Not in /tmp because in is stored in memory 12 | NB = 10000 13 | 14 | first_world = World(filename = tmp) 15 | onto = first_world.get_ontology("http://test.org/onto.owl") 16 | 17 | t = time.time() 18 | with onto: 19 | class Node(Thing): pass 20 | class next(ObjectProperty): pass 21 | previous = None 22 | for i in range(NB): 23 | node = Node() 24 | node.label = "node number %s" % i 25 | if previous: previous.next = [node] 26 | previous = node 27 | first_world.save() 28 | dt = time.time() - t 29 | print("Random write:", 1/dt*NB, "objects/second") 30 | 31 | first_world.close() 32 | 33 | 34 | 35 | second_world = World(filename = tmp) # Force reloading -- Owlready has aggressive caching behaviour! 36 | onto = second_world.get_ontology("http://test.org/onto.owl").load() 37 | 38 | t = time.time() 39 | node = onto.node1 40 | while node.next: 41 | label = node.label[0] 42 | node = node.next [0] 43 | dt = time.time() - t 44 | print("Random read:", 1/dt*NB, "objects/second") 45 | 46 | # import rdflib 47 | # g = second_world.as_rdflib_graph() 48 | # g.query("""SELECT ?b WHERE { 49 | # ?b . }""") 50 | # second_world.close() 51 | 52 | 53 | # t = time.time() 54 | # third_world = World(filename = tmp) 55 | # onto = third_world.get_ontology("http://test.org/onto.owl").load() 56 | # g = third_world.as_rdflib_graph() 57 | # r = g.query("""SELECT ?l ?y WHERE { 58 | # ?x . 59 | # ?x ?l . 60 | # ?x ?y . 61 | # }""") 62 | 63 | # dt = time.time() - t 64 | # print("Bulk read:", 1/dt*NB, "objects/second") 65 | 66 | 67 | os.unlink(tmp) 68 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to Owlready2's documentation! 2 | ************************************* 3 | 4 | Owlready2 is a package for ontology-oriented programming in Python. It can load OWL 2.0 ontologies 5 | as Python objects, modify them, save them, and perform reasoning via HermiT 6 | (included). Owlready2 allows a transparent access to OWL ontologies (contrary 7 | to usual Java-based API). 8 | 9 | Owlready version 2 includes an optimized triplestore / quadstore, based on SQLite3. 10 | This quadstore is optimized both for performance and memory consumption. Contrary to version 1, 11 | Owlready2 can deal with big ontologies. Owlready2 can also access to UMLS and medical terminology 12 | (using the integrated PyMedTermino2 submodule). 13 | 14 | Owlready2 has been created at the LIMICS reseach lab, 15 | University Paris 13, Sorbonne Paris Cité, INSERM UMRS 1142, Paris 6 University, by 16 | Jean-Baptiste Lamy. It was initially developed during the VIIIP research project funded by ANSM, 17 | the French Drug Agency; 18 | this is why some examples in this documentation relate to drug ;). 19 | 20 | Owlready2 is available under the GNU LGPL licence v3. 21 | If you use Owlready2 in scientific works, **please cite the following article**: 22 | 23 | **Lamy JB**. 24 | `Owlready: Ontology-oriented programming in Python with automatic classification and high level constructs for biomedical ontologies. `_ 25 | **Artificial Intelligence In Medicine 2017**;80:11-28 26 | 27 | In case of troubles, questions or comments, please use this Forum/Mailing list: http://owlready.8326.n8.nabble.com 28 | 29 | 30 | Table of content 31 | ---------------- 32 | 33 | .. toctree:: 34 | intro.rst 35 | install.rst 36 | onto.rst 37 | class.rst 38 | properties.rst 39 | datatype.rst 40 | restriction.rst 41 | disjoint.rst 42 | mixing_python_owl.rst 43 | reasoning.rst 44 | annotations.rst 45 | namespace.rst 46 | world.rst 47 | rule.rst 48 | pymedtermino2.rst 49 | porting1.rst 50 | contact.rst 51 | -------------------------------------------------------------------------------- /test/test_ntriples_bug.ntriples: -------------------------------------------------------------------------------- 1 | . 2 | . 3 | . 4 | . 5 | _:genid1 . 6 | _:genid1 . 7 | _:genid2 . 8 | _:genid2 . 9 | _:genid4 _:genid3 . 10 | _:genid3 "100.0"^^ . 11 | _:genid6 _:genid5 . 12 | _:genid4 _:genid6 . 13 | _:genid5 "110.0"^^ . 14 | _:genid6 . 15 | _:genid2 _:genid4 . 16 | _:genid1 _:genid2 . 17 | _:genid1 . 18 | _:genid7 . 19 | _:genid8 . 20 | _:genid7 21 | _:genid7 . 22 | _:genid7 . 23 | -------------------------------------------------------------------------------- /test/test_owlxml_2.ntriples: -------------------------------------------------------------------------------- 1 | . 2 | . 3 | . 4 | . 5 | _:genid1 . 6 | _:genid1 . 7 | _:genid2 . 8 | _:genid2 . 9 | _:genid4 _:genid3 . 10 | _:genid3 "100.0"^^ . 11 | _:genid6 _:genid5 . 12 | _:genid4 _:genid6 . 13 | _:genid5 "110.0"^^ . 14 | _:genid6 . 15 | _:genid2 _:genid4 . 16 | _:genid1 _:genid2 . 17 | _:genid1 . 18 | _:genid7 . 19 | _:genid8 . 20 | _:genid7 _:genid8 . 21 | _:genid7 . 22 | _:genid7 . 23 | -------------------------------------------------------------------------------- /test/test_mixed.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | ]> 11 | 12 | 13 | 20 | 21 | test_mixed 22 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /owlready_ontology.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | ]> 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /test/bench.py: -------------------------------------------------------------------------------- 1 | # python ./owlready2/test/bench.py > /dev/null 2 | 3 | # python ./owlready2/test/bench.py -f > /dev/null 4 | 5 | #Load time 10.203434944152832 s. 6 | #List class time 11.326752662658691 s. 7 | 8 | import sys, time#, cProfile 9 | 10 | import owlready2 11 | from owlready2 import * 12 | 13 | t = time.time() 14 | 15 | if "-f" in sys.argv: 16 | default_world.set_backend(filename = "/home/jiba/tmp/go.sqlite3", exclusive = True) #, profiling = True) 17 | #default_world.set_backend("postgresql", user = "jiba") 18 | #default_world.set_backend("mysql", user = "jiba") 19 | 20 | onto_path.append(os.path.dirname(__file__)) 21 | onto_path.append("/home/jiba/telechargements/base_med/") 22 | 23 | #dron_ndc = get_ontology("http://purl.obolibrary.org/obo/dron/dron-ndc.owl").load() 24 | #dron = get_ontology("http://purl.obolibrary.org/obo/dron.owl").load() 25 | #vto = get_ontology("http://purl.obolibrary.org/obo/vto.owl").load() 26 | go = get_ontology("http://purl.obolibrary.org/obo/go.owl").load() 27 | #go = get_ontology("/tmp/go.nt").load() 28 | default_world.save() 29 | 30 | t = time.time() - t 31 | print("Load time %s s." % t, file = sys.stderr) 32 | 33 | 34 | t = time.time() 35 | 36 | obo = go.get_namespace("http://purl.obolibrary.org/obo/") 37 | 38 | #nb = 0 39 | #def render(entity): 40 | # global nb 41 | # nb += 1 42 | # label = entity.label.first() 43 | # if label: return "%s:'%s'" % (entity.name, label) 44 | # return entity.name 45 | #set_render_func(render) 46 | 47 | #for c in default_world.classes(): 48 | # print(repr(c)) 49 | # for parent in c.is_a: 50 | # print(" is a %s" % parent) 51 | 52 | def recursive(e, depth = 0): 53 | # global nb 54 | # nb += 1 55 | label = e.label 56 | if label: print("%s%s:%s" % (" " * depth, e.name, label[0])) 57 | else: print("%s%s" % (" " * depth, e.name)) 58 | for s in e.subclasses(): 59 | recursive(s, depth + 1) 60 | 61 | recursive(obo.GO_0005575) 62 | recursive(obo.GO_0008150) 63 | recursive(obo.GO_0003674) 64 | 65 | #go.save("/tmp/t.ntriples", "ntriples") 66 | #go.save("/tmp/t.owl", "rdfxml") 67 | 68 | t = time.time() - t 69 | print("List class time %s s." % t, file = sys.stderr) 70 | 71 | #default_world.graph.show_profiling() 72 | 73 | #print(nb, file = sys.stderr) 74 | 75 | #print(obo.GO_0000001) 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /doc/install.rst: -------------------------------------------------------------------------------- 1 | Owlready2 Installation 2 | ====================== 3 | 4 | Owlready2 can be installed with 'pip', the Python Package Installer. 5 | 6 | Owlready2 include an optimized Cython module. This module speeds up by about 20% the loading of large ontologies, 7 | but its use is entirely optional. 8 | To build this module, you need a C compiler, and to install the 'cython' Python package. 9 | 10 | On the contrary, if you don't have a C compiler, to **not build** the optimized module you need to uninstall 11 | Cython if it is already installed (or to use the manual installation described below). 12 | 13 | Owlready2 can be installed from terminal, from Python, or manually. 14 | 15 | 16 | Installation from terminal (Bash under Linux or DOS under Windows) 17 | ------------------------------------------------------------------ 18 | 19 | You can use the following Bash / DOS commands to install Owlready2 in a terminal: 20 | 21 | :: 22 | 23 | pip install owlready2 24 | 25 | .. figure:: _images/terminal_installation.png 26 | 27 | 28 | If you don't have the permissions for writing in system files, 29 | you can install Owlready2 in your user directory with this command: 30 | 31 | :: 32 | 33 | pip install --user owlready2 34 | 35 | 36 | 37 | Installation in Spyder / IDLE (or any other Python console) 38 | ----------------------------------------------------------- 39 | 40 | You can use the following Python commands to install Owlready2 from a Python 3.7.x console 41 | (including those found in Spyder3 or IDLE): 42 | 43 | :: 44 | 45 | >>> import pip.__main__ 46 | >>> pip.__main__._main(["install", "--user", "owlready2"]) 47 | 48 | .. figure:: _images/spyder_installation.png 49 | 50 | 51 | Manual installation 52 | ------------------- 53 | 54 | Owlready2 can also be installed manually in 3 steps: 55 | 56 | # Uncompress the Owlready2-0.21.tar.gz source release file (or any other version), for example in C:\\ under Windows 57 | 58 | # Rename the directory C:\\Owlready2-0.21 as C:\\owlready2 59 | 60 | # Add the C:\\ directory in your PYTHONPATH; this can be done in Python as follows: 61 | 62 | :: 63 | 64 | import sys 65 | sys.path.append("C:\") 66 | import owlready2 67 | 68 | 69 | In the following screenshot, I used /home/jiba/src instead of C:\\, under Linux: 70 | 71 | .. figure:: _images/manual_installation.png 72 | -------------------------------------------------------------------------------- /test/test_propchain.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ]> 15 | 16 | 17 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/bench/dbtest_neo4j.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | import org.neo4j.driver.v1.*; 5 | 6 | /* 7 | 8 | Random write: 247.56763 objects/second 9 | Random read: 267.50842 objects/second 10 | 11 | */ 12 | 13 | public class dbtest_neo4j { 14 | private static final int NB = 10000; 15 | 16 | public static void main( String... args ) throws Exception { 17 | long t, dt; 18 | Driver db = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "", "" ) ); 19 | Session session = db.session(); 20 | Transaction tx = session.beginTransaction(); 21 | tx.run("CREATE INDEX ON :Node(label)"); 22 | tx.success(); 23 | tx.close(); 24 | 25 | t = (new Date().getTime()); 26 | tx = session.beginTransaction(); 27 | Value node; 28 | Value previous = null; 29 | for (int i = 0; i < NB; i++) { 30 | String label = "node number " + i; 31 | node = tx.run("CREATE (x:Node {label:'" + label + "'}) RETURN id(x)").single().get(0); 32 | if (previous != null) { 33 | tx.run("MATCH (x:Node) WHERE id(x)=" + previous + " MATCH (y:Node) WHERE id(y)=" + node + " CREATE (x)-[:NEXT]->(y)"); 34 | } 35 | previous = node; 36 | } 37 | tx.success(); 38 | tx.close(); 39 | dt = (new Date().getTime()) - t; 40 | System.err.print("Random write: "); System.err.print(1.0f/(dt/1000.0f)*NB); System.err.println(" objects/second"); 41 | 42 | t = (new Date().getTime()); 43 | tx = session.beginTransaction(); 44 | node = tx.run("MATCH (x:Node) WHERE x.label='node number 0' RETURN id(x)").single().get(0); 45 | while (true) { 46 | Value label = tx.run("MATCH (x:Node) WHERE id(x)=" + node + " RETURN x.label").single().get(0); 47 | try { 48 | node = tx.run("MATCH (x:Node)-[:NEXT]->(y:Node) WHERE id(x)=" + node + " RETURN id(y)").single().get(0); 49 | } 50 | catch (org.neo4j.driver.v1.exceptions.NoSuchRecordException e) { break; } 51 | } 52 | tx.success(); 53 | tx.close(); 54 | dt = (new Date().getTime()) - t; 55 | System.err.print("Random read: "); System.err.print(1.0f/(dt/1000.0f)*NB); System.err.println(" objects/second"); 56 | 57 | } 58 | } 59 | 60 | /* 61 | 62 | javac -cp ~/src/neo4j-java-driver-1.0.0.jar ./dbtest_neo4j.java 63 | 64 | java -cp ~/src/neo4j-java-driver-1.0.0.jar:. dbtest_neo4j 65 | 66 | 67 | Supprime toute la base : 68 | 69 | MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r 70 | 71 | 72 | 73 | */ 74 | -------------------------------------------------------------------------------- /test/test_owlxml_2.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 100.0 42 | 43 | 44 | 110.0 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /instance_editor_qt.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Owlready2 3 | # Copyright (C) 2013-2019 Jean-Baptiste LAMY 4 | # LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142 5 | # University Paris 13, Sorbonne paris-Cité, Bobigny, France 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | import owlready2, owlready2.editor 21 | from owlready2 import * 22 | from owlready2.instance_editor import * 23 | 24 | import editobj3, editobj3.undoredo as undoredo, editobj3.introsp as introsp, editobj3.field as field, editobj3.editor as editor, editobj3.editor_qt as editor_qt 25 | 26 | import PyQt5.QtCore as qtcore 27 | import PyQt5.QtWidgets as qtwidgets 28 | import PyQt5.QtGui as qtgui 29 | 30 | 31 | class QtOntologyInstanceEditor(OntologyInstanceEditor, editor_qt.QtEditorTabbedDialog): 32 | def check_save(self): 33 | if self.undo_stack.undoables != self.last_undoables: 34 | box = qtwidgets.QMessageBox() 35 | box.setText(editobj3.TRANSLATOR(u"Save modifications before closing?")) 36 | box.setStandardButtons(qtwidgets.QMessageBox.Save | qtwidgets.QMessageBox.Discard | qtwidgets.QMessageBox.Cancel) 37 | box.setDefaultButton(qtwidgets.QMessageBox.Cancel) 38 | response = box.exec() 39 | 40 | if response == qtwidgets.QMessageBox.Discard: return 0 41 | if response == qtwidgets.QMessageBox.Cancel: return 1 42 | elif response == qtwidgets.QMessageBox.Save: 43 | self.on_save() 44 | return self.check_save() # The user may have canceled a "save as" dialog box ! 45 | 46 | else: return 0 47 | 48 | def prompt_save_filename(self): 49 | filename = qtwidgets.QFileDialog.getSaveFileName(self.window, editobj3.TRANSLATOR(u"Save as..."), os.path.join(onto_path[0], self.ontology.name), "OWL/XML (*.owl)")[0] 50 | return filename 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /test/test_inverse.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /pellet/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Dual Licensing 2 | -------------- 3 | 4 | Pellet is available under a dual licensing [1] scheme whereby use of Pellet 5 | in projects that are licensed so as to be compatible with AGPL Version 6 | 3 may use Pellet under the terms of the compatible license. Please see 7 | agpl-3.0.txt in the Pellet distribution for more details. 8 | 9 | However, if AGPL Version 3.0 terms are incompatible with your use of 10 | Pellet, alternative license terms are available from Clark & Parsia LLC -- 11 | please direct inquiries about Pellet licensing to sales@clarkparsia.com or 12 | +1 202 408 8770. 13 | 14 | Why Dual Licensing? 15 | ------------------- 16 | 17 | Dual licensing has two advantages in this case: 18 | 19 | 1. it lets us focus on building Pellet as the best available OWL reasoner 20 | 21 | 2. it lowers the barriers of evaluation and adoption for organizations who 22 | want to try OWL and Semantic Web technologies 23 | 24 | Which License Should I Choose? 25 | ------------------------------ 26 | 27 | If your software is licensed under a recognized open source license [2], you 28 | can use Pellet under its open source license terms (see agpl-3.0.txt) without 29 | further consideration. 30 | 31 | However, if your software is not licensed under an open source compatible 32 | license, such as a proprietary license, then you should contact Clark & 33 | Parsia LLC in order to arrange alternative license terms to cover your use 34 | of Pellet. 35 | 36 | In short, 37 | 38 | * If you derive a commercial advantage by using Pellet with a closed source 39 | solution, you must arrange alternative license terms for your use of 40 | Pellet which will, at a minimum, remove the need to publish your source 41 | code. 42 | 43 | * If you wish to use Pellet under its open source terms, you must 44 | contribute back to the community the source code for the solution you use 45 | Pellet with, so that others may benefit from it as you benefit from Pellet. 46 | 47 | License Inquiries 48 | ----------------- 49 | 50 | For more about Pellet's dual license terms, or to arrange proprietary 51 | or alternative licensing terms, please direct inquires to 52 | sales@clarkparsia.com or, via phone, +1 202 408 8770. 53 | 54 | [1] http://en.wikipedia.org/wiki/Dual_license 55 | [2] http://www.opensource.org/licenses 56 | -------------------------------------------------------------------------------- /test/test_datatype_one_of_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 1 38 | 2 39 | 3 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Annotation on a triple with a datatype value. 51 | 52 | 53 | 54 | 1 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /doc/rule.rst: -------------------------------------------------------------------------------- 1 | SWRL rules 2 | ========== 3 | 4 | SWRL rules can be used to integrate 'if... then...' rules in ontologies. 5 | 6 | Note: loading SWRL rules is **only** supported from RDF/XML and NTriples files, but not from OWL/XML files. 7 | 8 | 9 | Creating SWRL rules 10 | ------------------- 11 | 12 | The Imp class ("Implies") represent a rule. The easiest way to create a rule is to define it 13 | using a Protégé-like syntax, with the .set_as_rule() method. 14 | 15 | The following example use a rule to compute the per-tablet cost of a drug: 16 | 17 | :: 18 | 19 | >>> onto = get_ontology("http://test.org/drug.owl") 20 | 21 | >>> with onto: 22 | ... class Drug(Thing): pass 23 | ... class number_of_tablets(Drug >> int, FunctionalProperty): pass 24 | ... class price(Drug >> float, FunctionalProperty): pass 25 | ... class price_per_tablet(Drug >> float, FunctionalProperty): pass 26 | ... 27 | ... rule = Imp() 28 | ... rule.set_as_rule("""Drug(?d), price(?d, ?p), number_of_tablets(?d, ?n), divide(?r, ?p, ?n) -> price_per_tablet(?d, ?r)""") 29 | 30 | 31 | We can now create a drug, run the reasoner (only Pellet support inferrence on data property value) 32 | and print the result: 33 | :: 34 | 35 | >>> drug = Drug(number_of_tablets = 10, price = 25.0) 36 | >>> sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True) 37 | >>> drug.price_per_tablet 38 | 2.5 39 | 40 | 41 | Displaying rules 42 | ---------------- 43 | 44 | The str() Python function can be used to format rules, for example: 45 | 46 | :: 47 | 48 | >>> str(rule) 49 | 'Drug(?d), price(?d, ?p), number_of_tablets(?d, ?n), divide(?r, ?p, ?n) -> price_per_tablet(?d, ?r)' 50 | 51 | 52 | 53 | Modifying rules manually 54 | ------------------------ 55 | 56 | Owlready also allows to access to the inner content of rules. Each rules have a body (= conditions) 57 | and head (= consequences) : 58 | 59 | :: 60 | 61 | >>> rule.body 62 | [Drug(?d), price(?d, ?p), number_of_tablets(?d, ?n), divide(?r, ?p, ?n)] 63 | >>> rule.head 64 | [price_per_tablet(?d, ?r)] 65 | 66 | 67 | Body and head are list of SWRL atoms. The attributes of each atom can be read and modified: 68 | 69 | :: 70 | 71 | >>> rule.body[0] 72 | Drug(?d) 73 | >>> rule.body[0].class_predicate 74 | drug.Drug 75 | >>> rule.body[0].arguments 76 | [?d] 77 | 78 | Please refer to SWRL documentation for the list of atoms and their description. One notable difference is that 79 | Owlready always use the "arguments" attributes for accessing arguments, while SWRL uses sometimes "arguments" 80 | and sometimes "argument1" and "argument2". 81 | -------------------------------------------------------------------------------- /test/test_annot_on_bn.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Test 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /test/test_annotated_axiom1.owl: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | female 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /doc/intro.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | Owlready2 is a package for manipulating OWL 2.0 ontologies in Python. It can load, modify, save ontologies, and 5 | it supports reasoning via HermiT (included). Owlready allows a transparent access to OWL ontologies. 6 | 7 | Owlready2 can: 8 | 9 | - Import ontologies in RDF/XML, OWL/XML or NTriples format. 10 | 11 | - Manipulates ontology classes, instances and annotations as if they were Python objects. 12 | 13 | - Add Python methods to ontology classes. 14 | 15 | - Re-classify instances automatically, using the HermiT reasoner. 16 | 17 | - Import medical terminologies from UMLS (see :doc:`pymedtermino2`). 18 | 19 | 20 | If you need to "convert" formulas between Protégé, Owlready2 and/or Description Logics, the following cheat sheet may be of interest: 21 | 22 | `The great table of Description Logics and formal ontology notations `_ 23 | 24 | 25 | Short example: What can I do with Owlready? 26 | ------------------------------------------- 27 | 28 | Load an ontology from a local repository, or from Internet: 29 | 30 | :: 31 | 32 | >>> from owlready2 import * 33 | >>> onto_path.append("/path/to/your/local/ontology/repository") 34 | >>> onto = get_ontology("http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl") 35 | >>> onto.load() 36 | 37 | Create new classes in the ontology, possibly mixing OWL constructs and Python methods: 38 | 39 | :: 40 | 41 | >>> class NonVegetarianPizza(onto.Pizza): 42 | ... equivalent_to = [ 43 | ... onto.Pizza 44 | ... & ( onto.has_topping.some(onto.MeatTopping) 45 | ... | onto.has_topping.some(onto.FishTopping) 46 | ... ) ] 47 | 48 | ... def eat(self): print("Beurk! I'm vegetarian!") 49 | 50 | Access the classes of the ontology, and create new instances / individuals: 51 | 52 | :: 53 | 54 | >>> onto.Pizza 55 | pizza_onto.Pizza 56 | 57 | >>> test_pizza = onto.Pizza("test_pizza_owl_identifier") 58 | >>> test_pizza.has_topping = [ onto.CheeseTopping(), 59 | ... onto.TomatoTopping() ] 60 | 61 | In Owlready2, almost any lists can be modified *in place*, 62 | for example by appending/removing items from lists. 63 | Owlready2 automatically updates the RDF quadstore. 64 | 65 | :: 66 | 67 | >>> test_pizza.has_topping.append(onto.MeatTopping()) 68 | 69 | Perform reasoning, and classify instances and classes: 70 | 71 | :: 72 | 73 | >>> test_pizza.__class__ 74 | onto.Pizza 75 | 76 | >>> # Execute HermiT and reparent instances and classes 77 | >>> sync_reasoner() 78 | 79 | >>> test_pizza.__class__ 80 | onto.NonVegetarianPizza 81 | >>> test_pizza.eat() 82 | Beurk! I'm vegetarian ! 83 | 84 | Export to OWL file: 85 | 86 | :: 87 | 88 | >>> onto.save() 89 | 90 | 91 | Architecture 92 | ------------ 93 | 94 | Owlready2 maintains a RDF quadstore in an optimized database (SQLite3), 95 | either in memory or on the disk (see :doc:`world`). It provides a high-level access to the Classes and the 96 | objects in the ontology (aka. ontology-oriented programming). Classes and Invididuals are loaded 97 | dynamically from the quadstore as needed, cached in memory and destroyed when no longer needed. 98 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Owlready2 4 | # Copyright (C) 2013-2018 Jean-Baptiste LAMY 5 | 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU Lesser General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU Lesser General Public License for more details. 15 | 16 | # You should have received a copy of the GNU Lesser General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | import os, os.path, sys, glob 21 | 22 | HERE = os.path.dirname(sys.argv[0]) or "." 23 | 24 | if len(sys.argv) <= 1: sys.argv.append("install") 25 | 26 | import setuptools 27 | 28 | version = open(os.path.join(HERE, "__init__.py")).read().split('VERSION = "', 1)[1].split('"', 1)[0] 29 | 30 | def do_setup(extensions): 31 | setuptools.setup( 32 | name = "Owlready2", 33 | version = version, 34 | license = "LGPLv3+", 35 | description = "A package for ontology-oriented programming in Python: load OWL 2.0 ontologies as Python objects, modify them, save them, and perform reasoning via HermiT. Includes an optimized RDF quadstore.", 36 | long_description = open(os.path.join(HERE, "README.rst")).read(), 37 | 38 | author = "Lamy Jean-Baptiste (Jiba)", 39 | author_email = "jibalamy@free.fr", 40 | url = "https://bitbucket.org/jibalamy/owlready2", 41 | classifiers = [ 42 | "Development Status :: 5 - Production/Stable", 43 | "Intended Audience :: Developers", 44 | "Intended Audience :: Information Technology", 45 | "Intended Audience :: Science/Research", 46 | "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", 47 | "Operating System :: OS Independent", 48 | "Programming Language :: Python :: 3", 49 | "Programming Language :: Python :: 3 :: Only", 50 | "Programming Language :: Python :: 3.6", 51 | "Programming Language :: Python :: 3.7", 52 | "Programming Language :: Python :: Implementation :: CPython", 53 | "Programming Language :: Python :: Implementation :: PyPy", 54 | "Topic :: Scientific/Engineering :: Artificial Intelligence", 55 | "Topic :: Software Development :: Libraries :: Python Modules", 56 | ], 57 | 58 | package_dir = {"owlready2" : "."}, 59 | packages = ["owlready2", "owlready2.pymedtermino2"], 60 | package_data = {"owlready2" : ["owlready_ontology.owl", 61 | "hermit/*.*", "hermit/org/semanticweb/HermiT/*", "hermit/org/semanticweb/HermiT/cli/*", "hermit/org/semanticweb/HermiT/hierarchy/*", 62 | "pellet/*.*", "pellet/org/mindswap/pellet/taxonomy/printer/*", 63 | ]}, 64 | 65 | ext_modules = extensions, 66 | ) 67 | 68 | try: 69 | import Cython.Build 70 | extensions = [ 71 | setuptools.Extension("owlready2_optimized", ["owlready2_optimized.pyx"]), 72 | ] 73 | extensions = Cython.Build.cythonize(extensions, compiler_directives = { "language_level" : 3 }) 74 | do_setup(extensions) 75 | 76 | except: 77 | do_setup([]) 78 | -------------------------------------------------------------------------------- /test/test_datatype.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | ]> 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 10.0 45 | 46 | 47 | 20.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |

12.0

89 |
90 |
91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /test/test_annotated_axiom2.owl: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | female 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /doc/porting1.rst: -------------------------------------------------------------------------------- 1 | Differences between Owlready version 1 and 2 2 | ============================================ 3 | 4 | This section summarizes the major differences between Owlready version 1 and 2. 5 | 6 | 7 | Creation of Classes, Properties and Individuals 8 | ----------------------------------------------- 9 | 10 | The 'ontology' parameters is now called 'namespace' in Owlready2. It accepts a namespace or an ontology. 11 | 12 | Owlready 1: 13 | 14 | :: 15 | 16 | >>> class Drug(Thing): 17 | ... ontology = onto 18 | 19 | Owlready 2: 20 | 21 | :: 22 | 23 | >>> class Drug(Thing): 24 | ... namespace = onto 25 | 26 | 27 | Generated Individual names 28 | -------------------------- 29 | 30 | Owlready 1 permitted to generate dynamically Individual names, depending on their relations. 31 | This is no longer possible in Owlready 2, due to the different architecture. 32 | 33 | 34 | Functional properties 35 | --------------------- 36 | 37 | In Owlready 1, functional properties had default values depending on their range. For example, 38 | if the range was float, the default value was 0.0. 39 | 40 | In Owlready 2, functional properties always returns None if not relation has been asserted. 41 | 42 | 43 | Creation of restrictions 44 | ------------------------ 45 | 46 | In Owlready 1, restrictions were created by calling the property: 47 | 48 | :: 49 | 50 | >> Property(SOME, Range_Class) 51 | >> Property(ONLY, Range_Class) 52 | >> Property(MIN, cardinality, Range_Class) 53 | >> Property(MAX, cardinality, Range_Class) 54 | >> Property(EXACTLY, cardinality, Range_Class) 55 | >> Property(VALUE, Range_Instance) 56 | 57 | In Owlready 2, they are created by calling the .some(), .only(), .min(), .max(), .exactly() and .value() 58 | methods of the Property: 59 | 60 | :: 61 | 62 | >> Property.some(Range_Class) 63 | >> Property.only(Range_Class) 64 | >> Property.min(cardinality, Range_Class) 65 | >> Property.max(cardinality, Range_Class) 66 | >> Property.exactly(cardinality, Range_Class) 67 | >> Property.value(Range_Individual) 68 | 69 | 70 | Logical operators and 'One of' constructs 71 | ----------------------------------------- 72 | 73 | In Owlready 1, the negation was called 'NOT()'. 74 | In Owlready 2, the negation is now called 'Not()'. 75 | 76 | In Owlready 1, the logical operators (Or and And) and the one_of construct expect several values as parameters. 77 | 78 | :: 79 | 80 | >>> Or(ClassA, ClassB,...) 81 | 82 | In Owlready 2, the logical operators (Or and And) and the OneOf construct expect a list of values. 83 | 84 | :: 85 | 86 | >>> Or([ClassA, ClassB,...]) 87 | 88 | 89 | Reasoning 90 | --------- 91 | 92 | In Owlready 1, the reasoner was executed by calling ontology.sync_reasoner(). 93 | 94 | :: 95 | 96 | >>> onto.sync_reasoner() 97 | 98 | In Owlready 2, the reasoner is executed by calling sync_reasoner(). The reasoning can involve several ontologies 99 | (all those that have been loaded). sync_reasoner() actually acts on a World (see :doc:`world`). 100 | 101 | :: 102 | 103 | >>> sync_reasoner() 104 | 105 | 106 | Annotations 107 | ----------- 108 | 109 | In Owlready 1, annotations were available through the ANNOTATIONS pseudo-dictionary. 110 | 111 | :: 112 | 113 | >>> ANNOTATIONS[Drug]["label"] = "Label for Class Drug" 114 | 115 | 116 | 117 | In Owlready 2, annotations are available as normal attributes. 118 | 119 | :: 120 | 121 | >>> Drug.label = "Label for Class Drug" 122 | 123 | -------------------------------------------------------------------------------- /test/pizza_onto.owl: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /doc/mixing_python_owl.rst: -------------------------------------------------------------------------------- 1 | Mixing Python and OWL 2 | ===================== 3 | 4 | Adding Python methods to an OWL Class 5 | ------------------------------------- 6 | 7 | Python methods can be defined in ontology Classes as usual in Python. In the example below, the Drug Class 8 | has a Python method for computing the per-tablet cost of a Drug, using two OWL Properties (which have been 9 | renamed in Python, see :ref:`associating-python-alias-name-to-properties`): 10 | 11 | :: 12 | 13 | >>> from owlready2 import * 14 | 15 | >>> onto = get_ontology("http://test.org/onto.owl") 16 | 17 | >>> with onto: 18 | ... class Drug(Thing): 19 | ... def get_per_tablet_cost(self): 20 | ... return self.cost / self.number_of_tablets 21 | 22 | ... class has_for_cost(Drug >> float, FunctionalProperty): 23 | ... python_name = "cost" 24 | 25 | ... class has_for_number_of_tablets(Drug >> int, FunctionalProperty): 26 | ... python_name = "number_of_tablets" 27 | 28 | >>> my_drug = Drug(cost = 10.0, number_of_tablets = 5) 29 | >>> print(my_drug.get_per_tablet_cost()) 30 | 2.0 31 | 32 | 33 | Forward declarations 34 | -------------------- 35 | 36 | Sometimes, you may need to forward-declare a Class or a Property. 37 | If the same Class or Property (same name, same namespace) is redefined, the new definition **extends** 38 | the previous one (and do not replace it!). 39 | 40 | For example: 41 | 42 | :: 43 | 44 | >>> class has_for_active_principle(Property): pass 45 | 46 | >>> with onto: 47 | ... class Drug(Thing): pass 48 | 49 | ... class has_for_active_principle(Drug >> ActivePrinciple): pass 50 | 51 | ... class Drug(Thing): # Extends the previous definition of Drug 52 | ... is_a = [has_for_active_principle.some(ActivePrinciple)] 53 | 54 | (Notice that this definition of drug exclude Placebo). 55 | 56 | 57 | 58 | Associating a Python module to an OWL ontology 59 | ---------------------------------------------- 60 | 61 | It is possible to associate a Python module with an OWL ontology. When Owlready2 loads the ontology, 62 | it will automatically import the Python module. 63 | This is done with the 'python_module' annotation, which should be set on the ontology itself. 64 | The value should be the name of your Python module, *e.g.* 'my_package.my_module'. 65 | This annotation can be set with editor like Protégé, after importing the 'owlready_ontology.owl' ontology 66 | (file 'owlready2/owlready_ontology.owl' in Owlready2 sources, URI http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl): 67 | 68 | .. figure:: _images/protege_python_module_annotation.png 69 | 70 | The Python module can countain Class and Properties definitions, and methods. 71 | However, it does not need to include all the is-a relations, domain, range,...: any such relation 72 | defined in OWL does not need to be specified again in Python. Therefore, if your Class hierarchy is 73 | defined in OWL, you can create all Classes as child of Thing. 74 | 75 | For example, in file 'my_python_module.py': 76 | 77 | :: 78 | 79 | >>> from owlready2 import * 80 | 81 | >>> onto = get_ontology("http://test.org/onto.owl") # Do not load the ontology here! 82 | 83 | >>> with onto: 84 | ... class Drug(Thing): 85 | ... def get_per_tablet_cost(self): 86 | ... return self.cost / self.number_of_tablets 87 | 88 | 89 | And then, in OWL file 'onto.owl', you can define: 90 | 91 | * The 'python_module' annotation (value: 'my_python_module') 92 | * The 'Drug' Class with superclasses if needed 93 | * The 'has_for_cost' Property (ommitted in Python -- not needed because it has no method) 94 | * The 'has_for_number_of_tablets' Property (also ommitted) 95 | 96 | In this way, Owlready2 allows you to take the best of Python and OWL! 97 | -------------------------------------------------------------------------------- /pellet/pellet/PelletRealize.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006 - 2008, Clark & Parsia, LLC. 2 | // This source code is available under the terms of the Affero General Public 3 | // License v3. 4 | // 5 | // Please see LICENSE.txt for full license terms, including the availability of 6 | // proprietary exceptions. 7 | // Questions, comments, or requests for clarification: licensing@clarkparsia.com 8 | 9 | package pellet; 10 | 11 | import java.util.List; 12 | 13 | import org.mindswap.pellet.KnowledgeBase; 14 | import org.mindswap.pellet.Role; 15 | import org.mindswap.pellet.taxonomy.printer.ClassTreePrinter; 16 | import org.mindswap.pellet.taxonomy.printer.TaxonomyPrinter; 17 | 18 | import aterm.ATermAppl; 19 | 20 | /** 21 | *

22 | * Title: PelletRealize 23 | *

24 | *

25 | * Description: 26 | *

27 | *

28 | * Copyright: Copyright (c) 2008 29 | *

30 | *

31 | * Company: Clark & Parsia, LLC. 32 | *

33 | * 34 | * @author Markus Stocker 35 | */ 36 | public class PelletRealize extends PelletCmdApp { 37 | 38 | public PelletRealize() { 39 | super( ); 40 | } 41 | 42 | @Override 43 | public String getAppCmd() { 44 | return "pellet realize " + getMandatoryOptions() + "[options] ..."; 45 | } 46 | 47 | @Override 48 | public String getAppId() { 49 | return "PelletRealize: Compute and display the most specific instances for each class"; 50 | } 51 | 52 | @Override 53 | public PelletCmdOptions getOptions() { 54 | PelletCmdOptions options = getGlobalOptions(); 55 | 56 | options.add( getLoaderOption() ); 57 | options.add( getIgnoreImportsOption() ); 58 | options.add( getInputFormatOption() ); 59 | options.add( getInferPropValuesOption() ); 60 | options.add( getInferDataPropValuesOption() ); 61 | 62 | return options; 63 | } 64 | 65 | @Override 66 | public void run() { 67 | KnowledgeBase kb = getKB(); 68 | 69 | startTask( "consistency check" ); 70 | boolean isConsistent = kb.isConsistent(); 71 | finishTask( "consistency check" ); 72 | 73 | if( !isConsistent ) 74 | throw new PelletCmdException( "Ontology is inconsistent, run \"pellet explain\" to get the reason" ); 75 | 76 | startTask( "classification" ); 77 | kb.classify(); 78 | finishTask( "classification" ); 79 | 80 | startTask( "realization" ); 81 | kb.realize(); 82 | finishTask( "realization" ); 83 | 84 | TaxonomyPrinter printer = new ClassTreePrinter(); 85 | printer.print( kb.getTaxonomy() ); 86 | 87 | // Jiba 88 | 89 | if ( options.getOption( "infer-prop-values" ).getValue() != null ) { 90 | for( ATermAppl ind : kb.getIndividuals() ) { 91 | for( Role role : kb.getRBox().getRoles() ) { 92 | if( role.isAnon() ) continue; 93 | if( role.isObjectRole() ) { 94 | ATermAppl name = role.getName(); 95 | List values = kb.getObjectPropertyValues( name, ind ); 96 | for( ATermAppl value : values ) { 97 | System.out.println("PROPINST: " + ind + " " + name + " " + value); 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | if ( options.getOption( "infer-data-prop-values" ).getValue() != null ) { 105 | for( ATermAppl ind : kb.getIndividuals() ) { 106 | for( Role role : kb.getRBox().getRoles() ) { 107 | if( role.isAnon() ) continue; 108 | if( role.isDatatypeRole() ) { 109 | ATermAppl name = role.getName(); 110 | List values = kb.getDataPropertyValues( name, ind ); 111 | for( ATermAppl value : values ) { 112 | System.out.println("DATAPROPVAL: " + ind + " " + name + " " + value); 113 | } 114 | } 115 | } 116 | } 117 | } 118 | 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /test/test_annot_on_bn2.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Annot on C 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Annot on D 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /pellet/org/mindswap/pellet/taxonomy/printer/ClassTreePrinter.java: -------------------------------------------------------------------------------- 1 | // Portions Copyright (c) 2006 - 2008, Clark & Parsia, LLC. 2 | // Clark & Parsia, LLC parts of this source code are available under the terms of the Affero General Public License v3. 3 | // 4 | // Please see LICENSE.txt for full license terms, including the availability of proprietary exceptions. 5 | // Questions, comments, or requests for clarification: licensing@clarkparsia.com 6 | // 7 | // --- 8 | // Portions Copyright (c) 2003 Ron Alford, Mike Grove, Bijan Parsia, Evren Sirin 9 | // Alford, Grove, Parsia, Sirin parts of this source code are available under the terms of the MIT License. 10 | // 11 | // The MIT License 12 | // 13 | // Permission is hereby granted, free of charge, to any person obtaining a copy 14 | // of this software and associated documentation files (the "Software"), to 15 | // deal in the Software without restriction, including without limitation the 16 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 17 | // sell copies of the Software, and to permit persons to whom the Software is 18 | // furnished to do so, subject to the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be included in 21 | // all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 | // IN THE SOFTWARE. 30 | 31 | package org.mindswap.pellet.taxonomy.printer; 32 | 33 | import java.io.PrintWriter; 34 | import java.util.Iterator; 35 | import java.util.Set; 36 | 37 | import org.mindswap.pellet.PelletOptions; 38 | import org.mindswap.pellet.utils.ATermUtils; 39 | import org.mindswap.pellet.utils.QNameProvider; 40 | import org.mindswap.pellet.utils.TaxonomyUtils; 41 | 42 | import aterm.ATermAppl; 43 | 44 | /** 45 | *

Title:

46 | * 47 | *

Description: Specialized tree printer for class hierarchies that prints instaces for each class

48 | * 49 | *

Copyright: Copyright (c) 2007

50 | * 51 | *

Company: Clark & Parsia, LLC.

52 | * 53 | * @author Evren Sirin 54 | */ 55 | public class ClassTreePrinter extends TreeTaxonomyPrinter implements TaxonomyPrinter { 56 | private QNameProvider qnames = new QNameProvider(); 57 | 58 | public ClassTreePrinter() { 59 | } 60 | 61 | @Override 62 | protected void printNode(Set set) { 63 | super.printNode( set ); 64 | 65 | Set instances = TaxonomyUtils.getDirectInstances( taxonomy, set.iterator().next() ); 66 | if(instances.size() > 0) { 67 | out.print(" - ("); 68 | boolean printed = false; 69 | int anonCount = 0; 70 | Iterator ins = instances.iterator(); 71 | for(int k = 0; ins.hasNext(); k++) { 72 | ATermAppl x = ins.next(); 73 | 74 | if( ATermUtils.isBnode( x ) ) { 75 | anonCount++; 76 | } 77 | else { 78 | if(printed) 79 | out.print(", "); 80 | else 81 | printed = true; 82 | printURI(out, x); 83 | } 84 | } 85 | if(anonCount > 0) { 86 | if(printed) out.print(", "); 87 | out.print(anonCount + " Anonymous Individual"); 88 | if(anonCount > 1) out.print("s"); 89 | } 90 | out.print(")"); 91 | } 92 | } 93 | 94 | @Override 95 | protected void printURI(PrintWriter out, ATermAppl c) { 96 | String str = null; 97 | 98 | if(c.equals(ATermUtils.TOP)) 99 | str = "http://www.w3.org/2002/07/owl#Thing"; 100 | else if(c.equals(ATermUtils.BOTTOM)) 101 | str = "http://www.w3.org/2002/07/owl#Nothing"; 102 | else if( ATermUtils.isPrimitive( c ) ) 103 | str = c.getName(); 104 | else 105 | str = c.toString(); 106 | 107 | out.print( str ); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /doc/namespace.rst: -------------------------------------------------------------------------------- 1 | Namespaces 2 | ========== 3 | 4 | Ontologies can define entities located in other namespaces. 5 | An example is Gene Ontology (GO): the ontology IRI is 'http://purl.obolibrary.org/obo/go.owl', 6 | but the IRI of GO entities are not of the form 'http://purl.obolibrary.org/obo/go.owl#GO_entity' but 7 | 'http://purl.obolibrary.org/obo/GO_entity' (note the missing 'go.owl#'). 8 | 9 | 10 | Accessing entities defined in another namespace 11 | ----------------------------------------------- 12 | 13 | These entities can be accessed in Owlready2 using a namespace. The get_namepace(base_iri) global function 14 | returns a namespace for the given base IRI. 15 | 16 | The namespace can then be used with the dot notation, similarly to the ontology. 17 | 18 | :: 19 | 20 | >>> # Loads Gene Ontology (~ 170 Mb), can take a moment! 21 | >>> go = get_ontology("http://purl.obolibrary.org/obo/go.owl").load() 22 | 23 | >>> print(go.GO_0000001) # Not in the right namespace 24 | None 25 | 26 | >>> obo = get_namespace("http://purl.obolibrary.org/obo/") 27 | 28 | >>> print(obo.GO_0000001) 29 | obo.GO_0000001 30 | 31 | >>> print(obo.GO_0000001.iri) 32 | http://purl.obolibrary.org/obo/obo.GO_0000001 33 | 34 | >>> print(obo.GO_0000001.label) 35 | ['mitochondrion inheritance'] 36 | 37 | 38 | .get_namepace(base_iri) can also be called on an Ontology, for example: 39 | 40 | :: 41 | 42 | >>> obo = go.get_namespace("http://purl.obolibrary.org/obo/") 43 | 44 | Namespaces created on an Ontology can also be used for asserting facts and creating classes, instances,...: 45 | 46 | :: 47 | 48 | >>> with obo: 49 | >>> class MyNewClass(Thing): pass # Create http://purl.obolibrary.org/obo/MyNewClass 50 | 51 | 52 | Creating classes in a specific namespace 53 | ---------------------------------------- 54 | 55 | When creating a Class or a Property, 56 | the namespace attribute is used to build the full IRI of the Class, 57 | and to define in which ontology the Class is defined 58 | (RDF triples are added to this ontology). 59 | The Class IRI is equals to the namespace's base IRI (base_iri) + the Class name. 60 | 61 | An ontology can always be used as a namespace, as seen in :doc:`class`. 62 | A namespace object can be used if you want to locate the Class at a different IRI. 63 | For example: 64 | 65 | :: 66 | 67 | >>> onto = get_ontology("http://test.org/onto/") 68 | >>> namespace = onto.get_namespace("http://test.org/onto/pharmaco") 69 | 70 | >>> class Drug(Thing): 71 | ... namespace = namespace 72 | 73 | 74 | In the example above, the Drug Class IRI is "http://test.org/pharmaco/Drug", but the Drug Class 75 | belongs to the 'http://test.org/onto' ontology. 76 | 77 | Owlready2 proposes 3 methods for indicating the namespace: 78 | 79 | * the 'namespace' Class attribute 80 | * the 'with namespace' statement 81 | * if not provided, the namespace is inherited from the first parent Class 82 | 83 | The following examples illustrate the 3 methods: 84 | 85 | :: 86 | 87 | >>> class Drug(Thing): 88 | ... namespace = namespace 89 | 90 | >>> with namespace: 91 | ... class Drug(Thing): 92 | ... pass 93 | 94 | >>> class Drug2(Drug): 95 | ... # namespace is implicitely Drug.namespace 96 | ... pass 97 | 98 | 99 | Modifying a class defined in another ontology 100 | --------------------------------------------- 101 | 102 | In OWL, an ontology can also *modify* a Class already defined in another ontology. 103 | 104 | In Owlready2, this can be done using the 'with namespace' statement. 105 | Every RDF triples added (or deleted) inside a 'with namespace' statement 106 | goes in the ontology corresponding to the namespace of the 'with namespace' statement. 107 | 108 | The following example creates the Drug Class in a first ontology, 109 | and then asserts that Drug is a subclass of Substance in a second ontology. 110 | 111 | :: 112 | 113 | >>> onto1 = get_ontology("http://test.org/my_first_ontology.owl") 114 | >>> onto2 = get_ontology("http://test.org/my_second_ontology.owl") 115 | 116 | >>> with onto1: 117 | ... class Drug(Thing): 118 | ... pass 119 | 120 | >>> with onto2: 121 | ... class Substance(Thing): 122 | ... pass 123 | 124 | ... Drug.is_a.append(Substance) 125 | 126 | -------------------------------------------------------------------------------- /test/onto2.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | ]> 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 3 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /close.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Owlready2 3 | # Copyright (C) 2013-2019 Jean-Baptiste LAMY 4 | # LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142 5 | # University Paris 13, Sorbonne paris-Cité, Bobigny, France 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | from owlready2.namespace import * 21 | from owlready2.entity import * 22 | from owlready2.entity import _inherited_property_value_restrictions 23 | from owlready2.prop import * 24 | from owlready2.individual import * 25 | from owlready2.class_construct import * 26 | 27 | 28 | def close_world(self, Properties = None, close_instance_list = True, recursive = True): 29 | if isinstance(self, Thing): # An instance 30 | if Properties is None: 31 | Properties2 = (Prop for Prop in self._get_instance_possible_relations() if issubclass_python(Prop, ObjectProperty)) 32 | else: 33 | Properties2 = Properties 34 | 35 | for Prop in Properties2: 36 | range_instances = list(Prop[self]) 37 | range_classes = [] 38 | for r in _inherited_property_value_restrictions(self, Prop, set()): 39 | if (r.type == SOME): range_classes .append(r.value) 40 | elif (r.type == VALUE): range_instances.append(r.value) 41 | if range_instances: range_classes.append(OneOf(range_instances)) 42 | 43 | if not range_classes: self.is_a.append(Prop.only(Nothing)) 44 | elif issubclass_python(Prop, FunctionalProperty): pass 45 | elif len(range_classes) == 1: self.is_a.append(Prop.only(range_classes[0])) 46 | else: self.is_a.append(Prop.only(Or(range_classes))) 47 | 48 | elif isinstance(self, ThingClass): # A class 49 | instances = set(self.instances()) 50 | subclasses = set(self.descendants()) 51 | 52 | if close_instance_list: 53 | if instances: self.is_a.append(OneOf(list(instances))) 54 | 55 | if Properties is None: 56 | Properties2 = (Prop for Prop in self._get_class_possible_relations() if issubclass_python(Prop, ObjectProperty)) 57 | else: 58 | Properties2 = Properties 59 | 60 | for Prop in Properties2: 61 | range_instances = [] 62 | range_classes = [] 63 | for subclass in subclasses: # subclasses includes self 64 | for r in _inherited_property_value_restrictions(subclass, Prop, set()): 65 | if r.type == VALUE: 66 | range_instances.append(r.value) 67 | elif (r.type == SOME) or ((r.type == EXACTLY) and r.cardinality >= 1) or ((r.type == MIN) and r.cardinality >= 1): 68 | if isinstance(r.value, OneOf): range_instances.extend(r.value.instances) 69 | else: range_classes.append(r.value) 70 | 71 | for instance in instances: 72 | range_instances.extend(Prop[instance]) 73 | for r in _inherited_property_value_restrictions(instance, Prop, set()): 74 | if (r.type == SOME): range_classes .append(r.value) 75 | elif (r.type == VALUE): range_instances.append(r.value) 76 | 77 | if range_instances: range_classes.append(OneOf(range_instances)) 78 | if len(range_classes) == 1: self.is_a.append(Prop.only(range_classes[0])) 79 | elif range_classes: self.is_a.append(Prop.only(Or(range_classes))) 80 | else: self.is_a.append(Prop.only(Nothing)) 81 | 82 | if recursive: 83 | subclasses.discard(self) 84 | for subclass in subclasses: close_world(subclass, Properties, close_instance_list, False) 85 | for instance in instances: close_world(instance, Properties, close_instance_list, False) 86 | 87 | 88 | elif isinstance(self, Ontology): 89 | for individual in self.individuals(): 90 | close_world(individual, Properties, close_instance_list, recursive) 91 | 92 | for Class in self.classes(): 93 | close_world(Class, Properties, close_instance_list, False) # False because all the loop will already close subclasses 94 | 95 | -------------------------------------------------------------------------------- /test/test_datatype_one_of.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | ]> 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 1 66 | 67 | 68 | 69 | 2 70 | 71 | 72 | 73 | 3 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |

1

105 |
106 | 107 | 1 108 | Annotation on a triple with a datatype value. 109 | 110 | 111 | 112 |
113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /doc/world.rst: -------------------------------------------------------------------------------- 1 | Worlds 2 | ====== 3 | 4 | Owlready2 stores every triples in a 'World' object, and it can handles several Worlds 5 | in parallel. 'default_world' is the World used by default. 6 | 7 | 8 | Persistent world: storing the quadstore in an SQLite3 file database 9 | ------------------------------------------------------------------- 10 | 11 | Owlready2 uses an optimized quadstore. By default, the quadstore is stored in memory, but it can also be 12 | stored in an SQLite3 file. This allows persistance: all ontologies loaded and created are stored in the file, 13 | and can be reused later. 14 | This is interesting for big ontologies: loading huge ontologies can take time, while opening the SQLite3 file 15 | takes only a fraction of second, even for big files. 16 | It also avoid to load huge ontologies in memory, if you only need to access a few 17 | entities from these ontologies. 18 | 19 | The .set_backend() method of World sets the SQLite3 filename associated to the quadstore, 20 | for example: 21 | 22 | :: 23 | 24 | >>> default_world.set_backend(filename = "/path/to/your/file.sqlite3") 25 | 26 | .. note:: 27 | 28 | If the quad store is not empty when calling .set_backend(), RDF triples are automatically copied. 29 | However, this operation can have a high performance cost (especially if there are many triples). 30 | 31 | 32 | When using persistence, the .save() method of World must be called for saving the actual 33 | state of the quadstore in the SQLite3 file: 34 | 35 | :: 36 | 37 | >>> default_world.save() 38 | 39 | Storing the quadstore in a file does not reduce the performance of Owlready2 (actually, 40 | it seems that Owlready2 performs a little *faster* when storing the quadstore on the disk). 41 | 42 | To reload an ontology stored in the quadstore (when the corresponding OWL file has been updated), 43 | the reload and reload_if_newer optional parameters of .load() can be used (the former reload the ontology, 44 | and the latter reload it only if the OWL file is more recent). 45 | 46 | By default, Owlready2 opens the SQLite3 database in exclusive mode. This mode is faster, but it does not allow 47 | several programs to use the same database simultaneously. If you need to have several Python programs that 48 | access simultaneously the same Owlready2 quadstore, you can disable the exclusive mode as follows: 49 | 50 | :: 51 | 52 | >>> default_world.set_backend(filename = "/path/to/your/file.sqlite3", exclusive = False) 53 | 54 | 55 | 56 | Using several isolated Worlds 57 | ----------------------------- 58 | 59 | Owlready2 can support several, isolated, Worlds. 60 | This is interesting if you want to load several version 61 | of the same ontology, for example before and after reasoning. 62 | 63 | A new World can be created using the World class: 64 | 65 | :: 66 | 67 | >>> my_world = World() 68 | >>> my_second_world = World(filename = "/path/to/quadstore.sqlite3") 69 | 70 | Ontologies are then created and loaded using the .get_ontology() methods of the World 71 | (when working with several Worlds, this method replaces the get_ontology() global function): 72 | 73 | :: 74 | 75 | >>> onto = my_world.get_ontology("http://test.org/onto/").load() 76 | 77 | The World object can be used as a pseudo-dictionary for accessing entities using their IRI. 78 | (when working with several Worlds, this method replaces the IRIS global pseudo-dictionary): 79 | 80 | :: 81 | 82 | >>> my_world["http://test.org/onto/my_iri"] 83 | 84 | Finally, the reasoner can be executed on a specific World: 85 | 86 | :: 87 | 88 | >>> sync_reasoner(my_world) 89 | 90 | 91 | Working with RDFlib for performing SPARQL queries 92 | ------------------------------------------------- 93 | 94 | Owlready2 uses an optimized RDF quadstore. This quadstore can also be accessed 95 | as an RDFlib graph as follows: 96 | 97 | :: 98 | 99 | >>> graph = default_world.as_rdflib_graph() 100 | 101 | 102 | In particular, the RDFlib graph can be used for performing SPARQL queries: 103 | 104 | :: 105 | 106 | >>> r = list(graph.query("""SELECT ?p WHERE { 107 | ?p . 108 | }""")) 109 | 110 | 111 | 112 | 113 | The results can be automatically converted to Python and Owlready using the .query_owlready() method instead of .query(): 114 | 115 | :: 116 | 117 | >>> r = list(graph.query_owlready("""SELECT ?p WHERE { 118 | ?p . 119 | }""")) 120 | 121 | 122 | Owlready blank nodes can be created with the graph.BNode() method: 123 | 124 | :: 125 | 126 | >>> bn = graph.BNode() 127 | >>> with onto: 128 | ... graph.add((bn, rdflib.URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), rdflib.URIRef("http://www.w3.org/2002/07/owl#Class"))) 129 | -------------------------------------------------------------------------------- /test/crepes_et_galettes.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /test/test_owlxml.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | Test 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | #d2 154 | Test2 155 | 156 | 157 | 158 | xsd:string 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /test/test_owlxml_bug.owl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | ]> 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | Test 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 153 | #d2 154 | Test2 155 | 156 | 157 | 158 | xsd:string 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /doc/disjoint.rst: -------------------------------------------------------------------------------- 1 | Disjointness, open and local closed world reasoning 2 | =================================================== 3 | 4 | By default, OWL considers the world as 'open', *i.e.* everything that is not stated in the ontology is 5 | not 'false' but 'possible' (this is known as *open world assumption*). 6 | Therfore, things and facts that are 'false' or 'impossible' must be clearly stated as so in the ontology. 7 | 8 | Disjoint Classes 9 | ---------------- 10 | 11 | Two (or more) Classes are disjoint if there is no Individual belonging to all these Classes (remember that, 12 | contrary to Python instances, an Individual can have several Classes, see :doc:`class`). 13 | 14 | A Classes disjointness is created with the AllDisjoint() function, which takes a list of Classes 15 | as parameter. In the example below, we have two Classes, Drug and ActivePrinciple, and we assert that they 16 | are disjoint (yes, we need to specify that explicitely -- sometimes ontologies seem a little dumb!). 17 | 18 | :: 19 | 20 | >>> from owlready2 import * 21 | 22 | >>> onto = get_ontology("http://test.org/onto.owl") 23 | 24 | >>> with onto: 25 | ... class Drug(Thing): 26 | ... pass 27 | ... class ActivePrinciple(Thing): 28 | ... pass 29 | ... AllDisjoint([Drug, ActivePrinciple]) 30 | 31 | 32 | Disjoint Properties 33 | ------------------- 34 | 35 | OWL also introduces Disjoint Properties. 36 | Disjoint Properties can also be created using AllDisjoint(). 37 | 38 | 39 | Different Individuals 40 | --------------------- 41 | 42 | Two Individuals are different if they are distinct. In OWL, two Individuals might be considered as being actually 43 | the same, single, Individual, unless they are stated different. 44 | Difference is to Individuals what disjointness is to Classes. 45 | 46 | The following example creates two active principles and asserts that they are different (yes, we also need 47 | to state explicitely that acetaminophen and aspirin are not the same!) 48 | 49 | :: 50 | 51 | >>> acetaminophen = ActivePrinciple("acetaminophen") 52 | >>> aspirin = ActivePrinciple("aspirin") 53 | 54 | >>> AllDifferent([acetaminophen, aspirin]) 55 | 56 | .. note:: 57 | 58 | In Owlready2, AllDifferent is actually the same function as AllDisjoint -- the exact meaning depends on the 59 | parameters (AllDisjoint if you provide Classes, AllDifferent if you provide Instances, 60 | and disjoint Properties if you provide Properties). 61 | 62 | 63 | Querying and modifying disjoints 64 | -------------------------------- 65 | 66 | The .disjoints() method returns a generator for iterating over AllDisjoint constructs involving the given Class 67 | or Property. For Individuals, .differents() behaves similarly. 68 | 69 | :: 70 | 71 | >>> for d in Drug.disjoints(): 72 | ... print(d.entities) 73 | [onto.Drug, onto.ActivePrinciple] 74 | 75 | The 'entities' attribute of an AllDisjoint is writable, so you can modify the AllDisjoint construct by adding 76 | or removing entities. 77 | 78 | OWL also provides the 'disjointWith' and 'propertyDisjointWith' relations for pairwise disjoints (involving 79 | only two elements). Owlready2 exposes **all** disjoints as AllDisjoints, *including* those declared with 80 | the 'disjointWith' or 'propertyDisjointWith' relations. In the quad store (or when saving OWL files), 81 | disjoints involving 2 entities are defined using the 'disjointWith' or 'propertyDisjointWith' relations, 82 | while others are defined using AllDisjoint or AllDifferent. 83 | 84 | 85 | Closing Individuals 86 | ------------------- 87 | 88 | The open world assumption also implies that the properties of a given Individual are not limited to the 89 | ones that are explicitely stated. For example, if you create a Drug Individual with a single Active 90 | Principle, it does not mean that it has *only* a single Active Principle. 91 | 92 | :: 93 | 94 | >>> with onto: 95 | ... class has_for_active_principle(Drug >> ActivePrinciple): pass 96 | 97 | >>> my_acetaminophen_drug = Drug(has_for_active_principle = [acetaminophen]) 98 | 99 | In the example above, 'my_acetaminophen_drug' has an acetaminophen Active Principle (this fact is true) and it 100 | may have other Active Principle(s) (this fact is possible). 101 | 102 | If you want 'my_acetaminophen_drug' to be a Drug with acetaminophen and no other Active Principle, you have to 103 | state it explicitely using a restriction (see :doc:`restriction`): 104 | 105 | :: 106 | 107 | >>> my_acetaminophen_drug.is_a.append(has_for_active_principle.only(OneOf([acetaminophen]))) 108 | 109 | Notice that we used OneOf() to 'turn' the acetaminophen Individual into a Class that we can use in the restriction. 110 | 111 | You'll quickly find that the open world assumption often leads to tedious and long lists 112 | of AllDifference and Restrictions. Hopefully, Owlready2 provides the close_world() function for automatically 113 | 'closing' an Individual. close_world() will automatically add ONLY restrictions as needed; it accepts an 114 | optional parameter: a list of the Properties to 'close' (defaults to all Properties whose domain is 115 | compatible with the Individual). 116 | 117 | :: 118 | 119 | >>> close_world(my_acetaminophen_drug) 120 | 121 | 122 | Closing Classes 123 | --------------- 124 | 125 | close_world() also accepts a Class. In this case, it closes the Class, its subclasses, and all their Individuals. 126 | 127 | By default, when close_world() is not called, the ontology performs **open world reasoning**. 128 | By selecting the Classes and the Individuals you want to 'close', 129 | the close_world() function enables **local closed world reasoning** with OWL. 130 | 131 | Closing an ontology 132 | ------------------- 133 | 134 | Finally, close_world() also accepts an ontology. In this case, it closes all the Classes defined in the ontology. 135 | This corresponds to fully **closed world reasoning**. 136 | 137 | -------------------------------------------------------------------------------- /test/Bench.java: -------------------------------------------------------------------------------- 1 | /* 2 | cd ./owlready2/hermit 3 | /usr/lib/jvm/java-7-openjdk/bin/javac -cp .:HermiT.jar ./org/semanticweb/HermiT/cli/CommandLine.java ./org/semanticweb/HermiT/Reasoner.java ./org/semanticweb/HermiT/hierarchy/HierarchyDumperFSS.java ./org/semanticweb/HermiT/hierarchy/InstanceManager.java 4 | 5 | javac -cp ./antibio_arcenciel/owlready_cas_dut_1/owlapi-3.4.3.jar ./owlready2/test/Bench.java 6 | java -cp ./antibio_arcenciel/owlready_cas_dut_1/owlapi-3.4.3.jar:./owlready2/test Bench > /dev/null 7 | 8 | Loading 11.229 9 | Listing 4.528 10 | 11 | */ 12 | 13 | import java.io.*; 14 | import java.util.*; 15 | 16 | import org.semanticweb.owlapi.model.*; 17 | import org.semanticweb.owlapi.util.*; 18 | import org.semanticweb.owlapi.io.*; 19 | import org.semanticweb.owlapi.apibinding.*; 20 | import org.semanticweb.owlapi.vocab.*; 21 | 22 | class Bench { 23 | static int nb = 0; 24 | 25 | public static void main(String[] args) throws Exception { 26 | 27 | long t; 28 | 29 | OWLOntologyManager m = OWLManager.createOWLOntologyManager(); 30 | OWLDataFactory df = OWLManager.getOWLDataFactory(); 31 | 32 | t = (new Date().getTime()); 33 | 34 | IRI iri = IRI.create("file:///home/jiba/telechargements/base_med/go.owl"); 35 | //IRI iri = IRI.create("file:///home/jiba/telechargements/base_med/obi.owl"); 36 | //IRI iri = IRI.create("file:///home/jiba/telechargements/base_med/vto.owl"); 37 | //IRI iri = IRI.create("file:///home/jiba/telechargements/base_med/uberon.owl"); 38 | //IRI iri = IRI.create("file:///home/jiba/src/owlready2/test/test.owl"); 39 | OWLOntology o = m.loadOntologyFromOntologyDocument(iri); 40 | 41 | t = (new Date().getTime()) - t; 42 | System.err.print("Loading "); 43 | System.err.println(t / 1000.0f); 44 | 45 | /* 46 | File saveas = new File("/home/jiba/telechargements/base_med/go2.owl"); 47 | OWLOntologyFormat format = m.getOntologyFormat(o); 48 | OWLXMLOntologyFormat owlxmlFormat = new OWLXMLOntologyFormat(); 49 | if (format.isPrefixOWLOntologyFormat()) { 50 | owlxmlFormat.copyPrefixesFrom(format.asPrefixOWLOntologyFormat()); 51 | } 52 | m.saveOntology(o, owlxmlFormat, IRI.create(saveas.toURI())); 53 | 54 | System.err.println("saved"); 55 | */ 56 | 57 | 58 | 59 | t = (new Date().getTime()); 60 | 61 | /* 62 | int nb = 0; 63 | for (OWLClass cls : o.getClassesInSignature()) { 64 | nb += 1; 65 | System.out.println(cls_2_str(df, o, cls)); 66 | Set superClasses = cls.getSuperClasses(o); 67 | for (OWLClassExpression desc : superClasses) { 68 | System.out.print(" is a "); 69 | if(desc instanceof OWLClass) { 70 | System.out.println(cls_2_str(df, o, (OWLClass) desc)); 71 | } 72 | else if(desc instanceof OWLObjectSomeValuesFrom) { 73 | OWLObjectSomeValuesFrom some = (OWLObjectSomeValuesFrom) desc; 74 | Object prop = some.getProperty(); 75 | Object fill = some.getFiller(); 76 | if (prop instanceof OWLEntity) 77 | System.out.print (cls_2_str(df, o, (OWLEntity) prop)); 78 | else 79 | System.out.print (prop); 80 | System.out.print (" some "); 81 | if (fill instanceof OWLEntity) 82 | System.out.println(cls_2_str(df, o, (OWLEntity) fill)); 83 | else 84 | System.out.println(fill); 85 | } 86 | else { 87 | System.out.println(desc); 88 | } 89 | } 90 | } 91 | */ 92 | 93 | recursive(df, o, df.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0005575")), 0); 94 | recursive(df, o, df.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0008150")), 0); 95 | recursive(df, o, df.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0003674")), 0); 96 | 97 | System.err.print("NB "); 98 | System.err.println(nb); 99 | 100 | t = (new Date().getTime()) - t; 101 | System.err.print("Listing "); 102 | System.err.println(t / 1000.0f); 103 | 104 | Thread.sleep(40000); 105 | } 106 | 107 | public static void recursive(OWLDataFactory df, OWLOntology o, OWLClass cls, int depth) { 108 | String iri = cls.getIRI().toString(); 109 | String name = iri.substring(iri.lastIndexOf("/") + 1, iri.length()); 110 | 111 | OWLAnnotationProperty label = df.getOWLAnnotationProperty(OWLRDFVocabulary.RDFS_LABEL.getIRI()); 112 | 113 | String tab = ""; 114 | for (int i = 0; i < depth; i++) { 115 | tab += " "; 116 | } 117 | 118 | boolean ok = false; 119 | for (OWLAnnotation annotation : cls.getAnnotations(o, label)) { 120 | if (annotation.getValue() instanceof OWLLiteral) { 121 | OWLLiteral val = (OWLLiteral) annotation.getValue(); 122 | System.out.println(tab + name + ":" + val.getLiteral()); 123 | ok = true; 124 | break; 125 | } 126 | } 127 | if (ok == false) { 128 | System.out.println(tab + name); 129 | } 130 | 131 | nb += 1; 132 | 133 | Set subClasses = cls.getSubClasses(o); 134 | for (OWLClassExpression desc : subClasses) { 135 | if(desc instanceof OWLClass) { 136 | recursive(df, o, (OWLClass) desc, depth + 1); 137 | } 138 | } 139 | } 140 | 141 | public static String cls_2_str(OWLDataFactory df, OWLOntology o, OWLEntity cls) { 142 | String iri = cls.getIRI().toString(); 143 | String name = iri.substring(iri.lastIndexOf("/") + 1, iri.length()); 144 | 145 | OWLAnnotationProperty label = df.getOWLAnnotationProperty(OWLRDFVocabulary.RDFS_LABEL.getIRI()); 146 | 147 | for (OWLAnnotation annotation : cls.getAnnotations(o, label)) { 148 | if (annotation.getValue() instanceof OWLLiteral) { 149 | OWLLiteral val = (OWLLiteral) annotation.getValue(); 150 | return name + ":'" + val.getLiteral() + "'"; 151 | } 152 | } 153 | return name; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /pymedtermino2/icd10_french.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Owlready2 3 | # Copyright (C) 2019 Jean-Baptiste LAMY 4 | # LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142 5 | # University Paris 13, Sorbonne paris-Cité, Bobigny, France 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import sys, os, io, types, zipfile, urllib.request 22 | from collections import defaultdict, Counter 23 | from owlready2 import * 24 | 25 | 26 | def import_icd10_french(atih_data = "https://www.atih.sante.fr/plateformes-de-transmission-et-logiciels/logiciels-espace-de-telechargement/telecharger/gratuit/11616/456"): 27 | PYM = get_ontology("http://PYM/").load() 28 | ICD10 = PYM["ICD10"] 29 | 30 | print("Importing CIM10 from %s..." % atih_data) 31 | if atih_data.startswith("http:") or atih_data.startswith("https:"): 32 | f = urllib.request.urlopen(atih_data) 33 | f = io.BytesIO(f.read()) 34 | else: 35 | f = open(atih_data, "rb") 36 | 37 | parents = [] 38 | 39 | onto = get_ontology("http://atih/cim10/") 40 | with onto: 41 | class mco_had(AnnotationProperty): pass 42 | class psy (AnnotationProperty): pass 43 | class ssr (AnnotationProperty): pass 44 | 45 | with onto.get_namespace("http://PYM/SRC/"): 46 | ICD10_FRENCH = types.new_class("CIM10", (PYM["SRC"],)) 47 | onto._set_obj_triple_spo (ICD10_FRENCH.storid, PYM.terminology.storid, PYM["SRC"].storid) 48 | onto._set_data_triple_spod(ICD10_FRENCH.storid, label.storid, "CIM10", "@fr") 49 | 50 | with onto.get_namespace("http://PYM/CIM10/"): 51 | for line in open(os.path.join(os.path.dirname(__file__), "icd10_french_group_name.txt")).read().split(u"\n"): 52 | line = line.strip() 53 | if line and not line.startswith("#"): 54 | code, term = line.split(" ", 1) 55 | icd10 = ICD10[code] 56 | if not icd10: 57 | icd10 = ICD10["%s.9" % code] 58 | if not icd10: 59 | if code == "B95-B98": icd10 = ICD10["B95-B97.9"] 60 | elif code == "G10-G14": icd10 = ICD10["G10-G13.9"] 61 | elif code == "J09-J18": icd10 = ICD10["J10-J18.9"] 62 | elif code == "K55-K64": icd10 = ICD10["K55-K63.9"] 63 | elif code == "O94-O99": icd10 = ICD10["O95-O99.9"] 64 | 65 | if icd10 is None: 66 | if not code in {"C00-C75", "V01-X59", "U00-U99", "U00-U49", "U82-U85", "U90-U99"}: 67 | print("WARNING: cannot align %s (%s) with ICD10 in UMLS!" % (code, term)) 68 | 69 | start, end = code.split("-") 70 | end = "%s.99" % end 71 | for parent_start, parent_end, parent in parents: 72 | if (start >= parent_start) and (end <= parent_end): 73 | break 74 | else: 75 | if not code in {'F00-F99', 'H60-H95', 'E00-E90', 'R00-R99', 'L00-L99', 'O00-O99', 'C00-D48', 'M00-M99', 'U00-U99', 'S00-T98', 'K00-K93', 'G00-G99', 'I00-I99', 'H00-H59', 'N00-N99', 'V01-Y98', 'Q00-Q99', 'P00-P96', 'Z00-Z99', 'A00-B99', 'D50-D89', 'J00-J99'}: 76 | print("WARNING: cannot find parent for %s (%s)!" % (code, term)) 77 | parent = ICD10_FRENCH 78 | 79 | icd10_french = types.new_class(code, (parent,)) 80 | icd10_french.label = locstr(term, "fr") 81 | onto._set_obj_triple_spo(icd10_french.storid, PYM.terminology.storid, ICD10_FRENCH.storid) 82 | if icd10: 83 | icd10.unifieds = icd10.unifieds 84 | #with PYM: 85 | for cui in icd10.unifieds: cui.originals.append(icd10_french) 86 | 87 | parents.append((start, end, icd10_french)) 88 | 89 | 90 | with zipfile.ZipFile(f, "r") as atih_zip: 91 | for line in atih_zip.open("LIBCIM10MULTI.TXT", "r"): 92 | if isinstance(line, bytes): line = line.decode("latin") 93 | line = line.strip() 94 | code, mco_had, ssr, psy, term_court, term = line.split("|") 95 | code = code.strip() 96 | if len(code) > 3: code = "%s.%s" % (code[:3], code[3:]) 97 | 98 | 99 | if "+" in code: 100 | parent_code = code.split("+", 1)[0] 101 | else: 102 | parent_code = code[:-1] 103 | if parent_code.endswith("."): parent_code = code[:-2] 104 | parent = ICD10_FRENCH[parent_code] 105 | 106 | if not parent: 107 | code2 = code.split("+", 1)[0] 108 | for parent_start, parent_end, parent in reversed(parents): 109 | if (code2 >= parent_start) and (code2 <= parent_end): 110 | break 111 | else: 112 | print("WARNING: cannot find parent for %s (%s)!" % (code, term)) 113 | parent = None 114 | 115 | icd10 = ICD10[code] 116 | 117 | if term.startswith("*** SU16 *** "): term = term.replace("*** SU16 *** ", "") 118 | 119 | icd10_french = types.new_class(code, (parent,)) 120 | onto._set_obj_triple_spo(icd10_french.storid, PYM.terminology.storid, ICD10_FRENCH.storid) 121 | icd10_french.label = locstr(term, "fr") 122 | icd10_french.mco_had = [int(mco_had)] 123 | icd10_french.ssr = [ssr] 124 | icd10_french.psy = [int(psy)] 125 | if icd10: 126 | icd10_french.unifieds = icd10.unifieds 127 | #with PYM: 128 | for cui in icd10.unifieds: cui.originals.append(icd10_french) 129 | 130 | default_world.save() 131 | 132 | -------------------------------------------------------------------------------- /disjoint.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Owlready2 3 | # Copyright (C) 2013-2019 Jean-Baptiste LAMY 4 | # LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142 5 | # University Paris 13, Sorbonne paris-Cité, Bobigny, France 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | from owlready2.namespace import * 21 | from owlready2.entity import * 22 | from owlready2.prop import * 23 | from owlready2.class_construct import * 24 | 25 | 26 | class AllDisjoint(object): 27 | def __init__(self, entities, ontology = None, bnode = None): 28 | #if not CURRENT_NAMESPACES[-1] is None: self.ontology = CURRENT_NAMESPACES[-1].ontology 29 | #else: self.ontology = ontology or entities[0].namespace.ontology 30 | self.ontology = (CURRENT_NAMESPACES.get() and CURRENT_NAMESPACES.get()[-1]) or ontology or entities[0].namespace.ontology 31 | 32 | # For AllDisjoint, storid can be either: 33 | # * a blank node, when at least 3 entities are involved 34 | # * a triple, when only 2 entities, e.g. (entity1.storid, owl_disjointwith, entity2.storid) 35 | 36 | if isinstance(entities, int): 37 | assert isinstance(bnode, int) 38 | self.storid = bnode 39 | self._list_bnode = entities 40 | elif isinstance(entities, tuple): 41 | self.storid = entities 42 | else: 43 | self.storid = bnode 44 | self._list_bnode = None 45 | self.entities = self.Properties = self.individuals = CallbackList(entities, self, AllDisjoint._callback) 46 | 47 | if not LOADING: self._create_triples() 48 | 49 | def __getattr__(self, attr): 50 | if attr == "entities": 51 | if isinstance(self.storid, int): 52 | r = self.ontology._parse_list(self._list_bnode) 53 | else: 54 | r = [self.ontology.world._to_python(self.storid[0]), self.ontology.world._to_python(self.storid[2])] 55 | r = CallbackList(r, self, AllDisjoint._callback) 56 | setattr(self, attr,r) 57 | return r 58 | return super().__getattribute__(attr) 59 | 60 | def _callback(self, old): 61 | if self.ontology: 62 | self._destroy_triples() 63 | self._create_triples () 64 | 65 | def _destroy_triples(self): 66 | if isinstance(self.storid, int): 67 | self.ontology._del_obj_triple_spo(self.storid, None, None) 68 | self.ontology._del_list(self._list_bnode) 69 | elif isinstance(self.storid, tuple): 70 | self.ontology._del_obj_triple_spo(*self.storid) 71 | 72 | def destroy(self): self._destroy_triples() 73 | 74 | def _create_triples(self): 75 | for entity in self.entities: 76 | if isinstance(entity, Construct): entity._set_ontology(self.ontology) 77 | 78 | if len(self.entities) == 2: 79 | if isinstance(self.entities[0], ThingClass): 80 | self.storid = (self.entities[0].storid, owl_disjointwith, self.entities[1].storid) 81 | self.ontology._add_obj_triple_spo(*self.storid) 82 | return 83 | elif isinstance(self.entities[0], PropertyClass): 84 | self.storid = (self.entities[0].storid, owl_propdisjointwith, self.entities[1].storid) 85 | self.ontology._add_obj_triple_spo(*self.storid) 86 | return 87 | # It seems that there is no 1-1 relation for individuals 88 | # => continue 89 | 90 | if len(self.entities) >= 2: 91 | if not isinstance(self.storid, int): self.storid = self.ontology.world.new_blank_node() 92 | if not self._list_bnode: self._list_bnode = self.ontology.world.new_blank_node() 93 | 94 | if isinstance(self.entities[0], ThingClass): 95 | self.ontology._add_obj_triple_spo(self.storid, rdf_type, owl_alldisjointclasses) 96 | self.ontology._add_obj_triple_spo(self.storid, owl_members, self._list_bnode) 97 | 98 | elif isinstance(self.entities[0], PropertyClass): 99 | self.ontology._add_obj_triple_spo(self.storid, rdf_type, owl_alldisjointproperties) 100 | self.ontology._add_obj_triple_spo(self.storid, owl_members, self._list_bnode) 101 | 102 | else: # Individuals 103 | self.ontology._add_obj_triple_spo(self.storid, rdf_type, owl_alldifferent) 104 | self.ontology._add_obj_triple_spo(self.storid, owl_distinctmembers, self._list_bnode) 105 | 106 | self.ontology._set_list(self._list_bnode, self.entities) 107 | 108 | def __repr__(self): 109 | if self.ontology != self.entities[0].namespace.ontology: onto = ", ontology = %s" % self.ontology 110 | else: onto = "" 111 | return "AllDisjoint([%s]%s)" % (", ".join(repr(Class) for Class in self.entities), onto) 112 | 113 | AllDifferent = AllDisjoint 114 | 115 | 116 | def partition(mother, children): 117 | mother.is_a.append(Or(children)) 118 | AllDisjoint(children) 119 | 120 | 121 | # class DisjointUnion(LogicalClassConstruct): 122 | # _owl_op = owl_disjointunion 123 | # is_a = () 124 | 125 | # def _satisfied_by(self, x): 126 | # for Class in self.Classes: 127 | # if Class._satisfied_by(x): return True 128 | # return False 129 | 130 | # def __repr__(self): 131 | # s = [] 132 | # for x in self.Classes: 133 | # if isinstance(x, LogicalClassConstruct): s.append("(%s)" % x) 134 | # else: s.append(repr(x)) 135 | # return "%s([%s])" % (self.__class__.__name__, ", ".join(s)) 136 | -------------------------------------------------------------------------------- /test/test_parser.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | 3 | HERE = os.path.dirname(__file__) 4 | 5 | def rm(f): 6 | try: os.unlink(f) 7 | except: pass 8 | 9 | 10 | def do(c): 11 | #print(c) 12 | r = os.system(c) 13 | if r: raise Exception("Error when running:'%s'!" % c) 14 | 15 | def make_variants(orig_filename, force_variant = None): 16 | control(orig_filename) 17 | 18 | if (not force_variant) or (force_variant == "original"): 19 | print("Test %s %s ..." % (orig_filename, "original")) 20 | rm("/tmp/t.rdf") 21 | b = open(orig_filename, "rb").read() 22 | open("/tmp/t.rdf", "wb").write(b) 23 | yield "original" 24 | 25 | if (not force_variant) or (force_variant == "owlready2-ntriples"): 26 | print("Test %s %s ..." % (orig_filename, "owlready2-ntriples")) 27 | rm("/tmp/t.rdf") 28 | do("""python -c 'from owlready2 import *;\ 29 | onto = get_ontology("file://%s").load();\ 30 | onto.save("/tmp/t.rdf", format = "ntriples");\ 31 | '""" % orig_filename) 32 | yield "owlready2-ntriples" 33 | 34 | if (not force_variant) or (force_variant == "owlready2-rdfxml"): 35 | print("Test %s %s ..." % (orig_filename, "owlready2-rdfxml")) 36 | rm("/tmp/t.rdf") 37 | do("""python -c 'from owlready2 import *;\ 38 | onto = get_ontology("file://%s").load();\ 39 | onto.save("/tmp/t.rdf", format = "rdfxml");\ 40 | '""" % orig_filename) 41 | yield "owlready2-rdfxml" 42 | 43 | if (not force_variant) or (force_variant == "rapper-ntriples"): 44 | print("Test %s %s ..." % (orig_filename, "rapper-ntriples")) 45 | rm("/tmp/t.rdf") 46 | do("rapper %s > /tmp/t.rdf 2> /dev/null" % orig_filename) 47 | yield "rapper-ntriples" 48 | 49 | if (not force_variant) or (force_variant == "rapper-rdfxml"): 50 | print("Test %s %s ..." % (orig_filename, "rapper-rdfxml")) 51 | rm("/tmp/t.rdf") 52 | do("rapper %s -o rdfxml > /tmp/t.rdf 2> /dev/null" % orig_filename) 53 | yield "rapper-rdfxml" 54 | 55 | if (not force_variant) or (force_variant == "rapper-rdfxml-abbrev"): 56 | print("Test %s %s ..." % (orig_filename, "rapper-rdfxml-abbrev")) 57 | rm("/tmp/t.rdf") 58 | do("rapper %s -o rdfxml-abbrev > /tmp/t.rdf 2> /dev/null" % orig_filename) 59 | yield "rapper-rdfxml-abbrev" 60 | 61 | if (not force_variant) or (force_variant == "owlapi-rdfxml"): 62 | print("Test %s %s ..." % (orig_filename, "owlapi-rdfxml")) 63 | rm("/tmp/t.rdf") 64 | owlapi(orig_filename, "/tmp/t.rdf", "rdf") 65 | rapper("/tmp/t.rdf", "/tmp/control.nt") 66 | yield "owlapi-rdfxml" 67 | 68 | if (not force_variant) or (force_variant == "owlapi-owlxml"): 69 | print("Test %s %s ..." % (orig_filename, "owlapi-owlxml")) 70 | rm("/tmp/t.rdf") 71 | owlapi(orig_filename, "/tmp/t.rdf", "owl") 72 | 73 | owlapi("/tmp/t.rdf", "/tmp/control.rdf", "rdf") 74 | rapper("/tmp/control.rdf", "/tmp/control.nt") 75 | yield "owlapi-owlxml" 76 | 77 | def rapper(filename, dest): 78 | rm(dest) 79 | do("rapper %s -g > %s 2> /dev/null" % (filename, dest)) 80 | b = open(dest, "rb").read() 81 | lb = b.split(b"\n") 82 | #ls = [i.replace(b"\\" + b"\"", b"\\\\" + b"\"").decode("unicode-escape").replace("\n", "\\n").replace("\\", "\\\\") for i in lb] 83 | ls = [] 84 | for i in lb: 85 | if not i: continue 86 | s,p,o = i.split(None, 2) 87 | if o.startswith(b'"'): 88 | v, d = o[1:].rsplit(b'"', 1) 89 | v = v.decode("unicode-escape").replace('\\', '\\\\').replace("\n", "\\n").replace('"', '\\"').encode("utf8") 90 | i = b'%s %s "%s"%s' % (s, p, v, d) 91 | ls.append(i) 92 | s = b"\n".join(ls) 93 | open(dest, "wb").write(s) 94 | 95 | 96 | def owlapi(orig, dest, format): 97 | #do("java -cp ./antibio_arcenciel/owlready_cas_dut_1/owlapi-3.4.3.jar:%s/test Save %s %s %s 2> /dev/null" % (HERE, orig, format, dest)) 98 | do("java -cp %s/../hermit/HermiT.jar:%s Save %s %s %s 2> /dev/null" % (HERE, HERE, orig, format, dest)) 99 | 100 | 101 | def control(filename): rapper(filename, "/tmp/control.nt") 102 | 103 | def test(filename, variant): 104 | rm("/tmp/py.nt") 105 | rm("/tmp/py.rdf") 106 | #do("python ./owlready2/rdfxml_2_ntriples.py %s > /tmp/py.nt 2> /dev/null" % tmp_filename) 107 | do("""python -c 'from owlready2 import *;\ 108 | onto = get_ontology("file:///tmp/t.rdf").load();\ 109 | onto.save("/tmp/py.nt", format = "ntriples");\ 110 | onto.save("/tmp/py.rdf", format = "rdfxml");\ 111 | '""") 112 | 113 | rm("/tmp/log") 114 | do("python %s/../ntriples_diff.py /tmp/control.nt /tmp/py.nt > /tmp/log" % HERE) 115 | s = open("/tmp/log").read() 116 | if s.strip() != "": 117 | print(" FAILED (ntriples)") 118 | return 0 119 | 120 | rm("/tmp/py.nt") 121 | rapper("/tmp/py.rdf", "/tmp/py.nt") 122 | 123 | rm("/tmp/log") 124 | do("python %s/../ntriples_diff.py /tmp/control.nt /tmp/py.nt > /tmp/log" % HERE) 125 | s = open("/tmp/log").read() 126 | if s.strip() != "": 127 | print(" FAILED (rdfxml)") 128 | return 0 129 | 130 | return 1 131 | 132 | 133 | if len(sys.argv) > 2: 134 | rdf_files = [sys.argv[1]] 135 | force_variant = sys.argv[2] 136 | 137 | elif len(sys.argv) > 1: 138 | rdf_files = [sys.argv[1]] 139 | force_variant = None 140 | 141 | else: 142 | rdf_files = [ 143 | "/home/jiba/src/owlready2/test/test.owl", 144 | "/home/jiba/src/owlready2/test/test_ns.owl", 145 | "/home/jiba/src/owlready2/test/test_breakline.owl", 146 | "/home/jiba/telechargements/base_med/aeo.owl", 147 | "/home/jiba/telechargements/base_med/agro.owl", 148 | "/home/jiba/telechargements/base_med/bfo.owl", 149 | "/home/jiba/telechargements/base_med/bfo-1.1.owl", 150 | "/home/jiba/telechargements/base_med/obi.owl", 151 | "/home/jiba/telechargements/base_med/uberon.owl", 152 | "/home/jiba/telechargements/base_med/vto.owl", 153 | "/home/jiba/telechargements/base_med/go.owl", 154 | ] 155 | force_variant = None 156 | 157 | 158 | nb_ok = nb_test = 0 159 | for filename in rdf_files: 160 | for variant in make_variants(filename, force_variant): 161 | nb_test += 1 162 | nb_ok += test(filename, variant) 163 | 164 | print("%s/%s tests passed" % (nb_ok, nb_test)) 165 | 166 | 167 | -------------------------------------------------------------------------------- /test/catalog-v001.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Owlready2 3 | # Copyright (C) 2013-2019 Jean-Baptiste LAMY 4 | # LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142 5 | # University Paris 13, Sorbonne paris-Cité, Bobigny, France 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | VERSION = "0.25" 21 | 22 | JAVA_EXE = "java" 23 | 24 | from owlready2.base import * 25 | #_render_func = default_render_func 26 | 27 | from owlready2.namespace import * 28 | from owlready2.entity import * 29 | from owlready2.prop import * 30 | from owlready2.prop import _FUNCTIONAL_FOR_CACHE 31 | from owlready2.individual import * 32 | from owlready2.class_construct import * 33 | from owlready2.disjoint import * 34 | from owlready2.annotation import * 35 | from owlready2.reasoning import * 36 | from owlready2.reasoning import _keep_most_specific 37 | from owlready2.close import * 38 | 39 | import owlready2.namespace, owlready2.entity, owlready2.prop, owlready2.class_construct, owlready2.triplelite 40 | owlready2.triplelite.Or = Or 41 | owlready2.namespace.EntityClass = EntityClass 42 | owlready2.namespace.ThingClass = ThingClass 43 | owlready2.namespace.PropertyClass = PropertyClass 44 | owlready2.namespace.AnnotationPropertyClass = AnnotationPropertyClass 45 | owlready2.namespace.ObjectPropertyClass = ObjectPropertyClass 46 | owlready2.namespace.DataPropertyClass = DataPropertyClass 47 | owlready2.namespace.ObjectProperty = ObjectProperty 48 | owlready2.namespace.DataProperty = DataProperty 49 | owlready2.namespace.AnnotationProperty = AnnotationProperty 50 | owlready2.namespace.Thing = Thing 51 | owlready2.namespace.Property = Property 52 | owlready2.namespace.Or = Or 53 | owlready2.namespace.And = And 54 | owlready2.namespace.Not = Not 55 | owlready2.namespace.Restriction = Restriction 56 | owlready2.namespace.OneOf = OneOf 57 | owlready2.namespace.FusionClass = FusionClass 58 | owlready2.namespace.AllDisjoint = AllDisjoint 59 | owlready2.namespace.ConstrainedDatatype = ConstrainedDatatype 60 | owlready2.namespace.Inverse = Inverse 61 | owlready2.namespace.IndividualValueList = IndividualValueList 62 | owlready2.entity.Thing = Thing 63 | owlready2.entity.Nothing = Nothing 64 | owlready2.entity.Construct = Construct 65 | owlready2.entity.And = And 66 | owlready2.entity.Or = Or 67 | owlready2.entity.Not = Not 68 | owlready2.entity.OneOf = OneOf 69 | owlready2.entity.Restriction = Restriction 70 | owlready2.entity.ObjectPropertyClass= ObjectPropertyClass 71 | owlready2.entity.ObjectProperty = ObjectProperty 72 | owlready2.entity.DataProperty = DataProperty 73 | owlready2.entity.AnnotationProperty = AnnotationProperty 74 | owlready2.entity.ReasoningPropertyClass = ReasoningPropertyClass 75 | owlready2.entity.FunctionalProperty = FunctionalProperty 76 | #owlready2.entity.ValueList = ValueList 77 | owlready2.entity.AllDisjoint = AllDisjoint 78 | owlready2.entity.Inverse = Inverse 79 | owlready2.entity._FUNCTIONAL_FOR_CACHE = _FUNCTIONAL_FOR_CACHE 80 | owlready2.entity._property_value_restrictions = owlready2.prop._property_value_restrictions 81 | owlready2.entity._inherited_properties_value_restrictions = owlready2.prop._inherited_properties_value_restrictions 82 | owlready2.disjoint.Or = Or 83 | owlready2.prop.Restriction = Restriction 84 | owlready2.prop.ConstrainedDatatype = ConstrainedDatatype 85 | owlready2.prop.Construct = Construct 86 | owlready2.prop.AnnotationProperty = AnnotationProperty 87 | owlready2.prop.Thing = Thing 88 | owlready2.prop.PropertyChain = PropertyChain 89 | owlready2.prop._check_superclasses = True 90 | 91 | owlready2.prop.ThingClass = ThingClass 92 | owlready2.prop.And = And 93 | owlready2.prop.Or = Or 94 | owlready2.prop.OneOf = OneOf 95 | owlready2.annotation.Construct = Construct 96 | 97 | owlready2.individual._keep_most_specific = _keep_most_specific 98 | owlready2.individual.Construct = Construct 99 | owlready2.individual.TransitiveProperty = TransitiveProperty 100 | owlready2.individual.SymmetricProperty = SymmetricProperty 101 | owlready2.individual.ReflexiveProperty = ReflexiveProperty 102 | owlready2.individual.InverseFunctionalProperty = InverseFunctionalProperty 103 | owlready2.individual.AnnotationPropertyClass = AnnotationPropertyClass 104 | owlready2.class_construct.Thing = Thing 105 | owlready2.class_construct.ThingClass = ThingClass 106 | owlready2.class_construct.EntityClass = EntityClass 107 | 108 | #owlready2.reasoning.Construct = Construct 109 | 110 | del owlready2 111 | 112 | from owlready2.rule import * 113 | 114 | LOADING.__exit__() 115 | 116 | # Not real property 117 | del owl_world._props["Property"] 118 | del owl_world._props["ObjectProperty"] 119 | del owl_world._props["DatatypeProperty"] 120 | del owl_world._props["FunctionalProperty"] 121 | del owl_world._props["InverseFunctionalProperty"] 122 | del owl_world._props["TransitiveProperty"] 123 | del owl_world._props["SymmetricProperty"] 124 | del owl_world._props["AsymmetricProperty"] 125 | del owl_world._props["ReflexiveProperty"] 126 | del owl_world._props["IrreflexiveProperty"] 127 | del owl_world._props["AnnotationProperty"] 128 | 129 | default_world = IRIS = World() 130 | get_ontology = default_world.get_ontology 131 | get_namespace = default_world.get_namespace 132 | 133 | 134 | def default_render_func(entity): 135 | if isinstance(entity.storid, int) and (entity.storid < 0): return "_:%s" % (-entity.storid) 136 | return "%s.%s" % (entity.namespace.name, entity.name) 137 | 138 | def set_render_func(func): 139 | type.__setattr__(EntityClass, "__repr__", func) 140 | type.__setattr__(Thing , "__repr__", func) 141 | 142 | set_render_func(default_render_func) 143 | --------------------------------------------------------------------------------