Skip to main content
Glama

prolog-reasoner

PyPI version Python versions CI License: MIT

SWI-Prolog como una "calculadora lógica" para LLMs: disponible como servidor MCP y biblioteca de Python.

Los LLMs destacan en lenguaje natural pero tienen dificultades con la lógica formal. Prolog destaca en el razonamiento lógico pero no puede procesar lenguaje natural. prolog-reasoner cierra esta brecha exponiendo la ejecución de SWI-Prolog a los LLMs a través de dos superficies complementarias:

  • Servidor MCP: el LLM conectado (p. ej., Claude) escribe Prolog y lo ejecuta a través del servidor. No se necesita una clave de API de LLM en el lado del servidor.

  • Biblioteca de Python: una canalización completa de LN→Prolog con autocorrección, para programas que no tienen un LLM en el bucle. Requiere una clave de API de OpenAI o Anthropic.

Ambas superficies comparten el mismo ejecutor de Prolog; la biblioteca añade un traductor basado en LLM por encima.

Características

  • Herramienta MCP (execute_prolog): ejecuta código SWI-Prolog arbitrario con una consulta

  • Soporte CLP(FD): programación lógica de restricciones para programación y optimización

  • Negación por fallo, recursión, todas las características estándar de SWI-Prolog

  • Representación intermedia transparente: inspeccionar / modificar Prolog antes de la ejecución

  • Modo biblioteca: traducción de LN→Prolog con bucle de autocorrección (OpenAI / Anthropic)

Requisitos

  • Python ≥ 3.10

  • SWI-Prolog instalado y en el PATH (≥ 9.0)

  • Clave de API para OpenAI o Anthropic: solo para el modo biblioteca, no para el servidor MCP

Instalación

# MCP server only (no LLM dependencies)
pip install prolog-reasoner

# Library with OpenAI
pip install prolog-reasoner[openai]

# Library with Anthropic
pip install prolog-reasoner[anthropic]

# Both providers
pip install prolog-reasoner[all]

Configuración del servidor MCP

El servidor MCP expone una única herramienta, execute_prolog, que ejecuta código Prolog escrito por el LLM conectado. No llama a ninguna API de LLM externa, por lo que no se requiere ninguna clave de API.

Claude Desktop / Claude Code

{
  "mcpServers": {
    "prolog-reasoner": {
      "command": "uvx",
      "args": ["prolog-reasoner"]
    }
  }
}

O, si prolog-reasoner está instalado directamente:

{
  "mcpServers": {
    "prolog-reasoner": {
      "command": "prolog-reasoner"
    }
  }
}

Docker (SWI-Prolog incluido)

Utilice Docker si no desea instalar SWI-Prolog localmente:

docker build -f docker/Dockerfile -t prolog-reasoner .
{
  "mcpServers": {
    "prolog-reasoner": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "prolog-reasoner"]
    }
  }
}

Referencia de herramientas

execute_prolog(prolog_code, query, max_results=100)

  • prolog_code: hechos y reglas de Prolog (cadena)

  • query: consulta de Prolog a ejecutar, p. ej., "mortal(X)" (cadena)

  • max_results: limita el número de soluciones devueltas (predeterminado 100)

Devuelve un objeto JSON con success, output, query, error y metadata (tiempo de ejecución, recuento de resultados, indicador de truncamiento).

Uso de la biblioteca

La biblioteca expone PrologExecutor (solo Prolog, sin LLM) y PrologReasoner (canalización LN→Prolog, necesita una clave de API de LLM).

Ejecutar Prolog directamente (sin LLM)

import asyncio
from prolog_reasoner.config import Settings
from prolog_reasoner.executor import PrologExecutor

async def main():
    settings = Settings()  # no API key needed
    executor = PrologExecutor(settings)
    result = await executor.execute(
        prolog_code="human(socrates). mortal(X) :- human(X).",
        query="mortal(X)",
    )
    print(result.output)  # mortal(socrates)

asyncio.run(main())

Canalización completa LN→Prolog (requiere clave de API de LLM)

import asyncio
from prolog_reasoner import PrologReasoner, TranslationRequest, ExecutionRequest
from prolog_reasoner.config import Settings
from prolog_reasoner.executor import PrologExecutor
from prolog_reasoner.translator import PrologTranslator
from prolog_reasoner.llm_client import LLMClient

async def main():
    settings = Settings(llm_api_key="sk-...")  # from env or explicit
    llm = LLMClient(
        provider=settings.llm_provider,
        api_key=settings.llm_api_key,
        model=settings.llm_model,
        timeout_seconds=settings.llm_timeout_seconds,
    )
    reasoner = PrologReasoner(
        translator=PrologTranslator(llm, settings),
        executor=PrologExecutor(settings),
    )
    translation = await reasoner.translate(
        TranslationRequest(query="Socrates is human. All humans are mortal. Is Socrates mortal?")
    )
    print(translation.prolog_code)
    result = await reasoner.execute(
        ExecutionRequest(prolog_code=translation.prolog_code, query=translation.suggested_query)
    )
    print(result.output)

asyncio.run(main())

Configuración

Todos los ajustes a través de variables de entorno (prefijo PROLOG_REASONER_):

Variable

Predeterminado

Requerido para

LLM_PROVIDER

openai

biblioteca (openai o anthropic)

LLM_API_KEY

""

solo biblioteca: dejar sin configurar para MCP

LLM_MODEL

gpt-5.4-mini

biblioteca

LLM_TEMPERATURE

0.0

biblioteca

LLM_TIMEOUT_SECONDS

30.0

biblioteca

SWIPL_PATH

swipl

ambos

EXECUTION_TIMEOUT_SECONDS

10.0

ambos

LOG_LEVEL

INFO

ambos

Benchmark

benchmarks/ contiene 30 problemas lógicos en 5 categorías (deducción, transitiva, restricción, contradicción, paso múltiple) para comparar el razonamiento solo con LLM frente al razonamiento con LLM+Prolog. El benchmark ejercita la ruta de la biblioteca (traductor + ejecutor), ya que requiere el paso de LN→Prolog.

Resultados

Medido en anthropic/claude-sonnet-4-6, ejecución única sobre 30 problemas:

Canalización

Precisión

Latencia media

Solo LLM

22/30 (73.3%)

1.7s

LLM + Prolog

27/30 (90.0%)

3.8s

Desglose por categoría:

Categoría

Solo LLM

LLM + Prolog

deducción

6/6

6/6

transitiva

6/6

5/6

restricción

3/7

6/7

contradicción

4/4

3/4

paso múltiple

3/7

7/7

La brecha se concentra en restricción (SEND+MORE, 6-reinas, mochila, coloreado K4, Einstein-lite) y paso múltiple (teoría de juegos Nim, caballeros y bribones de 3 personas, TSP-4, rompecabezas de cebra): exactamente el territorio pesado en combinatoria/búsqueda donde los solucionadores simbólicos superan al completado de patrones. En preguntas puramente deductivas o transitivas, el LLM ya es fuerte y Prolog añade latencia sin ganancias de precisión.

Los 3 fallos de LLM+Prolog fueron errores de ejecución de Prolog por código mal formado generado por el LLM (definiciones de predicados faltantes, variables CLP(FD) no vinculadas) en lugar de errores de razonamiento, abordables mediante el ajuste de prompts.

Ejecutarlo usted mismo

docker run --rm -e PROLOG_REASONER_LLM_API_KEY=sk-... \
    prolog-reasoner-dev python benchmarks/run_benchmark.py

Los resultados se guardan en benchmarks/results.json.

Desarrollo

# Build dev image
docker build -f docker/Dockerfile -t prolog-reasoner-dev .

# Run tests (no API key needed — LLM calls are mocked)
docker run --rm prolog-reasoner-dev

# With coverage
docker run --rm prolog-reasoner-dev pytest tests/ -v --cov=prolog_reasoner

# Or via docker compose
docker compose -f docker/docker-compose.yml run --rm test

Licencia

MIT

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rikarazome/prolog-reasoner'

If you have feedback or need assistance with the MCP directory API, please join our Discord server