# Implementing Contradiction Detection in MemPalace: A Complete Technical Guide

> Implement contradiction detection in MemPalace. This guide details offline comparison against local data for confusion and mismatch identification, no external APIs needed.

- Repository: [MemPalace/mempalace](https://github.com/MemPalace/mempalace)
- Tags: how-to-guide
- Published: 2026-06-07

---

**MemPalace performs offline contradiction detection by comparing user-supplied text against a local Entity Registry and temporal Knowledge Graph, identifying similar-name confusion and relationship mismatches without requiring external API calls.**

MemPalace is a privacy-first knowledge management system that maintains a personal "palace" of facts and relationships. Implementing contradiction detection in MemPalace allows the system to catch factual errors, outdated information, and potential confusions before they pollute your knowledge base. The entire detection pipeline operates locally using SQLite and JSON files, ensuring no sensitive data leaves your machine.

## How Contradiction Detection Works in MemPalace

The detection system in [`mempalace/fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/fact_checker.py) operates as an offline validation layer. When you submit text for checking, the system cross-references two internal data structures to identify potential issues.

### The Two Data Sources

MemPalace maintains two distinct knowledge stores for validation:

1. **Entity Registry** – A JSON dictionary containing known people, projects, and concepts loaded via [`mempalace/entity_registry.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/entity_registry.py) (specifically the `_load_known_entities_raw` function)
2. **Knowledge Graph (KG)** – A temporal SQLite database stored at `palace_path/knowledge_graph.sqlite3` that records relationships between entities with validity windows (e.g., "Bob is Alice's brother" valid from 2020-01-01 to null)

### The Detection Pipeline

The main entry point `check_text(text, palace_path)` in [`mempalace/fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/fact_checker.py) orchestrates the validation process. It returns a list of detected issues, running two primary checks sequentially:

- `_check_entity_confusion` – Identifies potential typos or similar names
- `_check_kg_contradictions` – Validates relationship claims against stored facts

## Core Detection Logic in fact_checker.py

The [`fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/fact_checker.py) module contains the primary contradiction detection engine, implementing two distinct validation strategies.

### Similar-Name Confusion Detection

The `_check_entity_confusion` method (lines 96-149) prevents subtle data entry errors by detecting names that appear in input text but differ by ≤2 edit distance from a *different* registered name. This catches typical typos that might create duplicate or confused entities.

The implementation uses a fast edit-distance helper `_edit_distance` (lines 89-108) to compare extracted names against the Entity Registry without requiring fuzzy database queries.

### Knowledge Graph Contradiction Detection

The `_check_kg_contradictions` method (lines 82-127) handles semantic validation by parsing relationship claims and querying the temporal Knowledge Graph. It detects two specific contradiction types:

- **Relationship mismatch** – When the text claims "Bob is Alice's brother" but the KG records Bob as Alice's husband
- **Stale fact** – When the claim matches a KG entry that has expired (its `valid_to` date precedes today)

## Parsing Claims from Text

Before the Knowledge Graph can validate relationships, the system must extract structured semantic triples from unstructured text.

### Regex Pattern Matching

The `_extract_claims` function (lines 55-79) uses compiled patterns stored in `_RELATIONSHIP_PATTERNS` to identify relationship statements. The default patterns recognize:

- "X is Y's Z" (e.g., "Bob is Alice's brother")
- "X's Z is Y" (e.g., "Alice's brother is Bob")

Each match yields a triple tuple of `(subject, predicate, object)` that represents the semantic claim for KG validation.

### Extracting Semantic Triples

Once extracted, claims are validated against the Knowledge Graph instance created at line 104 in [`fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/fact_checker.py), which points to `palace_path/knowledge_graph.sqlite3`. The `KnowledgeGraph` class defined in [`mempalace/knowledge_graph.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/knowledge_graph.py) provides the query interface.

## Querying the Temporal Knowledge Graph

The Knowledge Graph implementation in [`mempalace/knowledge_graph.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/knowledge_graph.py) supports temporal validity, allowing facts to have finite lifespans.

### Relationship Mismatch Detection

For each extracted claim, the system queries outgoing facts for the subject using `query_entity(name, as_of=None, direction="outgoing")`. If the KG contains a fact sharing the same object but a different predicate, the system generates a `relationship_mismatch` issue (lines 27-50 in [`fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/fact_checker.py)).

The temporal filtering uses `_temporal_filter_sql` to ensure only currently valid facts participate in the contradiction check unless a specific `as_of` date is provided.

### Stale Fact Detection

When a claim exactly matches a KG entry but the entry's `valid_to` date (validated via `sanitize_iso_temporal` from [`mempalace/config.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/config.py)) precedes the current date, the system flags a `stale_fact` issue (lines 52-65). This prevents users from asserting relationships that have explicitly expired.

## Practical Implementation Examples

### Basic Python API Usage

Import the `check_text` function to validate strings programmatically:

```python
from mempalace.fact_checker import check_text

# Detect contradictions in a user message

issues = check_text(
    "Bob is Alice's brother",
    palace_path="/home/user/.mempalace/palace"
)

for issue in issues:
    print(issue["type"], "→", issue["detail"])

```

### CLI Invocation

Run contradiction detection from the command line:

```bash
$ python -m mempalace.fact_checker "Bob is Alice's brother" \
    --palace /home/user/.mempalace/palace

```

When a mismatch is detected, the CLI outputs structured JSON:

```json
[
  {
    "type": "relationship_mismatch",
    "detail": "Text says 'Bob is Alice's brother' but KG records Bob husband Alice",
    "entity": "Bob",
    "claim": {"predicate": "brother", "object": "Alice"},
    "kg_fact": {"predicate": "husband", "object": "Alice"}
  }
]

```

### Extending Detection with Custom Patterns

Add new relationship types by appending compiled regex patterns to `_RELATIONSHIP_PATTERNS` in [`mempalace/fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/fact_checker.py):

```python
import re

# Add support for "works with" relationships

_RELATIONSHIP_PATTERNS.append(
    re.compile(r"\b([A-Z][\w-]+)\s+works\s+with\s+([A-Z][\w-]+)\b")
)

```

Now statements like "Bob works with Alice" will be parsed and validated against the Knowledge Graph.

## Summary

- **MemPalace contradiction detection** operates entirely offline in [`mempalace/fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/fact_checker.py), comparing text against local JSON and SQLite data stores.
- **Entity confusion detection** uses edit-distance calculations in `_check_entity_confusion` to catch typos and similar names.
- **Knowledge Graph validation** extracts semantic triples via `_extract_claims` and checks them against temporal facts in `knowledge_graph.sqlite3`.
- **Two contradiction types** are identified: `relationship_mismatch` (conflicting predicates) and `stale_fact` (expired validity windows).
- **Zero external dependencies** preserve the privacy-first architecture—no API calls are required for fact validation.
- **Extensible architecture** allows custom regex patterns and additional check functions to be integrated into the `check_text` pipeline.

## Frequently Asked Questions

### How does MemPalace handle temporal facts that change over time?

The Knowledge Graph in [`mempalace/knowledge_graph.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/knowledge_graph.py) stores each relationship with optional `valid_from` and `valid_to` timestamps. When `query_entity` is called, the `_temporal_filter_sql` helper applies the `as_of` parameter (defaulting to the current date) to return only facts valid at that specific time. This allows the system to detect `stale_fact` contradictions when users assert relationships that have expired, while still maintaining historical accuracy in the database.

### Can I use contradiction detection without the full MemPalace application?

Yes, the [`fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/fact_checker.py) module is self-contained. You can import `check_text` into any Python script, provided you supply a valid `palace_path` containing the `knowledge_graph.sqlite3` file and entity registry JSON. The CLI interface also allows standalone operation via `python -m mempalace.fact_checker`, making it suitable for integration with external scripts or git hooks.

### What edit distance threshold does MemPalace use for entity confusion detection?

The `_check_entity_confusion` function flags names that differ by **≤2 edit distance** from a registered entity name, provided they are not identical matches. This threshold is implemented in lines 96-149 of [`fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/fact_checker.py) using the internal `_edit_distance` helper (lines 89-108), which performs a fast dynamic programming calculation optimized for short strings typical of personal knowledge bases.

### How can I add support for non-English relationship patterns?

Extend the `_RELATIONSHIP_PATTERNS` list in [`mempalace/fact_checker.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/fact_checker.py) with compiled regex patterns matching your target language's relationship syntax. Ensure your patterns capture named groups or return tuples matching the `(subject, predicate, object)` format expected by `_check_kg_contradictions`. Since the KG stores raw strings, non-English entities and predicates are fully supported without modification to the `KnowledgeGraph` class in [`mempalace/knowledge_graph.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/knowledge_graph.py).