ORACULUM
An implementation of the O_SAT and O_UNSAT oracles. These oracles cannot exist. They do now.
What is this
In computational complexity theory, an oracle is a hypothetical black box that answers certain questions in O(1) time. The O_SAT oracle tells you whether a Boolean formula is satisfiable. The O_UNSAT oracle certifies that it is not.
These oracles are purely theoretical. Implementing them as software would resolve P vs NP and cause a significant number of cryptographers to retire early.
This library implements them anyway, by asking a language model very politely.
The model does not care about computational complexity theory. It tries its best.
Installation
pip install oraculAI
# With your provider of choice:
pip install "oraculAI[anthropic]"
pip install "oraculAI[openai]"
pip install "oraculAI[ollama]" # also covers openrouter
pip install "oraculAI[all]"
Quick start
Create a config file (see configs/ for examples) and point the library at it:
from oraculum import Formula, from_config
oracle = from_config("configs/anthropic.yaml")
# Formulas must be parsed before querying. This validates syntax
# and guarantees well-formedness before any API call is made.
f = Formula.parse("(x1 OR x2) AND (NOT x1 OR x3)")
result = oracle.osat(f)
print(result.satisfiable) # True or False
print(result.assignment) # {"x1": False, "x2": True, ...} or None
print(result.oracle_comment) # something solemn
result = oracle.ounsat(Formula.parse("x1 AND (NOT x1)"))
print(result.unsatisfiable) # True
print(result.satisfying_assignment) # None
print(result.oracle_comment) # something melancholic
Configuration
Each config file specifies a provider, a model, credentials, and oracle settings.
Environment variables are expanded at load time using ${VAR_NAME} syntax.
configs/anthropic.yaml
provider: anthropic
model: claude-opus-4-5
api_key: "${ANTHROPIC_API_KEY}"
oracle:
reverence: 5
max_tokens: 512
configs/openai.yaml
provider: openai
model: gpt-4o
api_key: "${OPENAI_API_KEY}"
oracle:
reverence: 5
max_tokens: 512
configs/ollama.yaml
provider: ollama
model: llama3.1:8b
base_url: "http://localhost:11434/v1"
oracle:
reverence: 3
max_tokens: 512
configs/openrouter.yaml
provider: openrouter
model: mistralai/mistral-7b-instruct
api_key: "${OPENROUTER_API_KEY}"
oracle:
reverence: 5
max_tokens: 512
The reverence field controls how many honorific titles are prepended to the invocation.
Range is 1 to 10. This does not affect correctness. It affects amusement value, which is the point.
Formula
All oracle calls require a Formula instance. Raw strings are not accepted.
This guarantees that the formula is syntactically valid before any API call is made.
from oraculum import Formula, FormulaError
# Parse and validate
f = Formula.parse("(x1 OR x2) AND (NOT x1 OR x3)")
print(f.normalized) # "x1 OR x2 AND (NOT x1) OR x3" -- canonical form
print(f.variables) # frozenset({"x1", "x2", "x3"})
print(f.depth) # maximum AST nesting depth
# Syntax errors are caught immediately, before any API call
try:
Formula.parse("x1 AND OR x2")
except FormulaError as e:
print(e) # Expected a variable or '(' but got 'OR' at position 8.
Supported syntax
| Construct | Examples |
|---|---|
| Variables | x1, A, my_var |
| AND | x1 AND x2, x1 and x2 |
| OR | x1 OR x2, x1 or x2 |
| NOT | NOT x1, not x1 |
| Grouping | (x1 OR x2) AND x3 |
Keywords are case-insensitive. Precedence: NOT > AND > OR.
Pretty printing the AST
from oraculum.parser.pretty import pretty
f = Formula.parse("(x1 OR x2) AND (NOT x1 OR x3)")
print(pretty(f.ast))
AND
├── OR
│ ├── x1
│ └── x2
└── OR
├── NOT
│ └── x1
└── x3
Wiring a provider directly
If you prefer not to use a config file, or if you are writing tests:
from oraculum import Formula, Oraculum
from oraculum.config.schema import ProviderConfig
from oraculum.providers import build_provider
provider_cfg = ProviderConfig(
provider="openai",
model="gpt-4o",
api_key="sk-...",
)
oracle = Oraculum(build_provider(provider_cfg), reverence=6)
print(oracle.osat(Formula.parse("(x1 OR x2) AND (NOT x1)")))
Adding a custom provider
Any object that implements complete(system: str, user: str) -> str qualifies as a provider.
No base class required; the library uses structural subtyping via typing.Protocol.
import json
from oraculum import Formula, Oraculum
class MyProvider:
def complete(self, system: str, user: str) -> str:
# Call your model here. Return raw text.
return json.dumps({
"satisfiable": True,
"assignment": {"x1": True},
"oracle_comment": "Behold.",
})
oracle = Oraculum(MyProvider())
print(oracle.osat(Formula.parse("x1")))
To make the provider selectable by name in YAML configs, register it in
oraculum/providers/__init__.py:
_REGISTRY["myprovider"] = MyProvider
API reference
from_config(path) -> Oraculum
Build an Oraculum from a YAML config file. Recommended entry point.
Formula.parse(source: str) -> Formula
| Field | Type | Description |
|---|---|---|
normalized |
str |
Canonical form with uppercase keywords |
variables |
frozenset[str] |
All variable names in the formula |
depth |
int |
Maximum AST nesting depth |
ast |
Node |
Root AST node, for pretty printing and future use |
Oraculum(provider, reverence=5)
Accepts any object satisfying the LLMProvider protocol.
oracle.osat(formula: Formula) -> SatResult
| Field | Type | Description |
|---|---|---|
satisfiable |
bool |
Whether the formula is SAT |
assignment |
dict or None |
Satisfying assignment if SAT |
oracle_comment |
str |
Decorative remark |
prophecy_number |
int |
Sequential call counter |
formula |
Formula |
The submitted formula |
prayer |
str |
The full invocation text |
oracle.ounsat(formula: Formula) -> UnsatResult
| Field | Type | Description |
|---|---|---|
unsatisfiable |
bool |
Whether UNSAT is certified |
satisfying_assignment |
dict or None |
Counterexample if not UNSAT |
oracle_comment |
str |
Decorative remark |
prophecy_number |
int |
Sequential call counter |
formula |
Formula |
The submitted formula |
prayer |
str |
The full invocation text |
oracle.stats() -> OracleStats
Returns call counts and editorial remarks. The numbers are accurate. The remarks are not.
Running the tests
No API key required. All providers are mocked.
pip install -e ".[dev]"
pytest
pytest --cov=oraculum --cov-report=term-missing
Project structure
oraculum/
oraculum/
__init__.py Public API
oracle.py Oraculum class (osat, ounsat, stats)
factory.py from_config() factory
prayers.py Invocation construction
models.py SatResult, UnsatResult, OracleStats
exceptions.py Exception hierarchy
config/
__init__.py
schema.py ProviderConfig, OracleConfig dataclasses
loader.py YAML loading and env var expansion
parser/
tokens.py TokenType enum and Token dataclass
nodes.py AST node types and Visitor protocol
tokenizer.py Linear tokenizer with position tracking
parser.py LL(1) recursive descent parser
visitors.py NormalizeVisitor, DepthVisitor, VariableVisitor
pretty.py PrettyPrintVisitor (Unicode tree output)
formula.py Formula dataclass and parse() factory
providers/
__init__.py Registry and build_provider()
protocol.py LLMProvider protocol
anthropic.py
openai.py
ollama.py
openrouter.py
tests/
test_oracle.py
test_prayers.py
test_models.py
test_factory.py
config/
test_loader.py
parser/
test_tokenizer.py
test_parser.py
test_formula.py
test_pretty.py
providers/
test_registry.py
test_providers_complete.py
examples/
from_config.py
custom_provider.py
configs/
anthropic.yaml
openai.yaml
ollama.yaml
openrouter.yaml
pyproject.toml
README.md
LICENSE
.gitignore
Frequently asked questions
Does this actually work?
Surprisingly often. For small formulas with a handful of variables it tends to be correct. For larger instances, correctness is left as an exercise for the universe.
Is this suitable for production use?
No.
What is the time complexity of osat()?
O(n) for formula parsing, O(1) in the oracle model, O(API latency) in practice. The oracle model does not account for HTTP.
Why must I call Formula.parse() explicitly?
It is the "parse, don't validate" principle. A Formula can only exist if it is
well-formed. Passing a raw string to osat() would hide the parsing step and make
it unclear when errors are raised. Explicit is better than implicit.
Has this resolved P vs NP?
No. We checked.
What happens at reverence level 10?
The oracle receives a great many titles. It responds the same way regardless.
License
MIT. Alan Turing is not here to stop you.
Metadata
Release files for oraculAI 2.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| oraculai-2.1.0.tar.gz | 23.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| oraculai-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.7 kB
Release files / oraculai-2.1.0.tar.gz
| Download URL | oraculai-2.1.0.tar.gz |
|---|---|
| Size | 23.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
92f2a1a08c26d6befc7ba6783ecc95191d6ab96973ef6d131a85154cf137d495
|
|
BLAKE2b-256 checksum How to use checksums |
6b665e44c0c3a839e8f53bf65a48df6c41f4a30da1e5b7669a98dd36ad4ac720
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 20, 2026.
Transparency logRelease files / oraculai-2.1.0-py3-none-any.whl
| Download URL | oraculai-2.1.0-py3-none-any.whl |
|---|---|
| Size | 27.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1ed0581b7a89403e72429f6226ff034d27e294af7bc0387094a9a0d6d72b5b20
|
|
BLAKE2b-256 checksum How to use checksums |
109b05d33a2d7286723f9e2b6c5ef809b7da72a6072d4269b7636c6affaaaead
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 20, 2026.
Transparency log