A directed-graph reasoning engine with transitive reachability, path explanations, and Pareto-optimal belief revision (counterfactual analysis).
Project description
Logic Engine
A directed-graph reasoning engine that resolves transitive relationships, explains the path it took, and — given a query — computes the minimum belief revision that would change the answer.
What it does
Given a set of directional facts, the engine answers two kinds of question:
Reachability. Is there a path from one node to another? Facts: John > Mike, Mike > Sam, Sam > Alex Query: John > Alex Result: TRUE Path: John -> Mike -> Sam -> Alex
Counterfactual revision. What is the smallest edit to the fact set that would flip the answer, and what else would change as a side effect? Facts: A > B, B > C, C > D, B > D, X > A Query: A > D (currently TRUE) Option 1 (cost=1, collateral=5): Remove: A > B Also lost: A > B, A > C, X > B, X > C, X > D Option 2 (cost=2, collateral=3): Remove: B > D, C > D Also lost: B > D, C > D, X > D
The engine returns Pareto-optimal revisions ranked by edit cost and by how many other entailments break as a result. This makes it possible to reason not just about whether something is true, but about how robustly true it is.
Project structure
engine.py Original DFS engine and visualization interactive_demo.py CLI demo with explainability and graph rendering logic_engine/ Belief revision package facts.py Fact and Query dataclasses with parsing graph.py Reachability, path-finding, entailment closure revision.py Minimum revision algorithms (falsify and satisfy) explain.py Human-readable revision summaries init.py Public API test_logic.py Original parameterized test suite (21 cases) test_comprehensive.py Edge cases, performance, input variations (34 tests) test_interactive.py Explainability and visualization tests (23 tests) test_revision.py Belief revision tests (17 tests) test_data.json Structured test cases for the original engine vercel.json Deployment configuration (security headers)
Installation
pip install pytest networkx matplotlib
The core revision module has no third-party dependencies. networkx and matplotlib are only needed for the original visualization layer in engine.py and interactive_demo.py.
Usage
Reachability and explanation (original engine)
from engine import logic_engine
from interactive_demo import explain_logic_path
facts = ["John > Mike", "Mike > Sam", "Sam > Alex"]
result = logic_engine(facts, "John > Alex")
explanation = explain_logic_path(facts, "John > Alex")
print(explanation["explanation"])
Belief revision (new)
from logic_engine import (
parse_facts, Query,
revise_to_falsify, revise_to_satisfy,
explain_all,
)
facts = parse_facts(["A > B", "B > C", "C > D", "B > D"])
# What's the smallest edit that would make A > D false?
revisions = revise_to_falsify(facts, Query("A", "D"))
print(explain_all(revisions))
# What's the smallest edit that would make A > Z true?
revisions = revise_to_satisfy(facts, Query("A", "Z"))
print(explain_all(revisions))
Interactive demo
python interactive_demo.py --demo
Public API
From logic_engine:
| Name | Purpose |
|---|---|
Fact(source, target) |
Immutable directed relationship |
Query(source, target) |
A reachability question |
parse_facts(items) |
Parse strings or Fact objects into a frozen set |
is_reachable(facts, source, target) |
Boolean reachability |
find_path(facts, source, target) |
One concrete path, or None |
compute_closure(facts, universe=None) |
Full set of true (source, target) pairs |
revise_to_falsify(facts, query, max_edits=4) |
Minimum removals to make a true query false |
revise_to_satisfy(facts, query, max_edits=3) |
Minimum additions to make a false query true |
Revision |
Result type: cost, collateral, edits, lost/gained entailments |
explain_revision(revision) |
Format a single revision as text |
explain_all(revisions) |
Format a list of revisions, separated by option |
How revision works
For a query that is currently true, the engine finds every edge that lies on at least one source-to-target path (irrelevant edges are pruned), then searches subsets of those edges in increasing size until it finds one whose removal disconnects the query. For each candidate, it computes the full entailment closure before and after the edit, and reports the difference as collateral damage.
Results are filtered to the Pareto frontier on (cost, collateral) — only revisions that aren't strictly dominated by another option on both dimensions are returned. This gives the user a meaningful menu of trade-offs: a low-cost, high-collateral edit versus a higher-cost, surgical one.
The dual problem (making a false query true) follows the same structure but searches over edges that could be added, with collateral measured as new entailments introduced.
Input format
Facts and queries use > as a directional separator:
A > Bmeans A has a direct relationship to B- Whitespace around node names is stripped
- Relationships are directional:
A > Bdoes not implyB > A - Cycles are supported and handled without infinite loops
- Unicode and special characters are valid in node names
Tests
python -m pytest -v
Total: 95 tests across four files.
| File | Count | Focus |
|---|---|---|
test_logic.py |
21 | Original parameterized cases from test_data.json |
test_comprehensive.py |
34 | Edge cases, error handling, performance, graph patterns |
test_interactive.py |
23 | Explainability output and visualization |
test_revision.py |
17 | Belief revision: falsification, satisfaction, collateral, Pareto filtering |
Limitations
- Directed only. Undirected relationships must be expressed as two facts.
- Single separator. Only
>is supported as the relation symbol. - Unweighted edges. All facts are treated as equally important.
- In-memory only. No persistence layer.
- Brute-force revision. The current revision search is exhaustive over edge subsets up to
max_edits. It performs well on graphs of a few hundred nodes; larger graphs would benefit from min-cut or ILP-based approaches.
License
Omry Damari
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file logic_engine-0.2.0.tar.gz.
File metadata
- Download URL: logic_engine-0.2.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbab830fcfd03aa04ce9b2658e4546a9cc1b1720b93fbc56cb0c17c779c0ed03
|
|
| MD5 |
192726612e0ee0bc1bc76f0096733aa3
|
|
| BLAKE2b-256 |
4420c6009daf1f0e2a12a329d8b0aa35baed53e5f6d171639e992d48b7ad175f
|
Provenance
The following attestation bundles were made for logic_engine-0.2.0.tar.gz:
Publisher:
publish.yml on Visigence/Logic-Engine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
logic_engine-0.2.0.tar.gz -
Subject digest:
bbab830fcfd03aa04ce9b2658e4546a9cc1b1720b93fbc56cb0c17c779c0ed03 - Sigstore transparency entry: 1428894226
- Sigstore integration time:
-
Permalink:
Visigence/Logic-Engine@342869d9d9bc813a67101f0808bc29a312895039 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Visigence
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@342869d9d9bc813a67101f0808bc29a312895039 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file logic_engine-0.2.0-py3-none-any.whl.
File metadata
- Download URL: logic_engine-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe9ffa31435550cba37cb76d515b017a1fb39a9c313679dc173e02cf368a1d47
|
|
| MD5 |
5462a2ff27d6c9a95bfbbb5673fbe080
|
|
| BLAKE2b-256 |
5866becd5820408b347a49e27a9ad1ff2afa9fbcc37826d54370396b0f795b65
|
Provenance
The following attestation bundles were made for logic_engine-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Visigence/Logic-Engine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
logic_engine-0.2.0-py3-none-any.whl -
Subject digest:
fe9ffa31435550cba37cb76d515b017a1fb39a9c313679dc173e02cf368a1d47 - Sigstore transparency entry: 1428894228
- Sigstore integration time:
-
Permalink:
Visigence/Logic-Engine@342869d9d9bc813a67101f0808bc29a312895039 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Visigence
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@342869d9d9bc813a67101f0808bc29a312895039 -
Trigger Event:
workflow_dispatch
-
Statement type: