pub enum Formula {
Top,
Bottom,
Atom {
predicate: Pred,
terms: Vec<Term>,
},
Equals {
left: Term,
right: Term,
},
Not {
formula: Box<Formula>,
},
And {
left: Box<Formula>,
right: Box<Formula>,
},
Or {
left: Box<Formula>,
right: Box<Formula>,
},
Implies {
left: Box<Formula>,
right: Box<Formula>,
},
Iff {
left: Box<Formula>,
right: Box<Formula>,
},
Exists {
variables: Vec<V>,
formula: Box<Formula>,
},
Forall {
variables: Vec<V>,
formula: Box<Formula>,
},
}Expand description
Is an abstract syntax tree (AST) for first-order formulae.
Variants§
Top
Is logical Top (⊤) or Truth
Bottom
Is logical Bottom (⟘) or Falsehood
Atom
Is an atomic formula, made by applying predicate on a list of terms.
Equals
Represents an equality between two terms.
Note: Equality is a special type of atomic formula.
Not
Makes the negation of the formula that it holds.
And
Makes a conjunction of the left and right formulae that it holds.
Or
Makes a disjunction of left and right formulae that it holds.
Implies
Makes an implication between left and right formulae that it holds.
Iff
Makes a bi-implication between left and right formulae that it holds.
Exists
Makes an existentially quantified formula with the bound variables and the formula that
it holds.
Forall
Makes a universally quantified formula with the bound variables and the formula that
it holds.
Implementations§
Source§impl Formula
impl Formula
Sourcepub fn implies(self, formula: Self) -> Self
pub fn implies(self, formula: Self) -> Self
Returns an implication between the receiver and formula.
Sourcepub fn iff(self, formula: Self) -> Self
pub fn iff(self, formula: Self) -> Self
Returns a bi-implication between the receiver and formula.
Sourcepub fn free_vars(&self) -> Vec<&V>
pub fn free_vars(&self) -> Vec<&V>
Returns a list of free variable symbols in the receiver formula.
Note: In the list of free variables, each variable symbol appears only once even if it is present at multiple positions of the receiver formula.
Example:
// `x`, `y` and `z` are variable symbols:
let x = V::from("x");
let y = V::from("y");
let z = V::from("z");
// (P(x) ∧ Q(x, f(g(x), y))) ∨ ('c = g(z))
let formula: Formula = "(P(x) & Q(x, f(g(x), y))) | 'c = g(z)".parse().unwrap();
assert_eq!(vec![&x, &y, &z].iter().sorted(), formula.free_vars().iter().sorted());
// ∀ x. P(x, y)
let formula: Formula = "forall x. P(x, y)".parse().unwrap();
// notice that the bound variable `x` is not in the list of free variables of `formula`
assert_eq!(vec![&y], formula.free_vars());
// ∃ x. P(x, y)
let formula: Formula = "exists x. P(x, y)".parse().unwrap();
assert_eq!(vec![&y], formula.free_vars());Source§impl Formula
impl Formula
Sourcepub fn pnf(&self) -> Formula
pub fn pnf(&self) -> Formula
Returns a Prenex Normal Form (PNF) equivalent to the receiver.
Hint: A PNF is a formula with all quantifiers (existential and universal) and bound variables at the front, followed by a quantifier-free part.
Example:
let formula: Formula = "Q(x, y) → ∃ x, y. P(x, y)".parse().unwrap();
assert_eq!("∃ x`, y`. (Q(x, y) → P(x`, y`))", formula.pnf().to_string());Sourcepub fn snf(&self) -> Formula
pub fn snf(&self) -> Formula
Returns a Skolem Normal Form (SNF) equivalent to the receiver.
Hint: An SNF is a PNF with only universal quantifiers (see: https://en.wikipedia.org/wiki/Skolem_normal_form).
Example:
let formula: Formula = "∃ y. P(x, y)".parse().unwrap();
assert_eq!("P(x, sk#0(x))", formula.snf().to_string());Sourcepub fn snf_with(&self, generator: &mut SkolemGenerator) -> Formula
pub fn snf_with(&self, generator: &mut SkolemGenerator) -> Formula
Is similar to Formula::snf but uses an existing SkolemGenerator to avoid collision
when generating Skolem function names (including Skolem constants).
Example:
use razor_fol::transform::SkolemGenerator;
let mut generator = SkolemGenerator::from("skolem");
let formula: Formula = "∃ y. P(x, y)".parse().unwrap();
assert_eq!("P(x, skolem0(x))", formula.snf_with(&mut generator).to_string());Sourcepub fn nnf(&self) -> Formula
pub fn nnf(&self) -> Formula
Returns an Negation Normal Form (NNF) equivalent to the receiver.
Hint: An NNF is a formula where negation is only applied to its atomic (including equations) sub-formulae.
Example:
let formula: Formula = "not (P(x) iff Q(y))".parse().unwrap();
assert_eq!("(P(x) ∧ (¬Q(y))) ∨ ((¬P(x)) ∧ Q(y))", formula.nnf().to_string());Sourcepub fn cnf(&self) -> Formula
pub fn cnf(&self) -> Formula
Returns a Conjunctive Normal Form (CNF) equivalent to the receiver.
Hint: A CNF is a formula that is a conjunction of zero or more clauses. A clause is a disjunction of atomic formulae (including equations).
Note: All free variables are assumed to be universally quantified.
Example:
let formula: Formula = "P(x) <=> Q(y)".parse().unwrap();
assert_eq!("((¬P(x)) ∨ Q(y)) ∧ ((¬Q(y)) ∨ P(x))", formula.cnf().to_string());Sourcepub fn cnf_with(&self, generator: &mut SkolemGenerator) -> Formula
pub fn cnf_with(&self, generator: &mut SkolemGenerator) -> Formula
Is similar to Formula::cnf but uses an existing SkolemGenerator to avoid collision
when generating Skolem function names (including Skolem constants).
Note: The CNF transformation includes Skolemization.
Example:
use razor_fol::transform::SkolemGenerator;
let mut generator = SkolemGenerator::from("s%");
let formula: Formula = "exists x. ((forall y. P(y) & Q(x, y)) -> R(x))".parse().unwrap();
assert_eq!("((¬P(\'s%1)) ∨ (¬Q(\'s%0, \'s%1))) ∨ R(\'s%0)",
formula.cnf_with(&mut generator).to_string());Sourcepub fn dnf(&self) -> Formula
pub fn dnf(&self) -> Formula
Returns a Disjunctive Normal Form (DNF) equivalent to the receiver.
Hint: A DNF is a formula that is a disjunction of zero or more conjuncts. A conjunct is a conjunction of atomic formulae (including equations).
Note: All of the free variables are assumed to be universally quantified.
Example:
let formula: Formula = "P(x) iff Q(y)".parse().unwrap();
assert_eq!("(((¬P(x)) ∧ (¬Q(y))) ∨ ((¬P(x)) ∧ P(x))) ∨ ((Q(y) ∧ (¬Q(y))) ∨ (Q(y) ∧ P(x)))",
formula.dnf().to_string());Sourcepub fn dnf_with(&self, generator: &mut SkolemGenerator) -> Formula
pub fn dnf_with(&self, generator: &mut SkolemGenerator) -> Formula
Is similar to Formula::dnf but uses an existing SkolemGenerator to avoid collision
when generating Skolem function names (including Skolem constants).
Note: The DNF transformation includes Skolemization.
Example:
use razor_fol::transform::SkolemGenerator;
let mut generator = SkolemGenerator::from("s%");
let formula: Formula = "!y. (!x. (P(y, x) | Q(x)) -> Q(y))".parse().unwrap();
assert_eq!("((¬P(y, s%0(y))) ∧ (¬Q(s%0(y)))) ∨ Q(y)",
formula.dnf_with(&mut generator).to_string());Sourcepub fn simplify(&self) -> Formula
pub fn simplify(&self) -> Formula
Applies a number of syntactic transformations to simplify the receiver formula.
Example:
let formula: Formula = "not (not P())".parse().unwrap();
assert_eq!("P()", formula.simplify().to_string());
let formula: Formula = "forall x. (P() and true) | (Q(x) or false)".parse().unwrap();
assert_eq!("∀ x. (P() ∨ Q(x))", formula.simplify().to_string());Sourcepub fn gnf(&self) -> Vec<Formula>
pub fn gnf(&self) -> Vec<Formula>
Returns a list of formulae in Geometric Normal Form (GNF), equivalent to the receiver.
Hint: For mor information about GNF, see Geometric Logic in Computer Science by Steve Vickers.
Example:
let formula: Formula = "P(x) & (Q(x) | R(x))".parse().unwrap();
let gnf_to_string: Vec<String> = formula.gnf().iter().map(|f| f.to_string()).collect();
assert_eq!(vec!["⊤ → P(x)", "⊤ → (Q(x) ∨ R(x))"], gnf_to_string);Sourcepub fn gnf_with(&self, generator: &mut SkolemGenerator) -> Vec<Formula>
pub fn gnf_with(&self, generator: &mut SkolemGenerator) -> Vec<Formula>
Is similar to Formula::gnf but uses an existing SkolemGenerator to avoid collision
when generating Skolem function names (including Skolem constants).
Note: The GNF transformation includes Skolemization.
Example:
use razor_fol::transform::SkolemGenerator;
let mut generator = SkolemGenerator::from("s%");
let formula: Formula = "P(y) -> exists x. P(x) & Q(y)".parse().unwrap();
let gnf_to_string: Vec<String> = formula.gnf().iter().map(|f| f.to_string()).collect();
assert_eq!(vec!["P(y) → P(sk#0(y))", "P(y) → Q(y)"], gnf_to_string);Trait Implementations§
Source§impl Ord for Formula
impl Ord for Formula
Source§impl PartialOrd for Formula
impl PartialOrd for Formula
Source§impl TermBased for Formula
impl TermBased for Formula
Source§fn rename_vars(&self, renaming: &impl VariableRenaming) -> Self
fn rename_vars(&self, renaming: &impl VariableRenaming) -> Self
Note: Applies a VariableRenaming on the free variables of the formula, keeping
the bound variables unchanged.
Source§fn substitute(&self, substitution: &impl Substitution) -> Self
fn substitute(&self, substitution: &impl Substitution) -> Self
Note: Applies a Substitution on the free variables of the formula, keeping the
bound variables unchanged.
impl Eq for Formula
impl StructuralPartialEq for Formula
Auto Trait Implementations§
impl Freeze for Formula
impl RefUnwindSafe for Formula
impl Send for Formula
impl Sync for Formula
impl Unpin for Formula
impl UnsafeUnpin for Formula
impl UnwindSafe for Formula
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more