Skip to main content

wKrQ: A Python Implementation of a Semantic Tableau Calculus for Weak Kleene Logic with Restricted Quantification

PyPI version Python 3.9+ License: MIT Tests

An implementation of a semantic tableau calculus for first-order weak Kleene logic with restricted quantification, featuring a command-line interface for satisfiability and inference checking.

Citation

This implementation is based on the wKrQ tableau system defined in:

Ferguson, Thomas Macaulay. "Tableaux and restricted quantification for systems related to weak Kleene logic." In International Conference on Automated Reasoning with Analytic Tableaux and Related Methods, pp. 3-19. Cham: Springer International Publishing, 2021.

The tableau construction algorithms and six-sign system (t, f, e, m, n, v) implemented here follow Ferguson's formal definitions exactly. This is a research implementation created for experimental and educational purposes.

Research Software Disclaimer

⚠️ This is research software. While extensively tested, this implementation may contain errors or behave unexpectedly in edge cases. It is intended for research, education, and experimentation. Use in production systems is not recommended without thorough validation. Please report any issues or unexpected behavior through the issue tracker.

Features

  • 🎯 Three-valued semantics: true (t), false (f), undefined (e)
  • 🔤 Weak Kleene logic: Operations with undefined propagate undefinedness
  • 🔢 Restricted quantification: Domain-bounded first-order reasoning
  • 📋 Ferguson's six-sign system: t, f, e, m, n, v exactly as in the 2021 paper
  • 🔄 ACrQ extension: Analytic Containment for paraconsistent/paracomplete reasoning
  • ⚡ Industrial performance: Optimized tableau with sub-millisecond response
  • 🖥️ CLI and API: Both command-line and programmatic interfaces
  • 📚 Comprehensive docs: Full documentation with examples
  • 🔍 Construction tracing: Step-by-step proof visualization showing all rule applications

Quick Start

Installation

pip install wkrq

Command Line Usage

# Test a simple formula
wkrq "p & q"

# Test with specific sign (t, f, e, m, n)
wkrq --sign=n "p | ~p"

# Show all models
wkrq --models "p | q"

# Display tableau tree
wkrq --tree "p -> q"

# Show construction trace
wkrq --trace "p & ~p"

# First-order logic with restricted quantifiers
# Unicode syntax:
wkrq "[∃X Student(X)]Human(X)"
wkrq "[∀X Human(X)]Mortal(X)"

# ASCII syntax (easier to type):
wkrq "[exists X Student(X)]Human(X)"
wkrq "[forall X Human(X)]Mortal(X)"

# Inference checking (uses |- turnstile syntax)
wkrq "p & q |- p"
wkrq "[forall X Human(X)]Mortal(X), Human(socrates) |- Mortal(socrates)"

# ACrQ paraconsistent reasoning (handles contradictions gracefully)
wkrq --mode=acrq "Human(alice) & ~Human(alice)"  # Satisfiable with glut!

# Interactive theory manager with LLM integration for ACrQ
acrq-llm  # Start interactive session
acrq-llm --file examples/example_13_maier_et_al.json  # Load existing theory

Python API

from wkrq import Formula, solve, valid, t, f, e, m, n

# Create formulas
p, q = Formula.atoms('p', 'q')
formula = p & (q | ~p)

# Test satisfiability
result = solve(formula, t)
print(f"Satisfiable: {result.satisfiable}")
print(f"Models: {result.models}")

# Test validity - Ferguson uses classical validity with weak Kleene
# semantics
tautology = p | ~p
print(f"Valid in Ferguson's system: {valid(tautology)}")  # True (classical
                                                         # tautologies are valid)

# Three-valued reasoning
result = solve(p | ~p, e)  # Can it be undefined?
print(f"Can be undefined: {result.satisfiable}")  # True

# ACrQ paraconsistent reasoning
from wkrq import parse_acrq_formula, SyntaxMode

# Handle contradictions gracefully (no explosion)
contradiction = parse_acrq_formula("Human(alice) & ~Human(alice)")
result = solve(contradiction, t)
print(f"Contradiction satisfiable: {result.satisfiable}")  # True (glut allowed)

# Different syntax modes for ACrQ
transparent = parse_acrq_formula("~Human(alice)", SyntaxMode.TRANSPARENT)  # Standard syntax
bilateral = parse_acrq_formula("Human*(alice)", SyntaxMode.BILATERAL)      # Explicit bilateral

# LLM Integration (requires pip install wkrq[llm])
from wkrq import create_openai_evaluator, ACrQTableau

# One line to create LLM evaluator!
evaluator = create_openai_evaluator(model='gpt-4')

# Use with tableau - LLM provides real-world knowledge
tableau = ACrQTableau(
    [SignedFormula(t, parse_acrq_formula("Planet(pluto)"))],
    llm_evaluator=evaluator
)
result = tableau.construct()  # LLM knows Pluto isn't a planet anymore

Theory Manager

The interactive theory manager provides a powerful environment for building and reasoning with logical theories:

# Start the ACrQ theory manager with LLM support
acrq-llm

# In the interactive session:
theory> assert Socrates is human
theory> assert All humans are mortal
theory> infer
# Infers: Mortal(socrates)

theory> claim firstManOnTheMoon(armstrong)  # LLM verifies: TRUE
theory> claim firstManOnTheMoon(scott)      # LLM refutes: FALSE

theory> check  # Check satisfiability and detect gluts/gaps
theory> save my_theory.json

Key features:

  • Natural language assertions with automatic translation
  • LLM-verified factual claims with the claim command
  • Paraconsistent reasoning (handles contradictions without explosion)
  • Gap and glut detection for information analysis
  • Persistent storage in JSON format
  • Integration with LLM providers for fact-checking

See the Theory Manager Tutorial for detailed usage.

Syntax and Semantics

Formal Language Definition

The language of wKrQ is defined by the following BNF grammar:

⟨formula⟩ ::= ⟨atom⟩ | ⟨compound⟩ | ⟨quantified⟩

⟨atom⟩ ::= p | q | r | ... | ⟨predicate⟩

⟨predicate⟩ ::= P(⟨term⟩,...,⟨term⟩)

⟨term⟩ ::= ⟨variable⟩ | ⟨constant⟩

⟨variable⟩ ::= X | Y | Z | ...

⟨constant⟩ ::= a | b | c | ...

⟨compound⟩ ::= ¬⟨formula⟩ | (⟨formula⟩ ∧ ⟨formula⟩) | 
               (⟨formula⟩ ∨ ⟨formula⟩) | (⟨formula⟩ → ⟨formula⟩)

⟨quantified⟩ ::= [∃⟨variable⟩ ⟨formula⟩]⟨formula⟩ | 
                 [∀⟨variable⟩ ⟨formula⟩]⟨formula⟩

Truth Tables

wKrQ implements weak Kleene three-valued logic with truth values:

  • t (true)
  • f (false)
  • e (undefined/error)

Negation (¬)

p ¬p
t f
f t
e e

Conjunction (∧)

p \ q t f e
t t f e
f f f e
e e e e

Disjunction (∨)

p \ q t f e
t t t e
f t f e
e e e e

Material Implication (→)

p \ q t f e
t t f e
f t t e
e e e e

Quantifier Semantics

Restricted Existential Quantification: [∃X φ(X)]ψ(X)

The formula is true iff there exists a domain element d such that both φ(d) and ψ(d) are true. It is false iff for all domain elements d, either φ(d) is false or ψ(d) is false (but not undefined). It is undefined if any evaluation results in undefined.

Restricted Universal Quantification: [∀X φ(X)]ψ(X)

The formula is true iff for all domain elements d, either φ(d) is false or ψ(d) is true. It is false iff there exists a domain element d such that φ(d) is true and ψ(d) is false. It is undefined if any evaluation results in undefined.

The key principle of weak Kleene logic is that any operation involving an undefined value produces an undefined result. This differs from strong Kleene logic where, for example, t ∨ e = t.

ACrQ: Analytic Containment with restricted Quantification

ACrQ extends wKrQ with bilateral predicates for paraconsistent and paracomplete reasoning:

Key Features

  • Paraconsistent: Handle contradictory information without explosion
  • Paracomplete: Handle incomplete information without classical assumptions
  • Bilateral predicates: Each predicate R has a dual R* for independent positive/negative tracking
  • Information states: Distinguishes true, false, gaps (missing info), and gluts (conflicting info)

Usage Modes

from wkrq import parse_acrq_formula, SyntaxMode

# Transparent mode (default): Standard syntax, automatic translation
formula1 = parse_acrq_formula("Human(alice) & ~Human(alice)")  # Handles gluts

# Bilateral mode: Explicit R/R* syntax required
formula2 = parse_acrq_formula("Human(alice) & Human*(alice)", SyntaxMode.BILATERAL)

# Mixed mode: Both syntaxes allowed
formula3 = parse_acrq_formula("Human(alice) & Robot*(bob)", SyntaxMode.MIXED)

Information States

State R(a) R*(a) Meaning
True t f Positive evidence only
False f t Negative evidence only
Gap f f No evidence (incomplete)
Glut t t Conflicting evidence (paraconsistent)

LLM Integration (ACrQ)

The ACrQ system seamlessly integrates with Large Language Models through the bilateral-truth package. This integration is specific to ACrQ because it leverages bilateral predicates to handle LLM uncertainty and conflicting information:

# Install with LLM support
pip install wkrq[llm]
from wkrq import create_openai_evaluator, ACrQTableau, parse_acrq_formula, SignedFormula, t

# One line to connect to your LLM
evaluator = create_openai_evaluator(model='gpt-4')  # Or use anthropic, google, local

# Combine formal logic with LLM knowledge
formulas = [
    SignedFormula(t, parse_acrq_formula("[∀X Orbits(X, sun)]Planet(X)")),  # Formal rule
    SignedFormula(t, parse_acrq_formula("Orbits(pluto, sun)")),            # Fact
]

tableau = ACrQTableau(formulas, llm_evaluator=evaluator)
result = tableau.construct()
# LLM knows modern astronomy: Pluto isn't a planet → contradiction detected

The bilateral-truth package handles all the complexity:

  • API connections and authentication
  • Prompt engineering for factuality assessment
  • Response parsing and error handling
  • Caching to minimize API calls

Supported providers: OpenAI, Anthropic, Google, local models (Ollama), and more.

Documentation

Core Documentation

Ferguson Compliance

ACrQ and LLM Integration

Examples

Philosophical Logic: Sorites Paradox

from wkrq import Formula, solve, T, N

# Model vague predicates with three-valued logic
heap_1000 = Formula.atom("Heap1000")  # Clearly a heap
heap_999 = Formula.atom("Heap999")    # Borderline case
heap_1 = Formula.atom("Heap1")        # Clearly not a heap

# Sorites principle
sorites = heap_1000.implies(heap_999)

# The paradox dissolves with undefined values
result = solve(heap_999, N)  # Can be undefined
print(f"Borderline case can be undefined: {result.satisfiable}")

First-Order Reasoning

from wkrq import Formula

# Variables and predicates
x = Formula.variable("X")
human = Formula.predicate("Human", [x])
mortal = Formula.predicate("Mortal", [x])

# Restricted quantification
all_humans_mortal = Formula.restricted_forall(x, human, mortal)
print(f"∀-formula: {all_humans_mortal}")  # [∀X Human(X)]Mortal(X)

Development

# Clone repository
git clone https://github.com/bradleypallen/wkrq.git
cd wkrq

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src tests
ruff check src tests

# Type checking
mypy src

Implementation Approach

The wKrQ package implements a semantic tableau calculus for three-valued weak Kleene logic with restricted quantification. The tableau engine (tableau.py) uses a six-sign system (t, f, e, m, n, v) following Ferguson (2021), where t and f represent definite truth values, e represents error/undefined, m represents epistemic uncertainty (both true and false are possible), n represents nontrue (false or undefined), and v is a meta-sign used in rule notation. The core algorithm maintains branches as collections of signed formulas, with hash-based indexing by sign and formula for O(1) contradiction detection. The system applies tableau rules in priority order: alpha-rules (non-branching) before beta-rules (branching), with explicit priority values assigned to each rule type. For quantifier instantiation, the engine tracks ground terms per branch and attempts unification with existing constants before generating fresh ones. Universal quantifiers are re-instantiated with new constants as they appear, with the system tracking which constants have been used for each quantified formula to prevent redundant applications. The implementation supports extension to ACrQ through polymorphic branch creation, where bilateral predicates R and R* are processed independently—t:R(a) generates only t:R(a) rather than also concluding f:R*(a), enabling paraconsistent reasoning where contradictory information (t:R(a) ∧ t:R*(a)) remains satisfiable. Model extraction from open branches assigns truth values based on the signs present: t-signed atoms map to true, f-signed to false, e-signed to undefined, with m-signed atoms arbitrarily assigned (true or false) to maintain completeness.

The ACrQ implementation extends wKrQ's tableau calculus to handle bilateral predicates for paraconsistent reasoning. Each predicate R has an associated dual predicate R*, with the system maintaining bidirectional mappings between them. The ACrQTableau class overrides the base tableau's branch creation to use ACrQBranch instances that track bilateral predicate pairs. During formula processing, negated predicates in transparent syntax mode are automatically converted: ¬R(x) becomes R*(x). The tableau rules for bilateral predicates differ fundamentally from standard predicates: t:R(x) produces only t:R(x) as a conclusion, while t:R*(x) produces only t:R*(x), without generating complementary constraints. Similarly, f:R(x) yields only f:R(x), and f:R*(x) yields only f:R*(x). The m-sign rules branch on individual predicates (m:R(x) branches to t:R(x) or f:R(x)), while n-sign rules generate knowledge gaps (n:R(x) produces f:R(x) and f:R*(x)). This design permits gluts where both R(a) and R*(a) hold true simultaneously—the _check_contradiction method in ACrQBranch explicitly allows t:R(a) and t:R*(a) to coexist without closing the branch. Model extraction constructs ACrQModel instances containing bilateral valuations: for each predicate-argument combination, the model tracks both positive and negative truth values as a BilateralTruthValue object. The semantic evaluator (ACrQEvaluator) retrieves the appropriate component based on whether the formula references R (positive component) or R* (negative component), maintaining weak Kleene semantics where any operation involving undefined values produces undefined results.

Note: Our implementation is validated against Ferguson (2021) and uses classical validity with weak Kleene semantics, meaning classical tautologies remain valid. The implementation has been thoroughly tested against literature examples - see the validation examples for comprehensive test results.

Citation

If you use wKrQ in academic work, please cite:

@software{wkrq2025,
  title={wKrQ: A Python Implementation of a Semantic Tableau Calculus for
         Weak Kleene Logic with Restricted Quantification},
  author={Allen, Bradley P.},
  year={2025},
  version={1.2.0},
  url={https://github.com/bradleypallen/wkrq}
}

License

MIT License - see LICENSE file for details.

Links

Metadata

Release files for wkrq 3.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wkrq 3.3.2
File Size Uploaded
wkrq-3.3.2.tar.gz 342.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wkrq 3.3.2
File Interpreter ABI Platform
wkrq-3.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 418.1 kB

Release files / wkrq-3.3.2.tar.gz

Download URL wkrq-3.3.2.tar.gz
Size 342.7 kB
Tags Source
SHA-256 checksum
How to use checksums
34c9554ffd8662faf6dc67e5e8290f80fd100901fa879fc84beae28b5acf8509
BLAKE2b-256 checksum
How to use checksums
4dc7095735a05f3df57c7099c442dc747125f874bf2ef9040e7521a0053b6252
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.13

Release files / wkrq-3.3.2-py3-none-any.whl

Download URL wkrq-3.3.2-py3-none-any.whl
Size 75.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e769b04adbd54a4f2072c024f82874e774e34233f5b631dbbee2451eb3d7bb62
BLAKE2b-256 checksum
How to use checksums
873755408e2d7e7713c393b6d03e4cfba32ca00cbc0ee41ae24cedb59b06c0e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.13

Release history Release notifications | RSS feed

This release

3.3.2 This release

2 release files

3.3.1

2 release files

3.3.0

2 release files

3.2.1

2 release files

3.2.0

2 release files

3.1.2

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page