# How to Implement Explainable Reasoning in Semantica: A Complete Guide to Transparent AI Inference

> Implement explainable reasoning in Semantica easily. Generate natural-language narratives and structured reasoning paths from inference results using ExplanationGenerator. Get transparent AI.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-08-15

---

**To implement explainable reasoning in Semantica, instantiate a `Reasoner` for inference, then pass the resulting `InferenceResult`, `Proof`, or `Explanation` objects to an `ExplanationGenerator` to produce natural-language narratives and structured reasoning paths.**

Semantica's layered reasoning stack converts raw logical inference into **human-readable justifications**. This article walks through the complete implementation using actual source files from the `semantica-agi/semantica` repository, covering deductive forward-chaining, formal proofs, and abductive hypothesis generation.

## Core Components for Explainable Reasoning

Semantica's explainability architecture rests on four specialized classes:

| Component | File Path | Purpose |
|-----------|-----------|---------|
| `Reasoner` | [`semantica/reasoning/reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/reasoner.py) | Unified forward/backward-chaining engine for rule-based inference |
| `ExplanationGenerator` | [`semantica/reasoning/explanation_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/explanation_generator.py) | Converts inference outputs to natural language with full reasoning paths |
| `DeductiveReasoner` | [`semantica/reasoning/deductive_reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/deductive_reasoner.py) | Generates formal `Proof` objects for logical verification |
| `AbductiveReasoner` | [`semantica/reasoning/abductive_reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/abductive_reasoner.py) | Creates and ranks explanatory hypotheses from observations |

All components share **progress tracking and logging infrastructure** via [`utils/progress_tracker.py`](https://github.com/semantica-agi/semantica/blob/main/utils/progress_tracker.py) and [`utils/logging.py`](https://github.com/semantica-agi/semantica/blob/main/utils/logging.py) for audit trails.

## Step 1: Initialize the Reasoner

Start by creating a `Reasoner` instance with optional iteration limits:

```python
from semantica.reasoning import Reasoner

reasoner = Reasoner(max_iterations=100)

```

The `Reasoner` stores facts as strings (e.g., `Person(John)`) and rules as `Rule` dataclasses. Rule parsing occurs in `Reasoner._parse_rule_definition` at line 51 of [`reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/reasoner.py).

## Step 2: Define Rules and Facts

### Add IF-THEN Rules

```python
rule = "IF Person(?x) AND LivesIn(?x, ?city) THEN CitizenOf(?x, ?city)"
reasoner.add_rule(rule)

```

The `add_rule` method automatically deduplicates identical rules.

### Register Base Facts

```python
facts = [
    "Person(John)",
    "LivesIn(John, Berlin)",
    "Person(Alice)",
    "LivesIn(Alice, Paris)"
]
for f in facts:
    reasoner.add_fact(f)

```

## Step 3: Run Inference

Execute **forward chaining** to derive new facts:

```python
new_facts = reasoner.infer_facts(facts)
print(new_facts)

# → ['CitizenOf(John, Berlin)', 'CitizenOf(Alice, Paris)']

```

This returns conclusions only. The full trace—including which rules fired and which premises were used—remains accessible as `InferenceResult` objects.

## Step 4: Generate Natural-Language Explanations

This is the critical step for **explainable reasoning in Semantica**: transform technical inference data into comprehensible output.

```python
from semantica.reasoning import ExplanationGenerator

explain_gen = ExplanationGenerator(detail_level="detailed")

# Retrieve first inference result from forward chaining

inference_result = reasoner.forward_chain()[0]

explanation = explain_gen.generate_explanation(inference_result)
print(explanation.natural_language)

```

Example output:

```

Given the premises: Person(John), LivesIn(John, Berlin), we conclude: CitizenOf(John, Berlin) using rule 'rule_1'.

```

The `Explanation` object contains:
- **`natural_language`**: Human-readable narrative
- **`reasoning_path`**: Structured `ReasoningPath` with premises, applied rule, and conclusion

The path construction logic resides in `ExplanationGenerator._explain_inference_result` at line 90 of [`explanation_generator.py`](https://github.com/semantica-agi/semantica/blob/main/explanation_generator.py).

## Step 5: Generate Formal Proofs for Auditability

For **deductive reasoning with formal verification**:

```python
from semantica.reasoning import DeductiveReasoner, Premise

deductive = DeductiveReasoner()

premises = [
    Premise("p1", "All humans are mortal"),
    Premise("p2", "Socrates is human")
]
conclusions = deductive.apply_logic(premises)

proof = deductive.prove_theorem("Socrates is mortal")
print(proof.valid)  # → True

```

Feed the `Proof` into the same generator:

```python
proof_expl = explain_gen.generate_explanation(proof)
print(proof_expl.natural_language)

```

This produces a **validated logical argument** with step-by-step justification.

## Step 6: Explain Abductive Hypotheses

For **observation-to-best-explanation inference**:

```python
from semantica.reasoning import AbductiveReasoner, Observation

abductive = AbductiveReasoner(ranking_strategy="simplicity")

obs = Observation("obs1", "Person(John) is in City(Berlin)")
hypotheses = abductive.generate_hypotheses([obs])
best = abductive.rank_hypotheses(hypotheses)[0]

print(best.explanation)  # → "Hypothesis based on rule: ..."

```

The `ExplanationGenerator` handles abductive results seamlessly:

```python
abduct_expl = explain_gen.generate_explanation(best)
print(abduct_expl.natural_language)

```

## Complete Working Example

```python
from semantica.reasoning import (
    Reasoner,
    ExplanationGenerator,
    DeductiveReasoner,
    AbductiveReasoner,
    Observation,
    Premise,
)

# Initialize components

reasoner = Reasoner(max_iterations=50)
explain = ExplanationGenerator(detail_level="verbose")
deductive = DeductiveReasoner()
abductive = AbductiveReasoner(ranking_strategy="plausibility")

# Load rule chain

rules = [
    "IF Person(?x) AND LivesIn(?x, ?city) THEN CitizenOf(?x, ?city)",
    "IF CitizenOf(?x, ?city) THEN EligibleToVote(?x, ?city)",
]
for r in rules:
    reasoner.add_rule(r)

# Add base facts

facts = ["Person(John)", "LivesIn(John, Berlin)"]
for f in facts:
    reasoner.add_fact(f)

# Forward-chain and explain each inference

print("=== FORWARD CHAINING EXPLANATIONS ===")
inferred = reasoner.forward_chain()
for res in inferred:
    expl = explain.generate_explanation(res)
    print(f"\nInference: {res.conclusion}")
    print(f"Explanation: {expl.natural_language}")

# Deductive proof

print("\n=== DEDUCTIVE PROOF ===")
prem = [
    Premise("p1", "All humans are mortal"),
    Premise("p2", "Socrates is human")
]
deductive.apply_logic(prem)
proof = deductive.prove_theorem("Socrates is mortal")
proof_expl = explain.generate_explanation(proof)
print(f"Valid: {proof.valid}")
print(f"Explanation: {proof_expl.natural_language}")

# Abductive reasoning

print("\n=== ABDUCTIVE EXPLANATION ===")
obs = Observation("obs1", "EligibleToVote(John, Berlin)")
abduct_hyp = abductive.generate_hypotheses([obs], reasoner=reasoner)
if abduct_hyp:
    best_hyp = abductive.rank_hypotheses(abduct_hyp)[0]
    abduct_expl = explain.generate_explanation(best_hyp)
    print(f"Best hypothesis: {abduct_expl.natural_language}")

```

## Key Source Files for Explainable Reasoning

| File | Function | Critical Methods |
|------|----------|----------------|
| [`semantica/reasoning/reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/reasoner.py) | Core inference engine | `add_rule()`, `add_fact()`, `forward_chain()`, `infer_facts()` |
| [`semantica/reasoning/explanation_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/explanation_generator.py) | Explanation construction | `generate_explanation()`, `_explain_inference_result()` |
| [`semantica/reasoning/deductive_reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/deductive_reasoner.py) | Formal proof generation | `apply_logic()`, `prove_theorem()` |
| [`semantica/reasoning/abductive_reasoner.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/reasoning/abductive_reasoner.py) | Hypothesis generation | `generate_hypotheses()`, `rank_hypotheses()` |
| [`semantica/utils/progress_tracker.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/utils/progress_tracker.py) | Execution tracing | `start_tracking()`, `update_tracking()`, `stop_tracking()` |
| [`semantica/utils/logging.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/utils/logging.py) | Audit logging | `get_logger()` |

## Summary

- **Initialize** a `Reasoner` with `max_iterations` and load rules/facts via `add_rule()` and `add_fact()`
- **Execute** forward chaining with `forward_chain()` or `infer_facts()` to produce `InferenceResult` objects
- **Transform** any result type—`InferenceResult`, `Proof`, or `Explanation`—into natural language using `ExplanationGenerator.generate_explanation()`
- **Select** `detail_level` ("compact", "detailed", "verbose") to control explanation granularity
- **Audit** complete reasoning paths through `explanation.reasoning_path` for compliance or debugging

## Frequently Asked Questions

### What explanation detail levels does Semantica support?

Semantica supports three levels: **"compact"** for brief summaries, **"detailed"** for standard narratives with rule citations, and **"verbose"** for complete premise-to-conclusion traces including intermediate steps. Pass the desired level when instantiating `ExplanationGenerator`.

### Can Semantica explain backward-chaining inferences?

Yes. The `Reasoner.forward_chain()` method shown above returns `InferenceResult` objects, but the same `ExplanationGenerator` accepts results from any inference mode. The generator's `generate_explanation()` method handles all reasoning types uniformly through polymorphic dispatch.

### How does formal proof generation differ from standard inference?

**Standard inference** (`Reasoner.infer_facts()`) derives new facts efficiently. **Formal proof generation** (`DeductiveReasoner.prove_theorem()`) produces a `Proof` object with explicit logical validation you can verify independently. The `Proof.valid` boolean and step-by-step structure support mathematical rigor and regulatory compliance.

### What ranking strategies work with abductive reasoning?

The `AbductiveReasoner` accepts `ranking_strategy="simplicity"` for Occam's razor preference, `"plausibility"` for prior-weighted scoring, or custom strategies. This determines which hypothesis the generator explains when multiple explanations fit an observation.