typedlogic 0.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. typedlogic-0.0.0/LICENSE +22 -0
  2. typedlogic-0.0.0/PKG-INFO +190 -0
  3. typedlogic-0.0.0/README.md +119 -0
  4. typedlogic-0.0.0/pyproject.toml +178 -0
  5. typedlogic-0.0.0/src/typedlogic/__init__.py +53 -0
  6. typedlogic-0.0.0/src/typedlogic/builtins.py +48 -0
  7. typedlogic-0.0.0/src/typedlogic/cli.py +412 -0
  8. typedlogic-0.0.0/src/typedlogic/compiler.py +173 -0
  9. typedlogic-0.0.0/src/typedlogic/compilers/__init__.py +0 -0
  10. typedlogic-0.0.0/src/typedlogic/compilers/fol_compiler.py +44 -0
  11. typedlogic-0.0.0/src/typedlogic/compilers/prolog_compiler.py +69 -0
  12. typedlogic-0.0.0/src/typedlogic/compilers/prover9_compiler.py +42 -0
  13. typedlogic-0.0.0/src/typedlogic/compilers/sexpr_compiler.py +99 -0
  14. typedlogic-0.0.0/src/typedlogic/compilers/tptp_compiler.py +49 -0
  15. typedlogic-0.0.0/src/typedlogic/compilers/yaml_compiler.py +75 -0
  16. typedlogic-0.0.0/src/typedlogic/datamodel.py +1230 -0
  17. typedlogic-0.0.0/src/typedlogic/datamodels/__init__.py +0 -0
  18. typedlogic-0.0.0/src/typedlogic/datamodels/typesystem.py +181 -0
  19. typedlogic-0.0.0/src/typedlogic/decorators.py +148 -0
  20. typedlogic-0.0.0/src/typedlogic/evaluation.py +207 -0
  21. typedlogic-0.0.0/src/typedlogic/extensions/__init__.py +0 -0
  22. typedlogic-0.0.0/src/typedlogic/extensions/probabilistic.py +56 -0
  23. typedlogic-0.0.0/src/typedlogic/generators.py +95 -0
  24. typedlogic-0.0.0/src/typedlogic/integrations/__init__.py +0 -0
  25. typedlogic-0.0.0/src/typedlogic/integrations/data/__init__.py +0 -0
  26. typedlogic-0.0.0/src/typedlogic/integrations/data/dask/__init__.py +0 -0
  27. typedlogic-0.0.0/src/typedlogic/integrations/data/ibis/__init__.py +0 -0
  28. typedlogic-0.0.0/src/typedlogic/integrations/data/pandas/__init__.py +0 -0
  29. typedlogic-0.0.0/src/typedlogic/integrations/data/polars/__init__.py +0 -0
  30. typedlogic-0.0.0/src/typedlogic/integrations/data/sqlmodel/__init__.py +0 -0
  31. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/__init__.py +0 -0
  32. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/hornedowl/__init__.py +0 -0
  33. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/hornedowl/horned_owl_bridge.py +448 -0
  34. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/hornedowl/owl_compiler.py +38 -0
  35. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/hornedowl/owl_parser.py +68 -0
  36. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/__init__.py +1 -0
  37. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/instance.py +260 -0
  38. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/linkml_parser.py +28 -0
  39. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/loader.py +399 -0
  40. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/meta.py +117 -0
  41. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/meta_axioms.py +87 -0
  42. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/linkml/validator.py +24 -0
  43. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/__init__.py +54 -0
  44. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/ontology_generators.py +0 -0
  45. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/owl_from_fol.py +89 -0
  46. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/owlpy_compiler.py +89 -0
  47. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/owlpy_parser.py +193 -0
  48. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/owltop.py +2397 -0
  49. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/owldl/reasoner.py +190 -0
  50. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/pandas/__init__.py +0 -0
  51. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/pandas/pandas_utils.py +72 -0
  52. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/pandera/__init__.py +5 -0
  53. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/pandera/pandera_bridge.py +37 -0
  54. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/prolog/__init__.py +0 -0
  55. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/prolog/basic_prolog.py +434 -0
  56. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/prolog/prolog_parser.py +72 -0
  57. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/pydantic/__init__.py +5 -0
  58. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/pydantic/pydantic_bridge.py +57 -0
  59. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/rdflib/__init__.py +3 -0
  60. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/rdflib/owlfull.py +93 -0
  61. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/rdflib/rdf.py +70 -0
  62. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/rdflib/rdf_parser.py +84 -0
  63. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/rdflib/rdfs.py +136 -0
  64. typedlogic-0.0.0/src/typedlogic/integrations/frameworks/sqlmodel/__init__.py +0 -0
  65. typedlogic-0.0.0/src/typedlogic/integrations/solvers/__init__.py +0 -0
  66. typedlogic-0.0.0/src/typedlogic/integrations/solvers/clingo/__init__.py +5 -0
  67. typedlogic-0.0.0/src/typedlogic/integrations/solvers/clingo/clingo_solver.py +132 -0
  68. typedlogic-0.0.0/src/typedlogic/integrations/solvers/clorm/__init__.py +0 -0
  69. typedlogic-0.0.0/src/typedlogic/integrations/solvers/formulog/__init__.py +0 -0
  70. typedlogic-0.0.0/src/typedlogic/integrations/solvers/llm/__init__.py +0 -0
  71. typedlogic-0.0.0/src/typedlogic/integrations/solvers/llm/llm_solver.py +114 -0
  72. typedlogic-0.0.0/src/typedlogic/integrations/solvers/problog/__init__.py +7 -0
  73. typedlogic-0.0.0/src/typedlogic/integrations/solvers/problog/problog_compiler.py +170 -0
  74. typedlogic-0.0.0/src/typedlogic/integrations/solvers/problog/problog_solver.py +105 -0
  75. typedlogic-0.0.0/src/typedlogic/integrations/solvers/prover9/__init__.py +3 -0
  76. typedlogic-0.0.0/src/typedlogic/integrations/solvers/prover9/prover9_solver.py +82 -0
  77. typedlogic-0.0.0/src/typedlogic/integrations/solvers/pyprover/__init__.py +0 -0
  78. typedlogic-0.0.0/src/typedlogic/integrations/solvers/snakelog/__init__.py +3 -0
  79. typedlogic-0.0.0/src/typedlogic/integrations/solvers/snakelog/snakelog_solver.py +239 -0
  80. typedlogic-0.0.0/src/typedlogic/integrations/solvers/souffle/__init__.py +3 -0
  81. typedlogic-0.0.0/src/typedlogic/integrations/solvers/souffle/souffle_compiler.py +100 -0
  82. typedlogic-0.0.0/src/typedlogic/integrations/solvers/souffle/souffle_solver.py +118 -0
  83. typedlogic-0.0.0/src/typedlogic/integrations/solvers/z3/__init__.py +3 -0
  84. typedlogic-0.0.0/src/typedlogic/integrations/solvers/z3/z3_compiler.py +45 -0
  85. typedlogic-0.0.0/src/typedlogic/integrations/solvers/z3/z3_solver.py +343 -0
  86. typedlogic-0.0.0/src/typedlogic/integrations/solvers/z3/z3_utils.py +0 -0
  87. typedlogic-0.0.0/src/typedlogic/integrations/variadic_generics.py +18 -0
  88. typedlogic-0.0.0/src/typedlogic/parser.py +139 -0
  89. typedlogic-0.0.0/src/typedlogic/parsers/__init__.py +0 -0
  90. typedlogic-0.0.0/src/typedlogic/parsers/catalog_parser.py +502 -0
  91. typedlogic-0.0.0/src/typedlogic/parsers/dataframe_parser.py +249 -0
  92. typedlogic-0.0.0/src/typedlogic/parsers/pyparser/__init__.py +5 -0
  93. typedlogic-0.0.0/src/typedlogic/parsers/pyparser/introspection.py +357 -0
  94. typedlogic-0.0.0/src/typedlogic/parsers/pyparser/python_ast_utils.py +403 -0
  95. typedlogic-0.0.0/src/typedlogic/parsers/pyparser/python_parser.py +201 -0
  96. typedlogic-0.0.0/src/typedlogic/parsers/yaml_parser.py +69 -0
  97. typedlogic-0.0.0/src/typedlogic/profiles.py +321 -0
  98. typedlogic-0.0.0/src/typedlogic/py.typed +0 -0
  99. typedlogic-0.0.0/src/typedlogic/pybridge.py +134 -0
  100. typedlogic-0.0.0/src/typedlogic/registry.py +170 -0
  101. typedlogic-0.0.0/src/typedlogic/solver.py +319 -0
  102. typedlogic-0.0.0/src/typedlogic/theories/__init__.py +0 -0
  103. typedlogic-0.0.0/src/typedlogic/theories/bfo/__init__.py +0 -0
  104. typedlogic-0.0.0/src/typedlogic/theories/jsonlog/__init__.py +0 -0
  105. typedlogic-0.0.0/src/typedlogic/theories/jsonlog/jsonlog.py +207 -0
  106. typedlogic-0.0.0/src/typedlogic/theories/jsonlog/jsonlog_axioms.py +37 -0
  107. typedlogic-0.0.0/src/typedlogic/theories/jsonlog/jsonlog_parser.py +56 -0
  108. typedlogic-0.0.0/src/typedlogic/theories/jsonlog/loader.py +139 -0
  109. typedlogic-0.0.0/src/typedlogic/transformations.py +1793 -0
  110. typedlogic-0.0.0/src/typedlogic/typechecking.py +0 -0
  111. typedlogic-0.0.0/src/typedlogic/utils/__init__.py +0 -0
  112. typedlogic-0.0.0/src/typedlogic/utils/detect_stratified_negation.py +149 -0
  113. typedlogic-0.0.0/src/typedlogic/utils/graph_utils.py +73 -0
  114. typedlogic-0.0.0/src/typedlogic/utils/import_closure.py +47 -0
  115. typedlogic-0.0.0/src/typedlogic/utils/ipython_utils.py +5 -0
  116. typedlogic-0.0.0/src/typedlogic/utils/term_maker.py +34 -0
@@ -0,0 +1,22 @@
1
+
2
+ The MIT License (MIT)
3
+
4
+ Copyright (c) 2024 Monarch Initiative
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
14
+ all 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
22
+ THE SOFTWARE.
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.4
2
+ Name: typedlogic
3
+ Version: 0.0.0
4
+ Summary: typedlogic
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Author: Author 1
8
+ Author-email: author@org.org
9
+ Requires-Python: >=3.10
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Provides-Extra: clingo
18
+ Provides-Extra: clorm
19
+ Provides-Extra: dev
20
+ Provides-Extra: gavel-owl
21
+ Provides-Extra: llm
22
+ Provides-Extra: owl
23
+ Provides-Extra: pandas
24
+ Provides-Extra: pandera
25
+ Provides-Extra: problog
26
+ Provides-Extra: pydantic
27
+ Provides-Extra: pyprover
28
+ Provides-Extra: rdflib
29
+ Provides-Extra: snakelog
30
+ Provides-Extra: sympy
31
+ Provides-Extra: tests
32
+ Provides-Extra: z3
33
+ Requires-Dist: black ; extra == "tests"
34
+ Requires-Dist: clingo ; extra == "clingo"
35
+ Requires-Dist: clorm ; extra == "clorm"
36
+ Requires-Dist: gavel-owl ; extra == "gavel-owl"
37
+ Requires-Dist: importlib-metadata (>=8.2.0)
38
+ Requires-Dist: jupyter ; extra == "dev"
39
+ Requires-Dist: llm ; extra == "llm"
40
+ Requires-Dist: mkdocs ; extra == "dev"
41
+ Requires-Dist: mkdocs-click ; extra == "dev"
42
+ Requires-Dist: mkdocs-material ; extra == "dev"
43
+ Requires-Dist: mkdocs-mermaid2-plugin ; extra == "dev"
44
+ Requires-Dist: mkdocs-windmill ; extra == "dev"
45
+ Requires-Dist: mkdocs-with-pdf ; extra == "dev"
46
+ Requires-Dist: mkdocstrings[crystal,python] ; extra == "dev"
47
+ Requires-Dist: mknotebooks (>=0.8.0) ; extra == "dev"
48
+ Requires-Dist: mypy ; extra == "dev"
49
+ Requires-Dist: nbdime ; extra == "dev"
50
+ Requires-Dist: nbformat ; extra == "dev"
51
+ Requires-Dist: pandas ; extra == "pandas"
52
+ Requires-Dist: pandera[mypy] ; extra == "pandera"
53
+ Requires-Dist: papermill ; extra == "dev"
54
+ Requires-Dist: ply ; extra == "gavel-owl"
55
+ Requires-Dist: pre-commit (>=3.3.3) ; extra == "dev"
56
+ Requires-Dist: problog ; extra == "problog"
57
+ Requires-Dist: py-horned-owl (>=1.0.0,!=1.0.1) ; extra == "owl"
58
+ Requires-Dist: pydantic ; extra == "pydantic"
59
+ Requires-Dist: pyprover ; extra == "pyprover"
60
+ Requires-Dist: pytest (>=8.3.2) ; extra == "dev"
61
+ Requires-Dist: rdflib ; extra == "rdflib"
62
+ Requires-Dist: ruff ; extra == "tests"
63
+ Requires-Dist: snakelog ; extra == "snakelog"
64
+ Requires-Dist: sympy ; extra == "sympy"
65
+ Requires-Dist: tox (>=4.16.0) ; extra == "dev"
66
+ Requires-Dist: typer (>=0.12.5)
67
+ Requires-Dist: types-PyYAML ; extra == "dev"
68
+ Requires-Dist: z3-solver ; extra == "z3"
69
+ Description-Content-Type: text/markdown
70
+
71
+ # py-typedlogic: Pythonic logic for your data models.
72
+
73
+ Define logical predicates directly in Python as Pydantic, dataclasses, SQLModel, or plain python objects:
74
+
75
+ ```python
76
+ # links.py
77
+ from pydantic import BaseModel
78
+ from typedlogic import FactMixin, Term
79
+
80
+ ID = str
81
+
82
+ class Link(BaseModel, FactMixin):
83
+ """A link between two entities"""
84
+ source: ID
85
+ target: ID
86
+
87
+ class Path(BaseModel, FactMixin):
88
+ """An N-hop path between two entities, consisting of one or more links"""
89
+ source: ID
90
+ target: ID
91
+ hops: int
92
+ ```
93
+
94
+ This data model has two classes, `Link` and `Path`. These also correspond to *predicate signatures*
95
+ in a logical theory.
96
+
97
+ You can use this to create objects (ground terms, in logic terms) using normal Python code:
98
+
99
+ ```python
100
+ links = []
101
+ for source, target in [('CA', 'OR'), ('OR', 'WA')]:
102
+ links.append(link)
103
+ ```
104
+
105
+ Define logical *constraints* or *rules* using Python syntax:
106
+
107
+ ```python
108
+ from typedlogic.decorators import axiom
109
+
110
+ @axiom
111
+ def path_from_link(x: ID, y: ID):
112
+ """If there is a link from x to y, there is a path from x to y"""
113
+ if Link(source=x, target=y):
114
+ assert Path(source=x, target=y, hops=1)
115
+
116
+ @axiom
117
+ def transitivity(x: ID, y: ID, z: ID, d1: int, d2: int):
118
+ """Transitivity of paths, plus hop counting"""
119
+ if Path(source=x, target=y, hops=d1) and Path(source=y, target=z, hops=d2):
120
+ assert Path(source=x, target=z, hops=d1+d2)
121
+ ```
122
+
123
+ Use a solver to infer new facts:
124
+
125
+ ```python
126
+ from typedlogic.registry import get_solver
127
+ from links import Link
128
+
129
+ solver = get_solver("clingo")
130
+ solver.load(links)
131
+ links = [Link(source='CA', target='OR'), Link(source='OR', target='WA')]
132
+ for link in links:
133
+ solver.add(link)
134
+ model = solver.model()
135
+ for fact in model.iter_retrieve("Path"):
136
+ print(fact)
137
+ ```
138
+
139
+ prints:
140
+
141
+ ```
142
+ Path(source='CA', target='OR')
143
+ Path(source='OR', target='WA')
144
+ Path(source='CA', target='WA')
145
+ ```
146
+
147
+ ## Key Features
148
+
149
+ - Write logical axioms and rules using [Python syntax](https://py-typedlogic.github.io/py-typedlogic/tutorial/01-first-program/)
150
+ - Interconvert between different logical formats and formalisms
151
+ - [Compilers](https://py-typedlogic.github.io/py-typedlogic/conversion/compilers/)
152
+ - [Parsers](https://py-typedlogic.github.io/py-typedlogic/conversion/parsers/)
153
+ - Benefit from strong typing and mypy validation
154
+ - Integration with multiple [FOL solvers](https://py-typedlogic.github.io/py-typedlogic/integrations/solvers/) and logic programming engines
155
+ - Integration with [OWL-DL](https://py-typedlogic.github.io/py-typedlogic/integrations/frameworks/owldl/)
156
+ - Integration with Python libraries like [Pydantic](https://py-typedlogic.github.io/py-typedlogic/integrations/frameworks/pydantic/)
157
+ - [Command Line](https://py-typedlogic.github.io/py-typedlogic/cli/) and Python interfaces
158
+
159
+ ## Installation
160
+
161
+ Install TypedLogic using pip:
162
+
163
+ ```bash
164
+ pip install "typedlogic"
165
+ ```
166
+
167
+ ## Next Steps
168
+
169
+ - Consult the [main docs](https://py-typedlogic.github.io/py-typedlogic/) for more information
170
+
171
+ ## Contributing
172
+
173
+ ### Testing with External Dependencies
174
+
175
+ Some tests require external executables (Prover9, Souffle) that may not be available in all environments.
176
+ The test suite is designed to automatically skip tests that require unavailable dependencies.
177
+
178
+ When running in CI environments:
179
+ - Tests for external solvers are automatically skipped if the dependency is not available
180
+ - This allows CI to pass while still testing all available functionality
181
+
182
+ To install optional dependencies for testing:
183
+ - Prover9: Install from your package manager or from source
184
+ - Souffle: Install from your package manager or from source
185
+
186
+ Run tests with:
187
+ ```bash
188
+ poetry run pytest
189
+ ```
190
+
@@ -0,0 +1,119 @@
1
+ # py-typedlogic: Pythonic logic for your data models.
2
+
3
+ Define logical predicates directly in Python as Pydantic, dataclasses, SQLModel, or plain python objects:
4
+
5
+ ```python
6
+ # links.py
7
+ from pydantic import BaseModel
8
+ from typedlogic import FactMixin, Term
9
+
10
+ ID = str
11
+
12
+ class Link(BaseModel, FactMixin):
13
+ """A link between two entities"""
14
+ source: ID
15
+ target: ID
16
+
17
+ class Path(BaseModel, FactMixin):
18
+ """An N-hop path between two entities, consisting of one or more links"""
19
+ source: ID
20
+ target: ID
21
+ hops: int
22
+ ```
23
+
24
+ This data model has two classes, `Link` and `Path`. These also correspond to *predicate signatures*
25
+ in a logical theory.
26
+
27
+ You can use this to create objects (ground terms, in logic terms) using normal Python code:
28
+
29
+ ```python
30
+ links = []
31
+ for source, target in [('CA', 'OR'), ('OR', 'WA')]:
32
+ links.append(link)
33
+ ```
34
+
35
+ Define logical *constraints* or *rules* using Python syntax:
36
+
37
+ ```python
38
+ from typedlogic.decorators import axiom
39
+
40
+ @axiom
41
+ def path_from_link(x: ID, y: ID):
42
+ """If there is a link from x to y, there is a path from x to y"""
43
+ if Link(source=x, target=y):
44
+ assert Path(source=x, target=y, hops=1)
45
+
46
+ @axiom
47
+ def transitivity(x: ID, y: ID, z: ID, d1: int, d2: int):
48
+ """Transitivity of paths, plus hop counting"""
49
+ if Path(source=x, target=y, hops=d1) and Path(source=y, target=z, hops=d2):
50
+ assert Path(source=x, target=z, hops=d1+d2)
51
+ ```
52
+
53
+ Use a solver to infer new facts:
54
+
55
+ ```python
56
+ from typedlogic.registry import get_solver
57
+ from links import Link
58
+
59
+ solver = get_solver("clingo")
60
+ solver.load(links)
61
+ links = [Link(source='CA', target='OR'), Link(source='OR', target='WA')]
62
+ for link in links:
63
+ solver.add(link)
64
+ model = solver.model()
65
+ for fact in model.iter_retrieve("Path"):
66
+ print(fact)
67
+ ```
68
+
69
+ prints:
70
+
71
+ ```
72
+ Path(source='CA', target='OR')
73
+ Path(source='OR', target='WA')
74
+ Path(source='CA', target='WA')
75
+ ```
76
+
77
+ ## Key Features
78
+
79
+ - Write logical axioms and rules using [Python syntax](https://py-typedlogic.github.io/py-typedlogic/tutorial/01-first-program/)
80
+ - Interconvert between different logical formats and formalisms
81
+ - [Compilers](https://py-typedlogic.github.io/py-typedlogic/conversion/compilers/)
82
+ - [Parsers](https://py-typedlogic.github.io/py-typedlogic/conversion/parsers/)
83
+ - Benefit from strong typing and mypy validation
84
+ - Integration with multiple [FOL solvers](https://py-typedlogic.github.io/py-typedlogic/integrations/solvers/) and logic programming engines
85
+ - Integration with [OWL-DL](https://py-typedlogic.github.io/py-typedlogic/integrations/frameworks/owldl/)
86
+ - Integration with Python libraries like [Pydantic](https://py-typedlogic.github.io/py-typedlogic/integrations/frameworks/pydantic/)
87
+ - [Command Line](https://py-typedlogic.github.io/py-typedlogic/cli/) and Python interfaces
88
+
89
+ ## Installation
90
+
91
+ Install TypedLogic using pip:
92
+
93
+ ```bash
94
+ pip install "typedlogic"
95
+ ```
96
+
97
+ ## Next Steps
98
+
99
+ - Consult the [main docs](https://py-typedlogic.github.io/py-typedlogic/) for more information
100
+
101
+ ## Contributing
102
+
103
+ ### Testing with External Dependencies
104
+
105
+ Some tests require external executables (Prover9, Souffle) that may not be available in all environments.
106
+ The test suite is designed to automatically skip tests that require unavailable dependencies.
107
+
108
+ When running in CI environments:
109
+ - Tests for external solvers are automatically skipped if the dependency is not available
110
+ - This allows CI to pass while still testing all available functionality
111
+
112
+ To install optional dependencies for testing:
113
+ - Prover9: Install from your package manager or from source
114
+ - Souffle: Install from your package manager or from source
115
+
116
+ Run tests with:
117
+ ```bash
118
+ poetry run pytest
119
+ ```
@@ -0,0 +1,178 @@
1
+ [project]
2
+ name = "typedlogic"
3
+ version = "0.0.0"
4
+ description = "typedlogic"
5
+ authors = [
6
+ {name = "Author 1", email = "author@org.org"}
7
+ ]
8
+ license = {text = "MIT"}
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "importlib-metadata>=8.2.0",
13
+ "typer>=0.12.5",
14
+ ]
15
+
16
+ [project.optional-dependencies]
17
+ pydantic = ["pydantic"]
18
+ clingo = ["clingo"]
19
+ z3 = ["z3-solver"]
20
+ pyprover = ["pyprover"]
21
+ snakelog = ["snakelog"]
22
+ problog = ["problog"]
23
+ clorm = ["clorm"]
24
+ rdflib = ["rdflib"]
25
+ sympy = ["sympy"]
26
+ owl = ["py-horned-owl>=1.0.0,!=1.0.1"]
27
+ gavel-owl = ["gavel-owl", "ply"]
28
+ llm = ["llm"]
29
+ pandas = ["pandas"]
30
+ pandera = ["pandera[mypy]"]
31
+ tests = ["black", "ruff"]
32
+ dev = [
33
+ "pytest>=8.3.2",
34
+ "tox>=4.16.0",
35
+ "mypy",
36
+ "types-PyYAML",
37
+ "jupyter",
38
+ "papermill",
39
+ "nbdime",
40
+ "nbformat",
41
+ "pre-commit>=3.3.3",
42
+ "mkdocs",
43
+ "mkdocs-mermaid2-plugin",
44
+ "mkdocstrings[crystal,python]",
45
+ "mknotebooks>=0.8.0",
46
+ "mkdocs-windmill",
47
+ "mkdocs-material",
48
+ "mkdocs-click",
49
+ "mkdocs-with-pdf",
50
+ ]
51
+
52
+ [project.scripts]
53
+ typedlogic = "typedlogic.cli:app"
54
+
55
+ [tool.poetry]
56
+ name = "typedlogic"
57
+ version = "0.2.1"
58
+ description = "typedlogic"
59
+ authors = ["Author 1 <author@org.org>"]
60
+ license = "MIT"
61
+ readme = "README.md"
62
+
63
+ [tool.poetry.dependencies]
64
+ python = "^3.10"
65
+ importlib-metadata = ">=8.2.0"
66
+ pydantic = { version="*", optional = true }
67
+ clingo = { version="*", optional = true }
68
+ z3-solver = { version="*", optional = true }
69
+ pyprover = { version="*", optional = true }
70
+ snakelog = { version="*", optional = true }
71
+ problog = { version="*", optional = true }
72
+ clorm = { version="*", optional = true }
73
+ rdflib = { version="*", optional = true }
74
+ sympy = { version="*", optional = true }
75
+ py-horned-owl = { version="^1.0.0,!=1.0.1", optional = true } ## https://github.com/ontology-tools/py-horned-owl/issues/34
76
+ llm = { version="*", optional = true }
77
+ gavel-owl = { version="*", optional = true }
78
+ ply = { version="*", optional = true }
79
+ pandas = { version="*", optional = true }
80
+ pandera = { version="*", extras = ["mypy"], optional = true }
81
+ typer = "^0.12.5"
82
+
83
+ [tool.poetry.group.dev.dependencies]
84
+ pytest = {version = ">=8.3.2"}
85
+ tox = {version = ">=4.16.0"}
86
+ mypy = {version = "*"}
87
+ types-PyYAML = {version = "*"}
88
+ jupyter = {version = "*"}
89
+ papermill = {version = "*"}
90
+ nbdime = {version = "*"}
91
+ nbformat = {version = "*"}
92
+ pre-commit = {version = ">=3.3.3"}
93
+ mkdocs = "*"
94
+ mkdocs-mermaid2-plugin = "*"
95
+ mkdocstrings = {extras = ["crystal", "python"], version = "*"}
96
+ mknotebooks = "^0.8.0"
97
+ mkdocs-windmill = "*"
98
+ mkdocs-material = "*"
99
+ mkdocs-click = "*"
100
+ mkdocs-with-pdf = "*"
101
+
102
+
103
+ [tool.poetry.extras]
104
+ tests = ["black", "ruff"]
105
+ pydantic = ["pydantic"]
106
+ z3 = ["z3-solver"]
107
+ clingo = ["clingo"]
108
+ pyprover = ["pyprover"]
109
+ snakelog = ["snakelog"]
110
+ problog = ["problog"]
111
+ clorm = ["clorm"]
112
+ rdflib = ["rdflib"]
113
+ owl = ["py-horned-owl"]
114
+ gavel-owl = ["gavel-owl", "ply"]
115
+ pandas = ["pandas"]
116
+ pandera = ["pandera"]
117
+ llm = ["llm"]
118
+ sympy = ["sympy"]
119
+
120
+
121
+ [tool.poetry.scripts]
122
+ typedlogic = "typedlogic.cli:app"
123
+
124
+ [tool.poetry-dynamic-versioning]
125
+ enable = false
126
+ vcs = "git"
127
+ style = "pep440"
128
+
129
+ [tool.black]
130
+ line-length = 120
131
+ target-version = ["py38", "py39", "py310"]
132
+
133
+ [tool.ruff]
134
+ lint.extend-ignore = [
135
+ "D211", # `no-blank-line-before-class`
136
+ "D212", # `multi-line-summary-first-line`
137
+ "D203", # `blank-line-before-docstring`
138
+ ]
139
+ line-length = 120
140
+
141
+ # Allow autofix for all enabled rules (when `--fix`) is provided.
142
+ lint.fixable = ["ALL"]
143
+
144
+ # Select or ignore from https://beta.ruff.rs/docs/rules/
145
+ lint.select = [
146
+ "B", # bugbear
147
+ "D", # pydocstyle
148
+ "E", # pycodestyle errors
149
+ "F", # Pyflakes
150
+ "I", # isort
151
+ "S", # flake8-bandit
152
+ "W", # Warning
153
+ ]
154
+
155
+ lint.unfixable = []
156
+ target-version = "py310"
157
+
158
+ [tool.ruff.lint.mccabe]
159
+ # Unlike Flake8, default to a complexity level of 10.
160
+ max-complexity = 10
161
+
162
+ [tool.codespell]
163
+ skip = "*.po,*.ts,.git,pyproject.toml,*.ofn,*.owl,*.ttl"
164
+ count = ""
165
+ quiet-level = 3
166
+ ignore-words-list = "fof,te,disjointness,NotIn,EHR"
167
+
168
+ [build-system]
169
+ requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
170
+ build-backend = "poetry_dynamic_versioning.backend"
171
+
172
+ [[tool.mypy.overrides]]
173
+ module = "pyhornedowl.*"
174
+ ignore_errors = true
175
+ follow_imports = "skip"
176
+
177
+ [tool.mypy]
178
+ exclude = "owl"
@@ -0,0 +1,53 @@
1
+ """typedlogic package."""
2
+ from typedlogic.datamodel import (
3
+ BooleanSentence,
4
+ And,
5
+ Or,
6
+ Not,
7
+ Implies,
8
+ Forall,
9
+ Exists,
10
+ Term,
11
+ NegationAsFailure,
12
+ not_provable,
13
+ Xor,
14
+ Implied,
15
+ Iff,
16
+ ExactlyOne,
17
+ Theory,
18
+ Sentence,
19
+ PredicateDefinition,
20
+ SentenceGroup,
21
+ Variable,
22
+ )
23
+ from typedlogic.pybridge import FactMixin, Fact
24
+ from typedlogic.generators import gen, gen1, gen2, gen3
25
+ from typedlogic.decorators import axiom, goal
26
+
27
+ __all__ = [
28
+ "BooleanSentence",
29
+ "And",
30
+ "Or",
31
+ "Not",
32
+ "Implies",
33
+ "Iff",
34
+ "Forall",
35
+ "Exists",
36
+ "Term",
37
+ "NegationAsFailure",
38
+ "not_provable",
39
+ "Xor",
40
+ "ExactlyOne",
41
+ "Implied",
42
+ "Theory",
43
+ "Sentence",
44
+ "Variable",
45
+ "PredicateDefinition",
46
+ "SentenceGroup",
47
+ "Fact",
48
+ "FactMixin",
49
+ "gen",
50
+ "gen1",
51
+ "gen2",
52
+ "gen3",
53
+ ]
@@ -0,0 +1,48 @@
1
+ """
2
+ Mappings for builtin functions and datatypes.
3
+ """
4
+ import operator as op
5
+ from typing import Callable, Mapping
6
+
7
+ NUMERIC_BUILTINS: Mapping[str, Callable] = {
8
+ "ge": op.ge,
9
+ "gt": op.gt,
10
+ "le": op.le,
11
+ "lt": op.lt,
12
+ "eq": op.eq,
13
+ "ne": op.ne,
14
+ "add": op.add,
15
+ "sub": op.sub,
16
+ "mul": op.mul,
17
+ "truediv": op.truediv,
18
+ "pow": op.pow,
19
+ "xor": op.xor,
20
+ "neg": op.neg,
21
+ }
22
+
23
+ NAME_TO_INFIX_OP: Mapping[str, str] = {
24
+ "add": "+",
25
+ "sub": "-",
26
+ "mul": "*",
27
+ "truediv": "/",
28
+ "floordiv": "//",
29
+ "mod": "%",
30
+ "pow": "**",
31
+ "lshift": "<<",
32
+ "rshift": ">>",
33
+ "or": "|",
34
+ "xor": "^",
35
+ "and": "&",
36
+ "matmul": "@",
37
+ # Comparison operators
38
+ "eq": "==",
39
+ "ne": "!=",
40
+ "lt": "<",
41
+ "le": "<=",
42
+ "gt": ">",
43
+ "ge": ">=",
44
+ "is": "is",
45
+ "is_not": "is not",
46
+ "in": "in",
47
+ "not_in": "not in",
48
+ }