pub struct Clause<L: Literal = PackedLiteral, S: LiteralStorage<L> = SmallVec<[L; 8]>> {
pub literals: S,
pub lbd: u32,
pub deleted: bool,
pub is_learnt: bool,
pub activity: OrderedFloat<f64>,
/* private fields */
}Expand description
Represents a clause in a SAT formula.
A clause is a set of literals, typically interpreted as a disjunction.
For example, the clause {L1, L2, L3} represents L1 OR L2 OR L3.
§Type Parameters
L: The type of literal stored in the clause. Defaults toPackedLiteral. Must implement theLiteraltrait.S: The storage type for the literals. Defaults toSmallVec<[L; 8]>. Must implement theLiteralStorage<L>trait, providing storage for literals.
Fields§
§literals: SThe collection of literals forming the clause.
The specific storage (e.g. Vec, SmallVec) is determined by the S type parameter.
lbd: u32Literal Blocks Distance (LBD) of the clause. LBD is a measure of the “locality” of a learnt clause in terms of decision levels. Lower LBD often indicates higher quality learnt clauses. Calculated for learnt clauses.
deleted: boolFlag indicating if the clause has been marked for deletion. Deleted clauses are removed by the solver during database cleaning.
is_learnt: boolFlag indicating if the clause was learnt during conflict analysis. Original clauses (from the input problem) are not marked as learnt.
activity: OrderedFloat<f64>Activity score of the clause, used in clause deletion heuristics (e.g. VSIDS-like). Higher activity suggests the clause has been more recently involved in conflicts or propagations.
Implementations§
Source§impl<L: Literal, S: LiteralStorage<L>> Clause<L, S>
impl<L: Literal, S: LiteralStorage<L>> Clause<L, S>
Sourcepub fn new(literals_slice: &[L]) -> Self
pub fn new(literals_slice: &[L]) -> Self
Creates a new clause from a slice of literals.
§Arguments
literals_slice: A slice of literals to form the clause.
Sourcepub fn resolve(&self, other: &Self, pivot: L) -> Self
pub fn resolve(&self, other: &Self, pivot: L) -> Self
Performs resolution between this clause and another clause on a pivot literal.
The resolution rule is: (A V x) AND (B V !x) => (A V B).
In this context, self represents (A V x) and other represents (B V !x).
The pivot argument is the literal x.
- If
pivot(i.e.x) is not found inself.literals, orpivot.negated()(i.e.!x) is not found inother.literals, resolution is not applicable with the given pivot. In this case, a clone ofselfis returned. - The resolvent clause is formed by taking the union of literals from
self(excludingpivot) andother(excludingpivot.negated()), with duplicates removed. - If the resulting resolvent is a tautology (e.g. contains both
yand!y), a default (typically empty and non-learnt) clause is returned. A tautological resolvent is logically true and provides no new constraints.
§Arguments
other: The other clause to resolve with.pivot: The literalxto resolve upon.selfshould containpivot, andothershould containpivot.negated().
§Returns
The resolved clause. This is a new Clause instance.
Sourcepub fn resolve_binary(&self, binary: &Self) -> Option<Self>
pub fn resolve_binary(&self, binary: &Self) -> Option<Self>
Performs binary resolution: resolves self with a binary clause binary.
A binary clause contains exactly two literals. Let binary be (L1 V L2).
- If
selfcontains!L1, the result is(self - {!L1}) V {L2}. - If
selfcontains!L2, the result is(self - {!L2}) V {L1}. The literals in the resulting clause are unique. If the resulting clause is a tautology,Noneis returned.
§Arguments
binary: A binary clause (must have exactly two literals).
§Returns
Some(resolved_clause) if resolution is possible and the result is not a tautology.
None if binary is not a binary clause, resolution is not applicable (no matching negated literal found),
or the result of resolution is a tautology.
§Panics
The unwrap_or_else for position might lead to unexpected behavior if the literal to be removed
is not found (which shouldn’t happen if lit was found in self.literals and new_clause is a clone).
If position returns None, remove_literal would attempt to remove the last element of new_clause.literals.
Sourcepub fn is_tautology(&self) -> bool
pub fn is_tautology(&self) -> bool
Checks if the clause is a tautology.
A clause is a tautology if it contains both a literal and its negation
(e.g. x OR !x). Such clauses are always true and not useful
§Returns
true if the clause is a tautology, false otherwise.
Sourcepub fn iter(&self) -> impl Iterator<Item = &L>
pub fn iter(&self) -> impl Iterator<Item = &L>
Returns an iterator over the literals in the clause.
Sourcepub fn iter_mut(&mut self) -> impl Iterator<Item = &mut L>
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut L>
Returns a mutable iterator over the literals in the clause.
Sourcepub fn is_unit(&self) -> bool
pub fn is_unit(&self) -> bool
Checks if the clause is a unit clause.
A unit clause is a clause with exactly one literal.
§Returns
true if the clause has exactly one literal, false otherwise.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Checks if the clause is empty.
An empty clause (containing no literals) represents a contradiction (logical false).
§Returns
true if the clause has no literals, false otherwise.
Sourcepub const fn is_deleted(&self) -> bool
pub const fn is_deleted(&self) -> bool
Checks if the clause is marked as deleted.
Sourcepub const fn delete(&mut self)
pub const fn delete(&mut self)
Marks the clause as deleted.
This only sets the deleted flag to true. It does not remove the clause
Sourcepub fn remove_literal(&mut self, idx: usize)
pub fn remove_literal(&mut self, idx: usize)
Removes a literal from the clause at the given index.
This method uses swap_remove for efficiency, which means the order of
the remaining literals in the clause may change (the last literal is swapped
into the idx position, and then the length is reduced).
§Arguments
idx: The index of the literal to remove.
§Panics
Panics if idx is out of bounds for self.literals.
Sourcepub fn calculate_lbd(&mut self, trail: &Trail<L, S>)
pub fn calculate_lbd(&mut self, trail: &Trail<L, S>)
Calculates and updates the Literal Block Distance (LBD) of the clause.
LBD is defined as the number of distinct decision levels (excluding level 0) of the variables in the clause’s literals. This metric is used to estimate the “quality” or “usefulness” of learnt clauses
Special LBD rules applied:
- If the clause is empty, LBD is 0.
- If all literals are at decision level 0 (or unassigned and treated as level 0), and the clause is not empty, LBD is 1.
- For learnt, non-empty clauses, LBD is ensured to be at least 1.
§Arguments
trail: The solver’s assignment trail, used to find the decision level of each literal’s variable.
§Panics
Behavior of BitVec indexing with level (a u32) depends on usize size.
Sourcepub fn convert<T: Literal, U: LiteralStorage<T>>(&self) -> Clause<T, U>
pub fn convert<T: Literal, U: LiteralStorage<T>>(&self) -> Clause<T, U>
Converts this clause into a clause with different literal or storage types.
This is useful for benchmarking primarily
The literals are converted one by one using T::new(original_lit.variable(), original_lit.polarity()).
Metadata like LBD, deleted status, learnt status, and activity are copied.
§Type Parameters
T: The targetLiteraltype for the new clause.U: The targetLiteralStorage<T>type for the new clause.
§Returns
A new Clause<T, U> with equivalent literals and copied metadata.
Sourcepub fn bump_activity(&mut self, increment: f64)
pub fn bump_activity(&mut self, increment: f64)
Increases the activity score of the clause by a specified increment.
This is part of VSIDS-like (Variable State Independent Decaying Sum) heuristics, where clauses involved in recent conflict analysis get their activity “bumped”, making them less likely to be deleted.
§Arguments
increment: The positive amount to add to the clause’s activity score.
Sourcepub fn decay_activity(&mut self, factor: f64)
pub fn decay_activity(&mut self, factor: f64)
Decays the activity score of the clause by a multiplicative factor.
§Arguments
factor: The factor to multiply the activity score by (typically between 0 and 1).
Trait Implementations§
Source§impl<L: Literal, S: LiteralStorage<L>> From<Vec<i32>> for Clause<L, S>
impl<L: Literal, S: LiteralStorage<L>> From<Vec<i32>> for Clause<L, S>
Source§fn from(literals_dimacs: Vec<i32>) -> Self
fn from(literals_dimacs: Vec<i32>) -> Self
Creates a clause from a Vec<i32>, where integers represent literals
in DIMACS format (e.g. 1 for variable 1 true, -2 for variable 2 false).
This constructor uses Clause::new, so literals will be deduplicated.
Other fields (lbd, deleted, etc.) are initialised to defaults.
Source§impl<L: Literal, S: LiteralStorage<L>> FromIterator<Clause<L, S>> for Cnf<L, S>
impl<L: Literal, S: LiteralStorage<L>> FromIterator<Clause<L, S>> for Cnf<L, S>
Source§fn from_iter<IterClauses: IntoIterator<Item = Clause<L, S>>>(
iter: IterClauses,
) -> Self
fn from_iter<IterClauses: IntoIterator<Item = Clause<L, S>>>( iter: IterClauses, ) -> Self
Creates a Cnf from an iterator of Clause<L, S>.
Each clause from the iterator is added using self.add_clause.
This initialises a default Cnf and then populates it.
non_learnt_idx will be implicitly managed by add_clause if it updates it,
or will remain 0 if add_clause only appends to clauses.
A more robust way would be to collect clauses, then initialise Cnf fields properly.
Source§impl<L: Literal, S: LiteralStorage<L>> FromIterator<L> for Clause<L, S>
impl<L: Literal, S: LiteralStorage<L>> FromIterator<L> for Clause<L, S>
Source§fn from_iter<I: IntoIterator<Item = L>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = L>>(iter: I) -> Self
Creates a new clause from an iterator of literals.
The literals from the iterator are collected into the literals field.
Literals are deduplicated during creation using itertools::Itertools::unique.
For example, [L1, L1, L2] becomes {L1, L2}.
The clause is initialised as not learnt, not deleted, with LBD 0 and activity 0.0.
Other fields (lbd, deleted, is_learnt, activity) are initialised to default values.
Source§impl<L: Literal, S: LiteralStorage<L>> FromIterator<i32> for Clause<L, S>
impl<L: Literal, S: LiteralStorage<L>> FromIterator<i32> for Clause<L, S>
Source§fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self
Creates a clause from an iterator of i32 (DIMACS literals).
This is similar to From<Vec<i32>>. Literals are converted from DIMACS format.
See From<Vec<i32>> for more details on DIMACS conversion and variable indexing.
Source§impl<L: Ord + Literal, S: Ord + LiteralStorage<L>> Ord for Clause<L, S>
impl<L: Ord + Literal, S: Ord + LiteralStorage<L>> Ord for Clause<L, S>
1.21.0 · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<L: PartialOrd + Literal, S: PartialOrd + LiteralStorage<L>> PartialOrd for Clause<L, S>
impl<L: PartialOrd + Literal, S: PartialOrd + LiteralStorage<L>> PartialOrd for Clause<L, S>
impl<L: Eq + Literal, S: Eq + LiteralStorage<L>> Eq for Clause<L, S>
impl<L: Literal, S: LiteralStorage<L>> StructuralPartialEq for Clause<L, S>
Auto Trait Implementations§
impl<L, S> Freeze for Clause<L, S>where
S: Freeze,
impl<L, S> RefUnwindSafe for Clause<L, S>where
S: RefUnwindSafe,
L: RefUnwindSafe,
impl<L = PackedLiteral, S = SmallVec<[L; 8]>> !Send for Clause<L, S>
impl<L = PackedLiteral, S = SmallVec<[L; 8]>> !Sync for Clause<L, S>
impl<L, S> Unpin for Clause<L, S>where
S: Unpin,
impl<L, S> UnwindSafe for Clause<L, S>where
S: UnwindSafe,
L: RefUnwindSafe,
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