├── mimir ├── src │ ├── main │ │ ├── resources │ │ │ └── application.yml │ │ ├── reasoner │ │ │ ├── owlrl │ │ │ │ ├── requirements.txt │ │ │ │ ├── setup.cfg │ │ │ │ ├── docs │ │ │ │ │ ├── source │ │ │ │ │ │ ├── installation.rst │ │ │ │ │ │ ├── usage.rst │ │ │ │ │ │ ├── indices_and_tables.rst │ │ │ │ │ │ ├── XsdDatatypes_source.rst │ │ │ │ │ │ ├── owlrl.rst │ │ │ │ │ │ ├── Closure.rst │ │ │ │ │ │ ├── Literals.rst │ │ │ │ │ │ ├── AxiomaticTriples_source.rst │ │ │ │ │ │ ├── DatatypeHandling_source.rst │ │ │ │ │ │ ├── OWLRLExtras.rst │ │ │ │ │ │ ├── RDFSClosure.rst │ │ │ │ │ │ ├── CombinedClosure.rst │ │ │ │ │ │ ├── XsdDatatypes.rst │ │ │ │ │ │ ├── OWL.rst │ │ │ │ │ │ ├── AxiomaticTriples.rst │ │ │ │ │ │ ├── RDFS.rst │ │ │ │ │ │ ├── stubs │ │ │ │ │ │ │ ├── owlrl.Closure.rst │ │ │ │ │ │ │ ├── owlrl.rst │ │ │ │ │ │ │ └── owlrl.DeductiveClosure.rst │ │ │ │ │ │ ├── RestrictedDatatype.rst │ │ │ │ │ │ ├── index.rst │ │ │ │ │ │ ├── DatatypeHandling.rst │ │ │ │ │ │ └── conf.py │ │ │ │ │ ├── Makefile │ │ │ │ │ └── make.bat │ │ │ │ ├── MANIFEST.in │ │ │ │ ├── OWL-RL.png │ │ │ │ ├── OWL-RL-250.png │ │ │ │ ├── Doc_OLD │ │ │ │ │ ├── crarr.png │ │ │ │ │ ├── frames.html │ │ │ │ │ ├── index.html │ │ │ │ │ ├── toc-RDFClosure.RDFSClosure-module.html │ │ │ │ │ ├── toc-RDFClosure.CombinedClosure-module.html │ │ │ │ │ ├── toc-RDFClosure.Literals-module.html │ │ │ │ │ ├── toc-RDFClosure.Closure-module.html │ │ │ │ │ ├── redirect.html │ │ │ │ │ ├── toc-RDFClosure.XsdDatatypes-module.html │ │ │ │ │ ├── toc-RDFClosure-module.html │ │ │ │ │ ├── toc.html │ │ │ │ │ ├── toc-RDFClosure.RDFS'-module.html │ │ │ │ │ └── module-tree.html │ │ │ │ ├── LICENSE.txt │ │ │ │ ├── .gitignore │ │ │ │ ├── requirements-dev.txt │ │ │ │ ├── setup.py.old │ │ │ │ ├── test │ │ │ │ │ ├── test_owlrl_extras.py │ │ │ │ │ ├── test_class_axioms.py │ │ │ │ │ ├── test_equality.py │ │ │ │ │ ├── test_rdfs_closure.py │ │ │ │ │ ├── test_basic.py │ │ │ │ │ ├── test_datatypes.py │ │ │ │ │ └── relatives.ttl │ │ │ │ ├── README.rst │ │ │ │ ├── owlrl │ │ │ │ │ ├── RDFS.py │ │ │ │ │ ├── OWL.py │ │ │ │ │ ├── XsdDatatypes.py │ │ │ │ │ └── CombinedClosure.py │ │ │ │ ├── PKG-INFO │ │ │ │ ├── setup.py │ │ │ │ └── scripts │ │ │ │ │ ├── owlrl │ │ │ │ │ └── RDFConvertService │ │ │ ├── temp │ │ │ │ └── gitdontdeleteme.txt │ │ │ ├── test.ttl │ │ │ └── OwlRLWrapper.kt │ │ ├── api │ │ │ ├── TDBConfig.kt │ │ │ ├── ShexConfig.kt │ │ │ ├── ReasonerConfig.kt │ │ │ ├── WebConfig.kt │ │ │ ├── Application.kt │ │ │ ├── tdb │ │ │ │ ├── Status.kt │ │ │ │ ├── GetModel.kt │ │ │ │ └── QueryModelResponse.kt │ │ │ ├── owl │ │ │ │ ├── ReasonTimeout.kt │ │ │ │ └── ReasonResponse.kt │ │ │ ├── model │ │ │ │ ├── Dot.kt │ │ │ │ ├── BrowseUri.kt │ │ │ │ └── SyntaxCheckResponse.kt │ │ │ └── shape │ │ │ │ ├── ShexResponse.kt │ │ │ │ └── SHACLIsValid.kt │ │ ├── shex │ │ │ ├── temp │ │ │ │ └── gitdonotdeleteme.txt │ │ │ ├── ShexShapeMap.kt │ │ │ └── ShexWrapper.kt │ │ ├── dot │ │ │ ├── NodeColoring.kt │ │ │ ├── DOTLang.kt │ │ │ ├── colorTemplate │ │ │ │ ├── NodeColor.kt │ │ │ │ └── ReasonerNodeColor.kt │ │ │ ├── DOT.kt │ │ │ ├── DOTWriter.kt │ │ │ └── DOTShell.kt │ │ └── Utils.kt │ └── test │ │ └── api │ │ ├── tdb │ │ ├── StatusControllerTest.kt │ │ ├── QueryTdbControllerTest.kt │ │ └── GetModelControllerTest.kt │ │ └── shape │ │ ├── ShexResponseControllerTest.kt │ │ └── SHACLIsValidControllerTest.kt ├── README.md └── pom.xml ├── odin ├── babel.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── assets │ │ ├── logo.png │ │ └── logo.svg │ ├── plugins │ │ └── vuetify.js │ ├── package-lock.json │ ├── main.js │ └── App.vue ├── vue.config.js ├── .gitignore ├── README.md └── package.json ├── LICENSES ├── README.md ├── Material Design Icons's License ├── VuetifyJs's License ├── uuid's License ├── Vue's License ├── Vue-Vis-Network's License └── OWL-RL's License ├── supervisord └── supervisord.conf ├── nginx └── default.conf ├── Dockerfile ├── .gitignore └── README.md /mimir/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port : 9060 -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/requirements.txt: -------------------------------------------------------------------------------- 1 | rdflib>=4.2.2 2 | rdflib-jsonld>=0.4.0 -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.rst 3 | -------------------------------------------------------------------------------- /odin/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | *Coming soon.* 5 | -------------------------------------------------------------------------------- /odin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RDFPlaygroundProject/RDFPlayground/HEAD/odin/public/favicon.ico -------------------------------------------------------------------------------- /odin/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RDFPlaygroundProject/RDFPlayground/HEAD/odin/src/assets/logo.png -------------------------------------------------------------------------------- /mimir/src/main/api/TDBConfig.kt: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | object TDBConfig { 4 | var TDB_DIR = "src/main/resources/tdb" 5 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/temp/gitdontdeleteme.txt: -------------------------------------------------------------------------------- 1 | ## this file only exists to avoid an error where temp folder does not get uploaded to git 2 | -------------------------------------------------------------------------------- /mimir/src/main/shex/temp/gitdonotdeleteme.txt: -------------------------------------------------------------------------------- 1 | ## this file only exists to avoid an error where temp folder does not get uploaded to git 2 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt *.md *.rst 2 | include test/relatives.ttl 3 | recursive-include docs *.txt *.md *.rst 4 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/OWL-RL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RDFPlaygroundProject/RDFPlayground/HEAD/mimir/src/main/reasoner/owlrl/OWL-RL.png -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/OWL-RL-250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RDFPlaygroundProject/RDFPlayground/HEAD/mimir/src/main/reasoner/owlrl/OWL-RL-250.png -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/crarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RDFPlaygroundProject/RDFPlayground/HEAD/mimir/src/main/reasoner/owlrl/Doc_OLD/crarr.png -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | *Coming soon.* 5 | 6 | .. note:: Refer to :class:`owlrl` for package entry details, etc. -------------------------------------------------------------------------------- /odin/src/plugins/vuetify.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuetify from 'vuetify/lib'; 3 | 4 | Vue.use(Vuetify); 5 | 6 | export default new Vuetify({ 7 | }); 8 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/indices_and_tables.rst: -------------------------------------------------------------------------------- 1 | 2 | Indices and tables 3 | ================== 4 | 5 | * :ref:`genindex` 6 | * :ref:`modindex` 7 | * :ref:`search` 8 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/test.ttl: -------------------------------------------------------------------------------- 1 | # test.tll 2 | @prefix : . 3 | @prefix rdfs: . 4 | :x rdfs:subPropertyOf :y . 5 | :a :x :b . -------------------------------------------------------------------------------- /mimir/src/main/api/ShexConfig.kt: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | object ShexConfig { 4 | var TMP_DIR_NAME = "src/main/shex/temp/" 5 | var TMP_NAME_PREFIX = "tmp" 6 | var TMP_NAME_SUFFIX = ".shex" 7 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/XsdDatatypes_source.rst: -------------------------------------------------------------------------------- 1 | .. _XsdDatatypes: 2 | 3 | XsdDatatypes.py 4 | --------------- 5 | 6 | .. literalinclude:: ../../owlrl/XsdDatatypes.py 7 | :linenos: -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/owlrl.rst: -------------------------------------------------------------------------------- 1 | owlrl 2 | ===== 3 | 4 | .. automodule:: owlrl 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/Closure.rst: -------------------------------------------------------------------------------- 1 | Closure 2 | ======= 3 | 4 | .. automodule:: owlrl.Closure 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/Literals.rst: -------------------------------------------------------------------------------- 1 | Literals 2 | ======== 3 | 4 | .. automodule:: owlrl.Literals 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/AxiomaticTriples_source.rst: -------------------------------------------------------------------------------- 1 | .. _AxiomaticTriples: 2 | 3 | AxiomaticTriples.py 4 | ------------------- 5 | 6 | .. literalinclude:: ../../owlrl/AxiomaticTriples.py 7 | :linenos: -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/DatatypeHandling_source.rst: -------------------------------------------------------------------------------- 1 | .. _DatatypeHandling: 2 | 3 | DatatypeHandling.py 4 | ------------------- 5 | 6 | .. literalinclude:: ../../owlrl/DatatypeHandling.py 7 | :linenos: -------------------------------------------------------------------------------- /odin/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "transpileDependencies": [ 3 | "vuetify", 4 | "vis", 5 | "vis-network" 6 | ], 7 | 'devServer': { 8 | 'disableHostCheck': true 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /mimir/src/main/dot/NodeColoring.kt: -------------------------------------------------------------------------------- 1 | package dot 2 | 3 | interface NodeColoring { 4 | val uri: String 5 | val literal: String 6 | val blank: String 7 | val literalEdge: String 8 | val normalEdge: String 9 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/OWLRLExtras.rst: -------------------------------------------------------------------------------- 1 | OWLRLExtras 2 | =========== 3 | 4 | .. automodule:: owlrl.OWLRLExtras 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/RDFSClosure.rst: -------------------------------------------------------------------------------- 1 | RDFSClosure 2 | =========== 3 | 4 | .. automodule:: owlrl.RDFSClosure 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/LICENSE.txt: -------------------------------------------------------------------------------- 1 | owlrl is released under the W3C© SOFTWARE NOTICE AND LICENSE, see: 2 | 3 | http://href="http//www.w3.org/Consortium/Legal/2002/copyright-software-20021231%22 4 | 5 | for further details. 6 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/CombinedClosure.rst: -------------------------------------------------------------------------------- 1 | CombinedClosure 2 | =============== 3 | 4 | .. automodule:: owlrl.CombinedClosure 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | -------------------------------------------------------------------------------- /mimir/src/main/dot/DOTLang.kt: -------------------------------------------------------------------------------- 1 | package dot 2 | 3 | import org.apache.jena.riot.Lang 4 | import org.apache.jena.riot.LangBuilder 5 | 6 | val DOTLang: Lang = LangBuilder 7 | .create("DOT", "text/dot") 8 | .addFileExtensions("dot") 9 | .build() -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/.gitignore: -------------------------------------------------------------------------------- 1 | # Jetbrains editors 2 | .idea/ 3 | 4 | * Python 5 | *.pyc 6 | .pytest_cache/ 7 | # 2to3 8 | *.bak 9 | 10 | /venv/ 11 | 12 | docs/build/ 13 | 14 | build/ 15 | dist/ 16 | deb_dist/ 17 | sdist/ 18 | *.egg-info/ 19 | 20 | owlrl*.tar.gz 21 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/XsdDatatypes.rst: -------------------------------------------------------------------------------- 1 | XsdDatatypes 2 | ============ 3 | 4 | .. automodule:: owlrl.XsdDatatypes 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | 10 | .. seealso:: View the source code :ref:`XsdDatatypes` -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/OWL.rst: -------------------------------------------------------------------------------- 1 | OWL 2 | === 3 | 4 | .. automodule:: owlrl 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | 10 | Source code 11 | ----------- 12 | 13 | .. literalinclude:: ../../owlrl/OWL.py 14 | :linenos: -------------------------------------------------------------------------------- /LICENSES/README.md: -------------------------------------------------------------------------------- 1 | The Apache 2 license (given in full in LICENSE) applies to all code in this repository which is copyright by 2 | Bastián Inostroza. Some sections of the repository contain or depend on third-party code, to which different licenses 3 | may apply and are contained in this folder. 4 | 5 | 6 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/AxiomaticTriples.rst: -------------------------------------------------------------------------------- 1 | AxiomaticTriples 2 | ================ 3 | 4 | .. automodule:: owlrl.AxiomaticTriples 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | 10 | .. seealso:: View the source code :ref:`AxiomaticTriples`. -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/RDFS.rst: -------------------------------------------------------------------------------- 1 | RDFS 2 | ==== 3 | 4 | .. automodule:: owlrl.RDFS 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | 10 | 11 | Source code 12 | ----------- 13 | 14 | .. literalinclude:: ../../owlrl/RDFS.py 15 | :linenos: -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/stubs/owlrl.Closure.rst: -------------------------------------------------------------------------------- 1 | owlrl.Closure 2 | ============= 3 | 4 | .. automodule:: owlrl.Closure 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Classes 13 | 14 | .. autosummary:: 15 | 16 | Core 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/RestrictedDatatype.rst: -------------------------------------------------------------------------------- 1 | RestrictedDatatype 2 | ================== 3 | 4 | .. automodule:: owlrl.RestrictedDatatype 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | 10 | 11 | .. autofunction:: owlrl.RestrictedDatatype._lit_to_value -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | sphinx 3 | sphinx_rtd_theme 4 | rdflib>=4.2.2 5 | rdflib-jsonld 6 | wheel 7 | twine 8 | 9 | #For debian packaging: (uncomment this line) 10 | #stdeb 11 | 12 | #Note, stdeb requires debian tools dpkg-buildpackage, python3-all, and debhelper (use apt-get) 13 | 14 | -------------------------------------------------------------------------------- /mimir/src/main/shex/ShexShapeMap.kt: -------------------------------------------------------------------------------- 1 | package shex 2 | 3 | import org.apache.commons.rdf.api.RDFTerm 4 | import fr.inria.lille.shexjava.schema.Label 5 | 6 | data class ShexShapeMap ( 7 | val nodeLabel: RDFTerm, 8 | val shapeLabel: Label, 9 | val originalNode: String, 10 | val originalShape: String 11 | ) 12 | -------------------------------------------------------------------------------- /odin/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /mimir/src/main/dot/colorTemplate/NodeColor.kt: -------------------------------------------------------------------------------- 1 | package dot.colorTemplate 2 | 3 | import dot.NodeColoring 4 | 5 | object NodeColor: NodeColoring { 6 | override val uri: String = "#9999ff" 7 | override val literal: String = "#44ff44" 8 | override val blank: String = "#aa00aa" 9 | override val literalEdge: String = "#44ff44" 10 | override val normalEdge: String = "#9999ff" 11 | } -------------------------------------------------------------------------------- /mimir/src/main/dot/colorTemplate/ReasonerNodeColor.kt: -------------------------------------------------------------------------------- 1 | package dot.colorTemplate 2 | 3 | import dot.NodeColoring 4 | 5 | object ReasonerNodeColor: NodeColoring { 6 | override val uri: String = "#FF9DF0" 7 | override val literal: String = "#FF9DF0" 8 | override val blank: String = "#FF9DF0" 9 | override val literalEdge: String = "#FF9DF0" 10 | override val normalEdge: String = "#FF9DF0" 11 | } -------------------------------------------------------------------------------- /supervisord/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | logfile=/dev/null 4 | logfile_maxbytes=0 5 | 6 | [program:mimir] 7 | stdout_logfile=/dev/fd/1 8 | stdout_logfile_maxbytes=0 9 | redirect_stderr=true 10 | directory=/app/mimir 11 | command=mvn spring-boot:run 12 | 13 | [program:nginx] 14 | stdout_logfile=/dev/fd/1 15 | stdout_logfile_maxbytes=0 16 | redirect_stderr=true 17 | command=/usr/sbin/nginx -g "daemon off;" 18 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/setup.py.old: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | setup(name="RDFClosure", 3 | description="RDFClosure Library", 4 | version="5.2.1", 5 | author="Ivan Herman", 6 | author_email="ivan@ivan-herman.net", 7 | maintainer="Ivan Herman", 8 | maintainer_email="ivan@ivan-herman.net", 9 | packages=['RDFClosure'], 10 | requires=['rdflib(>=4.2.2)', 'rdflib_jsonld'] 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /odin/src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "@fortawesome/fontawesome-free": { 6 | "version": "5.13.0", 7 | "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz", 8 | "integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==", 9 | "dev": true 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/stubs/owlrl.rst: -------------------------------------------------------------------------------- 1 | owlrl 2 | ===== 3 | 4 | .. automodule:: owlrl 5 | 6 | 7 | 8 | .. rubric:: Functions 9 | 10 | .. autosummary:: 11 | 12 | convert_graph 13 | interpret_owl_imports 14 | return_closure_class 15 | 16 | 17 | 18 | 19 | 20 | .. rubric:: Classes 21 | 22 | .. autosummary:: 23 | 24 | DeductiveClosure 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /odin/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import vuetify from './plugins/vuetify'; 4 | import Vuetify from 'vuetify'; 5 | import vis from 'vis'; 6 | import { Network } from 'vue-vis-network'; 7 | 8 | Vue.component('vis-network', Network); 9 | 10 | Vue.config.productionTip = false; 11 | 12 | Vue.use(Vuetify); 13 | Vue.use(vis); 14 | 15 | new Vue({ 16 | vis, 17 | vuetify, 18 | render: h => h(App) 19 | }).$mount('#app'); 20 | -------------------------------------------------------------------------------- /mimir/src/test/api/tdb/StatusControllerTest.kt: -------------------------------------------------------------------------------- 1 | package api.tdb 2 | 3 | import org.junit.jupiter.api.Test 4 | 5 | import org.junit.jupiter.api.Assertions.* 6 | 7 | internal class StatusControllerTest { 8 | 9 | @Test 10 | fun status() { 11 | // Only if you delete the resources/tdb directory or corrupt it should fail 12 | val controller = StatusController() 13 | val response = controller.status() 14 | assertEquals(200, response.statusCodeValue) 15 | } 16 | } -------------------------------------------------------------------------------- /odin/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | Artboard 46 2 | -------------------------------------------------------------------------------- /nginx/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | listen [::]:80 default_server; 4 | 5 | location / { 6 | root /app/odin/dist; 7 | index index.html; 8 | try_files $uri $uri/ /index.html; 9 | } 10 | 11 | location /api/ { 12 | proxy_http_version 1.1; 13 | proxy_set_header Upgrade $http_upgrade; 14 | proxy_set_header Connection "Upgrade"; 15 | proxy_set_header Host $host; 16 | proxy_set_header X-Real-IP $remote_addr; 17 | proxy_pass http://127.0.0.1:9060/api/; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /mimir/src/main/api/ReasonerConfig.kt: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | object ReasonerConfig { 4 | var TMP_DIR_NAME = "src/main/reasoner/temp/" 5 | var TMP_NAME_PREFIX = "tmp" 6 | var TMP_NAME_SUFFIX = ".ttl" 7 | 8 | var DEFAULT_DATA_NAME = "test.ttl" 9 | var DEFAULT_DATA_DIR = "src/main/reasoner/" 10 | var ENV_ACTIVATION_SCRIPT = "./src/main/reasoner/owlrl/venv/bin/activate" 11 | var CMD_NAME = "python src/main/reasoner/owlrl/scripts/owlrl" 12 | var DEFAULT_PROFILE = "rdfs" 13 | var DEFAULT_FLAG = " -r" 14 | 15 | var RDFS_FLAG = " -r" 16 | var RDFS_PROFILE = "rdfs" 17 | var OWL_PROFILE = "owl" 18 | var OWL_FLAG = " -w" 19 | } 20 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/stubs/owlrl.DeductiveClosure.rst: -------------------------------------------------------------------------------- 1 | owlrl.DeductiveClosure 2 | ====================== 3 | 4 | .. currentmodule:: owlrl 5 | 6 | .. autoclass:: DeductiveClosure 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DeductiveClosure.__init__ 17 | ~DeductiveClosure.expand 18 | ~DeductiveClosure.use_improved_datatypes_conversions 19 | ~DeductiveClosure.use_rdflib_datatypes_conversions 20 | 21 | 22 | 23 | 24 | 25 | .. rubric:: Attributes 26 | 27 | .. autosummary:: 28 | 29 | ~DeductiveClosure.improved_datatype_generic 30 | 31 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/frames.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /mimir/src/main/dot/DOT.kt: -------------------------------------------------------------------------------- 1 | package dot 2 | 3 | import org.apache.jena.atlas.io.IndentedWriter 4 | import org.apache.jena.graph.Graph 5 | import org.apache.jena.sparql.serializer.SerializationContext 6 | import org.apache.jena.sparql.sse.writers.WriterGraph 7 | import java.io.OutputStream 8 | 9 | 10 | object DOT { 11 | 12 | fun write(out: OutputStream, graph: Graph) { 13 | val indentedOut = IndentedWriter(out) 14 | write(indentedOut, graph) 15 | indentedOut.flush() 16 | } 17 | 18 | fun write(out: IndentedWriter, graph: Graph) { 19 | WriterGraph.output( 20 | out, 21 | graph, 22 | SerializationContext(graph.prefixMapping) 23 | ) 24 | out.ensureStartOfLine() 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /mimir/src/main/api/WebConfig.kt: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import org.springframework.context.annotation.Configuration 4 | import org.springframework.web.servlet.config.annotation.CorsRegistry 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer 7 | 8 | @Configuration 9 | @EnableWebMvc 10 | open class WebConfig: WebMvcConfigurer { 11 | 12 | override fun addCorsMappings(registry: CorsRegistry) { 13 | // Based on https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors-global 14 | registry.addMapping("/api/**") 15 | .allowedOrigins("*") 16 | .allowedMethods("GET", "POST") 17 | .maxAge(3600) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. OWL-RL documentation master file, created by 2 | sphinx-quickstart on Tue Nov 20 10:29:01 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ==================== 7 | OWL-RL Documentation 8 | ==================== 9 | 10 | .. include:: ../../README.rst 11 | 12 | 13 | .. toctree:: 14 | :maxdepth: 2 15 | :caption: Getting Started: 16 | 17 | installation 18 | usage 19 | indices_and_tables 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | :caption: Modules 24 | 25 | owlrl 26 | AxiomaticTriples 27 | Closure 28 | CombinedClosure 29 | DatatypeHandling 30 | Literals 31 | OWL 32 | OWLRL 33 | OWLRLExtras 34 | RDFS 35 | RDFSClosure 36 | RestrictedDatatype 37 | XsdDatatypes 38 | 39 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.14 2 | 3 | RUN apk update && apk add --no-cache \ 4 | openjdk8 \ 5 | maven \ 6 | python3 && ln -sf python3 /usr/bin/python 7 | RUN python3 -m ensurepip 8 | RUN pip3 install --no-cache --upgrade pip setuptools 9 | COPY mimir /app/mimir 10 | WORKDIR /app/mimir/src/main/reasoner/owlrl 11 | RUN python3 setup.py install 12 | WORKDIR /app/mimir 13 | RUN mvn install 14 | 15 | RUN apk update && apk add --no-cache \ 16 | nodejs \ 17 | npm 18 | COPY odin /app/odin 19 | WORKDIR /app/odin 20 | RUN npm install 21 | RUN npm run build 22 | 23 | RUN apk update && apk add --no-cache \ 24 | nginx 25 | COPY nginx/default.conf /etc/nginx/http.d/ 26 | 27 | RUN apk update && apk add --no-cache \ 28 | supervisor 29 | RUN mkdir -p /var/log/supervisor 30 | ADD supervisord/supervisord.conf /etc/ 31 | 32 | EXPOSE 80 33 | CMD ["/usr/bin/supervisord"] -------------------------------------------------------------------------------- /odin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | RDF Playground 9 | 10 | 11 | 12 | 13 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /LICENSES/Material Design Icons's License: -------------------------------------------------------------------------------- 1 | Pictogrammers Free License 2 | -------------------------- 3 | 4 | This icon collection is released as free, open source, and GPL friendly by 5 | the [Pictogrammers](http://pictogrammers.com/) icon group. You may use it 6 | for commercial projects, open source projects, or anything really. 7 | 8 | # Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) 9 | Some of the icons are redistributed under the Apache 2.0 license. All other 10 | icons are either redistributed under their respective licenses or are 11 | distributed under the Apache 2.0 license. 12 | 13 | # Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) 14 | All web and desktop fonts are distributed under the Apache 2.0 license. Web 15 | and desktop fonts contain some icons that are redistributed under the Apache 16 | 2.0 license. All other icons are either redistributed under their respective 17 | licenses or are distributed under the Apache 2.0 license. 18 | 19 | # Code: MIT (https://opensource.org/licenses/MIT) 20 | The MIT license applies to all non-font and non-icon files. -------------------------------------------------------------------------------- /mimir/src/main/api/Application.kt: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import org.apache.jena.riot.RDFFormat 4 | import org.apache.jena.riot.RDFLanguages 5 | import org.apache.jena.riot.RDFWriterRegistry 6 | import org.springframework.boot.SpringApplication 7 | import org.springframework.boot.autoconfigure.SpringBootApplication 8 | 9 | import dot.DOTLang 10 | import dot.DOTWriter 11 | import org.apache.jena.tdb.TDB 12 | import reasoner.OwlRLWrapper 13 | 14 | 15 | @SpringBootApplication 16 | open class Application 17 | 18 | fun main(args: Array) { 19 | // Load Our DOT Writer to Jena before app start 20 | 21 | // Register Lang and Format and WriterFactory 22 | RDFLanguages.register(DOTLang) 23 | RDFWriterRegistry.register(DOTLang, RDFFormat(DOTLang)) 24 | RDFWriterRegistry.register(RDFFormat(DOTLang), DOTWriter.DOTWriterFactory) 25 | 26 | // Check that OWL_RL Works 27 | OwlRLWrapper() 28 | 29 | // Start TDB to query it later 30 | TDB.init() 31 | 32 | // Runs the REST server 33 | SpringApplication.run(Application::class.java, *args) 34 | 35 | println("Running on http://localhost:9060") 36 | } 37 | -------------------------------------------------------------------------------- /LICENSES/VuetifyJs's License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2020 John Jeremy Leider 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LICENSES/uuid's License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2010-2020 Robert Kieffer and other contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LICENSES/Vue's License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-present, Yuxi (Evan) You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/test_owlrl_extras.py: -------------------------------------------------------------------------------- 1 | """ 2 | Unit tests for OWL RL extras closure. 3 | """ 4 | 5 | import io 6 | from rdflib import Graph, BNode, Literal, Namespace, OWL, RDF, RDFS, XSD 7 | 8 | import owlrl 9 | 10 | T = Namespace('http://test.org/') 11 | 12 | def test_one_time_rules(): 13 | """ 14 | Test OWL 2 RL extras closure one time rules. 15 | """ 16 | data = """ 17 | @prefix : . 18 | @prefix owl: . 19 | @prefix xsd: . 20 | @prefix rdfs: . 21 | 22 | :t a rdfs:Datatype ; 23 | owl:onDatatype xsd:integer; 24 | owl:withRestrictions ( 25 | [xsd:minInclusive "1"^^xsd:integer] 26 | [xsd:maxInclusive "6"^^xsd:integer] 27 | ). 28 | """ 29 | 30 | g = Graph() 31 | g.parse(io.StringIO(data), format='n3') 32 | 33 | lt = Literal(2, datatype=XSD.integer) 34 | g.add((lt, RDF.type, XSD.integer)) 35 | g.add((T.a, T.p, lt)) 36 | 37 | owlrl.DeductiveClosure(owlrl.OWLRL_Extension).expand(g) 38 | 39 | assert (lt, RDF.type, T.t) in g 40 | -------------------------------------------------------------------------------- /LICENSES/Vue-Vis-Network's License: -------------------------------------------------------------------------------- 1 | 2 | MIT License 3 | 4 | Copyright (c) 2019 Dmitriy S. Sinyavskiy 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /odin/README.md: -------------------------------------------------------------------------------- 1 | # Odin frontend 2 | This project runs on nodejs 13 and Vuetify framework (runs on Vue). 3 | 4 | ## Project setup 5 | ``` sh 6 | # install dependencies 7 | npm install 8 | ``` 9 | 10 | ### Compiles, hot-reloads for development and production compilation 11 | ``` sh 12 | # Run for development 13 | npm run-script serve 14 | 15 | # Compiles and minifies for production 16 | npm run-script build 17 | ``` 18 | 19 | ### Lints and fixes files 20 | ``` 21 | npm run lint 22 | ``` 23 | 24 | ## Customize configuration 25 | ### Port 26 | For development edit the `serve` script, changing the port option on the line: 27 | ``` sh 28 | "serve": "vue-cli-service serve --port 8090", 29 | ``` 30 | 31 | For production, you can take the statics under `dist/` folder and open them as 32 | a static website with any port you want. 33 | 34 | #### ⚠ Warning: Configure CORS on the backend if you change this. 35 | 36 | ### Change API URL 37 | If you need to change where the API is located, go to 38 | `src/components/HelloWorld.vue` and change `backAPI` const. 39 | 40 | ### More 41 | For more information see 42 | [Configuration Reference](https://cli.vuejs.org/config/). 43 | 44 | ## Future work 45 | - Refactor `HelloWorld.vue` to divide the code on several files. 46 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/test_class_axioms.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test for OWL 2 RL/RDF rules from 3 | 4 | Table 7. The Semantics of Class Axioms 5 | 6 | https://www.w3.org/TR/owl2-profiles/#Reasoning_in_OWL_2_RL_and_RDF_Graphs_using_Rules 7 | """ 8 | 9 | from rdflib import Graph, BNode, Literal, Namespace, RDF, XSD, RDFS, OWL 10 | 11 | import owlrl 12 | 13 | from unittest import mock 14 | 15 | DAML = Namespace('http://www.daml.org/2002/03/agents/agent-ont#') 16 | T = Namespace('http://test.org/') 17 | 18 | def test_cax_dw(): 19 | """ 20 | Test cax-dw rule for OWL 2 RL. 21 | 22 | If:: 23 | 24 | T(?c1, owl:disjointWith, ?c2) 25 | T(?x, rdf:type, ?c1) 26 | T(?x, rdf:type, ?c2) 27 | 28 | then:: 29 | 30 | false 31 | """ 32 | g = Graph() 33 | 34 | x = T.x 35 | c1 = T.c1 36 | c2 = T.c2 37 | 38 | g.add((c1, OWL.disjointWith, c2)) 39 | g.add((x, RDF.type, c1)) 40 | g.add((x, RDF.type, c2)) 41 | 42 | owlrl.DeductiveClosure(owlrl.OWLRL_Semantics).expand(g) 43 | 44 | result = next(g.objects(predicate=DAML.error)) 45 | expected = Literal( 46 | 'Disjoint classes http://test.org/c1 and http://test.org/c2' 47 | ' have a common individual http://test.org/x' 48 | ) 49 | assert expected == result 50 | -------------------------------------------------------------------------------- /odin/src/App.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 58 | -------------------------------------------------------------------------------- /mimir/src/test/api/tdb/QueryTdbControllerTest.kt: -------------------------------------------------------------------------------- 1 | package api.tdb 2 | 3 | import org.junit.jupiter.api.Test 4 | 5 | import org.junit.jupiter.api.Assertions.* 6 | import org.springframework.http.ResponseEntity 7 | 8 | internal class QueryTdbControllerTest { 9 | 10 | private val lineSep = System.lineSeparator() 11 | private var header = MimeType.text + ',' + MimeType.csv 12 | 13 | @Test 14 | fun selectQueryTdb() { 15 | val query: String = "SELECT (count(*) AS ?count) { ?s ?p ?o} LIMIT 10" 16 | val request: QueryTdbRequest = QueryTdbRequest(query, "query") 17 | 18 | val expected: String = "count${lineSep}" 19 | 20 | val response: ResponseEntity = QueryTdbController().queryTdb(header, request) 21 | 22 | assertTrue(response.body!!.startsWith(expected)) 23 | } 24 | 25 | @Test 26 | fun updateQueryTdb() { 27 | val query: String = """PREFIX : 28 | INSERT { :test :atTime ?now } WHERE { BIND(now() AS ?now) }""".trimIndent() 29 | val request: QueryTdbRequest = QueryTdbRequest(query, "update") 30 | 31 | header = MimeType.text 32 | 33 | val expected = "SPARQL update executed correctly" 34 | 35 | val response: ResponseEntity = QueryTdbController().queryTdb(header, request) 36 | 37 | assertEquals(expected, response.body) 38 | } 39 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/test_equality.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test for OWL 2 RL/RDF rules from 3 | 4 | Table 4. The Semantics of Equality 5 | 6 | https://www.w3.org/TR/owl2-profiles/#Reasoning_in_OWL_2_RL_and_RDF_Graphs_using_Rules 7 | """ 8 | 9 | from rdflib import Graph, BNode, Literal, Namespace, RDF, XSD, RDFS, OWL 10 | 11 | import owlrl 12 | 13 | DAML = Namespace('http://www.daml.org/2002/03/agents/agent-ont#') 14 | T = Namespace('http://test.org/') 15 | 16 | def test_eq_diff1(): 17 | """ 18 | Test eq-diff1 rule for OWL 2 RL. 19 | 20 | If:: 21 | 22 | T(?x, owl:sameAs, ?y) 23 | T(?x, owl:differentFrom, ?y) 24 | 25 | then:: 26 | 27 | false 28 | """ 29 | g = Graph() 30 | 31 | x = T.x 32 | y = T.y 33 | 34 | g.add((x, OWL.sameAs, y)) 35 | g.add((x, OWL.differentFrom, y)) 36 | 37 | owlrl.DeductiveClosure(owlrl.OWLRL_Semantics).expand(g) 38 | 39 | result = g.objects(predicate=DAML.error) 40 | expected = Literal( 41 | '\'sameAs\' and \'differentFrom\' cannot be used on the same' \ 42 | + ' subject-object pair:' 43 | ) 44 | 45 | # expect multiple error messages for pairs (x, y), (x, x) and (y, y) 46 | # due to contradiction: 47 | # 48 | # x == y and x != y => x != x and y != y and x == x and y == y 49 | assert all(r.startswith(expected) for r in result) 50 | 51 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/test_rdfs_closure.py: -------------------------------------------------------------------------------- 1 | """ 2 | Unit tests for RDFS closure. 3 | """ 4 | 5 | from rdflib import Graph, Literal, Namespace, RDF, XSD 6 | 7 | import owlrl 8 | 9 | from unittest import mock 10 | 11 | DAML = Namespace('http://www.daml.org/2002/03/agents/agent-ont#') 12 | T = Namespace('http://test.org/') 13 | 14 | def test_one_time_rules(): 15 | """ 16 | Test RDFS closure one time rules. 17 | """ 18 | g = Graph() 19 | 20 | lt1 = Literal(10, datatype=XSD.integer) 21 | lt2 = Literal(10, datatype=XSD.nonNegativeInteger) 22 | g.add((T.a1, T.p, lt1)) 23 | g.add((T.a2, T.p, lt2)) 24 | 25 | owlrl.DeductiveClosure(owlrl.RDFS_Semantics).expand(g) 26 | 27 | assert (T.a1, T.p, lt2) in g 28 | assert (T.a2, T.p, lt1) in g 29 | 30 | def test_d_axioms(): 31 | """ 32 | Test adding datatype axioms for RDFS closure. 33 | """ 34 | g = Graph() 35 | 36 | g.add((T.a1, T.p, Literal(10, datatype=XSD.integer))) 37 | g.add((T.a2, T.p, Literal('11', datatype=XSD.string))) 38 | g.add((T.a3, T.p, Literal('t'))) # no datatype 39 | 40 | owlrl.DeductiveClosure( 41 | owlrl.RDFS_Semantics, 42 | datatype_axioms=True 43 | ).expand(g) 44 | 45 | assert (Literal(10, datatype=XSD.integer), RDF.type, XSD.integer) in g 46 | assert (Literal('11', datatype=XSD.string), RDF.type, XSD.string) in g 47 | assert next(g.subjects(Literal('t'), RDF.type), None) is None 48 | 49 | -------------------------------------------------------------------------------- /mimir/src/test/api/tdb/GetModelControllerTest.kt: -------------------------------------------------------------------------------- 1 | package api.tdb 2 | 3 | import dot.DOTLang 4 | import dot.DOTWriter 5 | 6 | import org.apache.jena.riot.RDFFormat 7 | import org.apache.jena.riot.RDFLanguages 8 | import org.apache.jena.riot.RDFWriterRegistry 9 | import org.junit.jupiter.api.Test 10 | 11 | import org.junit.jupiter.api.Assertions.* 12 | import org.junit.jupiter.api.BeforeEach 13 | 14 | internal class GetModelControllerTest { 15 | 16 | @BeforeEach 17 | fun setUp() { 18 | // Register Lang and Format and WriterFactory 19 | RDFLanguages.register(DOTLang) 20 | RDFWriterRegistry.register(DOTLang, RDFFormat(DOTLang)) 21 | RDFWriterRegistry.register(RDFFormat(DOTLang), DOTWriter.DOTWriterFactory) 22 | } 23 | 24 | @Test 25 | fun getModel() { 26 | val response = GetModelController().getModel() 27 | when (response.body) { 28 | is String -> assertEquals("", response.body) // This is an error, and this should be working properly 29 | is GetModelResponse -> { 30 | assertNotEquals("", (response.body as GetModelResponse).data) 31 | assertNotEquals( 32 | """diagraph G{ 33 | charset="utf-8"; 34 | 35 | // Edges 36 | 37 | // Nodes 38 | } 39 | """.trimIndent().trimMargin(), 40 | (response.body as GetModelResponse).dot.trimIndent().trimMargin()) 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure.RDFSClosure-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | RDFSClosure 7 | 8 | 9 | 10 | 11 | 13 |

Module RDFSClosure

14 |
15 |

Classes

16 | RDFS_Semantics

Variables

18 | __author__
__license__
__package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /mimir/src/main/api/tdb/Status.kt: -------------------------------------------------------------------------------- 1 | package api.tdb 2 | 3 | import api.TDBConfig 4 | import org.apache.jena.query.Dataset 5 | import org.apache.jena.query.ReadWrite 6 | import org.apache.jena.rdf.model.Model 7 | import org.apache.jena.tdb.TDBFactory 8 | import org.springframework.http.HttpStatus 9 | import org.springframework.http.ResponseEntity 10 | import org.springframework.web.bind.annotation.GetMapping 11 | import org.springframework.web.bind.annotation.RestController 12 | 13 | data class Status(val status_code: Int, val status: String, val tdb_status: String) 14 | 15 | @RestController 16 | class StatusController{ 17 | 18 | @GetMapping("/api/tdb/status") 19 | fun status(): ResponseEntity { 20 | // Make a TDB-backed dataset to work 21 | val directory: String = TDBConfig.TDB_DIR 22 | val dataset: Dataset 23 | 24 | try { 25 | dataset = TDBFactory.createDataset(directory) 26 | } catch (e: Exception) { 27 | return ResponseEntity("Triples DB is offline, try later", HttpStatus.SERVICE_UNAVAILABLE) 28 | } 29 | 30 | // Access the DB to ensure everything is working properly 31 | dataset.begin(ReadWrite.READ) 32 | try { 33 | // Try to get te model to check that everything is fine 34 | val model: Model = dataset.defaultModel 35 | } catch (e: Exception) { 36 | dataset.end() 37 | return ResponseEntity("Triples DB is not currently working", HttpStatus.INTERNAL_SERVER_ERROR) 38 | } finally { 39 | dataset.end() 40 | } 41 | 42 | return ResponseEntity("Triples DB on-line", HttpStatus.OK) 43 | } 44 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure.CombinedClosure-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | CombinedClosure 7 | 8 | 9 | 10 | 11 | 13 |

Module CombinedClosure

14 |
15 |

Classes

16 | RDFS_OWLRL_Semantics

Variables

18 | __author__
__license__
__package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /odin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "odin", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --port 8090", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "@egjs/hammerjs": "^2.0.17", 12 | "@vue/runtime-dom": "^3.3.8", 13 | "core-js": "^3.6.5", 14 | "keycharm": "^0.3.1", 15 | "moment": "^2.25.3", 16 | "uuid": "^7.0.3", 17 | "vis": "^4.21.0-EOL", 18 | "vis-data": "^6.5.3", 19 | "vis-network": "^7.6.9", 20 | "vis-util": "^4.0.0", 21 | "vue": "^2.6.11", 22 | "vue-vis-network": "^1.0.2", 23 | "vuetify": "^2.2.32" 24 | }, 25 | "devDependencies": { 26 | "@vue/cli-plugin-babel": "~4.3.1", 27 | "@vue/cli-plugin-eslint": "~4.3.1", 28 | "@vue/cli-service": "~4.3.1", 29 | "@vue/cli": "~4.3.1", 30 | "babel-eslint": "^10.0.3", 31 | "eslint": "^6.7.2", 32 | "eslint-plugin-vue": "^6.1.2", 33 | "sass": "^1.19.0", 34 | "sass-loader": "^8.0.0", 35 | "vue-cli-plugin-vuetify": "~2.0.5", 36 | "vue-template-compiler": "^2.6.11", 37 | "vuetify-loader": "^1.4.3" 38 | }, 39 | "eslintConfig": { 40 | "root": true, 41 | "env": { 42 | "node": true 43 | }, 44 | "extends": [ 45 | "plugin:vue/essential", 46 | "eslint:recommended" 47 | ], 48 | "parserOptions": { 49 | "parser": "babel-eslint" 50 | }, 51 | "rules": {} 52 | }, 53 | "browserslist": [ 54 | "> 1%", 55 | "last 2 versions" 56 | ], 57 | "description": "## Project setup ``` npm install ```", 58 | "main": "babel.config.js", 59 | "keywords": [], 60 | "author": "Bastian Inostroza", 61 | "license": "Apache License v2.0" 62 | } 63 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/test_basic.py: -------------------------------------------------------------------------------- 1 | import rdflib 2 | import sys 3 | import os 4 | # add path for the owlrl module 5 | sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))) 6 | import owlrl 7 | 8 | 9 | def test_basic(): 10 | # create an RDF graph, load a simple OWL ontology and data 11 | g = rdflib.Graph() 12 | try: 13 | g.parse('relatives.ttl', format='turtle') 14 | except FileNotFoundError: 15 | # This test might be run from the parent directory root 16 | g.parse('test/relatives.ttl', format='turtle') 17 | 18 | # run a simple SPARQL query against it, no inferencing, should find 15 results 19 | q = ''' 20 | PREFIX : 21 | SELECT (COUNT(?s) AS ?cnt) 22 | WHERE { 23 | ?s a :Person . 24 | } 25 | ''' 26 | for r in g.query(q): 27 | cnt = int(r[0]) 28 | assert cnt == 15 29 | 30 | # run a SELECT query for grandParents, no inferencing, should find 0 results 31 | q = ''' 32 | PREFIX : 33 | SELECT (COUNT(?gc) AS ?cnt) 34 | WHERE { 35 | ?gc :hasGrandparent ?gp . 36 | } 37 | ''' 38 | for r in g.query(q): 39 | cnt = int(r[0]) 40 | assert cnt == 0 41 | 42 | # expand the graph with OWL-RL semantics 43 | owlrl.DeductiveClosure(owlrl.OWLRL_Semantics).expand(g) 44 | 45 | # run a SELECT query for grandParents, should find 7 results 46 | q = ''' 47 | PREFIX : 48 | SELECT (COUNT(?gc) AS ?cnt) 49 | WHERE { 50 | ?gc :hasGrandparent ?gp . 51 | } 52 | ''' 53 | for r in g.query(q): 54 | cnt = int(r[0]) 55 | assert cnt == 7 56 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure.Literals-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Literals 7 | 8 | 9 | 10 | 11 | 13 |

Module Literals

14 |
15 |

Classes

16 | LiteralProxies
20 |

Variables

21 | __author__
__license__
__package__

25 | [hide private] 27 | 28 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure.Closure-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Closure 7 | 8 | 9 | 10 | 11 | 13 |

Module Closure

14 |
15 |

Classes

16 | Core

Variables

18 | __author__
__license__
__package__
debugGlobal
offlineGeneration

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/redirect.html: -------------------------------------------------------------------------------- 1 | Epydoc Redirect Page 2 | 3 | 4 | 5 | 6 | 7 | 8 | 18 | 19 |

Epydoc Auto-redirect page

20 | 21 |

When javascript is enabled, this page will redirect URLs of 22 | the form redirect.html#dotted.name to the 23 | documentation for the object with the given fully-qualified 24 | dotted name.

25 |

 

26 | 27 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/README.rst: -------------------------------------------------------------------------------- 1 | |Original Author DOI| |PyPI badge| 2 | 3 | |OWL-RL Logo| 4 | 5 | .. |Original Author DOI| image:: https://zenodo.org/badge/9385/RDFLib/OWL-RL.svg 6 | :target: http://dx.doi.org/10.5281/zenodo.14543 7 | 8 | .. |PyPI badge| image:: https://badge.fury.io/py/owlrl.svg 9 | :target: https://badge.fury.io/py/owlrl 10 | 11 | .. |OWL-RL Logo| image:: OWL-RL-250.png 12 | :target: http://owl-rl.readthedocs.io/ 13 | 14 | 15 | OWL-RL 16 | ====== 17 | 18 | A simple implementation of the OWL2 RL Profile, as well as a basic RDFS inference, on top of RDFLib. Based mechanical forward chaining. The distribution contains: 19 | 20 | **OWL-RL**: the Python library. You should copy the directory somewhere into your :code:`PYTHONPATH`. Alternatively, you can also run the :code:`python setup.py install` script in the directory. 21 | 22 | * :code:`scripts/RDFConvertService`: can be used as a CGI script to invoke the library. It may have to be adapted to the local server setup. 23 | 24 | * :code:`scripts/owlrl`: script that can be run locally on to transform a file into RDF (on the standard output). Run the script with :code:`-h` to get the available flags. 25 | 26 | The package requires Python version 3.5 or higher; it depends on `RDFLib`_; version 4.2.2 or higher is required. If you need the python 2.7.x compatible version, see the @/py2 branch in this repository. 27 | 28 | .. _RDFLib: https://github.com/RDFLib 29 | 30 | For the details on RDFS, see the `RDF Semantics Specification`_; for OWL 2 RL, see the `OWL 2 Profile specification`_. 31 | 32 | .. _RDF Semantics Specification: http://www.w3.org/TR/rdf11-mt/ 33 | .. _OWL 2 Profile specification: http://www.w3.org/TR/owl2-profiles/#Reasoning_in_OWL_2_RL_and_RDF_Graphs_using_Rules 34 | 35 | View the **OWL-RL documentation** online: http://owl-rl.readthedocs.io/ 36 | 37 | To view the changelog for this software library, see `CHANGELOG.rst `_. 38 | 39 | This software is released under the W3C© SOFTWARE NOTICE AND LICENSE. See `LICENSE.txt `_. 40 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/owlrl/RDFS.py: -------------------------------------------------------------------------------- 1 | """ 2 | RDF(S) terms. Note that the set of terms is *complete*, i.e., it includes *all* OWL 2 terms, regardless of whether the 3 | term is used in OWL 2 RL or not. 4 | 5 | **Requires**: `RDFLib`_, 4.0.0 and higher. 6 | 7 | .. _RDFLib: https://github.com/RDFLib/rdflib 8 | 9 | **License**: This software is available for use under the `W3C Software License`_. 10 | 11 | .. _W3C Software License: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 12 | 13 | **Organization**: `World Wide Web Consortium`_ 14 | 15 | .. _World Wide Web Consortium: http://www.w3.org 16 | 17 | **Author**: `Ivan Herman`_ 18 | 19 | .. _Ivan Herman: http://www.w3.org/People/Ivan/ 20 | """ 21 | 22 | import rdflib 23 | from rdflib import Namespace 24 | 25 | RDFNS = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#") 26 | RDFSNS = Namespace("http://www.w3.org/2000/01/rdf-schema#") 27 | 28 | # RDF Classes 29 | Seq = RDFNS["Seq"] 30 | Bag = RDFNS["Bag"] 31 | Alt = RDFNS["Alt"] 32 | Statement = RDFNS["Statement"] 33 | Property = RDFNS["Property"] 34 | XMLLiteral = RDFNS["XMLLiteral"] 35 | HTMLLiteral = RDFNS["HTML"] 36 | LangString = RDFNS["LangString"] 37 | List = RDFNS["List"] 38 | 39 | # RDF Properties 40 | rdf_subject = RDFNS["subject"] 41 | rdf_predicate = RDFNS["predicate"] 42 | rdf_object = RDFNS["object"] 43 | rdf_type = RDFNS["type"] 44 | value = RDFNS["value"] 45 | first = RDFNS["first"] 46 | rest = RDFNS["rest"] 47 | # and _n where n is a non-negative integer 48 | 49 | # RDF Resources 50 | nil = RDFNS["nil"] 51 | 52 | Resource = RDFSNS["Resource"] 53 | Class = RDFSNS["Class"] 54 | subClassOf = RDFSNS["subClassOf"] 55 | subPropertyOf = RDFSNS["subPropertyOf"] 56 | comment = RDFSNS["comment"] 57 | label = RDFSNS["label"] 58 | rdfs_domain = RDFSNS["domain"] 59 | rdfs_range = RDFSNS["range"] 60 | seeAlso = RDFSNS["seeAlso"] 61 | isDefinedBy = RDFSNS["isDefinedBy"] 62 | Literal = RDFSNS["Literal"] 63 | Container = RDFSNS["Container"] 64 | ContainerMembershipProperty = RDFSNS["ContainerMembershipProperty"] 65 | member = RDFSNS["member"] 66 | Datatype = RDFSNS["Datatype"] 67 | -------------------------------------------------------------------------------- /mimir/src/main/api/owl/ReasonTimeout.kt: -------------------------------------------------------------------------------- 1 | package api.owl 2 | 3 | import kotlinx.coroutines.runBlocking 4 | import kotlinx.coroutines.withTimeoutOrNull 5 | import org.springframework.http.MediaType 6 | import org.springframework.http.HttpHeaders 7 | import org.springframework.http.ResponseEntity 8 | import org.springframework.http.HttpHeaders.CONTENT_TYPE 9 | import org.springframework.http.HttpStatus 10 | import org.springframework.web.bind.annotation.PostMapping 11 | import org.springframework.web.bind.annotation.RequestBody 12 | import org.springframework.web.bind.annotation.RestController 13 | import api.ReasonerConfig 14 | 15 | data class ReasonTimeoutRequest( 16 | val data: String = "", 17 | val data_lang: String = "TTL", 18 | val profile: String = ReasonerConfig.DEFAULT_PROFILE, 19 | val timeout: Long = 60000 20 | ) 21 | 22 | @RestController 23 | class ReasonTimeoutController { 24 | 25 | @PostMapping( 26 | "/api/owl/reason_timeout", 27 | consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], 28 | produces = [MediaType.APPLICATION_JSON_UTF8_VALUE, MediaType.TEXT_PLAIN_VALUE]) 29 | fun reasonTimeout( 30 | @RequestBody requestBody: ReasonTimeoutRequest 31 | ): ResponseEntity { 32 | val header = HttpHeaders() 33 | 34 | return runBlocking { 35 | // Runs ReasonResponse With a Timeout 36 | val response = withTimeoutOrNull(requestBody.timeout) { 37 | val request = ReasonRequest(requestBody.data, requestBody.data_lang, requestBody.profile) 38 | // delegate to ReasonResponse 39 | ReasonController().reason(request) 40 | } 41 | 42 | when(response) { 43 | null -> { 44 | // Time has run out, respond that 45 | header.add(CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) 46 | return@runBlocking ResponseEntity("Time ran out for this request", header, HttpStatus.REQUEST_TIMEOUT) 47 | } 48 | 49 | else -> return@runBlocking response 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /mimir/src/main/api/model/Dot.kt: -------------------------------------------------------------------------------- 1 | package api.model 2 | 3 | import dot.DOTLang 4 | import loadModel 5 | import org.apache.jena.rdf.model.Model 6 | import org.apache.jena.riot.RDFDataMgr 7 | import org.apache.jena.riot.RDFFormat 8 | import org.apache.jena.riot.RDFLanguages 9 | import org.springframework.http.HttpHeaders 10 | import org.springframework.http.HttpStatus 11 | import org.springframework.http.MediaType 12 | import org.springframework.http.ResponseEntity 13 | import org.springframework.web.bind.annotation.PostMapping 14 | import org.springframework.web.bind.annotation.RequestBody 15 | import org.springframework.web.bind.annotation.RestController 16 | import java.io.ByteArrayOutputStream 17 | 18 | 19 | data class DotRequest(val data: String = "", val data_lang: String = "TTL") 20 | 21 | @RestController 22 | class DotController { 23 | 24 | @PostMapping( 25 | "/api/model/dot", 26 | consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], 27 | produces = [MimeType.dot] 28 | ) 29 | fun dot(@RequestBody requestBody: DotRequest): ResponseEntity { 30 | 31 | val header = HttpHeaders() 32 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.dot) 33 | if (requestBody.data.isBlank()) { 34 | return ResponseEntity("", header, HttpStatus.OK) 35 | } 36 | // Create a model on Memory 37 | val model: Model 38 | 39 | // Convert to DOT and save on ByteArray Stream 40 | val modelOnDOT = ByteArrayOutputStream() 41 | 42 | try { 43 | model = loadModel(requestBody.data, requestBody.data_lang) 44 | // Check if DOT lang is loaded 45 | val dotLang = DOTLang 46 | assert(RDFLanguages.isRegistered(dotLang)) {"Controller Error, DOT is not registered on Jena"} 47 | RDFLanguages.isRegistered(dotLang) 48 | // write to DOT 49 | RDFDataMgr.write(modelOnDOT, model, RDFFormat(DOTLang)) // Writes DOT to modelOnDOT 50 | } catch (e: Exception) { 51 | return ResponseEntity("", header, HttpStatus.INTERNAL_SERVER_ERROR) 52 | } 53 | 54 | return ResponseEntity(modelOnDOT.toString(), header, HttpStatus.OK) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /mimir/src/main/dot/DOTWriter.kt: -------------------------------------------------------------------------------- 1 | package dot 2 | 3 | import org.apache.jena.atlas.io.IndentedWriter 4 | import org.apache.jena.graph.Graph 5 | import org.apache.jena.riot.* 6 | import org.apache.jena.riot.adapters.RDFWriterRIOT 7 | import org.apache.jena.riot.system.PrefixMap 8 | import org.apache.jena.riot.system.RiotLib 9 | import org.apache.jena.riot.writer.WriterGraphRIOTBase 10 | import org.apache.jena.sparql.util.Context 11 | import java.io.OutputStream 12 | import java.io.Writer 13 | 14 | 15 | class DOTWriter: WriterGraphRIOTBase() { 16 | override fun getLang(): Lang { 17 | return RDFLanguages.contentTypeToLang("text/dot") 18 | } 19 | 20 | override fun write(out: Writer, graph: Graph, prefixMap: PrefixMap, baseURI: String, context: Context) { 21 | // MAYBE check charset tp be UTF-8 22 | val indentedWriter: IndentedWriter = RiotLib.create(out) 23 | output(indentedWriter, graph, prefixMap, baseURI, context) 24 | } 25 | 26 | override fun write(out: OutputStream, graph: Graph, prefixMap: PrefixMap, baseURI: String?, context: Context) { 27 | val indentedWriter = IndentedWriter(out) 28 | output(indentedWriter, graph, prefixMap, baseURI, context) 29 | } 30 | 31 | companion object DOTWriterFactory: WriterGraphRIOTFactory { 32 | override fun create(syntaxRDFFormat: RDFFormat?): WriterGraphRIOT { 33 | return DOTWriter() 34 | } 35 | } 36 | 37 | private fun output( 38 | indentedOutput: IndentedWriter, 39 | graph: Graph, 40 | prefixMap: PrefixMap, 41 | baseURI: String?, 42 | context: Context 43 | ) { 44 | val privateWriter = PrivateTurtleWriter(indentedOutput, prefixMap, baseURI, context) 45 | privateWriter.write(graph) 46 | indentedOutput.flush() 47 | } 48 | 49 | private class PrivateTurtleWriter(out: IndentedWriter, prefixMap: PrefixMap, baseURI: String?, context: Context) : 50 | DOTShell(out, prefixMap, baseURI, context) { 51 | 52 | internal fun write(graph: Graph) { 53 | writeGraphDOT(graph) 54 | } 55 | } 56 | 57 | // Model.write adapter - must be public. 58 | object RDFWriterDOT : RDFWriterRIOT("DOT") 59 | } 60 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure.XsdDatatypes-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | XsdDatatypes 7 | 8 | 9 | 10 | 11 | 13 |

Module XsdDatatypes

14 |
15 |

Variables

16 | OWL_Datatype_Subsumptions
OWL_RL_Datatypes
RDFS_Datatype_Subsumptions
RDFS_Datatypes
23 | 26 | __author__
__license__
__package__

30 | [hide private] 32 | 33 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/OwlRLWrapper.kt: -------------------------------------------------------------------------------- 1 | package reasoner 2 | 3 | import api.ReasonerConfig 4 | import java.io.BufferedReader 5 | import java.nio.file.Files 6 | import java.nio.file.Paths 7 | 8 | class OwlRLWrapper (private val config: ReasonerConfig = ReasonerConfig) { 9 | var profile: String = config.DEFAULT_PROFILE 10 | 11 | init { 12 | try { 13 | // test getting the default file 14 | val defaultFilePath = Paths.get(config.DEFAULT_DATA_DIR+config.DEFAULT_DATA_NAME) 15 | Files.readAllBytes(defaultFilePath.toAbsolutePath()) 16 | } catch (e: Exception) { 17 | println("ERROR: could not get test file path. \n Reason: ${e.message}") 18 | // throw error to be used at response time 19 | throw e 20 | } 21 | } 22 | 23 | fun infer(data: String, profile: String = this.profile): Pair { 24 | val type: String = when (profile.toLowerCase()) { 25 | config.RDFS_PROFILE -> config.RDFS_FLAG 26 | config.OWL_PROFILE -> config.OWL_FLAG 27 | else -> this.config.DEFAULT_FLAG // error, we'll use default one 28 | } 29 | 30 | // Create temp file with out model 31 | val tempDirectory = Paths.get(config.TMP_DIR_NAME).toFile() 32 | val tempFile = createTempFile(config.TMP_NAME_PREFIX, config.TMP_NAME_SUFFIX,tempDirectory) 33 | tempFile.writeText(data, Charsets.UTF_8) 34 | 35 | // Run OWL-RL 36 | val runtime: Runtime = Runtime.getRuntime() 37 | // Executes the command that runs the owlrl script (activates the environment first) 38 | val process = runtime.exec("${config.CMD_NAME}$type -f ${tempFile.path}") 39 | 40 | val inferenceResult: String = BufferedReader(process.inputStream.reader()).readText() 41 | 42 | // Read the error and skip the stacktrace 43 | var stack: Boolean = true 44 | var errorResult: String = "" 45 | process.errorStream.reader().readLines().forEach { line -> 46 | run { 47 | if (!stack) { 48 | errorResult += "$line\n" 49 | } 50 | 51 | // Skip StackTrace 52 | if (line.contains(" at line ") && stack) { 53 | stack = false 54 | } 55 | } 56 | } 57 | 58 | // Delete temp file to save space 59 | if (!tempFile.delete()) println("ERROR: could not delete ${tempFile.name}") 60 | 61 | return Pair(inferenceResult, errorResult) 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /mimir/src/main/api/model/BrowseUri.kt: -------------------------------------------------------------------------------- 1 | package api.model 2 | 3 | 4 | import dot.DOTLang 5 | import org.apache.jena.rdf.model.Model 6 | import org.apache.jena.rdf.model.ModelFactory 7 | import org.apache.jena.riot.RDFDataMgr 8 | import org.apache.jena.riot.RDFFormat 9 | import org.apache.jena.riot.RDFLanguages 10 | import org.springframework.http.HttpStatus 11 | import org.springframework.http.MediaType 12 | import org.springframework.http.ResponseEntity 13 | import org.springframework.web.bind.annotation.PostMapping 14 | import org.springframework.web.bind.annotation.RequestBody 15 | import org.springframework.web.bind.annotation.RestController 16 | import java.io.ByteArrayOutputStream 17 | import formatAs 18 | 19 | 20 | data class UriRequest(val url: String = "") 21 | data class UriResponse(val browse_error: String = "", val model_dot: String = "", val model_ttl: String = "") 22 | 23 | @RestController 24 | class BrowseUriController { 25 | 26 | 27 | @PostMapping( 28 | "/api/model/browse", 29 | consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], 30 | produces = [MediaType.APPLICATION_JSON_UTF8_VALUE] 31 | ) 32 | fun browseUri(@RequestBody requestBody: UriRequest): ResponseEntity{ 33 | if (requestBody.url.isBlank()) { 34 | return ResponseEntity(UriResponse("Nothing to look up" + requestBody.url), HttpStatus.NO_CONTENT) 35 | } 36 | 37 | // Read Uri and load into Model 38 | val model : Model = ModelFactory.createDefaultModel() 39 | try { 40 | RDFDataMgr.read(model, requestBody.url) 41 | 42 | } catch (e: Exception) { 43 | return ResponseEntity( 44 | UriResponse("Apache Jena was unable to load data in a model. Error was: \n" + 45 | e.message.toString()), 46 | HttpStatus.OK, 47 | ) 48 | } 49 | 50 | // Check if DOT lang is loaded 51 | val dotLang = DOTLang 52 | assert(RDFLanguages.isRegistered(dotLang)) {"Controller Error, DOT is not registered on Jena"} 53 | RDFLanguages.isRegistered(dotLang) 54 | 55 | val modelOnDot = ByteArrayOutputStream() 56 | try { 57 | RDFDataMgr.write(modelOnDot, model, RDFFormat(DOTLang)) 58 | } catch (e:Exception) { 59 | return ResponseEntity(UriResponse(browse_error = e.message.toString()), HttpStatus.INTERNAL_SERVER_ERROR) 60 | } 61 | 62 | return ResponseEntity(UriResponse(model_dot = modelOnDot.toString(), model_ttl = model.formatAs("TTL").first), HttpStatus.OK) 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /LICENSES/OWL-RL's License: -------------------------------------------------------------------------------- 1 | License 2 | By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will 3 | comply with the following terms and conditions. 4 | 5 | Permission to copy, modify, and distribute this software and its documentation, with or without modification, for any 6 | purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the 7 | software and documentation or portions thereof, including modifications: 8 | 9 | - The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. 10 | - Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the 11 | W3C Software Short Notice should be included (hypertext is preferred, text is permitted) within the body of any 12 | redistributed or derivative code. 13 | - Notice of any changes or modifications to the files, including the date changes were made. (We recommend you provide 14 | URIs to the location from which the code is derived.) 15 | 16 | Disclaimers 17 | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE 19 | OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR 20 | OTHER RIGHTS. 21 | 22 | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY 23 | USE OF THE SOFTWARE OR DOCUMENTATION. 24 | 25 | The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software 26 | without specific, written prior permission. Title to copyright in this software and any associated documentation 27 | will at all times remain with copyright holders. 28 | 29 | Notes 30 | This version: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 31 | 32 | This formulation of W3C's notice and license became active on December 31 2002. This version removes the copyright 33 | ownership notice such that this license can be used with materials other than those owned by the W3C, reflects that 34 | ERCIM is now a host of the W3C, includes references to this specific dated version of the license, and removes the 35 | ambiguous grant of "use". Otherwise, this version is the same as the previous version and is written so as to preserve 36 | the Free Software Foundation's assessment of GPL compatibility and OSI's certification under the Open Source Definition. 37 | -------------------------------------------------------------------------------- /mimir/src/main/api/tdb/GetModel.kt: -------------------------------------------------------------------------------- 1 | package api.tdb 2 | 3 | import org.apache.jena.query.Dataset 4 | import org.apache.jena.query.ReadWrite 5 | import org.apache.jena.rdf.model.Model 6 | import org.apache.jena.tdb.TDBFactory 7 | import org.springframework.http.HttpHeaders 8 | import org.springframework.http.HttpHeaders.CONTENT_TYPE 9 | import org.springframework.http.HttpStatus 10 | import org.springframework.http.ResponseEntity 11 | import org.springframework.web.bind.annotation.GetMapping 12 | import org.springframework.web.bind.annotation.RestController 13 | import api.TDBConfig 14 | import formatAs 15 | import toDOT 16 | 17 | data class GetModelResponse( 18 | val data: String = "", 19 | val dot: String = "" 20 | ) 21 | 22 | @RestController 23 | class GetModelController { 24 | 25 | @GetMapping( 26 | "api/tdb/get_model" 27 | ) 28 | fun getModel(): ResponseEntity { 29 | // Gets the contents of the TDB and returns it to the user 30 | val header = HttpHeaders() 31 | 32 | // get TDB directory 33 | val directory: String = TDBConfig.TDB_DIR 34 | val dataset: Dataset 35 | 36 | try { 37 | //access database 38 | dataset = TDBFactory.createDataset(directory) 39 | } catch (e: Exception) { 40 | // if we cannot access the database there is no point on continuing 41 | header.add(CONTENT_TYPE, MimeType.text) 42 | return ResponseEntity("Couldn't get TDB", header, HttpStatus.INTERNAL_SERVER_ERROR) 43 | } 44 | 45 | val modelString: String 46 | val dotModel: String 47 | 48 | dataset.begin(ReadWrite.READ) 49 | try { 50 | // get the model from the Database 51 | val model: Model = dataset.defaultModel 52 | // format as TTL 53 | modelString = model.formatAs("TTL").first 54 | // get DOT version 55 | dotModel = model.toDOT() 56 | } catch (e: Exception) { 57 | dataset.end() 58 | // there was an error on the model or converting it to DOT 59 | header.add(CONTENT_TYPE, MimeType.text) 60 | return ResponseEntity("Error processing Database: ${e.message}", header, HttpStatus.INTERNAL_SERVER_ERROR) 61 | } finally { 62 | // end connection 63 | dataset.end() 64 | } 65 | 66 | // send data to the user 67 | header.add(CONTENT_TYPE, MimeType.json) 68 | return ResponseEntity( 69 | GetModelResponse(data = modelString, dot = dotModel), 70 | header, 71 | HttpStatus.OK 72 | ) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /mimir/src/main/api/model/SyntaxCheckResponse.kt: -------------------------------------------------------------------------------- 1 | package api.model 2 | 3 | import org.springframework.web.bind.annotation.RestController 4 | import org.springframework.web.bind.annotation.PostMapping 5 | import org.springframework.web.bind.annotation.RequestBody 6 | import org.springframework.http.ResponseEntity 7 | import org.springframework.http.HttpStatus 8 | import org.springframework.http.MediaType 9 | import org.apache.jena.rdf.model.Model 10 | import org.apache.jena.riot.RDFDataMgr 11 | import org.apache.jena.riot.RDFFormat 12 | import org.apache.jena.riot.RDFLanguages 13 | import java.io.ByteArrayOutputStream 14 | 15 | import org.apache.jena.query.Query; 16 | import org.apache.jena.query.QueryFactory; 17 | import org.apache.commons.lang3.mutable.Mutable 18 | import com.google.common.hash.Hashing; 19 | 20 | 21 | import dot.DOTLang 22 | import loadModel 23 | import kotlin.collections.mutableListOf 24 | import kotlin.io.println 25 | 26 | data class SyntaxCheckRequest(val data: String = "", val data_lang: String = "TTL") 27 | data class SyntaxCheckResponse(val syntax_error: String = "", val data_dot: String = "") 28 | 29 | @RestController 30 | class SyntaxCheckController { 31 | var union_count = 0; 32 | @PostMapping( 33 | "/api/model/syntax_check", 34 | consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], 35 | produces = [MediaType.APPLICATION_JSON_UTF8_VALUE] 36 | ) 37 | fun syntaxCheck(@RequestBody requestBody: SyntaxCheckRequest): ResponseEntity { 38 | // base case 39 | if (requestBody.data.isBlank()) { 40 | return ResponseEntity(SyntaxCheckResponse("Nothing received"), HttpStatus.NO_CONTENT) 41 | } 42 | 43 | // Create a model on Memory 44 | val model: Model 45 | try { 46 | model = loadModel(requestBody.data, requestBody.data_lang) 47 | } catch (e: Exception) { 48 | return ResponseEntity(SyntaxCheckResponse(syntax_error = e.message.toString()), HttpStatus.OK) 49 | } 50 | // Check if DOT lang is loaded 51 | val dotLang = DOTLang 52 | assert(RDFLanguages.isRegistered(dotLang)) {"Controller Error, DOT is not registered on Jena"} 53 | RDFLanguages.isRegistered(dotLang) 54 | 55 | // Convert to DOT and save on ByteArray Stream 56 | val modelOnDOT = ByteArrayOutputStream() 57 | try { 58 | // write to DOT 59 | RDFDataMgr.write(modelOnDOT, model, RDFFormat(DOTLang)) // Writes DOT to modelOnDOT 60 | 61 | } catch (e: Exception) { 62 | return ResponseEntity(SyntaxCheckResponse(syntax_error = e.message.toString()), HttpStatus.INTERNAL_SERVER_ERROR) 63 | } 64 | return ResponseEntity(SyntaxCheckResponse(data_dot = modelOnDOT.toString() ), HttpStatus.OK) 65 | } 66 | 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff 7 | .idea/**/workspace.xml 8 | .idea/**/tasks.xml 9 | .idea/**/usage.statistics.xml 10 | .idea/**/dictionaries 11 | .idea/**/shelf 12 | 13 | # Generated files 14 | .idea/**/contentModel.xml 15 | 16 | # Sensitive or high-churn files 17 | .idea/**/dataSources/ 18 | .idea/**/dataSources.ids 19 | .idea/**/dataSources.local.xml 20 | .idea/**/sqlDataSources.xml 21 | .idea/**/dynamic.xml 22 | .idea/**/uiDesigner.xml 23 | .idea/**/dbnavigator.xml 24 | 25 | # Gradle 26 | .idea/**/gradle.xml 27 | .idea/**/libraries 28 | 29 | # Gradle and Maven with auto-import 30 | # When using Gradle or Maven with auto-import, you should exclude module files, 31 | # since they will be recreated, and may cause churn. Uncomment if using 32 | # auto-import. 33 | # .idea/modules.xml 34 | # .idea/*.iml 35 | # .idea/modules 36 | # *.iml 37 | # *.ipr 38 | 39 | # CMake 40 | cmake-build-*/ 41 | 42 | # Mongo Explorer plugin 43 | .idea/**/mongoSettings.xml 44 | 45 | # File-based project format 46 | *.iws 47 | 48 | # IntelliJ 49 | out/ 50 | 51 | # mpeltonen/sbt-idea plugin 52 | .idea_modules/ 53 | 54 | # JIRA plugin 55 | atlassian-ide-plugin.xml 56 | 57 | # Cursive Clojure plugin 58 | .idea/replstate.xml 59 | 60 | # Crashlytics plugin (for Android Studio and IntelliJ) 61 | com_crashlytics_export_strings.xml 62 | crashlytics.properties 63 | crashlytics-build.properties 64 | fabric.properties 65 | 66 | # Editor-based Rest Client 67 | .idea/httpRequests 68 | 69 | # Android studio 3.1+ serialized cache file 70 | .idea/caches/build_file_checksums.ser 71 | 72 | ### Maven template 73 | # Project exclude paths 74 | /target/ 75 | target/ 76 | pom.xml.tag 77 | pom.xml.releaseBackup 78 | pom.xml.versionsBackup 79 | pom.xml.next 80 | release.properties 81 | dependency-reduced-pom.xml 82 | buildNumber.properties 83 | .mvn/timing.properties 84 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 85 | .mvn/wrapper/maven-wrapper.jar 86 | 87 | ### Kotlin template 88 | # Compiled class file 89 | *.class 90 | 91 | # Log file 92 | *.log 93 | 94 | # BlueJ files 95 | *.ctxt 96 | 97 | # Mobile Tools for Java (J2ME) 98 | .mtj.tmp/ 99 | 100 | # Package Files # 101 | *.jar 102 | *.war 103 | *.nar 104 | *.ear 105 | *.zip 106 | *.tar.gz 107 | *.rar 108 | 109 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 110 | hs_err_pid* 111 | 112 | # temp files 113 | mimir/src/main/reasoner/temp/*.ttl 114 | mimir/src/main/shex/temp/* 115 | mimir/src/main/resources/tdb/* 116 | /.idea/ 117 | /mimir/linkeddata.iml 118 | -------------------------------------------------------------------------------- /mimir/src/test/api/shape/ShexResponseControllerTest.kt: -------------------------------------------------------------------------------- 1 | package api.shape 2 | 3 | import org.junit.jupiter.api.Test 4 | import kotlin.test.assertEquals 5 | 6 | internal class ShexResponseControllerTest { 7 | 8 | @Test 9 | fun shexIsValid() { 10 | val data: String = """ 11 | @prefix : . 12 | @prefix schema: . 13 | @prefix xsd: . 14 | @prefix foaf: . 15 | 16 | 17 | :dave schema:name "Dave"; # Fails as a :User 18 | schema:gender "XYY"; # 19 | schema:birthDate 1980 . # 1980 is not an xsd:date *) 20 | 21 | :emily schema:name "Emilee" ; # Passes 22 | schema:gender schema:Female . # 23 | 24 | :frank foaf:name "Frank" ; # Fails as a :User 25 | schema:gender: schema:Male . # missing schema:name *) 26 | 27 | :grace schema:name "Grace" ; # Fails as a :User 28 | schema:gender schema:Male ; # 29 | schema:knows _:x . # \_:x is not an IRI *) 30 | 31 | :harold schema:name "Harold" ; # Fails as a :User 32 | schema:gender schema:Male ; 33 | schema:knows :grace . # :grace does not conform to :User *) 34 | """.trimIndent() 35 | val lang = "TTL" 36 | val shex: String = """ 37 | PREFIX : 38 | PREFIX schema: 39 | PREFIX xsd: 40 | 41 | :User { 42 | schema:name xsd:string ; 43 | schema:birthDate xsd:date? ; 44 | schema:gender [ schema:Male schema:Female ] OR xsd:string ; 45 | schema:knows IRI @:User* 46 | } 47 | """.trimIndent() 48 | val shapeMap: String = """ 49 | @, 50 | @, 51 | @, 52 | :emily@:User, 53 | @:User, 54 | :emily@, 55 | :dave@:User 56 | """.trimIndent() 57 | val expectedReport = """ 58 | ShEx Validation Report: 59 | ❌ does not conform with 60 | ❌ does not conform with 61 | ❌ does not conform with 62 | ✅ :emily conforms with :User 63 | ✅ conforms with :User 64 | ✅ :emily conforms with 65 | ❌ :dave does not conform with :User 66 | """.trimIndent() 67 | 68 | val testedClass = ShexIsValidController() 69 | 70 | val response = testedClass 71 | .shexIsValid( 72 | ShExRequest(data, lang, shex, shapeMap) 73 | ) 74 | 75 | assertEquals(expectedReport, response.body!!.trim()) 76 | } 77 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | RDFClosure 7 | 8 | 9 | 10 | 11 | 13 |

Module RDFClosure

14 |
15 |

Classes

16 | DeductiveClosure

Functions

18 | 21 | convert_graph
interpret_owl_imports
return_closure_class

Variables

25 | AUTO
FULL
JSON
NONE
OWL
RDF
RDFA
RDFS
RDFXML
TURTLE
__author__
__license__
__package__
json_ld_available

40 | [hide private] 42 | 43 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.2 2 | Name: owlrl 3 | Version: 5.2.1 4 | Summary: OWL-RL and RDFS based RDF Closure inferencing 5 | Home-page: https://github.com/RDFLib/OWL-RL/ 6 | Author: Ivan Herman 7 | Author-email: ivan@ivan-herman.net 8 | Maintainer: Nicholas Car 9 | Maintainer-email: nicholas.car@csiro.au 10 | License: LICENSE.txt 11 | Download-URL: https://github.com/RDFLib/OWL-RL/archive/v5.2.1.tar.gz 12 | Description: |Original Author DOI| 13 | 14 | .. |Original Author DOI| image:: https://zenodo.org/badge/9385/RDFLib/OWL-RL.svg 15 | :target: http://dx.doi.org/10.5281/zenodo.14543 16 | 17 | 18 | OWL-RL 19 | ====== 20 | 21 | A simple implementation of the OWL2 RL Profile, as well as a basic RDFS inference, on top of RDFLib. Based mechanical forward chaining. The distribution contains: 22 | 23 | **OWL-RL**: the Python library. You should copy the directory somewhere into your :code:`PYTHONPATH`. Alternatively, you can also run the :code:`python setup.py install` script in the directory. 24 | 25 | * :code:`scripts/RDFConvertService`: can be used as a CGI script to invoke the library. It may have to be adapted to the local server setup. 26 | 27 | * :code:`scripts/owlrl`: script that can be run locally on to transform a file into RDF (on the standard output). Run the script with :code:`-h` to get the available flags. 28 | 29 | The package requires Python version 3.5 or higher; it depends on `RDFLib`_; version 4.2.2 or higher is required. If you need the python 2.7.x compatible version, see the @/py2 branch in this repository. 30 | 31 | .. _RDFLib: https://github.com/RDFLib 32 | 33 | For the details on RDFS, see the `RDF Semanics Specification`_; for OWL 2 RL, see the `OWL 2 Profile specification`_. 34 | 35 | .. _RDF Semanics Specification: http://www.w3.org/TR/rdf11-mt/ 36 | .. _OWL 2 Profile specification: http://www.w3.org/TR/owl2-profiles/#Reasoning_in_OWL_2_RL_and_RDF_Graphs_using_Rules 37 | 38 | View the **OWL-RL documentation** online: http://owl-rl.readthedocs.io/ 39 | Keywords: Linked Data,Semantic Web,Python,triples,inferencing,RDF,OWL,OWL-RL,owlrl,RDFS 40 | Platform: UNKNOWN 41 | Classifier: Development Status :: 5 - Production/Stable 42 | Classifier: Topic :: Utilities 43 | Classifier: Topic :: Software Development :: Libraries :: Python Modules 44 | Classifier: Intended Audience :: Developers 45 | Classifier: License :: OSI Approved :: W3C License 46 | Classifier: Natural Language :: English 47 | Classifier: Programming Language :: Python 48 | Classifier: Programming Language :: Python :: 3 49 | Classifier: Programming Language :: Python :: 3.5 50 | Classifier: Programming Language :: Python :: 3.6 51 | Classifier: Programming Language :: Python :: 3.7 52 | Classifier: Programming Language :: Python :: 3.8 53 | Classifier: Programming Language :: Python :: 3 :: Only 54 | Classifier: Programming Language :: Python :: Implementation :: CPython 55 | Classifier: Programming Language :: Python :: Implementation :: PyPy 56 | Classifier: Operating System :: OS Independent 57 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: latin-1 -*- 3 | import re 4 | import os 5 | import io 6 | from setuptools import setup 7 | 8 | def open_local(paths, mode='r', encoding='utf8'): 9 | path = os.path.join( 10 | os.path.abspath(os.path.dirname(__file__)), 11 | *paths 12 | ) 13 | return io.open(path, mode, encoding=encoding) 14 | 15 | 16 | with open_local(['owlrl', '__init__.py'], encoding='utf-8') as fp: 17 | try: 18 | version = re.findall(r"^__version__ = '([^']+)'\r?$", 19 | fp.read(), re.M)[0] 20 | except IndexError: 21 | raise RuntimeError('Unable to determine version.') 22 | 23 | with open_local(['README.rst']) as readme: 24 | long_description = readme.read() 25 | 26 | with open_local(['requirements.txt']) as req: 27 | found_requirements = req.read().split("\n") 28 | dependency_links = [] 29 | requirements = [] 30 | for f in found_requirements: 31 | if 'git+' in f: 32 | pkg = f.split('#')[-1] 33 | dependency_links.append(f.strip() + '-9876543210') 34 | requirements.append(pkg.replace('egg=', '').rstrip()) 35 | else: 36 | requirements.append(f.strip()) 37 | 38 | setup( 39 | name='owlrl', 40 | packages=['owlrl'], 41 | scripts=['scripts/owlrl', 'scripts/RDFConvertService'], 42 | package_dir={'owlrl': './owlrl'}, 43 | version=version, 44 | description='OWL-RL and RDFS based RDF Closure inferencing for Python', 45 | author='Ivan Herman', 46 | author_email='ivan@ivan-herman.net', 47 | maintainer='Nicholas Car', 48 | maintainer_email='nicholas.car@csiro.au', 49 | url='https://github.com/RDFLib/OWL-RL/', 50 | download_url='https://github.com/RDFLib/OWL-RL/'\ 51 | 'archive/v{:s}.tar.gz'.format(version), 52 | license='LICENSE.txt', 53 | keywords=['Linked Data', 'Semantic Web', 'Python', 'triples', 54 | 'inferencing', 'RDF', 'OWL', 'OWL-RL', 'owlrl', 'RDFS'], 55 | long_description=long_description, 56 | long_description_content_type='text/x-rst', 57 | classifiers=[ 58 | 'Development Status :: 5 - Production/Stable', 59 | 'Topic :: Utilities', 60 | 'Topic :: Software Development :: Libraries :: Python Modules', 61 | 'Intended Audience :: Developers', 62 | 'License :: OSI Approved :: W3C License', 63 | 'Natural Language :: English', 64 | 'Programming Language :: Python', 65 | 'Programming Language :: Python :: 3', 66 | 'Programming Language :: Python :: 3.5', 67 | 'Programming Language :: Python :: 3.6', 68 | 'Programming Language :: Python :: 3.7', 69 | 'Programming Language :: Python :: 3.8', 70 | 'Programming Language :: Python :: 3 :: Only', 71 | 'Programming Language :: Python :: Implementation :: CPython', 72 | 'Programming Language :: Python :: Implementation :: PyPy', 73 | 'Operating System :: OS Independent' 74 | ], 75 | install_requires=requirements, 76 | tests_require=['pytest']+requirements, 77 | dependency_links=dependency_links 78 | ) 79 | 80 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/DatatypeHandling.rst: -------------------------------------------------------------------------------- 1 | DatatypeHandling 2 | ================ 3 | 4 | .. automodule:: owlrl.DatatypeHandling 5 | :members: 6 | :undoc-members: 7 | :inherited-members: 8 | :show-inheritance: 9 | 10 | 11 | AltXSDToPYTHON Table 12 | -------------------- 13 | 14 | .. note:: The code below is not extracted automatically from the source code. 15 | 16 | If there are any errors, please make a pull request or an issue: https://github.com/RDFLib/OWL-RL 17 | 18 | .. code-block:: python 19 | 20 | AltXSDToPYTHON = { 21 | ns_xsd["language"]: lambda v: _strToVal_Regexp(v, _re_language), 22 | ns_xsd["NMTOKEN"]: lambda v: _strToVal_Regexp(v, _re_NMTOKEN, re.U), 23 | ns_xsd["Name"]: lambda v: _strToVal_Regexp(v, _re_NMTOKEN, re.U, _re_Name_ex), 24 | ns_xsd["NCName"]: lambda v: _strToVal_Regexp(v, _re_NCName, re.U, _re_NCName_ex), 25 | ns_xsd["token"]: _strToToken, 26 | ns_rdf["PlainLiteral"]: _strToPlainLiteral, 27 | ns_xsd["boolean"]: _strToBool, 28 | ns_xsd["decimal"]: _strToDecimal, 29 | ns_xsd["anyURI"]: _strToAnyURI, 30 | ns_xsd["base64Binary"]: _strToBase64Binary, 31 | ns_xsd["double"]: _strToDouble, 32 | ns_xsd["float"]: _strToFloat, 33 | ns_xsd["byte"]: lambda v: _strToBoundNumeral(v, _limits_byte, int), 34 | ns_xsd["int"]: lambda v: _strToBoundNumeral(v, _limits_int, int), 35 | ns_xsd["long"]: lambda v: _strToBoundNumeral(v, _limits_long, int), 36 | ns_xsd["positiveInteger"]: lambda v: _strToBoundNumeral(v, _limits_positiveInteger, int), 37 | ns_xsd["nonPositiveInteger"]: lambda v: _strToBoundNumeral(v, _limits_nonPositiveInteger, int), 38 | ns_xsd["negativeInteger"]: lambda v: _strToBoundNumeral(v, _limits_negativeInteger, int), 39 | ns_xsd["nonNegativeInteger"]: lambda v: _strToBoundNumeral(v, _limits_nonNegativeInteger, int), 40 | ns_xsd["short"]: lambda v: _strToBoundNumeral(v, _limits_short, int), 41 | ns_xsd["unsignedByte"]: lambda v: _strToBoundNumeral(v, _limits_unsignedByte, int), 42 | ns_xsd["unsignedShort"]: lambda v: _strToBoundNumeral(v, _limits_unsignedShort, int), 43 | ns_xsd["unsignedInt"]: lambda v: _strToBoundNumeral(v, _limits_unsignedInt, int), 44 | ns_xsd["unsignedLong"]: lambda v: _strToBoundNumeral(v, _limits_unsignedLong, int), 45 | ns_xsd["hexBinary"]: _strToHexBinary, 46 | ns_xsd["dateTime"]: lambda v: _strToDateTimeAndStamp(v, False), 47 | ns_xsd["dateTimeStamp"]: lambda v: _strToDateTimeAndStamp(v, True), 48 | ns_rdf["XMLLiteral"]: _strToXMLLiteral, 49 | ns_xsd["integer"]: int, 50 | ns_xsd["string"]: lambda v: v, 51 | ns_rdf["HTML"]: lambda v: v, 52 | ns_xsd["normalizedString"]: lambda v: _strToVal_Regexp(v, _re_token), 53 | 54 | # These are RDFS specific... 55 | ns_xsd["time"]: _strToTime, 56 | ns_xsd["date"]: _strToDate, 57 | ns_xsd["gYearMonth"]: _strTogYearMonth, 58 | ns_xsd["gYear"]: _strTogYear, 59 | ns_xsd["gMonthDay"]: _strTogMonthDay, 60 | ns_xsd["gDay"]: _strTogDay, 61 | ns_xsd["gMonth"]: _strTogMonth, 62 | } 63 | 64 | .. seealso:: View the source code :ref:`DatatypeHandling`. -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/test_datatypes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test for OWL 2 RL/RDF rules from 3 | 4 | Table 8. The Semantics of Datatypes 5 | 6 | https://www.w3.org/TR/owl2-profiles/#Reasoning_in_OWL_2_RL_and_RDF_Graphs_using_Rules 7 | 8 | NOTE: The following axioms are skipped on purpose 9 | 10 | - dt-eq 11 | - dt-diff 12 | """ 13 | 14 | from rdflib import Graph, Literal, Namespace, RDF, XSD, RDFS 15 | 16 | import owlrl 17 | 18 | DAML = Namespace('http://www.daml.org/2002/03/agents/agent-ont#') 19 | T = Namespace('http://test.org/') 20 | 21 | def test_dt_type1(): 22 | """ 23 | Test dt-type1 rule for OWL 2 RL. 24 | """ 25 | g = Graph() 26 | owlrl.DeductiveClosure(owlrl.OWLRL_Semantics).expand(g) 27 | 28 | assert (RDF.PlainLiteral, RDF.type, RDFS.Datatype) in g 29 | assert (RDF.XMLLiteral, RDF.type, RDFS.Datatype) in g 30 | assert (RDFS.Literal, RDF.type, RDFS.Datatype) in g 31 | assert (XSD.decimal, RDF.type, RDFS.Datatype) in g 32 | assert (XSD.integer, RDF.type, RDFS.Datatype) in g 33 | assert (XSD.nonNegativeInteger, RDF.type, RDFS.Datatype) in g 34 | assert (XSD.nonPositiveInteger, RDF.type, RDFS.Datatype) in g 35 | assert (XSD.positiveInteger, RDF.type, RDFS.Datatype) in g 36 | assert (XSD.negativeInteger, RDF.type, RDFS.Datatype) in g 37 | assert (XSD.long, RDF.type, RDFS.Datatype) in g 38 | assert (XSD.int, RDF.type, RDFS.Datatype) in g 39 | assert (XSD.short, RDF.type, RDFS.Datatype) in g 40 | assert (XSD.byte, RDF.type, RDFS.Datatype) in g 41 | assert (XSD.unsignedLong, RDF.type, RDFS.Datatype) in g 42 | assert (XSD.unsignedInt, RDF.type, RDFS.Datatype) in g 43 | assert (XSD.unsignedShort, RDF.type, RDFS.Datatype) in g 44 | assert (XSD.unsignedByte, RDF.type, RDFS.Datatype) in g 45 | assert (XSD.float, RDF.type, RDFS.Datatype) in g 46 | assert (XSD.double, RDF.type, RDFS.Datatype) in g 47 | assert (XSD.string, RDF.type, RDFS.Datatype) in g 48 | assert (XSD.normalizedString, RDF.type, RDFS.Datatype) in g 49 | assert (XSD.token, RDF.type, RDFS.Datatype) in g 50 | assert (XSD.language, RDF.type, RDFS.Datatype) in g 51 | assert (XSD.Name, RDF.type, RDFS.Datatype) in g 52 | assert (XSD.NCName, RDF.type, RDFS.Datatype) in g 53 | assert (XSD.NMTOKEN, RDF.type, RDFS.Datatype) in g 54 | assert (XSD.boolean, RDF.type, RDFS.Datatype) in g 55 | assert (XSD.hexBinary, RDF.type, RDFS.Datatype) in g 56 | assert (XSD.base64Binary, RDF.type, RDFS.Datatype) in g 57 | assert (XSD.anyURI, RDF.type, RDFS.Datatype) in g 58 | assert (XSD.dateTime, RDF.type, RDFS.Datatype) in g 59 | assert (XSD.dateTimeStamp, RDF.type, RDFS.Datatype) in g 60 | 61 | def test_dt_type2(): 62 | """ 63 | Test dt-type2 rule for OWL 2 RL. 64 | """ 65 | p_one = Literal(1, datatype=XSD.positiveInteger) 66 | 67 | g = Graph() 68 | g.add((T.A, T.prop, p_one)) 69 | owlrl.DeductiveClosure(owlrl.OWLRL_Semantics).expand(g) 70 | 71 | assert (T.A, T.prop, p_one) in g 72 | assert (p_one, RDF.type, XSD.positiveInteger) in g 73 | 74 | def test_dt_not_type(): 75 | """ 76 | Test dt-not-type rule for OWL 2 RL. 77 | """ 78 | m_one = Literal(-1, datatype=XSD.nonNegativeInteger) 79 | 80 | g = Graph() 81 | g.add((T.A, T.prop, m_one)) 82 | owlrl.DeductiveClosure(owlrl.OWLRL_Semantics).expand(g) 83 | 84 | # TODO, we know this one fails. It is not supposed to. 85 | #assert (m_one, RDF.type, XSD.nonNegativeInteger) not in g 86 | assert True 87 | 88 | result = next(g.objects(predicate=DAML.error)) 89 | expected = Literal( 90 | 'Lexical value of the literal \'-1\' does not match its datatype' 91 | ' (http://www.w3.org/2001/XMLSchema#nonNegativeInteger)' 92 | ) 93 | assert expected == result 94 | -------------------------------------------------------------------------------- /mimir/src/main/api/shape/ShexResponse.kt: -------------------------------------------------------------------------------- 1 | package api.shape 2 | 3 | import fr.inria.lille.shexjava.schema.ShexSchema 4 | import fr.inria.lille.shexjava.validation.RecursiveValidationWithMemorization 5 | import fr.inria.lille.shexjava.validation.ValidationAlgorithm 6 | import org.apache.commons.rdf.api.Graph 7 | import org.apache.commons.rdf.rdf4j.RDF4J 8 | import org.springframework.http.HttpHeaders 9 | import org.springframework.http.HttpStatus 10 | import org.springframework.http.ResponseEntity 11 | import org.springframework.web.bind.annotation.PostMapping 12 | import org.springframework.web.bind.annotation.RequestBody 13 | import org.springframework.web.bind.annotation.RestController 14 | 15 | import shex.ShexShapeMap 16 | import shex.ShexWrapper 17 | 18 | 19 | data class ShExRequest( 20 | val data: String = "", 21 | val data_lang: String = "TTL", 22 | val shape: String = "", 23 | val shape_map: String = "" 24 | ) 25 | 26 | @RestController 27 | class ShexIsValidController { 28 | 29 | @PostMapping( 30 | "/api/shape/shex_isvalid", 31 | consumes = [MimeType.json], 32 | produces = [MimeType.text] 33 | ) 34 | fun shexIsValid(@RequestBody requestBody: ShExRequest): ResponseEntity { 35 | val header = HttpHeaders() 36 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) // all responses are purely on text 37 | 38 | val dataGraph: Graph // data graph 39 | val shape: ShexSchema // shape expression graph 40 | val mapping: List // fixed shape mapping (custom) 41 | val validation: ValidationAlgorithm // validation of the entire data graph 42 | val validationResult: String // validation of the mapping 43 | 44 | if (requestBody.data.isBlank() || requestBody.shape.isBlank() || requestBody.shape_map.isBlank()) { 45 | return ResponseEntity("No Content", header, HttpStatus.NO_CONTENT) 46 | } 47 | 48 | val shexFactory = RDF4J() // Create a factory to be used by ShexJava 49 | val shexWrap = ShexWrapper(shexFactory) // set global factory for ShexJava and start wrapper 50 | 51 | try { 52 | // Load data model as Graph 53 | dataGraph = shexWrap.createDataGraph(requestBody.data, requestBody.data_lang) 54 | } catch (e: Exception) { 55 | return ResponseEntity( 56 | "Data graph ill formed, ${e.message.toString()}", header, HttpStatus.BAD_REQUEST 57 | ) 58 | } 59 | 60 | try { 61 | // Load schema to shex java 62 | shape = shexWrap.createSchema(requestBody.shape) 63 | } catch (e: Exception) { 64 | return ResponseEntity( 65 | "Shapes ill formed, ${e.message.toString()}", header, HttpStatus.BAD_REQUEST 66 | ) 67 | } 68 | 69 | try { 70 | // Parse Shape map as Pairs with it's corresponding absolute IRIs 71 | mapping = shexWrap.parseMap(requestBody.shape_map) 72 | } catch (e: Exception) { 73 | return ResponseEntity( 74 | "Shape map ill formed, ${e.message.toString()}", header, HttpStatus.BAD_REQUEST 75 | ) 76 | } 77 | 78 | try { 79 | // Validate graph and generate result text 80 | validation = RecursiveValidationWithMemorization(shape, dataGraph) 81 | validationResult = shexWrap.validateMapping(validation, mapping) 82 | } catch (e: Exception) { 83 | return ResponseEntity( 84 | "Error generating validation report: ${e.message.toString()}", 85 | header, 86 | HttpStatus.INTERNAL_SERVER_ERROR 87 | 88 | ) 89 | } 90 | 91 | // Return validation results 92 | return ResponseEntity( 93 | validationResult, header, HttpStatus.OK 94 | ) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Table of Contents 7 | 8 | 9 | 10 | 11 | 13 |

Table of Contents

14 |
15 | Everything 16 |
17 |

Modules

18 | RDFClosure
RDFClosure.AxiomaticTriples
RDFClosure.Closure
RDFClosure.CombinedClosure
RDFClosure.DatatypeHandling
RDFClosure.Literals
RDFClosure.OWL'
RDFClosure.OWLRL
RDFClosure.OWLRLExtras
RDFClosure.RDFS'
RDFClosure.RDFSClosure
RDFClosure.RestrictedDatatype
RDFClosure.XsdDatatypes

32 | [hide private] 34 | 35 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /mimir/src/main/api/shape/SHACLIsValid.kt: -------------------------------------------------------------------------------- 1 | package api.shape 2 | 3 | import toPrintableString 4 | import loadModel 5 | import org.apache.jena.graph.Graph 6 | import org.apache.jena.rdf.model.Model 7 | import org.apache.jena.shacl.ShaclValidator 8 | import org.apache.jena.shacl.Shapes 9 | import org.apache.jena.shacl.ValidationReport 10 | import org.springframework.http.HttpHeaders 11 | import org.springframework.http.HttpStatus 12 | import org.springframework.http.ResponseEntity 13 | import org.springframework.web.bind.annotation.PostMapping 14 | import org.springframework.web.bind.annotation.RequestBody 15 | import org.springframework.web.bind.annotation.RestController 16 | import toDOT 17 | 18 | data class SHACLRequest( 19 | val data: String = "", 20 | val data_lang: String = "TTL", 21 | val shape: String = "", 22 | val shape_lang: String = "TTL" 23 | ) 24 | 25 | data class SHACLResponse( 26 | val report: String, 27 | val fusion_dot: String 28 | ) 29 | 30 | @RestController 31 | class SHACLIsValidController { 32 | 33 | @PostMapping( 34 | "/api/shape/shacl_isvalid", 35 | consumes = [MimeType.json] 36 | ) 37 | fun shaclIsValid(@RequestBody requestBody: SHACLRequest): ResponseEntity { 38 | val header = HttpHeaders() 39 | 40 | // Define the terms outside of try in to use them later 41 | val dataGraph: Graph 42 | val shapesModel: Model 43 | val shapes: Shapes 44 | val fusionDot: String // dot of the union of both graphs 45 | val validationReport: ValidationReport // SCHACL report 46 | 47 | if (requestBody.data.isBlank() || requestBody.shape.isBlank()) { 48 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 49 | return ResponseEntity("No Content", header, HttpStatus.NO_CONTENT) 50 | } 51 | 52 | try { 53 | // Load shape graph 54 | shapesModel = loadModel(requestBody.shape, requestBody.shape_lang) 55 | shapes = Shapes.parse(shapesModel) 56 | } catch (e: Exception) { 57 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 58 | return ResponseEntity("Shapes ill formed, ${e.message.toString()}", header, HttpStatus.BAD_REQUEST) 59 | } 60 | 61 | try { 62 | // Load data graph 63 | dataGraph = loadModel(requestBody.data, requestBody.data_lang).graph 64 | } catch (e: Exception) { 65 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 66 | return ResponseEntity( 67 | "Data graph ill formed, ${e.message.toString()}", header, HttpStatus.BAD_REQUEST 68 | ) 69 | } 70 | 71 | try { 72 | // Create DOT with data and shapes 73 | fusionDot = loadModel(requestBody.data, requestBody.data_lang).union(shapesModel).toDOT() 74 | } catch (e: Exception) { 75 | return ResponseEntity(e.message.toString(), header, HttpStatus.BAD_REQUEST) 76 | } 77 | 78 | try { 79 | // Get a validation report 80 | validationReport = ShaclValidator.get().validate(shapes, dataGraph) 81 | } catch (e: Exception) { 82 | // Error trying to make the report 83 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 84 | return ResponseEntity(e.message.toString(), header, HttpStatus.INTERNAL_SERVER_ERROR) 85 | } 86 | 87 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.json) 88 | // default Response as text 89 | return when { 90 | validationReport.conforms() -> { 91 | // Respond "" instead of Conforms\n 92 | ResponseEntity( 93 | SHACLResponse("", fusionDot), 94 | header, 95 | HttpStatus.OK 96 | ) 97 | } 98 | 99 | else -> { 100 | // Return complete report as given by Jena 101 | ResponseEntity( 102 | SHACLResponse(validationReport.toPrintableString(), fusionDot), 103 | header, 104 | HttpStatus.OK 105 | ) 106 | } 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /mimir/src/test/api/shape/SHACLIsValidControllerTest.kt: -------------------------------------------------------------------------------- 1 | package api.shape 2 | 3 | import org.apache.jena.graph.Graph 4 | import org.apache.jena.rdf.model.Model 5 | import org.apache.jena.shacl.ShaclValidator 6 | import org.apache.jena.shacl.Shapes 7 | import org.apache.jena.shacl.ValidationReport 8 | import org.junit.jupiter.api.Test 9 | import org.junit.jupiter.api.Assertions.* 10 | 11 | import loadModel 12 | import toPrintableString 13 | 14 | internal class SHACLIsValidControllerTest { 15 | 16 | @Test 17 | fun shaclIsValid() { 18 | assertTrue(true) 19 | } 20 | 21 | @Test 22 | fun jenaSHACLDoNotConforms() { 23 | // Generates a valid report without exceptions 24 | val data = """ 25 | @prefix : . 26 | @prefix foaf: . 27 | @prefix schema: . 28 | 29 | :dave a :User ; #Fails as a :UserShape 30 | schema:name "Dave"; 31 | schema:gender :Unknown ; 32 | schema:birthDate 1980 ; 33 | schema:knows :grace . 34 | 35 | :emily a :User ; #Fails as a :UserShape 36 | schema:name "Emily", "Emilee"; 37 | schema:gender schema:Female . 38 | 39 | :frank a :User ; #Fails as a :UserShape 40 | foaf:name "Frank" ; 41 | schema:gender schema:Male . 42 | 43 | _:x a :User; #Fails as a :UserShape 44 | schema:name "Unknown" ; 45 | schema:gender schema:Male ; 46 | schema:knows _:x . 47 | """.trimIndent() 48 | val shape = """ 49 | @prefix : . 50 | @prefix foaf: . 51 | @prefix schema: . 52 | @prefix sh: . 53 | @prefix xsd: . 54 | 55 | 56 | :UserShape a sh:NodeShape; 57 | sh:targetClass :User ; 58 | sh:property [ # Blank node 1 59 | sh:path schema:name ; 60 | sh:minCount 1; 61 | sh:maxCount 1; 62 | sh:datatype xsd:string ; 63 | ] ; 64 | sh:property [ # Blank node 2 65 | sh:path schema:gender ; 66 | sh:minCount 1; 67 | sh:maxCount 1; 68 | sh:or ( 69 | [ sh:in (schema:Male schema:Female) ] 70 | [ sh:datatype xsd:string] 71 | ) 72 | ] ; 73 | sh:property [ # Blank node 3 74 | sh:path schema:birthDate ; 75 | sh:maxCount 1; 76 | sh:datatype xsd:date ; 77 | ] ; 78 | sh:property [ # Blank node 4 79 | sh:path schema:knows ; 80 | sh:nodeKind sh:IRI ; 81 | sh:class :User ; 82 | ] . 83 | """.trimIndent() 84 | 85 | val dataModel: Model = loadModel(data, "TTL") 86 | val shapeModel: Model = loadModel(shape, "TTL") 87 | 88 | val shapes: Shapes = Shapes.parse(shapeModel) 89 | val dataGraph: Graph = dataModel.graph 90 | // get validation report 91 | val validationReport: ValidationReport = ShaclValidator.get().validate(shapes, dataGraph) 92 | 93 | assertNotEquals("Conforms\r\n", validationReport.toPrintableString()) 94 | } 95 | 96 | @Test 97 | fun jenaSHACLConforms() { 98 | val data: String = """ 99 | @prefix : . 100 | :alice a :User . #Passes as a :UserShape 101 | 102 | a :User . #Passes as a :UserShape 103 | """.trimIndent() 104 | val shape: String = """ 105 | @prefix : . 106 | @prefix schema: . 107 | @prefix sh: . 108 | :UserShape a sh:NodeShape; 109 | sh:targetClass :User ; 110 | sh:nodeKind sh:IRI . 111 | """.trimIndent() 112 | 113 | val dataModel: Model = loadModel(data, "TTL") 114 | val shapeModel: Model = loadModel(shape, "TTL") 115 | 116 | val shapes: Shapes = Shapes.parse(shapeModel) 117 | val dataGraph: Graph = dataModel.graph 118 | // get validation report 119 | val validationReport: ValidationReport = ShaclValidator.get().validate(shapes, dataGraph) 120 | assertEquals("Conforms\r\n", validationReport.toPrintableString()) 121 | } 122 | } -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/test/relatives.ttl: -------------------------------------------------------------------------------- 1 | @prefix : . 2 | @prefix owl: . 3 | @prefix rdf: . 4 | @prefix xml: . 5 | @prefix xsd: . 6 | @prefix rdfs: . 7 | @base . 8 | 9 | rdf:type owl:Ontology . 10 | 11 | ################################################################# 12 | # Object Properties 13 | ################################################################# 14 | 15 | ### http://example.org/relatives#hasChild 16 | :hasChild rdf:type owl:ObjectProperty ; 17 | owl:inverseOf :hasParent . 18 | 19 | 20 | ### http://example.org/relatives#hasParent 21 | :hasParent rdf:type owl:ObjectProperty . 22 | 23 | :hasGrandparent rdf:type owl:ObjectProperty ; 24 | owl:propertyChainAxiom ( :hasParent 25 | :hasParent 26 | ) . 27 | 28 | ################################################################# 29 | # Classes 30 | ################################################################# 31 | 32 | ### http://example.org/relatives#Child 33 | :Child rdf:type owl:Class ; 34 | rdfs:subClassOf :Person . 35 | 36 | 37 | ### http://example.org/relatives#Parent 38 | :Parent rdf:type owl:Class ; 39 | rdfs:subClassOf :Person . 40 | 41 | 42 | ### http://example.org/relatives#Person 43 | :Person rdf:type owl:Class . 44 | 45 | 46 | ################################################################# 47 | # Individuals 48 | ################################################################# 49 | 50 | ### http://example.org/relatives#Aaron 51 | :Aaron rdf:type owl:NamedIndividual . 52 | 53 | 54 | ### http://example.org/relatives#Ann 55 | :Ann rdf:type owl:NamedIndividual , 56 | :Person . 57 | 58 | 59 | ### http://example.org/relatives#Bill 60 | :Bill rdf:type owl:NamedIndividual , 61 | :Person . 62 | 63 | 64 | ### http://example.org/relatives#Bob 65 | :Bob rdf:type owl:NamedIndividual , 66 | :Person ; 67 | :hasParent :Bill . 68 | 69 | 70 | ### http://example.org/relatives#Cathy 71 | :Cathy rdf:type owl:NamedIndividual , 72 | :Person ; 73 | :hasParent :Bill . 74 | 75 | 76 | ### http://example.org/relatives#Fred 77 | :Fred rdf:type owl:NamedIndividual , 78 | :Person ; 79 | :hasChild :James ; 80 | :hasParent :Cathy . 81 | 82 | 83 | ### http://example.org/relatives#Jacob 84 | :Jacob rdf:type owl:NamedIndividual , 85 | :Person ; 86 | :hasParent :Fred . 87 | 88 | 89 | ### http://example.org/relatives#James 90 | :James rdf:type owl:NamedIndividual , 91 | :Person . 92 | 93 | 94 | ### http://example.org/relatives#James2 95 | :James2 rdf:type owl:NamedIndividual , 96 | :Person ; 97 | :hasChild :John . 98 | 99 | 100 | ### http://example.org/relatives#John 101 | :John rdf:type owl:NamedIndividual , 102 | :Person ; 103 | :hasChild :Mary , 104 | :Michael ; 105 | :hasParent :James2 . 106 | 107 | 108 | ### http://example.org/relatives#Mary 109 | :Mary rdf:type owl:NamedIndividual , 110 | :Person . 111 | 112 | 113 | ### http://example.org/relatives#Michael 114 | :Michael rdf:type owl:NamedIndividual , 115 | :Person ; 116 | :hasParent :John . 117 | 118 | 119 | ### http://example.org/relatives#Simon 120 | :Simon rdf:type owl:NamedIndividual , 121 | :Person ; 122 | :hasParent :Michael . 123 | 124 | 125 | ### http://example.org/relatives#Tim 126 | :Tim rdf:type owl:NamedIndividual , 127 | :Person ; 128 | :hasParent :Simon , 129 | :Valerie . 130 | 131 | 132 | ### http://example.org/relatives#Valerie 133 | :Valerie rdf:type owl:NamedIndividual , 134 | :Person . 135 | 136 | 137 | ### http://example.org/relatives#Victor 138 | :Victor rdf:type owl:NamedIndividual , 139 | :Person . 140 | 141 | 142 | ### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi 143 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/toc-RDFClosure.RDFS'-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | RDFS' 7 | 8 | 9 | 10 | 11 | 13 |

Module RDFS'

14 |
15 |

Variables

16 | Alt
Bag
Class
Container
ContainerMembershipProperty
Datatype
HTMLLiteral
LangString
List
Literal
Property
RDFNS
RDFSNS
Resource
Seq
Statement
XMLLiteral
__package__
comment
domain
first
isDefinedBy
label
member
nil
object
predicate
range
rest
seeAlso
subClassOf
subPropertyOf
subject
type
value

52 | [hide private] 54 | 55 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/owlrl/OWL.py: -------------------------------------------------------------------------------- 1 | """ 2 | OWL and OWL2 terms. Note that the set of terms is *complete*, I.e., it includes *all* OWL 2 terms, regardless of 3 | whether the term is used in OWL 2 RL or not. 4 | 5 | **Requires**: `RDFLib`_, 4.0.0 and higher. 6 | 7 | .. _RDFLib: https://github.com/RDFLib/rdflib 8 | 9 | **License**: This software is available for use under the `W3C Software License`_. 10 | 11 | .. _W3C Software License: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 12 | 13 | **Organization**: `World Wide Web Consortium`_ 14 | 15 | .. _World Wide Web Consortium: http://www.w3.org 16 | 17 | **Author**: `Ivan Herman`_ 18 | 19 | .. _Ivan Herman: http://www.w3.org/People/Ivan/ 20 | """ 21 | 22 | 23 | import rdflib 24 | from rdflib import Namespace 25 | 26 | 27 | # The OWL namespace as used for RDFLib 28 | OWLNS = Namespace("http://www.w3.org/2002/07/owl#") 29 | 30 | annotatedSource = OWLNS["annotatedSource"] 31 | annotatedTarget = OWLNS["annotatedTarget"] 32 | annotatedProperty = OWLNS["annotatedProperty"] 33 | allValuesFrom = OWLNS["allValuesFrom"] 34 | assertionProperty = OWLNS["assertionProperty"] 35 | backwardCompatibleWith = OWLNS["backwardCompatibleWith"] 36 | cardinality = OWLNS["cardinality"] 37 | complementOf = OWLNS["complementOf"] 38 | BottomDataProperty = OWLNS["BottomDataProperty"] 39 | BottomObjectProperty = OWLNS["BottomObjectProperty"] 40 | datatypeComplementOf = OWLNS["datatypeComplementOf"] 41 | deprecated = OWLNS["deprecated"] 42 | differentFrom = OWLNS["differentFrom"] 43 | disjointUnionOf = OWLNS["disjointUnionOf"] 44 | disjointClasses = OWLNS["disjointClasses"] 45 | disjointWith = OWLNS["disjointWith"] 46 | distinctMembers = OWLNS["distinctMembers"] 47 | equivalentClass = OWLNS["equivalentClass"] 48 | equivalentProperty = OWLNS["equivalentProperty"] 49 | hasKey = OWLNS["hasKey"] 50 | hasValue = OWLNS["hasValue"] 51 | hasSelf = OWLNS["hasSelf"] 52 | imports = OWLNS["imports"] 53 | incompatibleWith = OWLNS["incompatibleWith"] 54 | intersectionOf = OWLNS["intersectionOf"] 55 | inverseOf = OWLNS["inverseOf"] 56 | maxCardinality = OWLNS["maxCardinality"] 57 | maxQualifiedCardinality = OWLNS["maxQualifiedCardinality"] 58 | members = OWLNS["members"] 59 | minCardinality = OWLNS["minCardinality"] 60 | minQualifiedCardinality = OWLNS["minQualifiedCardinality"] 61 | onClass = OWLNS["onClass"] 62 | onDataRange = OWLNS["onDataRange"] 63 | onDatatype = OWLNS["onDatatype"] 64 | oneOf = OWLNS["oneOf"] 65 | onProperty = OWLNS["onProperty"] 66 | onProperties = OWLNS["onProperties"] 67 | OWLpredicate = OWLNS["predicate"] 68 | priorVersion = OWLNS["priorVersion"] 69 | propertyChainAxiom = OWLNS["propertyChainAxiom"] 70 | propertyDisjointWith = OWLNS["propertyDisjointWith"] 71 | qualifiedCardinality = OWLNS["qualifiedCardinality"] 72 | sameAs = OWLNS["sameAs"] 73 | someValuesFrom = OWLNS["someValuesFrom"] 74 | sourceIndividual = OWLNS["sourceIndividual"] 75 | OWLsubject = OWLNS["subject"] 76 | targetIndividual = OWLNS["targetIndividual"] 77 | targetValue = OWLNS["targetValue"] 78 | TopDataProperty = OWLNS["TopDataProperty"] 79 | TopObjectProperty = OWLNS["TopObjectProperty"] 80 | unionOf = OWLNS["unionOf"] 81 | versionInfo = OWLNS["versionInfo"] 82 | versionIRI = OWLNS["versionIRI"] 83 | withRestrictions = OWLNS["withRestrictions"] 84 | 85 | AllDisjointProperties = OWLNS["AllDisjointProperties"] 86 | AllDifferent = OWLNS["AllDifferent"] 87 | AllDisjointClasses = OWLNS["AllDisjointClasses"] 88 | Annotation = OWLNS["Annotation"] 89 | AnnotationProperty = OWLNS["AnnotationProperty"] 90 | AsymmetricProperty = OWLNS["AsymmetricProperty"] 91 | Axiom = OWLNS["Axiom"] 92 | OWLClass = OWLNS["Class"] 93 | DataRange = OWLNS["DataRange"] 94 | DatatypeProperty = OWLNS["DatatypeProperty"] 95 | DeprecatedClass = OWLNS["DeprecatedClass"] 96 | DeprecatedProperty = OWLNS["DeprecatedProperty"] 97 | FunctionalProperty = OWLNS["FunctionalProperty"] 98 | InverseFunctionalProperty = OWLNS["InverseFunctionalProperty"] 99 | IrreflexiveProperty = OWLNS["IrreflexiveProperty"] 100 | NamedIndividual = OWLNS["NamedIndividual"] 101 | NegativePropertyAssertion = OWLNS["NegativePropertyAssertion"] 102 | Nothing = OWLNS["Nothing"] 103 | ObjectProperty = OWLNS["ObjectProperty"] 104 | Ontology = OWLNS["Ontology"] 105 | OntologyProperty = OWLNS["OntologyProperty"] 106 | ReflexiveProperty = OWLNS["ReflexiveProperty"] 107 | Restriction = OWLNS["Restriction"] 108 | Thing = OWLNS["Thing"] 109 | SelfRestriction = OWLNS["SelfRestriction"] 110 | SymmetricProperty = OWLNS["SymmetricProperty"] 111 | TransitiveProperty = OWLNS["TransitiveProperty"] 112 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/owlrl/XsdDatatypes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | """ 4 | Lists of XSD datatypes and their mutual relationships 5 | 6 | **Requires**: `RDFLib`_, 4.0.0 and higher. 7 | 8 | .. _RDFLib: https://github.com/RDFLib/rdflib 9 | 10 | **License**: This software is available for use under the `W3C Software License`_. 11 | 12 | .. _W3C Software License: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 13 | 14 | **Organization**: `World Wide Web Consortium`_ 15 | 16 | .. _World Wide Web Consortium: http://www.w3.org 17 | 18 | **Author**: `Ivan Herman`_ 19 | 20 | .. _Ivan Herman: http://www.w3.org/People/Ivan/ 21 | 22 | """ 23 | __author__ = 'Ivan Herman' 24 | __contact__ = 'Ivan Herman, ivan@w3.org' 25 | __license__ = 'W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231' 26 | 27 | # noinspection PyPep8Naming 28 | from .RDFS import RDFNS as ns_rdf 29 | from .RDFS import Literal 30 | from .RDFS import XMLLiteral 31 | from .RDFS import HTMLLiteral 32 | from .RDFS import LangString 33 | 34 | import rdflib 35 | # noinspection PyPep8Naming 36 | from rdflib.namespace import XSD as ns_xsd 37 | 38 | #: The basic XSD types used everywhere; this means not the complete set of day/month types 39 | _Common_XSD_Datatypes = [ 40 | ns_xsd['integer'], ns_xsd['decimal'], ns_xsd['nonNegativeInteger'], ns_xsd['nonPositiveInteger'], 41 | ns_xsd['negativeInteger'], ns_xsd['positiveInteger'], ns_xsd['long'], ns_xsd['int'], ns_xsd['short'], 42 | ns_xsd['byte'], ns_xsd['unsignedLong'], ns_xsd['unsignedInt'], ns_xsd['unsignedShort'], 43 | ns_xsd['unsignedByte'], ns_xsd['float'], ns_xsd['double'], ns_xsd['string'], ns_xsd['normalizedString'], 44 | ns_xsd['token'], ns_xsd['language'], ns_xsd['Name'], ns_xsd['NCName'], ns_xsd['NMTOKEN'], 45 | ns_xsd['boolean'], ns_xsd['hexBinary'], ns_xsd['base64Binary'], ns_xsd['anyURI'], 46 | ns_xsd['dateTimeStamp'], ns_xsd['dateTime'], ns_xsd['time'], ns_xsd['date'], 47 | Literal, XMLLiteral, HTMLLiteral, LangString 48 | ] 49 | 50 | #: RDFS Datatypes: the basic ones plus the complete set of day/month ones 51 | RDFS_Datatypes = _Common_XSD_Datatypes + [ns_xsd['gYearMonth'], ns_xsd['gMonthDay'], ns_xsd['gYear'], 52 | ns_xsd['gDay'], ns_xsd['gMonth']] 53 | 54 | #: OWL RL Datatypes: the basic ones plus plain literal 55 | OWL_RL_Datatypes = _Common_XSD_Datatypes + [ns_rdf['PlainLiteral']] 56 | 57 | #: XSD Datatype subsumptions 58 | _Common_Datatype_Subsumptions = { 59 | ns_xsd['dateTimeStamp']: [ns_xsd['dateTime']], 60 | ns_xsd['integer']: [ns_xsd['decimal']], 61 | ns_xsd['long']: [ns_xsd['integer'], ns_xsd['decimal']], 62 | ns_xsd['int']: [ns_xsd['long'], ns_xsd['integer'], ns_xsd['decimal']], 63 | ns_xsd['short']: [ns_xsd['int'], ns_xsd['long'], ns_xsd['integer'], ns_xsd['decimal']], 64 | ns_xsd['byte']: [ns_xsd['short'], ns_xsd['int'], ns_xsd['long'], ns_xsd['integer'], ns_xsd['decimal']], 65 | 66 | ns_xsd['nonNegativeInteger']: [ns_xsd['integer'], ns_xsd['decimal']], 67 | ns_xsd['positiveInteger']: [ns_xsd['nonNegativeInteger'], ns_xsd['integer'], ns_xsd['decimal']], 68 | ns_xsd['unsignedLong']: [ns_xsd['nonNegativeInteger'], ns_xsd['integer'], ns_xsd['decimal']], 69 | ns_xsd['unsignedInt']: [ns_xsd['unsignedLong'], ns_xsd['nonNegativeInteger'], ns_xsd['integer'], ns_xsd['decimal']], 70 | ns_xsd['unsignedShort']: [ns_xsd['unsignedInt'], ns_xsd['unsignedLong'], ns_xsd['nonNegativeInteger'], 71 | ns_xsd['integer'], ns_xsd['decimal']], 72 | ns_xsd['unsignedByte']: [ns_xsd['unsignedShort'], ns_xsd['unsignedInt'], ns_xsd['unsignedLong'], 73 | ns_xsd['nonNegativeInteger'], ns_xsd['integer'], ns_xsd['decimal']], 74 | 75 | ns_xsd['nonPositiveInteger']: [ns_xsd['integer'], ns_xsd['decimal']], 76 | ns_xsd['negativeInteger']: [ns_xsd['nonPositiveInteger'], ns_xsd['integer'], ns_xsd['decimal']], 77 | 78 | ns_xsd['normalizedString']: [ns_xsd["string"]], 79 | ns_xsd['token']: [ns_xsd['normalizedString'], ns_xsd["string"]], 80 | ns_xsd['language']: [ns_xsd['token'], ns_xsd['normalizedString'], ns_xsd["string"]], 81 | ns_xsd['Name']: [ns_xsd['token'], ns_xsd['normalizedString'], ns_xsd["string"]], 82 | ns_xsd['NCName']: [ns_xsd['Name'], ns_xsd['token'], ns_xsd['normalizedString'], ns_xsd["string"]], 83 | ns_xsd['NMTOKEN']: [ns_xsd['Name'], ns_xsd['token'], ns_xsd['normalizedString'], ns_xsd["string"]], 84 | } 85 | 86 | #: RDFS Datatype subsumptions: at the moment, there is no extra to XSD 87 | RDFS_Datatype_Subsumptions = _Common_Datatype_Subsumptions 88 | 89 | #: OWL Datatype subsumptions: at the moment, there is no extra to XSD 90 | OWL_Datatype_Subsumptions = _Common_Datatype_Subsumptions 91 | -------------------------------------------------------------------------------- /mimir/README.md: -------------------------------------------------------------------------------- 1 | ## Set up and running 2 | The backend is written on Kotlin using Spring Boot framework, dependencies and 3 | configurations are done using Maven, so you should install that before. 4 | 5 | However, given that it also uses BastyZ/OWL-RL instead of RDFLib/OWL-RL, you 6 | must set up and environment before launching the backend. 7 | 8 | ⚠ For this to work you should use Python 3.5+ and Pip 9 | 10 | Go to `src/main/reasoner/owlrl` and create a virtualenv (we use _venv_) according to 11 | [venv documentation](https://docs.python.org/3/library/venv.html) and install BastyZ/OWL-RL: 12 | ```shell script 13 | # Create venv environment 14 | python3 -m venv venv 15 | 16 | # Activate 17 | source venv/bin/activate 18 | 19 | # Install BastyZ/OWL-RL on the current environment 20 | python setup.py install 21 | 22 | ``` 23 | 24 | Having _maven_ installed, write on your terminal: 25 | 26 | ``` shell script 27 | # install dependencies 28 | mvn install 29 | ``` 30 | 31 | And you can run it with: 32 | 33 | ``` shell script 34 | # Activate venv before running SpringBoot 35 | source src/main/reasoner/owlrl/venv/bin/activate 36 | 37 | mvn spring-boot:run 38 | ``` 39 | 40 | ## Configuration 41 | ### Port 42 | Go to `src/main/resources` and edit the file `application.yml`, modifying: 43 | ``` sh 44 | port : 9060 45 | ``` 46 | 47 | You can modify a lot of things here, see 48 | [this documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-yaml) 49 | to learn more. 50 | 51 | ### CORS 52 | This API only accepts request from accepted origins, this is added like several 53 | mappings, defining controllers, origins, methods and timeouts. Edit the file 54 | `WebConfig.kt` at `src/main/api/` adding or editing existing mappings. 55 | 56 | A mapping looks like: 57 | ``` Kotlin 58 | // Based on https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors-global 59 | registry.addMapping("/api/**") 60 | .allowedOrigins("http://localhost:9080") 61 | .allowedMethods("GET", "POST") 62 | .maxAge(3600) 63 | ``` 64 | 65 | ### OWL 2 RL / RDFS Reasoners 66 | The backend contains a full copy of 67 | [OWL-RL](https://github.com/BastyZ/OWL-RL) 68 | written on python 3 on the directory `src/main/reasoner/owlrl`, to run the 69 | `script/owlrl` CLI script. 70 | 71 | Our OWL-RL wrapper (on `OwlRLWrapper.kt:38`) executes the following configuration 72 | elements to infer using BastyZ/OWL-RL where **flag** is either -r or -w for RDFS and OWL 73 | respectively: 74 | 75 | ```shell script 76 | CMD_NAME flag -f 77 | ``` 78 | 79 | Then read the Runtime CLI for the inference result, and converts this result to DOT. 80 | 81 | #### Modify OWL-RL location or version 82 | 83 | If you want to upgrade it or use another version of OWL-RL you can place it on the 84 | same place and configuring the environment again, or change the 85 | `ReasonerConfig.kt` file on the `src/main/api/` directory, to change where 86 | the runtime looks for an environment, and the script (lines 10 and 11). 87 | 88 | ``` Kotlin 89 | # Activations script is not being used right now, because the runtime will get a denied access 90 | var ENV_ACTIVATION_SCRIPT = "source src/main/reasoner/owlrl/venv/bin/activate" 91 | var CMD_NAME = "python src/main/reasoner/owlrl/scripts/owlrl" 92 | ``` 93 | 94 | Pointing to the same script on another place you desire. 95 | 96 | #### Configure an environment for OWL-RL 97 | This configuration is exactly the same that the one on the initial setup. 98 | 99 | Go to `src/main/reasoner/owlrl` and create a virtualenv (we use _venv_) according to 100 | [venv documentation](https://docs.python.org/3/library/venv.html): 101 | ```shell script 102 | # Create venv environment 103 | python3 -m venv venv 104 | 105 | # Activate on Windows systems (See configuration section for more info) 106 | venv/Scripts/activate.bat 107 | # for Linux based systems (default configuration) 108 | source venv/bin/activate 109 | 110 | # Install BastyZ/OWL-RL on the current environment 111 | python setup.py install 112 | 113 | ``` 114 | 115 | ## Directories 116 | This project is divided on the following way: 117 | ``` 118 | src/main 119 | | 120 | + -- api # API controllers and code 121 | | | 122 | | + -- model # api/model endpoints 123 | | | 124 | | + -- owl # api/owl endpoints 125 | | | 126 | | + -- shape # api/shape endpoints 127 | | | 128 | | + -- tdb # api/tdb endpoints 129 | | | 130 | | + -- Application.kt # App main() 131 | | 132 | + -- dot # DOT writter extension for Jena 133 | | 134 | + -- reasoner # OWL-RL sources copy, wrapper and temp directory 135 | | 136 | + -- shex # ShEx Wrapper, map extension and temp directory 137 | | 138 | + -- Utils.kt # Auxiliary functions 139 | ``` 140 | 141 | 142 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/scripts/owlrl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | from optparse import OptionParser 5 | from owlrl import convert_graph, RDFXML, TURTLE, JSON, AUTO, RDFA 6 | 7 | 8 | def main(): 9 | parser = OptionParser(usage="%prog [options] fname1 fname2 ...") 10 | parser.disable_interspersed_args() 11 | 12 | # The 'text' field is not used in the command line, but the CGI environment uses it. This means that there 13 | # is no option to change that, but is added to the final option structure 14 | parser.set_defaults(format=TURTLE, owlClosure="no", rdfsClosure="no", owlExtras="no", axioms="no", daxioms="no", 15 | iformat=AUTO, trimming="no", maximal="no", text=None) 16 | 17 | parser.add_option("-f", "--file", type="string", dest="source", 18 | help="input file; should be a .rdf or .ttl file, for RDF/XML or Turtle, respectively. If " 19 | "missing, or if the value is '-' then standard input is used. Usage of this options is not " 20 | "really necessary, the fname in the command lines refer to files by themselves") 21 | 22 | parser.add_option("--owlrl", action="store", dest="owlClosure", choices=["yes", "no"], 23 | help="execute OWL RL closure; argument must be yes|no [default: %default]") 24 | 25 | parser.add_option("-w", action="store_const", dest="owlClosure", const="yes", 26 | help="OWL-RL is executed; shorthand for --owlrl=yes") 27 | 28 | parser.add_option("--rdfs", action="store", dest="rdfsClosure", choices=["yes", "no"], 29 | help="execute RDFS closure; argument must be yes|no [default: %default]") 30 | 31 | parser.add_option("-r", action="store_const", dest="rdfsClosure", const="yes", 32 | help="RDFS is executed; shorthand for --rdfs=yes") 33 | 34 | parser.add_option("--extras", action="store", dest="owlExtras", choices=["yes", "no"], 35 | help="additional owl features added; argument must be yes|no [default: %default]") 36 | 37 | parser.add_option("-e", action="store_const", dest="owlExtras", const="yes", 38 | help="additional owl features added; shorthand for --extras=yes [default: %default]") 39 | 40 | parser.add_option("--axioms", action="store", dest="axioms", choices=["yes", "no"], 41 | help="axiomatic triples; argument must be yes|no [default: %default]") 42 | 43 | parser.add_option("-a", action="store_const", dest="axioms", const="yes", 44 | help="add axiomatic triples; shorthand for --axioms=yes [default: %default]") 45 | 46 | parser.add_option("--daxioms", action="store", dest="daxioms", choices=["yes", "no"], 47 | help="datatype axiomatic triples; argument must be true|false [default: %default]") 48 | 49 | parser.add_option("-d", action="store_const", dest="daxioms", const="yes", 50 | help="add axiomatic triples; shorthand for --daxioms=yes [default: %default]") 51 | 52 | parser.add_option("--trimming", action="store", dest="trimming", choices=["yes", "no"], 53 | help="trim the output of OWL 2 RL and extension; 'yes' is ineffective unless --extras=yes " 54 | "[default: %default]") 55 | 56 | parser.add_option("-m", "--maximal", action="store_const", dest="maximal", const="yes", 57 | help="maximal possibilities switched on: RDFS, OWL with extensions, and with trimming") 58 | 59 | parser.add_option("-t", action="store_const", dest="trimming", const="yes", 60 | help="trim the output of OWL 2 RL and extension; shorthand for --trimming=yes " 61 | "[default: %default]") 62 | 63 | parser.add_option("-o", "-s", "--serialization", "--syntax", action="store", dest="format", 64 | choices=[TURTLE, JSON, RDFXML], 65 | help="output format; argument must be turtle|json|xml [default: %default]") 66 | 67 | parser.add_option("-i", "--input_syntax", action="store", dest="iformat", 68 | choices=[AUTO, TURTLE, JSON, RDFA, RDFXML], 69 | help="format of input; argument must be auto|turtle|xml|rdfa|json [default: %default]; auto " 70 | "means that file suffix defines the format. This flag is valid for all input files.") 71 | 72 | (options, args) = parser.parse_args() 73 | if options.source is None: 74 | options.sources = [] 75 | else: 76 | options.sources = [options.source] 77 | 78 | if len(args) > 0: 79 | options.sources += args 80 | 81 | if len(options.sources) == 0: 82 | # the default mechanism, ie, to use standard input 83 | options.sources = ["-"] 84 | 85 | if options.maximal == "yes": 86 | options.trimming = "yes" 87 | options.owlClosure = "yes" 88 | options.owlExtras = "yes" 89 | 90 | print(convert_graph(options)) 91 | 92 | 93 | # The standard startup idiom... 94 | if __name__ == '__main__': 95 | main() 96 | -------------------------------------------------------------------------------- /mimir/src/main/api/tdb/QueryModelResponse.kt: -------------------------------------------------------------------------------- 1 | package api.tdb 2 | 3 | import org.apache.jena.query.* 4 | import org.apache.jena.rdf.model.Model 5 | import org.apache.jena.rdf.model.ModelFactory.createDefaultModel 6 | import org.springframework.http.ResponseEntity 7 | import org.springframework.http.HttpHeaders 8 | import org.springframework.http.HttpStatus 9 | import org.springframework.http.MediaType 10 | import org.springframework.web.bind.annotation.PostMapping 11 | import org.springframework.web.bind.annotation.RequestBody 12 | import org.springframework.web.bind.annotation.RequestHeader 13 | import org.springframework.web.bind.annotation.RestController 14 | 15 | import formatAs 16 | import formatAskAs 17 | import loadModel 18 | import parseFormat 19 | import toDOT 20 | import toMimeType 21 | import api.tdb.sparqlPatternToDot 22 | 23 | 24 | data class QueryModelRequest( 25 | val data: String = "", 26 | val data_lang: String = "TTL", 27 | val query: String = "", 28 | val query_response_lang:String = "" 29 | ) 30 | 31 | fun pickFormat(formats: MutableList): String { 32 | return when (formats.size) { 33 | 0 -> "No Format" 34 | 1 -> formats.first() 35 | else -> { 36 | // We always expect to receive Text and Another format, 37 | // so we pick the other one 38 | if (formats.filterNot { it == "Text" }.isEmpty()) return "Text" 39 | else formats 40 | .filterNot { it == "Text" } 41 | .first() 42 | } 43 | } 44 | 45 | } 46 | 47 | @RestController 48 | class QueryModelController { 49 | 50 | @PostMapping( 51 | "/api/tdb/query_model", 52 | consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE] 53 | ) 54 | fun queryModel( 55 | @RequestHeader(HttpHeaders.ACCEPT) formats: String, 56 | @RequestBody request: QueryModelRequest 57 | ): ResponseEntity { 58 | val responseLangOptions = parseFormat(formats) 59 | var responseLang = pickFormat(responseLangOptions) 60 | val header = HttpHeaders() 61 | 62 | // no info case 63 | if (request.data.isBlank()) { 64 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 65 | return ResponseEntity("No Content", header, HttpStatus.NO_CONTENT) 66 | } 67 | 68 | // load model to Memory 69 | val model: Model 70 | try { 71 | model = loadModel(request.data, request.data_lang) 72 | val dataOnDOT: String = model.toDOT() 73 | } catch (e: Exception) { 74 | // could not load model by some reason 75 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 76 | return ResponseEntity("Can't read model", header, HttpStatus.BAD_REQUEST) 77 | } 78 | val query: Query 79 | 80 | try { 81 | // Query that model 82 | query = QueryFactory.create(request.query) 83 | } catch (e: Exception) { 84 | // could not load model by some reason 85 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 86 | return ResponseEntity("Can't run query: \n Reason: ${e.message}", header, HttpStatus.BAD_REQUEST) 87 | } 88 | 89 | var queryResponseBody = String() 90 | var response_type:String = request.query_response_lang 91 | if (response_type == "Query") { 92 | queryResponseBody = sparqlPatternToDot(request.query) 93 | } 94 | else { 95 | try { 96 | QueryExecutionFactory.create(query, model).let { qExecution: QueryExecution -> 97 | when { 98 | query.isSelectType -> { 99 | val resultSet: ResultSet = qExecution.execSelect() 100 | queryResponseBody = resultSet.formatAs(responseLang) 101 | } 102 | query.isAskType -> { 103 | val resultSet: Boolean = qExecution.execAsk() 104 | queryResponseBody = resultSet.formatAskAs(responseLang) 105 | } 106 | query.isConstructType or query.isDescribeType -> { 107 | val resultModel: Model = when { 108 | query.isConstructType -> qExecution.execConstruct() 109 | query.isDescribeType -> qExecution.execDescribe() 110 | else -> createDefaultModel() // Should not be possible, but when is exhaustive 111 | } 112 | // Format to response, defaults to TTL 113 | val responsePair: Pair = resultModel.formatAs(responseLang) 114 | queryResponseBody = responsePair.first 115 | responseLang = responsePair.second 116 | } 117 | } 118 | } 119 | } catch (e: Exception) { 120 | // Return an error response 121 | header.add(HttpHeaders.CONTENT_TYPE, MimeType.text) 122 | return ResponseEntity("Unsupported Media type / Format", header, HttpStatus.UNSUPPORTED_MEDIA_TYPE) 123 | } 124 | } 125 | header.add(HttpHeaders.CONTENT_TYPE, toMimeType(responseLang)) 126 | return ResponseEntity(queryResponseBody, header, HttpStatus.OK) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RDF Playground 2 | This project allows web users to write RDF as Turtle, check its syntax, 3 | visualize the data as a graph, and use SPARQL, RDFS, OWL, SHACL and ShEx. 4 | 5 | The project is intended to provide many functionalities in one system, 6 | and is intended to be used for small examples (e.g., for teaching or demos). 7 | 8 | You can see a [demo here](http://rdfplayground.dcc.uchile.cl/). Note that the 9 | demo is not intended to be a production system. If you intend to use RDF Playground 10 | regularly (e.g., for a class), we would recommend to install and run it locally in a 11 | server you control. There are two options: direct or Docker. 12 | 13 | # Installation and running (direct) 14 | 15 | Ensure you've cloned or downloaded this repository on the machine you want to run RDF Playground. You will need to install and run the back-end (Mimir) and the front-end (Odin) for RDF Playground to run. 16 | 17 | ### Back end (mimir folder) 18 | The backend is written in Kotlin using the Spring Boot framework; dependencies and 19 | configurations are done using Maven. The code also has [a fork](https://github.com/BastyZ/OWL-RL) of the (Python) [OWL-RL reasoner](https://github.com/RDFLib/OWL-RL) 20 | inside, so you have to create and environment for this code before executing the backend. 21 | 22 | ⚠ For this to work you should use Python 3.5+ and Pip 23 | 24 | Go to `src/main/reasoner/owlrl` and create a virtualenv (we use _venv_) according to 25 | [venv documentation](https://docs.python.org/3/library/venv.html) and install BastyZ/OWL-RL: 26 | ```shell script 27 | # Create venv environment 28 | python3 -m venv venv 29 | 30 | # Activate 31 | source venv/bin/activate 32 | 33 | # Install BastyZ/OWL-RL on the current environment 34 | python setup.py install 35 | ``` 36 | 37 | Then, having _maven_ installed, you go to `mimir/` directory where `pom.xml` is and 38 | write in your terminal: 39 | 40 | ``` sh 41 | # install dependencies 42 | mvn install 43 | ``` 44 | 45 | And you can run it with: 46 | 47 | ``` sh 48 | # Activate venv before running SpringBoot 49 | source src/main/reasoner/owlrl/venv/bin/activate 50 | 51 | mvn spring-boot:run 52 | ``` 53 | 54 | ### Front end (odin folder) 55 | The frontend is written in Javascript + HTML using Vuetify framework and nodejs 56 | 13; having that and npm installed you can go to the `odin/` directory and write: 57 | 58 | ``` sh 59 | # install dependencies 60 | npm install 61 | ``` 62 | 63 | And you can run it with: 64 | ``` sh 65 | # run for development 66 | npm run-script serve 67 | 68 | # create a production build 69 | npm run-script build 70 | ``` 71 | This last command produces a production-ready bundle in the `dist/` directory, 72 | see https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build for more 73 | information. 74 | 75 | For more information on the serve command see 76 | https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve. 77 | 78 | ### Configuration 79 | For configurations on the backend and frontend see their respective README 80 | files. 81 | 82 | # Installation and running (Docker) 83 | 84 | Ensure you've cloned or downloaded this repository on the machine you want to run RDF Playground. 85 | 86 | The repository also provides a `Dockerfile` that facilitates installing and running RDF Playground in Docker (credit to [@fvillena](https://github.com/fvillena)). 87 | 88 | Ensure that Docker is installed and running ([see instructions](https://docs.docker.com/engine/install/)). 89 | 90 | The following commands assume a Unix-like environment. **Some commands may need `sudo` depending on how you've installed and run Docker.** 91 | 92 | With Docker running, go to the RDFPlayground main folder (the one containing `Dockerfile`): 93 | 94 | ```sh 95 | cd /path/to/RDFPlayground 96 | ``` 97 | 98 | Next we build a Docker image: 99 | 100 | ```sh 101 | docker build -t rdf-playground . 102 | ``` 103 | 104 | This might take some time. The final Docker image should be around 1GB. Once installed you can run 105 | 106 | ```sh 107 | sudo docker image list 108 | ``` 109 | 110 | Where you should see the `rdf-playground` image listed. 111 | 112 | Next we need to run a Docker container for RDF Playground. Here we assume that we want to map between port `80` of the container for the front-end to port `80` of the `localhost` of the machine running Docker (the first `80` is the port of the machine; the second `80` is the port of the container) and port `9060` of the container for the back-end to port `9060` of the `localhost` of the machine. We also assume that we want to restart RDF Playground if for any reason it is not running with the `always` option ([see more options](https://docs.docker.com/config/containers/start-containers-automatically/)). 113 | 114 | ```sh 115 | docker run -d -p 127.0.0.1:80:80 -p 127.0.0.1:9060:9060 --restart always rdf-playground 116 | ``` 117 | 118 | You should now see the container running with: 119 | 120 | ```sh 121 | docker ps 122 | ``` 123 | 124 | If this worked, you should be able to call (in the case of port `80` on the machine, otherwise adding `:1234` without space if using port `1234` on the machine): 125 | 126 | ```sh 127 | wget localhost 128 | ``` 129 | 130 | This should download a HTML file, which you can preview with: 131 | 132 | ```sh 133 | more index.html 134 | ``` 135 | 136 | It may indicate that Javascript is not running, but this should not be a problem once you load the page from the browser. 137 | 138 | Now RDF Playground should be running on the selected port of your machine. (You may still need to configure external Web access via a static I.P. or hostname to the selected port on your machine.) 139 | 140 | Copyright © 2020 Bastián Inostroza, Licensed under the Apache License, Version 2.0. 141 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/scripts/RDFConvertService: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Possible CGI entry point for the owl package. 5 | 6 | @author: U{Ivan Herman} 7 | @license: This software is available for use under the 8 | U{W3C® SOFTWARE NOTICE AND LICENSE} 9 | @contact: Ivan Herman, ivan@w3.org 10 | """ 11 | 12 | """ 13 | $Id: RDFConvertService.py,v 1.3 2009/07/10 08:45:14 ivan Exp $ 14 | """ 15 | 16 | import os 17 | import sys 18 | import cgi 19 | import cgitb 20 | # prevent accidentally importing `scripts/owlrl` file when calling 21 | # `from owlrl import ...` below. 22 | HERE_DIR = os.path.abspath(os.path.dirname(__file__)) 23 | if HERE_DIR in sys.path: 24 | sys.path.remove(HERE_DIR) 25 | 26 | # Add 'owlrl' module from the parent directory into the path if it exists. 27 | PARENT_DIR = os.path.dirname(HERE_DIR) 28 | parent_dir_list = os.listdir(PARENT_DIR) 29 | if 'owlrl' in parent_dir_list: 30 | possible_owlrl = os.path.join(PARENT_DIR, 'owlrl') 31 | if os.path.isdir(possible_owlrl): 32 | sys.path.append(possible_owlrl) 33 | 34 | __version__ = "4.0" 35 | cgitb.enable() 36 | form = cgi.FieldStorage() 37 | from owlrl import convert_graph, RDFXML, TURTLE, AUTO 38 | 39 | # --------------------------------------------------------------------------------------------------------------------- 40 | 41 | 42 | class Options: 43 | def __init__(self, frm): 44 | self.iformat = AUTO 45 | self.owlClosure = "no" 46 | self.rdfsClosure = "no" 47 | self.owlExtras = "no" 48 | self.axioms = "no" 49 | self.daxioms = "no" 50 | self.sources = [] 51 | self.text = None 52 | self.format = TURTLE 53 | 54 | if "source_1" in list(frm.keys()): 55 | self.sources.append(frm["source_1"].value) 56 | if "source_2" in list(frm.keys()): 57 | self.sources.append(frm["source_2"].value) 58 | 59 | if "text" in list(frm.keys()): 60 | self.text = frm["text"].value 61 | if "format" in list(frm.keys()): 62 | self.format = frm["format"].value 63 | if "iformat" in list(frm.keys()): 64 | v = frm["iformat"].value 65 | if v == "xml" or v == "turtle": 66 | self.iformat = v 67 | 68 | if "fullClosure" in list(frm.keys()) and frm["fullClosure"].value == "yes": 69 | self.owlClosure = "yes" 70 | self.rdfsClosure = "yes" 71 | self.axioms = "no" 72 | self.daxioms = "no" 73 | self.owlExtras = "no" 74 | else: 75 | if "owlClosure" in list(frm.keys()): 76 | self.owlClosure = frm["owlClosure"].value 77 | if "rdfsClosure" in list(frm.keys()): 78 | self.rdfsClosure = frm["rdfsClosure"].value 79 | if "owlExtras" in list(frm.keys()): 80 | self.owlExtras = frm["owlExtras"].value 81 | if "axioms" in list(frm.keys()): 82 | self.axioms = frm["axioms"].value 83 | if "daxioms" in list(frm.keys()): 84 | self.daxioms = frm["daxioms"].value 85 | 86 | # this one is for backward compatibility... 87 | if "uri" in list(frm.keys()): 88 | self.sources.append(frm["uri"].value) 89 | if "source" in list(frm.keys()): 90 | self.sources.append(frm["source"].value) 91 | 92 | def to_html(self): 93 | print('
') 94 | 95 | print('
Sources:
') 96 | print('
') 97 | if len(self.sources) == 0: 98 | print("none") 99 | elif len(self.sources) == 1: 100 | print(cgi.escape(self.sources[0])) 101 | else: 102 | print(cgi.escape(self.sources[0]), ", ", cgi.escape(self.sources[1])) 103 | print('
') 104 | 105 | print('
Input format:
') 106 | print('
%s
' % self.iformat) 107 | print('
Output format:
%s
' % self.format) 108 | print('
OWL 2 RL Processing:
%s
' % self.owlClosure) 109 | print('
RDFS Processing:
%s
' % self.rdfsClosure) 110 | print('
Extra OWL Processing:
%s
' % self.owlExtras) 111 | print('
Axiomatic triples added:
%s
' % self.axioms) 112 | print('
Datatype Axiomatic triples added:
%s
' % self.daxioms) 113 | if self.text is not None: 114 | print('
Turtle code added to the graph:
') 115 | print('
') 116 | if self.text is not None: 117 | print(cgi.escape(self.text).replace('\n', '
')) 118 | 119 | # --------------------------------------------------------------------------------------------------------------------- 120 | 121 | 122 | options = Options(form) 123 | 124 | try: 125 | retval = convert_graph(options) 126 | if options.format == TURTLE: 127 | print('Content-Type: text/turtle; charset=utf-8') 128 | else: 129 | print('Content-Type: application/rdf+xml; charset=utf-8') 130 | print() 131 | print(retval) 132 | except: 133 | (typ, value, traceback) = sys.exc_info() 134 | print('Content-type: text/html; charset=utf-8') 135 | print('Status: 400 Invalid Input') 136 | print() 137 | print("") 138 | print("") 139 | print("Error in RDF Closure processing") 140 | print("") 141 | print("

Error in RDF Closure processing:

") 142 | print("
%s
" % value) 143 | print("

For reference, the input arguments were:

") 144 | options.to_html() 145 | print("") 146 | print("") 147 | -------------------------------------------------------------------------------- /mimir/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | bastyz 7 | linkeddata 8 | 1.0-SNAPSHOT 9 | jar 10 | 11 | mimir 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.3.1.RELEASE 17 | 18 | 19 | 20 | UTF-8 21 | 1.4.10 22 | official 23 | 1.8 24 | 1.4.0-M1 25 | 4.13 26 | 5.6.2 27 | 3.14.0 28 | 2.1.8.RELEASE 29 | 1.2.3 30 | 1.8 31 | 32 | 33 | 34 | 35 | org.jetbrains.kotlin 36 | kotlin-stdlib 37 | ${kotlin.version} 38 | 39 | 40 | org.apache.jena 41 | apache-jena-libs 42 | pom 43 | ${jena.version} 44 | 45 | 46 | org.apache.jena 47 | jena-text 48 | ${jena.version} 49 | 50 | 51 | org.jetbrains.kotlin 52 | kotlin-test-junit 53 | ${kotlin.version} 54 | test 55 | 56 | 57 | 58 | org.jetbrains.kotlinx 59 | kotlinx-coroutines-core 60 | ${kotlinx.version} 61 | 62 | 63 | junit 64 | junit 65 | ${junit.version} 66 | test 67 | 68 | 69 | 70 | org.junit.jupiter 71 | junit-jupiter-api 72 | ${junit.jupiter.version} 73 | test 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-starter-web 78 | ${springboot.version} 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-starter-logging 83 | 84 | 85 | 86 | 87 | io.spring.gradle 88 | dependency-management-plugin 89 | 0.5.3.RELEASE 90 | 91 | 92 | fr.inria.lille.shexjava 93 | shexjava-core 94 | ${shexjava.version} 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | org.jetbrains.kotlin 103 | kotlin-maven-plugin 104 | ${kotlin.version} 105 | 106 | 107 | compile 108 | compile 109 | 110 | compile 111 | 112 | 113 | ${project.basedir}/src/main 114 | ${project.build.outputDirectory} 115 | 116 | 117 | 118 | test-compile 119 | test-compile 120 | 121 | test-compile 122 | 123 | 124 | 125 | 126 | 127 | 128 | org.springframework.boot 129 | spring-boot-maven-plugin 130 | 131 | api.ApplicationKt 132 | 133 | ${springboot.version} 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /mimir/src/main/api/owl/ReasonResponse.kt: -------------------------------------------------------------------------------- 1 | package api.owl 2 | 3 | import api.ReasonerConfig 4 | import dot.colorTemplate.ReasonerNodeColor 5 | import loadModel 6 | import org.apache.jena.rdf.model.Model 7 | import org.apache.jena.riot.RDFFormat 8 | import org.apache.jena.riot.system.PrefixMapFactory 9 | import org.springframework.http.HttpHeaders 10 | import org.springframework.http.HttpHeaders.CONTENT_TYPE 11 | import org.springframework.http.HttpStatus 12 | import org.springframework.http.MediaType 13 | import org.springframework.http.MediaType.TEXT_PLAIN_VALUE 14 | import org.springframework.http.ResponseEntity 15 | import org.springframework.web.bind.annotation.PostMapping 16 | import org.springframework.web.bind.annotation.RequestBody 17 | import org.springframework.web.bind.annotation.RestController 18 | import reasoner.OwlRLWrapper 19 | import toAlternateColoursDOT 20 | import toDOT 21 | import writeTo 22 | 23 | data class ReasonRequest( 24 | val data: String = "", 25 | val data_lang: String = "TTL", 26 | val profile: String = ReasonerConfig.DEFAULT_PROFILE 27 | ) 28 | data class ReasonResponse( 29 | val data: String = "", 30 | val error: String = "", 31 | val data_dot: String = "" 32 | ) 33 | 34 | @RestController 35 | class ReasonController { 36 | 37 | @PostMapping( 38 | "/api/owl/reason", 39 | consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], 40 | produces = [MediaType.APPLICATION_JSON_UTF8_VALUE, TEXT_PLAIN_VALUE] 41 | ) 42 | fun reason( 43 | @RequestBody requestBody: ReasonRequest 44 | ): ResponseEntity { 45 | val header = HttpHeaders() 46 | if (requestBody.data.isBlank()) return ResponseEntity(ReasonResponse(),HttpStatus.NO_CONTENT) 47 | 48 | var data: String = requestBody.data 49 | val reasoner = OwlRLWrapper() 50 | 51 | try { 52 | // convert to TTL if not TTL 53 | if (requestBody.data_lang != "TTL") 54 | data = loadModel(data, requestBody.data_lang).writeTo(RDFFormat.TTL) 55 | 56 | // Call reasoner and get the result 57 | val (inferred, error) = reasoner.infer(data = data, profile = requestBody.profile) 58 | var dot: String = "" 59 | 60 | // try to convert to DOT (fails when there is literals, because it owlrl uses them as subjects) 61 | dot = try { 62 | loadModel(inferred, "TTL").toDOT() 63 | } catch (e: Exception) { 64 | println("Error reasoning, DOT creation failed: \n reason: ${e.message}") 65 | // display an empty DOT 66 | "digraph G{\n charset=\"utf-8\";\n \n // Edges\n \n // Nodes\n}\n" 67 | } 68 | 69 | // try to get a DOT of the original model and one of the difference 70 | // between original and inferred 71 | val dataModel: Model = loadModel(data, requestBody.data_lang) 72 | val dataDot: String = dataModel.toDOT() 73 | // exclude elements that are in the original model 74 | val diffModel: Model = loadModel(inferred, "TTL").difference(dataModel) 75 | // convert to a differently coloured DOT 76 | val diffDOT = diffModel.toAlternateColoursDOT( 77 | ReasonerNodeColor, 78 | prefixMap = PrefixMapFactory.create(dataModel.nsPrefixMap) 79 | ) 80 | 81 | // Mix this DOT strings to display them with different pallets 82 | val mixDOT: String = deleteRepeatedNodes(original = dataDot, other = diffDOT) 83 | 84 | dot = mixDOT 85 | 86 | header.add(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE) 87 | return ResponseEntity(ReasonResponse(inferred, error, dot), header, HttpStatus.OK) 88 | 89 | } catch (e: Exception) { 90 | println("Error while reasoning, aborting with Error: ${e.message}") 91 | header.add(CONTENT_TYPE, TEXT_PLAIN_VALUE) 92 | return ResponseEntity("Internal Server Error", header, HttpStatus.INTERNAL_SERVER_ERROR) 93 | } 94 | } 95 | } 96 | 97 | fun deleteRepeatedNodes(original: String, other: String): String { 98 | val originLines: List = original.reader().readLines() 99 | val otherLines: List = other.reader().readLines() 100 | 101 | // final Nodes and Edges 102 | val nodes = mutableListOf() 103 | val edges = mutableListOf() 104 | 105 | val nodeRegex: Regex = """"[-a-zA-Z0-9+&@#/%?=~_|!:,.; ]+" \[""".toRegex() 106 | 107 | // Clean lines 108 | originLines.forEach { line: String -> 109 | // process this lines before the __other__ ones 110 | when { 111 | line.isBlank() -> {} // do nothing 112 | line.trim().contains(" -> ") -> edges.add(line.trim()) 113 | nodeRegex.containsMatchIn(line.trim()) -> nodes.add(line.trim()) 114 | } 115 | } 116 | 117 | // Add only the nodes that are not on the original, and all the edges 118 | otherLines.forEach { line: String -> 119 | when { 120 | line.isBlank() -> {} 121 | line.trim().contains(" -> ") -> edges.add(line.trim()) 122 | nodeRegex.containsMatchIn(line.trim()) -> { 123 | // FIXME: un-hardcode 124 | // temp Line is hardcoded to not include the color 125 | val tempLine: String = line.substring(0, line.length - 7).trim() 126 | // see if exist already, add it if it doesn't 127 | if (nodes.none { nodeLine -> nodeLine.startsWith(tempLine) }) { 128 | nodes.add(line.trim()) 129 | } 130 | } 131 | } 132 | } 133 | 134 | // build DOT document 135 | return """ 136 | digraph G{ 137 | 138 | charset="utf-8"; 139 | 140 | // Edges 141 | ${(edges.map { it }).joinToString(separator = "\n\t")} 142 | 143 | // Nodes 144 | ${(nodes.map { it }).joinToString(separator = "\n\t")} 145 | 146 | } 147 | """.trimIndent() 148 | } 149 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/master/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | import os 16 | import sys 17 | sys.path.insert(0, os.path.abspath('../..')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = 'OWL-RL' 23 | copyright = '2020, RDFlib developers' 24 | author = 'RDFlib developers' 25 | 26 | # The short X.Y version 27 | version = '' 28 | # The full version, including alpha/beta/rc tags 29 | release = '5.2.1' 30 | 31 | 32 | # -- General configuration --------------------------------------------------- 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | # 36 | # needs_sphinx = '1.0' 37 | 38 | # Add any Sphinx extension module names here, as strings. They can be 39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 40 | # ones. 41 | extensions = [ 42 | 'sphinx.ext.autodoc', 43 | 'sphinx.ext.intersphinx', 44 | 'sphinx.ext.viewcode', 45 | 'sphinx.ext.autosummary' 46 | ] 47 | 48 | # generate classes and add to the toctree. See owlrl.rst for example usage. 49 | # autodoc_default_flags = ['members'] 50 | autosummary_generate = True 51 | 52 | # Add any paths that contain templates here, relative to this directory. 53 | templates_path = ['_templates'] 54 | 55 | # The suffix(es) of source filenames. 56 | # You can specify multiple suffix as a list of string: 57 | # 58 | # source_suffix = ['.rst', '.md'] 59 | source_suffix = '.rst' 60 | 61 | # The master toctree document. 62 | master_doc = 'index' 63 | 64 | # The language for content autogenerated by Sphinx. Refer to documentation 65 | # for a list of supported languages. 66 | # 67 | # This is also used if you do content translation via gettext catalogs. 68 | # Usually you set "language" from the command line for these cases. 69 | language = None 70 | 71 | # List of patterns, relative to source directory, that match files and 72 | # directories to ignore when looking for source files. 73 | # This pattern also affects html_static_path and html_extra_path. 74 | exclude_patterns = [] 75 | 76 | # The name of the Pygments (syntax highlighting) style to use. 77 | pygments_style = None 78 | 79 | 80 | # -- Options for HTML output ------------------------------------------------- 81 | 82 | # The theme to use for HTML and HTML Help pages. See the documentation for 83 | # a list of builtin themes. 84 | # 85 | html_theme = 'sphinx_rtd_theme' 86 | 87 | # Theme options are theme-specific and customize the look and feel of a theme 88 | # further. For a list of options available for each theme, see the 89 | # documentation. 90 | # 91 | # html_theme_options = {} 92 | 93 | # Add any paths that contain custom static files (such as style sheets) here, 94 | # relative to this directory. They are copied after the builtin static files, 95 | # so a file named "default.css" will overwrite the builtin "default.css". 96 | html_static_path = ['_static'] 97 | 98 | # Custom sidebar templates, must be a dictionary that maps document names 99 | # to template names. 100 | # 101 | # The default sidebars (for documents that don't match any pattern) are 102 | # defined by theme itself. Builtin themes are using these templates by 103 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 104 | # 'searchbox.html']``. 105 | # 106 | # html_sidebars = {} 107 | 108 | html_logo = "../../OWL-RL.png" 109 | 110 | 111 | # -- Options for HTMLHelp output --------------------------------------------- 112 | 113 | # Output file base name for HTML help builder. 114 | htmlhelp_basename = 'OWL-RLdoc' 115 | 116 | 117 | # -- Options for LaTeX output ------------------------------------------------ 118 | 119 | latex_elements = { 120 | # The paper size ('letterpaper' or 'a4paper'). 121 | # 122 | # 'papersize': 'letterpaper', 123 | 124 | # The font size ('10pt', '11pt' or '12pt'). 125 | # 126 | # 'pointsize': '10pt', 127 | 128 | # Additional stuff for the LaTeX preamble. 129 | # 130 | # 'preamble': '', 131 | 132 | # Latex figure (float) alignment 133 | # 134 | # 'figure_align': 'htbp', 135 | } 136 | 137 | # Grouping the document tree into LaTeX files. List of tuples 138 | # (source start file, target name, title, 139 | # author, documentclass [howto, manual, or own class]). 140 | latex_documents = [ 141 | (master_doc, 'OWL-RL.tex', 'OWL-RL Documentation', 142 | 'CSIRO Land and Water', 'manual'), 143 | ] 144 | 145 | 146 | # -- Options for manual page output ------------------------------------------ 147 | 148 | # One entry per manual page. List of tuples 149 | # (source start file, name, description, authors, manual section). 150 | man_pages = [ 151 | (master_doc, 'owl-rl', 'OWL-RL Documentation', 152 | [author], 1) 153 | ] 154 | 155 | 156 | # -- Options for Texinfo output ---------------------------------------------- 157 | 158 | # Grouping the document tree into Texinfo files. List of tuples 159 | # (source start file, target name, title, author, 160 | # dir menu entry, description, category) 161 | texinfo_documents = [ 162 | (master_doc, 'OWL-RL', 'OWL-RL Documentation', 163 | author, 'OWL-RL', 'One line description of project.', 164 | 'Miscellaneous'), 165 | ] 166 | 167 | 168 | # -- Options for Epub output ------------------------------------------------- 169 | 170 | # Bibliographic Dublin Core info. 171 | epub_title = project 172 | 173 | # The unique identifier of the text. This can be a ISBN number 174 | # or the project homepage. 175 | # 176 | # epub_identifier = '' 177 | 178 | # A unique identification for the text. 179 | # 180 | # epub_uid = '' 181 | 182 | # A list of files that should not be packed into the epub file. 183 | epub_exclude_files = ['search.html'] 184 | 185 | 186 | # -- Extension configuration ------------------------------------------------- 187 | 188 | # -- Options for intersphinx extension --------------------------------------- 189 | 190 | # Example configuration for intersphinx: refer to the Python standard library. 191 | intersphinx_mapping = {'https://docs.python.org/': None} -------------------------------------------------------------------------------- /mimir/src/main/dot/DOTShell.kt: -------------------------------------------------------------------------------- 1 | package dot 2 | 3 | import dot.colorTemplate.NodeColor 4 | import org.apache.jena.atlas.io.IndentedWriter 5 | import org.apache.jena.graph.Graph 6 | import org.apache.jena.graph.Node 7 | import org.apache.jena.graph.Triple 8 | import org.apache.jena.riot.other.GLib 9 | import org.apache.jena.riot.system.PrefixMap 10 | import org.apache.jena.riot.system.PrefixMapFactory 11 | import org.apache.jena.sparql.util.Context 12 | 13 | open class DOTShell( 14 | protected var out: IndentedWriter, 15 | protected var prefixMap: PrefixMap = PrefixMapFactory.emptyPrefixMap(), 16 | protected var baseURI: String?, 17 | protected var context: Context? 18 | ) { 19 | private var graph: Graph = Graph.emptyGraph 20 | 21 | private fun writeGraphStart() { 22 | // Prints the start of the graph, and places new lines for readability 23 | out.print("digraph G{\n") 24 | } 25 | 26 | private fun writeGraphEnd() { 27 | // Prints end of graph, ending with empty line 28 | out.println("}") 29 | } 30 | 31 | fun writeGraphDOT(graph: Graph, colors: NodeColoring = NodeColor) { 32 | this.graph = graph 33 | // Writes graph on DOT syntax 34 | writeGraphStart() 35 | out.incIndent() 36 | out.println("charset=\"utf-8\";") 37 | out.println() 38 | 39 | // Get every Triple on the Graph 40 | val tripleIterator: Iterator = graph.find(Node.ANY, Node.ANY, Node.ANY) 41 | // Get Nodes 42 | val nodesIterator: Iterator = listSubjectsAndObjects() 43 | 44 | out.println("// Edges") 45 | tripleIterator.forEach { triple: Triple -> 46 | // Prints a row for each Edge 47 | run { 48 | when { 49 | triple.`object`.isLiteral -> 50 | out.println( 51 | "\"${ triple.subject }\" -> \"${ prettyTriple(triple) }\" " + 52 | "[label=\"${ prettyLabel(triple.predicate) }\",color=\"${colors.literalEdge}\"]" 53 | ) 54 | else -> 55 | out.println( 56 | "\"${ triple.subject }\" -> \"${ triple.`object` }\" " + 57 | "[label=\"${ prettyLabel(triple.predicate) }\",color=\"${colors.normalEdge}\"]" 58 | ) 59 | } 60 | } 61 | } 62 | out.println() 63 | 64 | out.println("// Nodes") 65 | nodesIterator.forEach { node: Node -> 66 | run { 67 | when { 68 | // Write a row for each node 69 | node.isURI -> 70 | out.println( 71 | "\"${ node.uri }\" [label=\"${ prettyLabel(node) }\",shape=ellipse,color=\"${colors.uri}\"]" 72 | ) 73 | node.isBlank -> 74 | out.println( 75 | "\"${node.blankNodeLabel}\" [label=\"\",shape=circle,color=\"${colors.blank}\"]" 76 | ) 77 | node.isLiteral -> 78 | when { 79 | node.literal.value.toString().isNotEmpty() -> 80 | out.println( 81 | "\"${prettyNode(node)}\" [label=\"${prettyLiteralLabel(node)}\"," + 82 | "shape=record,color=\"${colors.literal}\",${langLiteral(node)}" + 83 | "${dataTypeLiteral(node)}]" 84 | ) 85 | } 86 | } 87 | } 88 | } 89 | 90 | out.decIndent() 91 | writeGraphEnd() 92 | } 93 | 94 | // Graph writing functions 95 | private fun listSubjects(): Iterator { 96 | return GLib.listSubjects(graph) 97 | } 98 | 99 | private fun listObjects(): Iterator { 100 | return GLib.listObjects(graph) 101 | } 102 | 103 | private fun listSubjectsAndObjects(): Iterator { 104 | val subjectsIterator: Iterator = listSubjects() 105 | val objectsIterator: Iterator = listObjects() 106 | 107 | val nodes = mutableListOf() 108 | // add all elements to a list 109 | subjectsIterator.forEach { aNode: Node -> nodes.add(aNode) } 110 | objectsIterator.forEach { aNode: Node -> nodes.add(aNode) } 111 | 112 | val filteredNodes = nodes.distinct() 113 | 114 | return filteredNodes.iterator() 115 | } 116 | 117 | private fun prettyLabel(node: Node): String { 118 | return when (node.prefix(prefixMap)) { 119 | null -> node.uri 120 | else -> "${node.prefix(prefixMap)}:${nodeLocalName(node)}" 121 | } 122 | } 123 | 124 | private fun nodeLocalName(node: Node): String { 125 | return node.getURI().substring(Math.max(node.getURI().lastIndexOf('/'),node.getURI().lastIndexOf('#'))+1) 126 | } 127 | 128 | private fun prettyTriple(triple: Triple): String { 129 | return when (triple.`object`.literalLanguage) { 130 | "" -> triple.`object`.literal.lexicalForm.toString().replace("\"", "\'") 131 | else -> triple.`object`.literal.lexicalForm.toString().replace("\"", "\'") + 132 | "@" + triple.`object`.literalLanguage 133 | } 134 | } 135 | 136 | private fun prettyNode(node: Node): String { 137 | return when (node.literalLanguage) { 138 | "" -> node.literal.lexicalForm.toString().replace("\"", "\'") 139 | else -> node.literal.lexicalForm.toString().replace("\"", "\'") + 140 | "@" + node.literalLanguage 141 | } 142 | } 143 | 144 | private fun prettyLiteralLabel(node: Node): String { 145 | return node.literal.lexicalForm.toString().replace("\"", "\'") 146 | } 147 | 148 | private fun langLiteral(node: Node): String { 149 | return when (node.literalLanguage) { 150 | "" -> "" 151 | else -> "lang= \"${node.literalLanguage}\"," 152 | } 153 | } 154 | 155 | private fun dataTypeLiteral(node: Node): String { 156 | return "datatype= \"${node.literalDatatypeURI}\"" 157 | } 158 | 159 | } 160 | 161 | // Auxiliary function that obtains a prefix for a given Node, must be URI 162 | private fun Node.prefix(prefixMap: PrefixMap): String? { 163 | return when (prefixMap.abbrev(this.nameSpace)) { 164 | null -> null 165 | else -> prefixMap.abbrev(this.nameSpace).left 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/Doc_OLD/module-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Module Hierarchy 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 50 | 51 |
  40 | 41 | 42 | 44 | 48 |
[hide private]
[frames] | no frames]
49 |
52 |
53 | [ Module Hierarchy 54 | | Class Hierarchy ] 55 |

56 |

Module Hierarchy

57 | 86 | 87 | 89 | 90 | 91 | 93 | 94 | 95 | 97 | 98 | 99 | 101 | 102 | 103 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 114 | 118 | 119 |
120 | 121 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /mimir/src/main/shex/ShexWrapper.kt: -------------------------------------------------------------------------------- 1 | package shex 2 | 3 | import api.ShexConfig 4 | import fr.inria.lille.shexjava.GlobalFactory 5 | import fr.inria.lille.shexjava.schema.Label 6 | import fr.inria.lille.shexjava.schema.ShexSchema 7 | import fr.inria.lille.shexjava.schema.parsing.GenParser 8 | import fr.inria.lille.shexjava.validation.ValidationAlgorithm 9 | import isAbbreviatedIRI 10 | import loadModel 11 | import org.apache.commons.rdf.api.Graph 12 | import org.apache.commons.rdf.api.IRI 13 | import org.apache.commons.rdf.rdf4j.RDF4J 14 | import org.apache.jena.atlas.io.IndentedWriter 15 | import org.apache.jena.riot.system.PrefixMap 16 | import org.apache.jena.riot.system.PrefixMapFactory 17 | import org.eclipse.rdf4j.rio.RDFFormat 18 | import org.eclipse.rdf4j.rio.Rio 19 | import writeTo 20 | import java.io.ByteArrayOutputStream 21 | import java.io.File 22 | import java.nio.file.Paths 23 | 24 | class ShexWrapper(private val factory: RDF4J = RDF4J()) { 25 | private val modelPrefixMap: PrefixMap = PrefixMapFactory.create() 26 | private val shapePrefixMap: PrefixMap = PrefixMapFactory.create() 27 | 28 | init { 29 | GlobalFactory.RDFFactory = factory // set global factory for ShexJava 30 | } 31 | 32 | fun createDataGraph(data: String, lang: String): Graph { 33 | // Convert Data to Turtle (on Jena) 34 | val dataModel = loadModel(data, lang) 35 | val dataOnTTL: String = dataModel.writeTo(org.apache.jena.riot.RDFFormat.TTL) 36 | 37 | val baseIRI = "http://example.org/" 38 | 39 | // use RDF4J with eclipse to create apache.commons.rdf.api.Graph 40 | val eclipseModel: org.eclipse.rdf4j.model.Model = Rio.parse( 41 | dataOnTTL.reader(), 42 | baseIRI, 43 | RDFFormat.TURTLE 44 | ) 45 | 46 | // generate data model prefixMap 47 | modelPrefixMap.putAll(dataModel.nsPrefixMap) 48 | 49 | // Get a graph from the data 50 | return factory.asGraph(eclipseModel) 51 | } 52 | 53 | fun createSchema(shape: String): ShexSchema { 54 | // Load schema to shex java 55 | val tempDirectory = Paths.get(ShexConfig.TMP_DIR_NAME).toFile() 56 | val tempShexFile: File = createTempFile( 57 | ShexConfig.TMP_NAME_PREFIX, 58 | ShexConfig.TMP_NAME_SUFFIX, 59 | tempDirectory 60 | ) 61 | tempShexFile.writeText(shape, Charsets.UTF_8) 62 | 63 | // create custom prefixMapping from Schema 64 | generatePrefixMap(shapePrefixMap, tempShexFile) 65 | 66 | val schema: ShexSchema = GenParser.parseSchema(factory, tempShexFile.toPath()) 67 | tempShexFile.delete() 68 | return schema 69 | } 70 | 71 | private fun generatePrefixMap(prefixMap: PrefixMap, file: File) { 72 | // look for prefixes to create our map 73 | val regex = Regex("^prefix\\s+[a-zA-Z]*:\\s+<(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>|PREFIX\\s+[a-zA-Z]*:\\s+<(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>") 74 | file.forEachLine { 75 | when { 76 | it.contains(regex) -> { 77 | var prefixString = it.trim() 78 | // get prefix abbreviation 79 | prefixString = prefixString.removePrefix("prefix ").removePrefix("PREFIX ").trimStart() 80 | val abbreviation = prefixString.substringBefore(':') + ':' 81 | val extended = prefixString.substringAfter('<').substringBefore('>') 82 | prefixMap.add(abbreviation, extended) 83 | } 84 | } 85 | } 86 | } 87 | 88 | fun parseMap(shapeMap: String): List { 89 | val mappingList: MutableList = mutableListOf() 90 | 91 | // format map 92 | shapeMap.trim() 93 | shapeMap.replace("\n\r ".toRegex(), "") // delete line breaks betweeen statements 94 | 95 | // convert to List 96 | val elements = shapeMap.split(",", ";") 97 | elements.forEach { element -> 98 | run { 99 | if (!element.contains('@')) { 100 | throw Exception("Bad Mapping Syntax: missing @, use nodeLabel@shapeLabel syntax") 101 | } else { 102 | val pair = element.split('@') 103 | if (pair.size != 2) { 104 | throw Exception("Bad Mapping Syntax: missing element on mapping") 105 | } else { 106 | // shex java uses exclusively expanded IRIs, so here we create expanded 107 | // versions for any mapping and save the user input to be printed later 108 | 109 | // Node label processing 110 | val nodeLabel = pair[0].trim() 111 | var expandedNodeLabel = nodeLabel.trim('<').trim('>') 112 | // expand node IRI for shex java 113 | if (pair[0].trim().isAbbreviatedIRI()) expandedNodeLabel = modelPrefixMap.expand(nodeLabel) 114 | val node: IRI = factory.createIRI(expandedNodeLabel) 115 | 116 | // Shape label processing 117 | val shapeLabel = pair[1].trim('<').trim('>') 118 | var expandedShapeLabel = shapeLabel 119 | if (shapeLabel.isAbbreviatedIRI()) expandedShapeLabel = shapePrefixMap.expand(shapeLabel) 120 | val shape: Label = Label(factory.createIRI(expandedShapeLabel)) 121 | 122 | // save to mapping object 123 | mappingList.add( 124 | ShexShapeMap( 125 | node, // RDF term 126 | shape, // shape label 127 | pair[0].trim(), // original node as given 128 | pair[1].trim() // original shape as given 129 | ) // save original terms 130 | ) 131 | } 132 | } 133 | } 134 | } 135 | return mappingList.toList() 136 | } 137 | 138 | fun validateMapping(validationAlgorithm: ValidationAlgorithm, shapeMapping: List): String { 139 | val baos = ByteArrayOutputStream() 140 | val writer: IndentedWriter = IndentedWriter(baos) 141 | writer.println("ShEx Validation Report:") 142 | writer.incIndent() // adds an indentation to each line 143 | 144 | shapeMapping.forEach { mapping: ShexShapeMap -> 145 | // Validate pair 146 | validationAlgorithm.validate(mapping.nodeLabel, mapping.shapeLabel) 147 | 148 | // Print results for each pair 149 | when (validationAlgorithm.typing.isConformant(mapping.nodeLabel, mapping.shapeLabel)) { 150 | true -> 151 | writer.println("✅ ${mapping.originalNode} conforms with ${mapping.originalShape}") 152 | false -> 153 | writer.println("❌ ${mapping.originalNode} does not conform with ${mapping.originalShape}") 154 | } 155 | } 156 | writer.flush() 157 | return baos.toString() 158 | } 159 | } -------------------------------------------------------------------------------- /mimir/src/main/Utils.kt: -------------------------------------------------------------------------------- 1 | import org.apache.jena.query.ResultSet 2 | import org.apache.jena.query.ResultSetFormatter.* 3 | import org.apache.jena.rdf.model.Model 4 | import org.apache.jena.rdf.model.ModelFactory 5 | import org.apache.jena.riot.Lang 6 | import org.apache.jena.riot.RDFDataMgr 7 | import org.apache.jena.riot.RDFFormat 8 | import org.apache.jena.sparql.sse.SSE 9 | import java.io.ByteArrayInputStream 10 | import java.io.ByteArrayOutputStream 11 | import java.lang.Exception 12 | import kotlin.text.contains 13 | 14 | import dot.DOTLang 15 | import dot.DOTShell 16 | import dot.NodeColoring 17 | import org.apache.commons.rdf.api.Graph 18 | import org.apache.jena.atlas.io.IndentedWriter 19 | import org.apache.jena.query.Dataset 20 | import org.apache.jena.rdf.model.ResourceFactory 21 | import org.apache.jena.riot.system.PrefixMap 22 | import org.apache.jena.riot.system.PrefixMapBase 23 | import org.apache.jena.riot.system.PrefixMapFactory 24 | import org.apache.jena.riot.system.PrefixMapWrapper 25 | import org.apache.jena.shacl.ValidationReport 26 | import org.apache.jena.shacl.lib.ShLib 27 | import org.apache.jena.sparql.util.Context 28 | 29 | fun loadModel(data: String, lang: String): Model { 30 | // Load data on to a model and returns the model 31 | val model = ModelFactory.createDefaultModel() 32 | val inputStream = ByteArrayInputStream(data.toByteArray(Charsets.UTF_8)) 33 | try { 34 | model.read(inputStream, null, lang) 35 | } catch (e: Exception) { 36 | throw e 37 | } 38 | return model 39 | } 40 | 41 | fun Model.writeTo(lang: RDFFormat): String { 42 | // Writes to specified Lang 43 | val baos = ByteArrayOutputStream() 44 | try { 45 | RDFDataMgr.write(baos, this, lang) 46 | } catch (e: Exception) { 47 | throw e 48 | } 49 | return baos.toString() 50 | } 51 | 52 | fun Model.toDOT(): String { 53 | return this.writeTo(RDFFormat(DOTLang)) 54 | } 55 | 56 | fun Model.toAlternateColoursDOT(colors: NodeColoring, prefixMap: PrefixMap = PrefixMapFactory.create(this.nsPrefixMap)): String { 57 | // Uses the internal DOT Writer added to Jena, with a different 58 | // set of colors for the nodes 59 | val graph = this.graph 60 | val baos = ByteArrayOutputStream() 61 | val indWriter = IndentedWriter(baos) 62 | val shell = DOTShell(indWriter, prefixMap, baseURI = "rdfplayground.dcc.uchile.cl", context = Context.emptyContext) 63 | shell.writeGraphDOT(graph, colors) 64 | 65 | indWriter.flush() 66 | return baos.toString() 67 | } 68 | 69 | fun ResultSet.formatAs(format: String): String { 70 | val set: ResultSet = this 71 | val outStream = ByteArrayOutputStream() 72 | // Write to ByteArray stream using ResultSetFormatter and return as String 73 | when (format) { 74 | "Text" -> out(outStream, set) 75 | "XML" -> outputAsXML(outStream, set) 76 | "SSE" -> outputAsSSE(outStream, set) 77 | "CSV" -> outputAsCSV(outStream, set) 78 | "JSON" -> outputAsJSON(outStream, set) 79 | "TSV" -> outputAsTSV(outStream, set) 80 | "TTL" -> output(outStream, set, Lang.TURTLE) 81 | else -> throw Exception("Unsupported language") 82 | } 83 | return outStream.toString() 84 | } 85 | 86 | fun Boolean.formatAskAs(format: String): String { 87 | val bool: Boolean = this 88 | val outStream = ByteArrayOutputStream() 89 | // Write Ask response to ByteArray stream using ResultSetFormatter and return as String 90 | when (format) { 91 | "Text" -> out(outStream, bool) 92 | "XML" -> outputAsXML(outStream, bool) 93 | "SSE" -> outputAsSSE(outStream, bool) 94 | "CSV" -> outputAsCSV(outStream, bool) 95 | "JSON" -> outputAsJSON(outStream, bool) 96 | "TSV" -> outputAsTSV(outStream, bool) 97 | "TTL" -> output(outStream, bool, Lang.TURTLE) 98 | else -> throw Exception("Unsupported language") 99 | } 100 | return outStream.toString() 101 | } 102 | 103 | fun Model.formatAs(format: String): Pair { 104 | val outStream = ByteArrayOutputStream() 105 | var outFormat = "TTL" 106 | // Write Ask response to ByteArray stream using ResultSetFormatter and return as String 107 | when (format) { 108 | "Text" -> RDFDataMgr.write(outStream, this, Lang.TTL) 109 | "XML" -> { 110 | RDFDataMgr.write(outStream, this, Lang.RDFXML) 111 | outFormat = "XML" 112 | } 113 | "SSE" -> { 114 | SSE.write(outStream, this) 115 | outFormat = "SSE" 116 | } 117 | "CSV" -> { 118 | RDFDataMgr.write(outStream, this, Lang.CSV) 119 | outFormat = "CSV" 120 | } 121 | "JSON" -> { 122 | RDFDataMgr.write(outStream, this, Lang.RDFJSON) 123 | outFormat = "JSON" 124 | } 125 | "TSV" -> { 126 | RDFDataMgr.write(outStream, this, Lang.TSV) 127 | outFormat = "TSV" 128 | } 129 | "TTL" -> RDFDataMgr.write(outStream, this, Lang.TURTLE) 130 | "NTRIPLES" -> RDFDataMgr.write(outStream, this, Lang.NTRIPLES) 131 | "DOT" -> RDFDataMgr.write(outStream, this, DOTLang) 132 | else -> throw Exception("Unsupported language") 133 | } 134 | return Pair(outStream.toString(), outFormat) 135 | } 136 | 137 | fun parseFormat(acceptHeader: String): MutableList { 138 | val list: MutableList = mutableListOf() 139 | val accept: List = acceptHeader.split(',', ignoreCase = true) 140 | accept.forEach { 141 | when { 142 | it.contains(MimeType.text, ignoreCase = true) -> list.add("Text") 143 | it.contains(MimeType.xml, ignoreCase = true) -> list.add("XML") 144 | it.contains(MimeType.sse, ignoreCase = true) -> list.add("SSE") 145 | it.contains(MimeType.csv, ignoreCase = true) -> list.add("CSV") 146 | it.contains(MimeType.json, ignoreCase = true) -> list.add("JSON") 147 | it.contains(MimeType.tsv, ignoreCase = true) -> list.add("TSV") 148 | it.contains(MimeType.ttl, ignoreCase = true) -> list.add("TTL") 149 | it.contains(MimeType.ntriples, ignoreCase = true) -> list.add("NTRIPLES") 150 | it.contains(MimeType.dot, ignoreCase = true) -> list.add("DOT") 151 | else -> println("Formato no reconocido") 152 | } 153 | } 154 | return list 155 | } 156 | 157 | object MimeType { 158 | const val text = "text/plain ;charset=utf-8" 159 | const val xml = "application/xml ;charset=utf-8" 160 | const val sse = "text/x-sse ;charset=utf-8" 161 | const val csv = "text/csv ;charset=utf-8" 162 | const val json = "application/json ;charset=utf-8" 163 | const val tsv = "text/tab-separated-values ;charset=utf-8" 164 | const val ttl = "text/turtle ;charset=utf-8" 165 | const val ntriples = "application/n-triples ;charset=utf-8" 166 | const val dot = "text/vnd.graphviz ;charset=utf-8" 167 | } 168 | 169 | fun toMimeType(type: String): String { 170 | return when (type) { 171 | "Text" -> MimeType.text 172 | "XML" -> MimeType.xml 173 | "SSE" -> MimeType.sse 174 | "CSV" -> MimeType.csv 175 | "JSON" -> MimeType.json 176 | "TSV" -> MimeType.tsv 177 | "TTL" -> MimeType.ttl 178 | "NTRIPLES" -> MimeType.ntriples 179 | "DOT" -> MimeType.dot 180 | else -> "" 181 | } 182 | } 183 | 184 | fun ValidationReport.toPrintableString(): String { 185 | val outStream = ByteArrayOutputStream() 186 | ShLib.printReport(outStream, this) 187 | 188 | return outStream.toString() 189 | } 190 | 191 | fun String.isAbbreviatedIRI(): Boolean { 192 | return this.contains(Regex("^[_a-zA-Z]*:[a-zA-Z]+")) 193 | } 194 | -------------------------------------------------------------------------------- /mimir/src/main/reasoner/owlrl/owlrl/CombinedClosure.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | """ 4 | The combined closure: performing *both* the OWL 2 RL and RDFS closures. 5 | 6 | The two are very close but there are some rules in RDFS that are not in OWL 2 RL (eg, the axiomatic 7 | triples concerning the container membership properties). Using this closure class the 8 | OWL 2 RL implementation becomes a full extension of RDFS. 9 | 10 | **Requires**: `RDFLib`_, 4.0.0 and higher. 11 | 12 | .. _RDFLib: https://github.com/RDFLib/rdflib 13 | 14 | **License**: This software is available for use under the `W3C Software License`_. 15 | 16 | .. _W3C Software License: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 17 | 18 | **Organization**: `World Wide Web Consortium`_ 19 | 20 | .. _World Wide Web Consortium: http://www.w3.org 21 | 22 | **Author**: `Ivan Herman`_ 23 | 24 | .. _Ivan Herman: http://www.w3.org/People/Ivan/ 25 | 26 | """ 27 | 28 | __author__ = 'Ivan Herman' 29 | __contact__ = 'Ivan Herman, ivan@w3.org' 30 | __license__ = 'W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231' 31 | 32 | from owlrl.RDFS import Resource, Class, Datatype 33 | from owlrl.OWL import OWLClass, Thing, equivalentClass, DataRange 34 | 35 | from owlrl.RDFSClosure import RDFS_Semantics 36 | from owlrl.OWLRL import OWLRL_Semantics 37 | 38 | ###################################################################################################### 39 | 40 | 41 | # noinspection PyPep8Naming 42 | class RDFS_OWLRL_Semantics(RDFS_Semantics, OWLRL_Semantics): 43 | """ 44 | Common subclass of the RDFS and OWL 2 RL semantic classes. All methods simply call back 45 | to the functions in the superclasses. This may lead to some unnecessary duplication of terms 46 | and rules, but it it not so bad. Also, the additional identification defined for OWL Full, 47 | ie, Resource being the same as Thing and OWL and RDFS classes being identical are added to the 48 | triple store. 49 | 50 | Note that this class is also a possible user extension point: subclasses can be created that 51 | extend the standard functionality by extending this class. This class *always*} performs RDFS inferences. 52 | Subclasses have to set the :code:`self.rdfs` flag explicitly to the requested value if that is to be controlled. 53 | 54 | :param graph: The RDF graph to be extended. 55 | :type graph: :class:`rdflib.Graph` 56 | 57 | :param axioms: Whether (non-datatype) axiomatic triples should be added or not. 58 | :type axioms: bool 59 | 60 | :param daxioms: Whether datatype axiomatic triples should be added or not. 61 | :type daxioms: bool 62 | 63 | :param rdfs: Placeholder flag (used in subclassed only, it is always defaulted to True in this class) 64 | :type rdfs: bool 65 | 66 | :var full_binding_triples: Additional axiom type triples that are added to the combined semantics; these 'bind' 67 | the RDFS and the OWL worlds together. 68 | 69 | :var rdfs: (bool) Whether RDFS inference is to be performed or not. In this class instance the value is *always* 70 | :code:`True`, subclasses may explicitly change it at initialization time. 71 | :type rdfs: bool 72 | """ 73 | full_binding_triples = [ 74 | (Thing, equivalentClass, Resource), 75 | (Class, equivalentClass, OWLClass), 76 | (DataRange, equivalentClass, Datatype) 77 | ] 78 | 79 | def __init__(self, graph, axioms, daxioms, rdfs=True): 80 | """ 81 | @param graph: the RDF graph to be extended 82 | @type graph: rdflib.Graph 83 | @param axioms: whether (non-datatype) axiomatic triples should be added or not 84 | @type axioms: bool 85 | @param daxioms: whether datatype axiomatic triples should be added or not 86 | @type daxioms: bool 87 | @param rdfs: placeholder flag (used in subclassed only, it is always defaulted to True in this class) 88 | @type rdfs: boolean 89 | """ 90 | OWLRL_Semantics.__init__(self, graph, axioms, daxioms, rdfs) 91 | RDFS_Semantics.__init__(self, graph, axioms, daxioms, rdfs) 92 | self.rdfs = True 93 | 94 | # noinspection PyMethodMayBeStatic 95 | @staticmethod 96 | def add_new_datatype(uri, conversion_function, datatype_list, subsumption_dict=None, subsumption_key=None, 97 | subsumption_list=None): 98 | """ 99 | If an extension wants to add new datatypes, this method should be invoked at initialization time. 100 | 101 | :param uri: URI for the new datatypes, like owl_ns["Rational"]. 102 | 103 | :param conversion_function: A function converting the lexical representation of the datatype to a Python value, 104 | possibly raising an exception in case of unsuitable lexical form. 105 | 106 | :param datatype_list: List of datatypes already in use that has to be checked. 107 | :type datatype_list: list 108 | 109 | :param subsumption_dict: Dictionary of subsumption hierarchies (indexed by the datatype URI-s). 110 | :type subsumption_dict: dict 111 | 112 | :param subsumption_key: Key in the dictionary, if None, the uri parameter is used. 113 | :type subsumption_key: str 114 | 115 | :param subsumption_list: List of subsumptions associated to a subsumption key (ie, all datatypes that are 116 | superclasses of the new datatype). 117 | :type subsumption_list: list 118 | """ 119 | from .DatatypeHandling import AltXSDToPYTHON, use_Alt_lexical_conversions 120 | 121 | if datatype_list: 122 | datatype_list.append(uri) 123 | 124 | if subsumption_dict and subsumption_list: 125 | if subsumption_key: 126 | subsumption_dict[subsumption_key] = subsumption_list 127 | else: 128 | subsumption_dict[uri] = subsumption_list 129 | 130 | AltXSDToPYTHON[uri] = conversion_function 131 | use_Alt_lexical_conversions() 132 | 133 | def post_process(self): 134 | """ 135 | Do some post-processing step. This method when all processing is done, but before handling possible 136 | errors (I.e., the method can add its own error messages). By default, this method is empty, subclasses 137 | can add content to it by overriding it. 138 | """ 139 | OWLRL_Semantics.post_process(self) 140 | 141 | def rules(self, t, cycle_num): 142 | """ 143 | :param t: A triple (in the form of a tuple). 144 | :type t: tuple 145 | 146 | :param cycle_num: Which cycle are we in, starting with 1. This value is forwarded to all local rules; it is 147 | also used locally to collect the bnodes in the graph. 148 | :type cycle_num: int 149 | """ 150 | OWLRL_Semantics.rules(self, t, cycle_num) 151 | if self.rdfs: 152 | RDFS_Semantics.rules(self, t, cycle_num) 153 | 154 | def add_axioms(self): 155 | if self.rdfs: 156 | RDFS_Semantics.add_axioms(self) 157 | OWLRL_Semantics.add_axioms(self) 158 | 159 | def add_d_axioms(self): 160 | if self.rdfs: 161 | RDFS_Semantics.add_d_axioms(self) 162 | OWLRL_Semantics.add_d_axioms(self) 163 | 164 | def one_time_rules(self): 165 | """Adds some extra axioms and calls for the d_axiom part of the OWL Semantics.""" 166 | for t in self.full_binding_triples: 167 | self.store_triple(t) 168 | 169 | # Note that the RL one time rules include the management of datatype which is a true superset 170 | # of the rules in RDFS. It is therefore unnecessary to add those even self.rdfs is True. 171 | OWLRL_Semantics.one_time_rules(self) 172 | --------------------------------------------------------------------------------