Skip to main content

symbolic-reasoning

A policy compiles to a symbolic reasoning graph that the solver evaluates. The solver asks an oracle, which draws on case knowledge, and the result is a reasoning trace that leads to an outcome.

Policy-adherent, auditable reasoning for AI agents.

Research preview. symbolic-reasoning is pre-1.0 and under active development. The API, the .srg language and output formats may change between minor releases without deprecation. Review its outputs before relying on them for consequential decisions. Provided "as is", without warranty, under the Apache 2.0 License.

symbolic-reasoning evaluates policies deterministically. You write a policy in the .srg language; the library works out which questions need answering, asks your oracle (an LLM, a database, a human), and returns the outcomes with a reasoning trace.

Concern Handled by
What are the rules? Your policy (.srg)
What is true in this case? Your oracle
Which question or decision follows? The runtime
Why was that decision made? The reasoning trace

Installation

Requires Python 3.12+.

uv add symbolic-reasoning  # or: pip install symbolic-reasoning

Quick start

Save a policy as loan_approval.srg:

predicate has_good_credit:   "Does the applicant have a credit score of 700 or above?"
predicate has_stable_income: "Does the applicant have stable employment for at least 2 years?"
predicate has_low_dti:       "Is the applicant's debt-to-income ratio below 43%?"
predicate has_down_payment:  "Has the applicant provided at least 20% down payment?"

outcome approved:      "Loan Approved"
outcome denied:        "Loan Denied"
outcome manual_review: "Sent to Manual Review"

define core_eligible: all(has_good_credit, has_stable_income, has_low_dti)

path approve: all(core_eligible, has_down_payment) => approved
path review:  all(core_eligible, not(has_down_payment)) => manual_review
path deny:    not(core_eligible) => denied

Solve it with an oracle. This one asks you at the terminal:

import asyncio

import symbolic_reasoning as sr


async def oracle(request: sr.OracleRequest) -> dict[str, sr.Answer]:
    answers = {}
    for predicate_request in request.predicate_requests:
        p = predicate_request.predicate
        reply = input(f"{p.question} (y/n): ")
        answers[p.id] = sr.Answer(is_met=reply == "y", reasoning=f"User answered {reply}")
    return answers


async def main() -> None:
    srg = sr.compile_srg_file("loan_approval.srg")
    execution = await sr.asolve(srg, oracle)

    for path in sr.reasoning_trace(execution).outcome_paths:
        print(srg.outcomes[path.outcome_id].description)
        for step in path.steps:
            mark = "YES" if step.is_met else "NO "
            print(f"  {mark}  {srg.predicates[step.predicate_id].question}")


asyncio.run(main())

It prints each outcome reached and the answers that led to it:

Sent to Manual Review
  YES  Does the applicant have a credit score of 700 or above?
  YES  Does the applicant have stable employment for at least 2 years?
  YES  Is the applicant's debt-to-income ratio below 43%?
  NO   Has the applicant provided at least 20% down payment?

Learn more

  • The SRG language: the .srg syntax, how policies are evaluated and how to design them.
  • Python guide: oracles, step-by-step solving, coverage, reasoning traces, recording and replay, and the API reference.

Use with agents

The quick start runs a policy as a workflow: your code drives the solve and calls the oracle for each round of questions. The agent tools invert that control. The agent drives the solve through tool calls, starting an execution, answering each question from the case evidence and reading the outcomes, while the library still decides which questions are asked and how the answers combine.

Serve the tools over MCP with the mcp extra:

uv add "symbolic-reasoning[mcp]"
uv run python -m symbolic_reasoning.mcp --srg loan_approval loan_approval.srg

The server talks over stdio, so a host such as Claude Code launches it. See MCP setup to connect one.

To use the tools without MCP, see the Python guide.

Use with decision models

Every predicate is a yes/no question about the case, which is what a decision model answers. Use one as the oracle: the policy fixes which questions are asked and how their answers combine, and the model answers each from the case evidence. Map its probability to is_met and keep the probability in reasoning, so the trace shows how confident each answer was.

The Jev example does this with TypeSafe's Jev.

Examples

  • examples/integrations/jev: an oracle backed by the Jev decision model, which answers a policy's questions from Markdown case files and records the run.
  • examples/data: an underwriting policy with an application, and a medical necessity review policy with a synthetic clinical record and a replay.

Metadata

Release files for symbolic-reasoning 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for symbolic-reasoning 0.7.0
File Size Uploaded Provenance Actions
symbolic_reasoning-0.7.0.tar.gz 88.2 kB Without provenance Details for symbolic_reasoning-0.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for symbolic-reasoning 0.7.0
File Interpreter ABI Platform Actions
symbolic_reasoning-0.7.0-py3-none-any.whl Python 3 none any Details for symbolic_reasoning-0.7.0-py3-none-any.whl

Total release size: 185.4 kB

Release files / symbolic_reasoning-0.7.0.tar.gz

Download URL symbolic_reasoning-0.7.0.tar.gz
Size 88.2 kB
Tags Source
SHA-256 checksum
How to use checksums
920ced0fcd96a2466694cd354f321ad52b84cb9178853fdfaa09f8dc646119ea
BLAKE2b-256 checksum
How to use checksums
b0b22662da4c407e1f6da33ff1ec1c038436250d3734816b37698503a0b77b9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / symbolic_reasoning-0.7.0-py3-none-any.whl

Download URL symbolic_reasoning-0.7.0-py3-none-any.whl
Size 97.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bbfb0fd0122b482314e326e4eab7c3b6bea9c7adb3babb12410ef7be41dd4be0
BLAKE2b-256 checksum
How to use checksums
5bbffaea4845b9d46a2d07b5b6dd587d0829b3d31edad4d3dc1923d1dceb672b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for symbolic-reasoning 0.7.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page