Skip to main content

DreamLog: Logic Programming That Dreams to Improve Itself

DreamLog is a logic programming system that learns by alternating between wake and sleep phases. During wake, it uses LLMs to generate missing knowledge. During sleep, it compresses what it knows into more general principles. Like biological brains, roughly.

Compression is learning

The theoretical basis comes from algorithmic information theory: the system that explains your data with the shortest program is the one most likely to generalize. This is Solomonoff induction, the mathematical formalization of Occam’s razor.

For logic programming, the sleep phase searches for minimal representations that preserve deductive closure:

minimize KB subject to Closure(KB)=Closure(KB) \text{minimize } |KB'| \text{ subject to } \text{Closure}(KB') = \text{Closure}(KB)

Find the shortest knowledge base that still derives all the same facts.

Wake phase: generate knowledge

During wake, DreamLog operates as a logic programming engine with LLM-based knowledge generation:

from dreamlog.pythonic import dreamlog

kb = dreamlog(llm_provider="openai")

# Add some facts
kb.fact("parent", "john", "mary")
kb.fact("parent", "mary", "alice")

# Add a rule
kb.rule("grandparent", ["X", "Z"]) \
  .when("parent", ["X", "Y"]) \
  .and_("parent", ["Y", "Z"])

# Query
for result in kb.query("grandparent", "X", "alice"):
    print(f"{result.bindings['X']} is Alice's grandparent")  # john

The interesting part is what happens with undefined predicates:

# Query a predicate we never defined
for result in kb.query("sibling", "X", "Y"):
    # LLM generates knowledge about siblings on-the-fly
    print(result)

When the evaluator encounters an undefined predicate, it triggers the LLM hook to generate both facts and rules. The system infers primitive properties (like gender from names) and derives rules compositionally.

Sleep phase: compress knowledge

During sleep, DreamLog reorganizes through compression operators:

from dreamlog.kb_dreamer import KnowledgeBaseDreamer

dreamer = KnowledgeBaseDreamer(kb.provider)

session = dreamer.dream(
    kb,
    dream_cycles=3,            # Multiple REM cycles
    exploration_samples=10,     # Try different optimizations
    verify=True                # Ensure behavior preservation
)

print(f"Compression: {session.compression_ratio:.1%}")
print(f"Generalization: {session.generalization_score:.2f}")

The compression operators:

  • Anti-unification: find general patterns from specific instances
  • Predicate invention: discover intermediate concepts that simplify rules
  • Subsumption elimination: remove specific rules subsumed by general ones

This is where the real learning happens. The wake phase accumulates facts and rules. The sleep phase finds the structure in them.

KB-aware RAG

A key design choice: the retrieval-augmented generation is knowledge-base-aware. The system uses weighted embeddings combining query similarity (70%) with knowledge base context (30%), so example selection considers both the query structure and current reasoning state.

A success-based learning mechanism tracks which examples lead to successful inference, progressively improving retrieval quality through experience.

Validation

Generated rules and facts undergo:

  1. Structural validation: syntax, variable safety
  2. Semantic validation: preventing circular rules while allowing undefined predicates
  3. LLM-as-judge verification: fact-checking consistency with common-sense knowledge

Error-tolerant parsing handles common LLM formatting errors with correction-based retry.

Interactive TUI

python -m dreamlog.tui

Commands:

  • fact parent john mary to add facts
  • rule grandparent X Z :- parent X Y, parent Y Z to add rules
  • query grandparent X alice to run queries
  • dream 3 to run sleep cycles
  • show to display the knowledge base

The idea

Intelligence emerges from the interplay of exploration and exploitation. Wake accumulates. Sleep consolidates. The cycle repeats:

  1. Consolidation: strengthen important patterns
  2. Abstraction: find general principles
  3. Compression: achieve more with less
  4. Creativity: explore novel reorganizations

This isn’t logic programming with LLMs bolted on. It’s a system where knowledge representation evolves through use.

Getting started

pip install dreamlog
from dreamlog.pythonic import dreamlog

kb = dreamlog(llm_provider="ollama")

kb.parse("""
(parent john mary)
(parent mary alice)
(grandparent X Z) :- (parent X Y), (parent Y Z)
""")

for result in kb.query("grandparent", "john", "X"):
    print(result.bindings['X'])  # alice

Discussion