aspalchemy 1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Jolyon Bloomfield
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.4
2
+ Name: aspalchemy
3
+ Version: 1.0.0
4
+ Summary: A Python ORM interface for building and solving clingo ASP programs
5
+ Author: Jolyon Bloomfield
6
+ Author-email: Jolyon Bloomfield <jolyonb84@gmail.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE.txt
9
+ Requires-Dist: clingo>=5.8.0,<6
10
+ Requires-Python: >=3.14
11
+ Description-Content-Type: text/markdown
12
+
13
+ # ASPAlchemy
14
+
15
+ ASPAlchemy is a Python library for building clingo ASP (Answer Set Programming) programs with a clean, object-oriented interface.
16
+
17
+ ## Term Hierarchy
18
+
19
+ The library is built around a rich hierarchy of term types that represent different ASP constructs:
20
+
21
+ - `Term` (abstract base class)
22
+ - `ComparableTerm` (abstract: usable in comparisons; provides `==`, `!=`, `<`, `<=`, `>`, `>=`)
23
+ - `Value` (abstract, for basic values — also a `BasicTerm`)
24
+ - `Variable` (e.g., `X`, `Y`)
25
+ - `ConstantBase` (abstract)
26
+ - `Number` (numeric constants, e.g., `42`)
27
+ - `String` (string literals, e.g., `"hello"`)
28
+ - `DefinedConstant` (#const-defined constants, e.g., `max_size`)
29
+ - `Supremum` / `Infimum` (`#sup`/`#inf`, the ordering's end markers; `SUP` and `INF` are the singletons)
30
+ - `Expression` (arithmetic expressions, e.g., `X+Y*2`)
31
+ - `AggregateBase` (abstract marker so core can recognize aggregates)
32
+ - `Aggregate` (abstract)
33
+ - `Count`, `Sum`, `SumPlus`, `Min`, `Max`
34
+ - `BasicTerm` (abstract, can be direct predicate arguments: `Value`, `Predicate`, `Pool`)
35
+ - `Predicate` (e.g., `person(john, 42)`)
36
+ - `Pool` (abstract)
37
+ - `RangePool` (e.g., `1..5`)
38
+ - `ExplicitPool` (e.g., `(1;3;5)`)
39
+ - `Negatable` (abstract mixin: `~` builds `not term` on atoms; on plain comparisons it builds the complement — see `Not`)
40
+ - `Comparison` (comparisons, e.g., `X < Y`)
41
+ - `DefaultNegation` (default negation, e.g., `not p(X)`)
42
+ - `ConditionalLiteral` (e.g., `p(X) : q(X)`)
43
+ - `Choice` (e.g., `{ p(X) : q(X) }`)
44
+
45
+ ## Core Concepts
46
+
47
+ ### Values
48
+
49
+ Values represent basic elements in an ASP program. Plain Python literals coerce
50
+ automatically wherever terms are expected — an int becomes an ASP number, a str
51
+ becomes a quoted ASP string. Variables you construct by hand, and bare atoms
52
+ (the `n` in `direction(n)`) are zero-arity predicates:
53
+
54
+ ```python
55
+ from aspalchemy import Predicate, Variable
56
+
57
+ X = Variable("X") # an ASP variable
58
+ n = Predicate.define("n", [], show=False)() # a bare atom: n, distinct from the string "n"
59
+ ```
60
+
61
+ ### Predicates
62
+
63
+ Declare predicates as classes; fields are statically checked, so typos and
64
+ missing arguments are type errors, and instances autocomplete:
65
+
66
+ ```python
67
+ from aspalchemy import Predicate, PredicateField
68
+
69
+ class Person(Predicate):
70
+ name: PredicateField
71
+ age: PredicateField
72
+
73
+ john = Person(name="john", age=30)
74
+ mary = Person(name="mary", age=25)
75
+ ```
76
+
77
+ The ASP name defaults to the class name, snake-cased (HasSymbol becomes
78
+ has_symbol); class kwargs override it and set namespacing and visibility (`class Pipe(Predicate, name="pipe_seg",
79
+ show=False)`). When the schema is only known at runtime, build the same thing
80
+ dynamically:
81
+
82
+ ```python
83
+ Edge = Predicate.define("edge", ["a", "b"])
84
+ ```
85
+
86
+ For fully typed fields, annotate them as `Field[int]`, `Field[str]`, or
87
+ `Field[SomePredicate]`. Writes accept rule terms (Variables, Expressions) as
88
+ well as ground values, and are validated per field; reads are plain Python
89
+ values, statically typed — so solution atoms come back as real ints and strs:
90
+
91
+ ```python
92
+ from aspalchemy import ASPProgram, Field, Predicate
93
+
94
+ class Score(Predicate):
95
+ player: Field[str]
96
+ points: Field[int]
97
+
98
+ program = ASPProgram()
99
+ program.fact(Score(player="ada", points=3), Score(player="ben", points=5))
100
+ model = program.solve().first() # raises UnsatisfiableError if there is no model
101
+ total = sum(score.points for score in model.atoms(Score)) # plain ints
102
+ assert total == 8
103
+ ```
104
+
105
+ ### Rules
106
+
107
+ Build rules with clear syntax:
108
+
109
+ ```python
110
+ from aspalchemy import ANY, ASPProgram, Variable
111
+
112
+ program = ASPProgram()
113
+ X, Y = Variable("X"), Variable("Y")
114
+ Adult = Predicate.define("adult", ["name"])
115
+
116
+ # Facts
117
+ program.fact(john)
118
+ program.fact(mary)
119
+
120
+ # Rules
121
+ program.when(Person(name=X, age=Y), Y >= 18).derive(Adult(name=X))
122
+
123
+ # Constraints
124
+ program.forbid(Person(name=ANY, age=Y), Y < 0)
125
+ ```
126
+
127
+ ### Comparisons
128
+
129
+ Compare terms:
130
+
131
+ ```python
132
+ X < Y # Creates a comparison X < Y
133
+ ```
134
+
135
+ ### Aggregates
136
+
137
+ Use aggregates for advanced computations:
138
+
139
+ ```python
140
+ from aspalchemy import ANY, Count, Variable
141
+
142
+ X = Variable("X")
143
+ count = Count(X, Person(name=X, age=ANY)) > 5
144
+ ```
145
+
146
+ ### Solving
147
+
148
+ Solve your ASP program:
149
+
150
+ ```python
151
+ # Generate ASP code
152
+ asp_code = program.render()
153
+ print(asp_code)
154
+
155
+ # Solve
156
+ result = program.solve() # a lazy stream: consume the models you want
157
+ for model in result:
158
+ print("Solution found:")
159
+ for adult in model.atoms(Adult):
160
+ print(f" {adult}")
161
+ print(f"Satisfiable: {result.satisfiable}")
162
+ ```
163
+
164
+ ### Diagnostics point at your code
165
+
166
+ Every statement remembers the Python line that authored it. A `when()` left
167
+ unclosed reports where it was opened; grounding diagnostics from clingo carry
168
+ a "generated by file:line" note back to your source;
169
+ `program.render(annotate=True)` appends a trailing `% file:line` comment to
170
+ each rule — without changing line numbers, so the annotated text doubles as
171
+ a map from raw-clingo error lines back to your source; and when a grounding
172
+ is slow or huge, `program.ground().analyze_grounding()` reports ground-atom
173
+ counts per signature, largest first, each joined back to the lines that
174
+ derive it. Frameworks built on
175
+ aspalchemy call `register_skip_package()` (whole package, or per-module dotted
176
+ prefixes) so locations point at *their* caller's code; mark a single helper
177
+ with `@attribute_to_caller` to attribute its statements to its call sites.
178
+ Switch capture off with `ASPProgram(source_locations=False)` when
179
+ generating rules in bulk.
180
+
181
+ ## Requirements
182
+
183
+ - Python 3.14+
184
+ - clingo 5.8+
185
+
186
+ ## License
187
+
188
+ MIT License
@@ -0,0 +1,176 @@
1
+ # ASPAlchemy
2
+
3
+ ASPAlchemy is a Python library for building clingo ASP (Answer Set Programming) programs with a clean, object-oriented interface.
4
+
5
+ ## Term Hierarchy
6
+
7
+ The library is built around a rich hierarchy of term types that represent different ASP constructs:
8
+
9
+ - `Term` (abstract base class)
10
+ - `ComparableTerm` (abstract: usable in comparisons; provides `==`, `!=`, `<`, `<=`, `>`, `>=`)
11
+ - `Value` (abstract, for basic values — also a `BasicTerm`)
12
+ - `Variable` (e.g., `X`, `Y`)
13
+ - `ConstantBase` (abstract)
14
+ - `Number` (numeric constants, e.g., `42`)
15
+ - `String` (string literals, e.g., `"hello"`)
16
+ - `DefinedConstant` (#const-defined constants, e.g., `max_size`)
17
+ - `Supremum` / `Infimum` (`#sup`/`#inf`, the ordering's end markers; `SUP` and `INF` are the singletons)
18
+ - `Expression` (arithmetic expressions, e.g., `X+Y*2`)
19
+ - `AggregateBase` (abstract marker so core can recognize aggregates)
20
+ - `Aggregate` (abstract)
21
+ - `Count`, `Sum`, `SumPlus`, `Min`, `Max`
22
+ - `BasicTerm` (abstract, can be direct predicate arguments: `Value`, `Predicate`, `Pool`)
23
+ - `Predicate` (e.g., `person(john, 42)`)
24
+ - `Pool` (abstract)
25
+ - `RangePool` (e.g., `1..5`)
26
+ - `ExplicitPool` (e.g., `(1;3;5)`)
27
+ - `Negatable` (abstract mixin: `~` builds `not term` on atoms; on plain comparisons it builds the complement — see `Not`)
28
+ - `Comparison` (comparisons, e.g., `X < Y`)
29
+ - `DefaultNegation` (default negation, e.g., `not p(X)`)
30
+ - `ConditionalLiteral` (e.g., `p(X) : q(X)`)
31
+ - `Choice` (e.g., `{ p(X) : q(X) }`)
32
+
33
+ ## Core Concepts
34
+
35
+ ### Values
36
+
37
+ Values represent basic elements in an ASP program. Plain Python literals coerce
38
+ automatically wherever terms are expected — an int becomes an ASP number, a str
39
+ becomes a quoted ASP string. Variables you construct by hand, and bare atoms
40
+ (the `n` in `direction(n)`) are zero-arity predicates:
41
+
42
+ ```python
43
+ from aspalchemy import Predicate, Variable
44
+
45
+ X = Variable("X") # an ASP variable
46
+ n = Predicate.define("n", [], show=False)() # a bare atom: n, distinct from the string "n"
47
+ ```
48
+
49
+ ### Predicates
50
+
51
+ Declare predicates as classes; fields are statically checked, so typos and
52
+ missing arguments are type errors, and instances autocomplete:
53
+
54
+ ```python
55
+ from aspalchemy import Predicate, PredicateField
56
+
57
+ class Person(Predicate):
58
+ name: PredicateField
59
+ age: PredicateField
60
+
61
+ john = Person(name="john", age=30)
62
+ mary = Person(name="mary", age=25)
63
+ ```
64
+
65
+ The ASP name defaults to the class name, snake-cased (HasSymbol becomes
66
+ has_symbol); class kwargs override it and set namespacing and visibility (`class Pipe(Predicate, name="pipe_seg",
67
+ show=False)`). When the schema is only known at runtime, build the same thing
68
+ dynamically:
69
+
70
+ ```python
71
+ Edge = Predicate.define("edge", ["a", "b"])
72
+ ```
73
+
74
+ For fully typed fields, annotate them as `Field[int]`, `Field[str]`, or
75
+ `Field[SomePredicate]`. Writes accept rule terms (Variables, Expressions) as
76
+ well as ground values, and are validated per field; reads are plain Python
77
+ values, statically typed — so solution atoms come back as real ints and strs:
78
+
79
+ ```python
80
+ from aspalchemy import ASPProgram, Field, Predicate
81
+
82
+ class Score(Predicate):
83
+ player: Field[str]
84
+ points: Field[int]
85
+
86
+ program = ASPProgram()
87
+ program.fact(Score(player="ada", points=3), Score(player="ben", points=5))
88
+ model = program.solve().first() # raises UnsatisfiableError if there is no model
89
+ total = sum(score.points for score in model.atoms(Score)) # plain ints
90
+ assert total == 8
91
+ ```
92
+
93
+ ### Rules
94
+
95
+ Build rules with clear syntax:
96
+
97
+ ```python
98
+ from aspalchemy import ANY, ASPProgram, Variable
99
+
100
+ program = ASPProgram()
101
+ X, Y = Variable("X"), Variable("Y")
102
+ Adult = Predicate.define("adult", ["name"])
103
+
104
+ # Facts
105
+ program.fact(john)
106
+ program.fact(mary)
107
+
108
+ # Rules
109
+ program.when(Person(name=X, age=Y), Y >= 18).derive(Adult(name=X))
110
+
111
+ # Constraints
112
+ program.forbid(Person(name=ANY, age=Y), Y < 0)
113
+ ```
114
+
115
+ ### Comparisons
116
+
117
+ Compare terms:
118
+
119
+ ```python
120
+ X < Y # Creates a comparison X < Y
121
+ ```
122
+
123
+ ### Aggregates
124
+
125
+ Use aggregates for advanced computations:
126
+
127
+ ```python
128
+ from aspalchemy import ANY, Count, Variable
129
+
130
+ X = Variable("X")
131
+ count = Count(X, Person(name=X, age=ANY)) > 5
132
+ ```
133
+
134
+ ### Solving
135
+
136
+ Solve your ASP program:
137
+
138
+ ```python
139
+ # Generate ASP code
140
+ asp_code = program.render()
141
+ print(asp_code)
142
+
143
+ # Solve
144
+ result = program.solve() # a lazy stream: consume the models you want
145
+ for model in result:
146
+ print("Solution found:")
147
+ for adult in model.atoms(Adult):
148
+ print(f" {adult}")
149
+ print(f"Satisfiable: {result.satisfiable}")
150
+ ```
151
+
152
+ ### Diagnostics point at your code
153
+
154
+ Every statement remembers the Python line that authored it. A `when()` left
155
+ unclosed reports where it was opened; grounding diagnostics from clingo carry
156
+ a "generated by file:line" note back to your source;
157
+ `program.render(annotate=True)` appends a trailing `% file:line` comment to
158
+ each rule — without changing line numbers, so the annotated text doubles as
159
+ a map from raw-clingo error lines back to your source; and when a grounding
160
+ is slow or huge, `program.ground().analyze_grounding()` reports ground-atom
161
+ counts per signature, largest first, each joined back to the lines that
162
+ derive it. Frameworks built on
163
+ aspalchemy call `register_skip_package()` (whole package, or per-module dotted
164
+ prefixes) so locations point at *their* caller's code; mark a single helper
165
+ with `@attribute_to_caller` to attribute its statements to its call sites.
166
+ Switch capture off with `ASPProgram(source_locations=False)` when
167
+ generating rules in bulk.
168
+
169
+ ## Requirements
170
+
171
+ - Python 3.14+
172
+ - clingo 5.8+
173
+
174
+ ## License
175
+
176
+ MIT License
@@ -0,0 +1,81 @@
1
+ [project]
2
+ name = "aspalchemy"
3
+ version = "1.0.0"
4
+ description = "A Python ORM interface for building and solving clingo ASP programs"
5
+ license = "MIT"
6
+ license-files = ["LICENSE.txt"]
7
+ readme = "docs/README.md"
8
+ requires-python = ">=3.14"
9
+ authors = [{ name = "Jolyon Bloomfield", email = "jolyonb84@gmail.com" }]
10
+ dependencies = ["clingo>=5.8.0,<6"]
11
+
12
+ [dependency-groups]
13
+ dev = [
14
+ "mypy>=2.1",
15
+ "pre-commit>=4.6",
16
+ "pyright>=1.1.411",
17
+ "ruff>=0.15",
18
+ "pytest>=9.1",
19
+ "ty>=0.0.56",
20
+ "pytest-cov>=7.1.0",
21
+ ]
22
+
23
+ [build-system]
24
+ requires = ["uv_build>=0.11,<0.13"]
25
+ build-backend = "uv_build"
26
+
27
+ [tool.uv.build-backend]
28
+ # Internal docs and OS litter must not ship in the wheel
29
+ source-exclude = ["src/aspalchemy/CLAUDE.md", "**/.DS_Store"]
30
+
31
+ [tool.mypy]
32
+ python_version = "3.14"
33
+ warn_return_any = true
34
+ warn_unused_configs = true
35
+ disallow_untyped_defs = true
36
+ disallow_incomplete_defs = true
37
+ check_untyped_defs = true
38
+ disallow_untyped_decorators = true
39
+ no_implicit_optional = true
40
+ strict_optional = true
41
+ files = ["src", "tests"]
42
+
43
+ [tool.pyright]
44
+ include = ["src", "tests"]
45
+
46
+ [tool.ruff]
47
+ line-length = 120
48
+
49
+ [tool.ruff.lint]
50
+ select = ["A", "B", "C4", "E", "F", "I", "Q", "RET", "RUF", "SIM", "UP", "W"]
51
+ # RUF001/RUF002/RUF003: flag legitimate typography ("9×9 grid") as ambiguous unicode
52
+ ignore = [
53
+ "RUF001", "RUF002", "RUF003", # legitimate typography (9×9 grids)
54
+ "SIM300", # 'yoda' flips change which operand builds the ASP Comparison, churning rendered output
55
+ ]
56
+ fixable = ["ALL"]
57
+
58
+ [tool.ruff.lint.isort]
59
+ known-first-party = ["aspalchemy"]
60
+ section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
61
+
62
+ [tool.pytest.ini_options]
63
+ testpaths = ["tests", "src/aspalchemy"]
64
+ addopts = "--doctest-modules"
65
+ markers = [
66
+ "allow_invalid_render: opt this test out of the suite-wide render parse-check (for tests exercising invalid-program error handling)",
67
+ ]
68
+ python_files = "test_*.py"
69
+ python_functions = "test_*"
70
+
71
+ [tool.coverage.run]
72
+ source = ["aspalchemy"]
73
+
74
+ [tool.coverage.report]
75
+ # Line coverage of aspalchemy must be total. Genuinely unexecutable lines are
76
+ # excluded here (not with scattered pragmas): abstract-method bodies that
77
+ # subclasses always override, and type-checking-only imports.
78
+ exclude_also = [
79
+ "if TYPE_CHECKING:",
80
+ "@(abc\\.)?abstractmethod",
81
+ ]
@@ -0,0 +1,171 @@
1
+ """
2
+ ASPAlchemy: A Python library for building clingo ASP (Answer Set Programming) programs
3
+ with a clean, object-oriented interface.
4
+ """
5
+
6
+ from .aggregates import (
7
+ Aggregate,
8
+ Count,
9
+ Max,
10
+ Min,
11
+ Sum,
12
+ SumPlus,
13
+ )
14
+ from .choice import CardinalityType, Choice
15
+ from .clingo_handler import ClingoMessage, LogLevel
16
+ from .conditional_literal import ConditionalLiteral
17
+ from .conditioned_element import ConditionedElement, ConditionType
18
+ from .core import (
19
+ ANY,
20
+ INF,
21
+ SUP,
22
+ BasicTerm,
23
+ ComparableTerm,
24
+ Comparison,
25
+ Compl,
26
+ ConstantBase,
27
+ DefaultNegation,
28
+ DefinedConstant,
29
+ ExplicitPool,
30
+ Expression,
31
+ Infimum,
32
+ Negatable,
33
+ Not,
34
+ Number,
35
+ Pool,
36
+ PredicateOccurrence,
37
+ RangePool,
38
+ RenderingContext,
39
+ String,
40
+ Supremum,
41
+ Term,
42
+ V,
43
+ Value,
44
+ Variable,
45
+ Vars,
46
+ pool,
47
+ )
48
+ from .exceptions import ASPAlchemyError, GroundingError, UnsatisfiableError
49
+ from .operators import ComparisonOperator, Operation
50
+ from .optimization import OptStrategy
51
+ from .predicate import Field, FieldAsTermType, NegatedSignature, Predicate, PredicateField, TupleTermType
52
+ from .program_elements import ProgramElement, RenderedLine
53
+ from .segment import Segment, When
54
+ from .solve_result import (
55
+ AtomCollection,
56
+ BraveConsequences,
57
+ CautiousConsequences,
58
+ Consequences,
59
+ CostedModel,
60
+ Model,
61
+ OptimizeSteps,
62
+ Optimum,
63
+ PredicateTypes,
64
+ RefinementSteps,
65
+ Search,
66
+ SolveResult,
67
+ convert_predicate_to_symbol,
68
+ convert_symbol_to_predicate,
69
+ )
70
+ from .solver import ASPProgram, GroundedProgram, SignatureGrounding
71
+ from .source_location import (
72
+ SourceLocation,
73
+ attribute_to_caller,
74
+ capture_location,
75
+ location_override,
76
+ register_skip_package,
77
+ )
78
+ from .version import __version__
79
+
80
+ __all__ = [ # noqa: RUF022 (categorized deliberately, not sorted)
81
+ # The program and its results
82
+ "ASPProgram",
83
+ "Segment",
84
+ "When",
85
+ "GroundedProgram",
86
+ "SignatureGrounding",
87
+ "SolveResult",
88
+ "Model",
89
+ "CostedModel",
90
+ "AtomCollection",
91
+ "Consequences",
92
+ "BraveConsequences",
93
+ "CautiousConsequences",
94
+ "RefinementSteps",
95
+ "OptimizeSteps",
96
+ "Optimum",
97
+ "OptStrategy",
98
+ "Search",
99
+ "LogLevel",
100
+ "ClingoMessage",
101
+ "ASPAlchemyError",
102
+ "GroundingError",
103
+ "UnsatisfiableError",
104
+ "RenderedLine",
105
+ # Source locations (diagnostics point at the authoring Python line)
106
+ "SourceLocation",
107
+ "capture_location",
108
+ "register_skip_package",
109
+ "attribute_to_caller",
110
+ "location_override",
111
+ # Declaring predicates
112
+ "Predicate",
113
+ "NegatedSignature",
114
+ "Field",
115
+ "PredicateField",
116
+ # Rule-building objects
117
+ "Variable",
118
+ "ANY",
119
+ "V",
120
+ "Vars",
121
+ "Choice",
122
+ "ConditionalLiteral",
123
+ "RangePool",
124
+ "ExplicitPool",
125
+ "SUP",
126
+ "INF",
127
+ # Aggregates
128
+ "Count",
129
+ "Sum",
130
+ "SumPlus",
131
+ "Min",
132
+ "Max",
133
+ # Rule-building utilities
134
+ "pool",
135
+ "Not",
136
+ "Compl",
137
+ # Hierarchy types: these appear in public signatures and return types —
138
+ # annotate with them; you rarely construct them directly
139
+ "ConditionType",
140
+ "ConditionedElement",
141
+ "TupleTermType",
142
+ "CardinalityType",
143
+ "PredicateTypes",
144
+ "FieldAsTermType",
145
+ "PredicateOccurrence",
146
+ "Term",
147
+ "BasicTerm",
148
+ "Value",
149
+ "ConstantBase",
150
+ "ComparableTerm",
151
+ "Negatable",
152
+ "ProgramElement",
153
+ "Expression",
154
+ "Comparison",
155
+ "ComparisonOperator",
156
+ "Operation",
157
+ "RenderingContext",
158
+ "DefaultNegation",
159
+ "DefinedConstant",
160
+ "Aggregate",
161
+ "Pool",
162
+ "Number",
163
+ "String",
164
+ "Supremum",
165
+ "Infimum",
166
+ # Interop with raw clingo symbols
167
+ "convert_predicate_to_symbol",
168
+ "convert_symbol_to_predicate",
169
+ # Metadata
170
+ "__version__",
171
+ ]