Author's bio: ππ Hi, I'm CryptoPatrick! I'm currently enrolled as an
Undergraduate student in Mathematics, at Chalmers & the University of Gothenburg, Sweden.
If you have any questions or need more info, then please join my Discord Channel: AiMath
What is Foras β’ Features β’ How To Use β’ Examples β’ Documentation β’ License
- Logic System: Implements first-order logic (FOL) with automated reasoning capabilities
- Inference Engine: Uses resolution and unification for theorem proving
- Inspired by: Prover9, Vampire, E Prover, Z3, and the TPTP library
Table of Contents
foras (First-Order ReASoner) is a Rust library implementing a first-order reasoner, which automatically draws logical conclusions from statements expressed in first-order logic (FOL). It provides automated theorem proving capabilities, enabling you to build knowledge bases, submit queries, and derive logical conclusions automatically.
Built for reliability and performance in Rust, Foras enables:
- Building knowledge bases from logical formulas (axioms, facts, and rules)
- Submitting queries to check logical entailment
- Using inference rules (resolution, unification) to generate proofs or find counterexamples
- Automated theorem proving for AI, verification, and logical computing tasks
- Automated Theorem Proving: Verify mathematical theorems and logical propositions
- AI Knowledge Representation: Build intelligent systems with formal reasoning capabilities
- Program Verification: Prove properties about programs and systems
- Ontology Reasoning: Semantic web and knowledge graph reasoning
- Model Checking: Verify system properties and specifications
First-order logic (FOL) extends propositional logic by introducing:
- Predicates: Properties or relations about objects (e.g.,
Loves(Alice, Bob)) - Variables: Placeholders for objects (e.g.,
x,y) - Quantifiers: For expressing generality or existence:
- Universal quantifier: βx ("for all x")
- Existential quantifier: βx ("there exists an x")
Example:
βx (Human(x) β Mortal(x))
Human(Socrates)
βΉ Mortal(Socrates)
Foras can automatically derive Mortal(Socrates) from these premises using formal inference rules.
foras provides a complete first-order logic reasoning engine with automated theorem proving:
- Knowledge Base Management: Build and maintain sets of logical formulas
- Query Resolution: Check if queries logically follow from the knowledge base
- Automated Inference: Apply resolution and unification automatically
- Proof Generation: Produce formal proofs for entailed queries
- Resolution-Based Inference: Core inference engine using resolution
- Unification Algorithm: Pattern matching for logical terms
- Skolemization: Handle existential quantifiers systematically
- Clause Normal Form: Automatic conversion to CNF for reasoning
- Theorem Proving: Verify mathematical and logical propositions
- Knowledge Representation: Formal representation of domain knowledge
- Program Verification: Prove correctness properties
- Semantic Reasoning: Ontology and knowledge graph inference
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Application (CLI/Library) β
β reasoner.add() / reasoner.entails() β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
β Reasoner Component β
β β’ Parse formulas from string/AST β
β β’ Convert to Clause Normal Form (CNF) β
β β’ Apply Skolemization for β quantifiers β
β β’ Store in knowledge base β
β β’ Run resolution algorithm for queries β
β β’ Generate proofs or countermodels β
ββββββββββββββββ¬βββββββββββββββββββββββββββ¬βββββββββββββββββ
β β
βββββββββΌβββββββββ ββββββββββΌββββββββββ
β Parser/AST β β Inference Engineβ
β β’ Formula β β β’ Resolution β
β β’ Term β β β’ Unification β
β β’ Predicate β β β’ Subsumption β
ββββββββββββββββββ ββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β reasoner.entails("Mortal(Socrates)") β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
ββββββββββΌβββββββββ
β 1. Parse β
β Query β
ββββββββββββββββββββ
β
β Formula AST
βΌ
ββββββββββββββββββββββ
β 2. Negate β
β Query β
βββββββββββ¬βββββββββββ
β
β Β¬Mortal(Socrates)
βΌ
ββββββββββββββββββββββ
β 3. Convert β
β KB + Β¬Query β
β to CNF β
βββββββββββ¬βββββββββββ
β
β Clause set
βΌ
ββββββββββββββββββββββ
β 4. Resolution β
β Loop β
β β’ Unify β
β β’ Resolve β
β β’ Check β₯ β
βββββββββββ¬βββββββββββ
β
β Empty clause found?
βΌ
ββββββββββββββββββββββ
β 5. Return β
β β’ true (proved) β
β β’ false + model β
ββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Knowledge Base β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Formula Store β β
β β β’ Universal formulas: βx P(x) β β
β β β’ Existential formulas: βy Q(y) β β
β β β’ Ground facts: Human(Socrates) β β
β β β’ Rules: P(x) β Q(x) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ β
β β CNF Conversion Layer β β
β β β’ Eliminate implications β β
β β β’ Move negations inward β β
β β β’ Skolemize existentials β β
β β β’ Distribute disjunctions β β
β ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ β
β β Clause Database β β
β β β’ Set of clauses (disjunctions of literals) β β
β β β’ Indexed for efficient unification β β
β β β’ Subsumption checking β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Add foras to your Cargo.toml:
[dependencies]
foras = "0.1"Or install with cargo:
cargo add forasuse foras::{Formula, Reasoner};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut reasoner = Reasoner::new();
// Add premises
reasoner.add(Formula::parse("βx (Human(x) β Mortal(x))").unwrap());
reasoner.add(Formula::parse("Human(Socrates)").unwrap());
// Query
let query = Formula::parse("Mortal(Socrates)").unwrap();
if reasoner.entails(&query) {
println!("Query is entailed!");
println!("Proof: {:?}", reasoner.get_proof());
}
Ok(())
}use foras::{Formula, Reasoner, Term, Predicate};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut reasoner = Reasoner::new();
// Build knowledge base programmatically
reasoner.add_axiom("transitivity",
"βx βy βz ((Ancestor(x, y) β§ Ancestor(y, z)) β Ancestor(x, z))"
)?;
reasoner.add_fact("Parent(Alice, Bob)")?;
reasoner.add_fact("Parent(Bob, Charlie)")?;
reasoner.add_rule("βx βy (Parent(x, y) β Ancestor(x, y))")?;
// Query with variables
let query = Formula::parse("βz Ancestor(Alice, z)").unwrap();
if let Some(bindings) = reasoner.solve(&query) {
println!("Found solutions: {:?}", bindings);
}
// Get proof trace
if reasoner.entails(&query) {
let proof = reasoner.get_proof_trace();
for step in proof.steps {
println!("{}: {} by {}", step.index, step.clause, step.rule);
}
}
Ok(())
}The repository includes several examples demonstrating different features:
# Basic first-order logic reasoning
cargo run --example basic
# Propositional logic with resolution
cargo run --example propositional_logic_answer
# Group theory commutator properties
cargo run --example group_theory_commutator
# Pigeonhole principle proof
cargo run --example pigeonhole_principle
# Robbins algebra verification
cargo run --example robbins_algebra
# Classic zebra puzzle solver
cargo run --example zebra_puzzleRun the test suite:
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run smoke tests
cargo test --test smoke_tests
# Run specific test
cargo test test_nameComprehensive documentation is available at docs.rs/foras, including:
- API reference for all public types and functions
- Tutorial on building knowledge bases and querying
- Examples of theorem proving and automated reasoning
- Best practices for formula representation
- Guide to the resolution algorithm and unification
The name Foras comes from the demon president of Hell, who teaches logic and ethics to his twenty-nine legions according to demonology. The name is fitting for a tool that mechanically applies logical rules.
Learn more:
Keybase Verification: https://keybase.io/cryptopatrick/sigs/8epNh5h2FtIX1UNNmf8YQ-k33M8J-Md4LnAN
Leave a β if you think this project is cool.
This project is licensed under MIT. See LICENSE for details.
This project is based on the Otter project. For questions regarding Otter and its license, please read: https://www.mcs.anl.gov/research/projects/AR/otter/legal.html