LogosLab is a powerful logical reasoning framework designed for automated deduction, symbolic logic evaluation, and knowledge base inference. It implements a complete reasoning engine with three-valued logic (TRUE, FALSE, UNKNOWN), multiple inference rules, and an extensible architecture for building intelligent systems.
- Tripartite Logic: Support for TRUE, FALSE, and UNKNOWN truth values with proper semantics
- Advanced Inference Engine:
- Modus Ponens: P -> Q, P therefore Q
- Modus Tollens: P -> Q, !Q therefore !P
- Hypothetical Syllogism: P -> Q, Q -> R therefore P -> R
- Disjunctive Syllogism: P || Q, !P therefore Q
- Resolution: P || Q, !P || R therefore Q || R
- Expression Evaluation: Full support for complex logical expressions with parentheses
- Inference Tracing: Track how conclusions were derived with complete provenance information
- Extensible Parser: Plugin-style relation handlers for custom knowledge representation
- AND (
&&,and): Logical conjunction - OR (
||,or): Logical disjunction - NOT (
!,~,not): Logical negation - IMPLIES (
->,implies): Material implication - EQUIVALENT (
<->,==,iff): Biconditional
Advanced filtering and sorting options for query results:
- Filter by truth value (true/false/unknown)
- Filter by derivation (axioms vs derived propositions)
- Pattern matching (prefix, contains)
- Sort by name, truth value, or derivation
- Limit results and show inference traces
Evaluates complex logical expressions using the Shunting-Yard algorithm:
- Handles operator precedence and associativity
- Supports parentheses for grouping
- Token-based expression building
- Efficient postfix evaluation
Models logical propositions with rich metadata:
- Three-valued logic support
- Inference provenance tracking
- Conflict detection (when values are overwritten)
- Quantifier support (universal/particular, affirmative/negative)
Tokenizes input with detailed error reporting:
- Multi-character operator support
- Identifier parsing with hyphens (e.g.,
big-bang) - Line/column tracking for error messages
- Configurable keyword handling
Parses knowledge base files with extensible handlers:
- Built-in relations:
implies,some,not,discovered - Custom relation registration via
RelationHandlerAPI - Expression parsing from strings
- Supports both assumptions and facts files
Applies inference rules until fixed-point:
- Forward and backward chaining
- Handles complex inference chains
- Safe proposition lookup (no crashes on missing data)
- Optimized iteration to prevent redundant work
High-level facade for the reasoning system:
- Load assumptions and facts from files
- Run inference to deduce new knowledge
- Query and filter results
- Format and export reasoning traces
Comprehensive test suite in tests/:
testExpression.cpp: Expression evaluation and operator precedencetestExpressionProperties.cpp: Property-based expression teststestLexer.cpp: Tokenization and error handlingtestProposition.cpp: Proposition logic and operationstestRatiocinator.cpp: End-to-end reasoning scenarios
CMake-based build with multiple presets:
dev-debug: Development build with debug symbolsdev-release: Optimized development buildasan: AddressSanitizer (memory errors)tsan: ThreadSanitizer (race conditions)ubsan: UndefinedBehaviorSanitizermsan: MemorySanitizer (uninitialized reads)clang-tidy: Static analysiscppcheck: Additional static analysisci-release: CI/CD release buildbench-release: Performance benchmarking
- C++ Compiler: C++17 or later (GCC 8+, Clang 7+, MSVC 2019+)
- CMake: Version 3.15 or later
git clone https://github.com/milanfusco/LogosLab.git
cd LogosLab
cmake --preset dev-debug
cmake --build --preset dev-debug# List available presets
cmake --list-presets
# Configure with a specific preset
cmake --preset dev-release
# Build
cmake --build --preset dev-release
# Run tests
ctest --preset dev-releasemkdir build
cd build
cmake ..
make# Run with assumptions and facts files
./build/dev-debug/main assumptions_file.txt facts_file.txt
# Or use the demo files
./build/dev-debug/main demo_assumptions.txt demo_facts.txt# Show only TRUE propositions with traces
./main --true-only --traces assumptions.txt facts.txt
# Filter by prefix and limit results
./main --prefix=user_ --limit=10 assumptions.txt facts.txt
# Show derived propositions sorted alphabetically
./main --derived-only --sort=alpha assumptions.txt facts.txt
# Multiple filters
./main --known-only --prefix=big --verbose assumptions.txt facts.txtAvailable options:
--traces: Include inference traces in output--true-only,--false-only,--unknown-only: Filter by truth value--known-only: Show only TRUE and FALSE (exclude UNKNOWN)--derived-only: Show only inferred propositions--axioms-only: Show only direct assertions--prefix=PREFIX: Filter by name prefix--contains=STR: Filter by substring in name--limit=N: Limit number of results--sort=ORDER: Sort byalpha,alpha-desc,truth, orderivation--verbose: Print results to console--help: Show help message
Define logical relations and implications:
n, implies(big-bang, occurred, microwave-radiation, present)
s, some(gravity, exists)
r, not(perpetual-motion)
d, discovered(cosmic-background, radiation)
Assert truth values and logical expressions:
# Simple assertions
big-bang
!perpetual-motion
# Compound expressions with assignment
t = p && n
result = (a || b) && !c
# Expressions without assignment
p && q
!r || s
ctest --preset dev-debug./build/dev-debug/testExpression
./build/dev-debug/testProposition
./build/dev-debug/testRatiocinator
./build/dev-debug/testLexer# Memory error detection
cmake --preset asan
cmake --build --preset asan
ctest --preset asan
# Thread safety
cmake --preset tsan
cmake --build --preset tsan
ctest --preset tsancmake --preset bench-release
cmake --build --preset bench-release
./build/bench-release/benchmarkInferenceResults are saved to benchmarks/results/ with system information.
assumptions.txt:
i1, implies(rain, falls, ground, wet)
facts.txt:
rain
Result: The system infers ground = TRUE via Modus Ponens.
assumptions.txt:
i1, implies(A, true, B, true)
i2, implies(B, true, C, true)
facts.txt:
A
Result: The system infers B = TRUE (via Modus Ponens) and C = TRUE (via Hypothetical Syllogism).
facts.txt:
result = p || q
!p
Result: The system infers q = TRUE via Disjunctive Syllogism.
#include "Ratiocinator.h"
int main() {
Ratiocinator engine;
// Load knowledge base
engine.loadAssumptions("assumptions.txt");
engine.loadFacts("facts.txt");
// Run inference
engine.deduce();
// Query results with filtering
ResultFilter filter = ResultFilter::trueOnly()
.withPrefix("user_")
.withLimit(10)
.withTraces(true);
std::string results = engine.formatResults(filter);
std::cout << results;
// Trace specific proposition
if (engine.hasInferenceProvenance("conclusion")) {
std::cout << engine.formatTrace("conclusion");
}
return 0;
}- Separation of Concerns: Lexer, Parser, and Inference Engine are independent
- Extensibility: Plugin-style relation handlers and custom filters
- Safety: Null-safe lookups, no iterator invalidation, comprehensive error handling
- Performance: Fixed-point iteration, lazy evaluation, optimized data structures
- Observability: Complete provenance tracking and inference traces
- Parse: Load assumptions (structure) and facts (truth values)
- Evaluate: Calculate truth values of compound expressions
- Infer: Apply inference rules until no more deductions can be made
- Report: Format results with optional filtering and tracing
Contributions are welcome! Please ensure:
- Code follows existing style conventions
- All tests pass (
ctest) - New features include test coverage
- Documentation is updated (comments + README)