# TorchVeritas ⚖️
**Differentiable Logic for Inference-Time Latent Correction**

[![PyPI version](https://img.shields.io/pypi/v/torchveritas.svg)](https://pypi.org/project/torchveritas/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)

> **"Stop trying to prompt-engineer your model not to lie. Constrain it mathematically."**

## 💡 What is TorchVeritas?

**TorchVeritas** is a lightweight yet powerful PyTorch library that enforces logical consistency *inside* a neural network's hidden layers during inference.

Unlike standard "guardrails" that filter output *after* it is generated (which is slow and wasteful), TorchVeritas uses **Test-Time Optimization (TTO)** to apply "Logical Hooks." These hooks actively steer latent vectors toward a truthful manifold *before* the model makes a final decision.

### Why does this exist?
* **For Autonomous Agents:** Prevent an agent from executing a "delete" command if specific safety flags are not present.
* **For Fintech/Compliance:** Ensure outputs strictly adhere to non-negotiable rules (e.g., "If Credit_Score < 600, Interest_Rate MUST be 0%").
* **For Reliability:** Move from "Probabilistic Safety" (it might work) to "Deterministic Safety" (it must work).

---

## 📦 Installation

```bash
pip install torchveritas

```

---

## ⚡ Quick Start

Here is how to turn a standard "hallucinating" model into a logically consistent one in 4 lines of code.

```python
import torch
import torch.nn as nn
from torchveritas import attach_veritas, Logic

# 1. Your existing model (Standard PyTorch)
model = nn.Sequential(
    nn.Linear(10, 10), 
    nn.ReLU(), 
    nn.Linear(10, 2) # Output: [Neuron A, Neuron B]
)

# 2. Define a Logical Rule
# Rule: "Neuron A and Neuron B cannot BOTH be active at the same time."
# (e.g., A="Turn Left", B="Turn Right")
rule = Logic.exclusion(idx_a=0, idx_b=1)

# 3. Attach the Safety Layer
# This injects the optimization loop into the '2' layer (the final Linear layer)
attach_veritas(model, layer_name='2', constraint_fn=rule)

# 4. Run Inference
# The library automatically pauses execution, corrects any logic violations 
# in the latent vector, and resumes.
input_data = torch.randn(1, 10)
output = model(input_data)

print("Safe Output:", output)

```

---

## 🔧 How It Works

When you attach `TorchVeritas` to a layer, it registers a **Forward Hook**.

1. **Intercept:** As the data flows through the network, the hook captures the latent tensor.
2. **Check:** It evaluates your `constraint_fn`. If the "Violation Energy" is 0, it does nothing.
3. **Optimize:** If there is a violation, it runs a micro-optimization loop (using SGD) on the latent tensor itself to minimize the violation energy.
4. **Release:** The corrected tensor is passed to the next layer.

This happens in milliseconds and ensures the downstream layers never see "illegal" thoughts.

---

## 🛠 Advanced Usage: Custom Logic

You are not limited to pre-built logic. You can define complex, domain-specific laws using standard PyTorch operations.

```python
def strict_banking_law(latents):
    """
    Custom Law: If 'Loan_Status' (index 0) is < 0.5 (Rejected),
    then 'Interest_Rate' (index 1) must be exactly 0.0.
    """
    loan_status = torch.sigmoid(latents[:, 0])
    interest_rate = latents[:, 1]
    
    # Violation = (1 - Loan_Status) * Interest_Rate
    # This value is high only if Loan is Rejected AND Rate is high.
    violation = (1.0 - loan_status) * interest_rate
    
    return violation.mean()

# Attach with custom tuning parameters
attach_veritas(
    model, 
    layer_name='output_layer', 
    constraint_fn=strict_banking_law,
    steps=20,       # More steps for harder constraints
    lr=0.1,         # Learning rate for the correction
    verbose=True    # Print when corrections happen
)

```

---

## 🤝 Contributing

We welcome contributions! Whether it's adding new Logic primitives (like `Logic.xor` or `Logic.implies`) or optimizing the steering engine, please submit a Pull Request.

## 📄 License

MIT License. Free for research and commercial use.
