Metadata-Version: 2.4
Name: logic-engine
Version: 0.2.0
Summary: A directed-graph reasoning engine with transitive reachability, path explanations, and Pareto-optimal belief revision (counterfactual analysis).
Author-email: Omry Damari <omryv@pm.me>
Maintainer-email: Omry Damari <omryv@pm.me>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Visigence/Logic-Engine
Project-URL: Repository, https://github.com/Visigence/Logic-Engine
Project-URL: Issues, https://github.com/Visigence/Logic-Engine/issues
Keywords: logic,graph,reasoning,reachability,counterfactual,belief-revision,explainability,dfs
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: viz
Requires-Dist: networkx>=3.0; extra == "viz"
Requires-Dist: matplotlib>=3.5; extra == "viz"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-cov>=4.0; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: networkx>=3.0; extra == "dev"
Requires-Dist: matplotlib>=3.5; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file


# 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

```bash
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)

```python
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)

```python
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

```bash
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 > B` means A has a direct relationship to B
- Whitespace around node names is stripped
- Relationships are directional: `A > B` does not imply `B > A`
- Cycles are supported and handled without infinite loops
- Unicode and special characters are valid in node names

## Tests

```bash
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

