1+ //! This module implements the core reasoning engine of Q, designed similarly to
2+ //! ["E – A Brainiac Theorem Prover"](https://wwwlehre.dhbw-stuttgart.de/~sschulz/PAPERS/Schulz-AICOM-2002.pdf)
3+ //! with:
4+ //! - the DISCOUNT loop
5+ //! - a subsumption index
6+ //! - term indices for rewriting and paramodulation
7+ //! - a couple but not all of the simplification rules
8+ //!
9+ //! The key entry point of this module is [search_proof].
10+
111use std:: {
212 cmp:: Ordering ,
313 fs:: File ,
@@ -28,9 +38,12 @@ use crate::{
2838
2939use memory_stats:: memory_stats;
3040
41+ /// The resource limits that should cause the saturation loop to abort.
3142#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
3243pub struct ResourceLimitConfig {
44+ /// The maximum duration for which the saturation should run.
3345 pub duration : Option < Duration > ,
46+ /// The maximum memory the saturation process is allowed to consume.
3447 pub memory_limit : Option < usize > ,
3548}
3649
@@ -125,12 +138,9 @@ fn ordering_check(
125138 if ok { Some ( new_literals) } else { None }
126139}
127140
128- /*
129- Takes a `clause` and an index `check_lit_id` to some literal `check_lit` in `clause` together
130- with a substitution `subst`. Then checks whether `subst(check_lit)` is maximal in `subst(clause)`.
131-
132- Returns `None` if maximality check fails, otherwise `Some(subst(clause) \ subst(check_lit))`
133- */
141+ /// Takes a `clause` and an index `check_lit_id` to some literal `check_lit` in `clause` together
142+ /// with a substitution `subst`. Then checks whether `subst(check_lit)` is maximal in `subst(clause)`.
143+ /// Returns `None` if maximality check fails, otherwise `Some(subst(clause) \ subst(check_lit))`
134144fn maximality_check (
135145 clause : & Clause ,
136146 check_lit_id : LiteralId ,
@@ -146,10 +156,10 @@ fn maximality_check(
146156 )
147157}
148158
149- // Eligiblity for Resolution Check given a non-empty selection:
150- // Returns the substituted and filtered literals,
151- // if the given literal is maximal in the intersection of the selection
152- // with either the positive or negative literalset of the clause with the mgu applied
159+ /// Eligiblity for Resolution Check given a non-empty selection:
160+ /// Returns the substituted and filtered literals,
161+ /// if the given literal is maximal in the intersection of the selection
162+ /// with either the positive or negative literalset of the clause with the mgu applied
153163fn eligible_resolution_with_selection (
154164 clause : & Clause ,
155165 check_lit_id : LiteralId ,
@@ -213,6 +223,7 @@ impl SuperpositionState<'_> {
213223 }
214224 }
215225
226+ /// Insert `clause` into the `active` set, updating all of the term indices to account for it.
216227 fn insert_active ( & mut self , clause : Clause ) {
217228 let clause_id = clause. get_id ( ) ;
218229 info ! (
@@ -320,8 +331,7 @@ impl SuperpositionState<'_> {
320331 self . active . insert ( clause) ;
321332 }
322333
323- // remove from the active set
324- // remove from index structures
334+ /// Remove `clause` from the `active` set, updating all of the term indices to account for it.
325335 pub ( crate ) fn erase_active ( & mut self , clause : & Clause ) {
326336 let clause_id = clause. get_id ( ) ;
327337 info ! ( "Erasing active: {}" , pretty_print( clause, self . term_bank) ) ;
@@ -370,6 +380,7 @@ impl SuperpositionState<'_> {
370380 self . active . remove ( clause) ;
371381 }
372382
383+ /// Insert `clause` into the passive set, this is a very cheap operation.
373384 fn insert_passive ( & mut self , clause : Clause ) {
374385 info ! (
375386 "Inserting passive: {}" ,
@@ -716,6 +727,7 @@ impl SuperpositionState<'_> {
716727 }
717728 }
718729
730+ /// Run all generating inferences, this is the core of the reasoning engine.
719731 fn generate ( & mut self , clause : Clause ) -> Vec < Clause > {
720732 let mut acc = Vec :: new ( ) ;
721733 self . equality_resolution ( & clause, & mut acc) ;
@@ -724,6 +736,8 @@ impl SuperpositionState<'_> {
724736 acc
725737 }
726738
739+ /// Check if one of the resource exhaustion conditions is met. May cause garbage collection on
740+ /// the term bank if the memory limit is almost exhausted.
727741 fn resources_exhausted ( & self ) -> Option < UnknownReason > {
728742 if let Some ( time_limit) = self . resource_limits . time_limit {
729743 let now = Instant :: now ( ) ;
@@ -750,6 +764,7 @@ impl SuperpositionState<'_> {
750764 None
751765 }
752766
767+ /// Check whether `g` is redundant with respect to the active set via subsumption.
753768 fn redundant ( & self , g : & Clause ) -> bool {
754769 for active_clause_id in self . subsumption_index . forward_candidates ( g, self . term_bank ) {
755770 let active_clause = self . active . get_by_id ( active_clause_id) . unwrap ( ) ;
@@ -765,6 +780,26 @@ impl SuperpositionState<'_> {
765780 false
766781 }
767782
783+ /// Remove all clauses in the active subsumed by `g` from the active set
784+ fn backward_subsumption ( & mut self , g : & Clause ) {
785+ let mut redundant_active = Vec :: new ( ) ;
786+ for active_clause_id in self
787+ . subsumption_index
788+ . backward_candidates ( & g, self . term_bank )
789+ {
790+ let active_clause = self . active . get_by_id ( active_clause_id) . unwrap ( ) ;
791+ if g. subsumes ( active_clause, self . term_bank ) {
792+ info ! (
793+ "Backward Subsumption: {} subsumes {}" ,
794+ pretty_print( g, self . term_bank) ,
795+ pretty_print( active_clause, self . term_bank) ,
796+ ) ;
797+ redundant_active. push ( active_clause. clone ( ) ) ;
798+ }
799+ }
800+ redundant_active. iter ( ) . for_each ( |c| self . erase_active ( c) ) ;
801+ }
802+
768803 fn run ( & mut self ) -> SuperpositionResult {
769804 while let Some ( g_queue) = self . passive . pop ( ) {
770805 let mut g = g_queue. fresh_variable_clone ( self . term_bank ) ;
@@ -787,22 +822,7 @@ impl SuperpositionState<'_> {
787822 continue ;
788823 }
789824
790- let mut redundant_active = Vec :: new ( ) ;
791- for active_clause_id in self
792- . subsumption_index
793- . backward_candidates ( & g, self . term_bank )
794- {
795- let active_clause = self . active . get_by_id ( active_clause_id) . unwrap ( ) ;
796- if g. subsumes ( active_clause, self . term_bank ) {
797- info ! (
798- "Backward Subsumption: {} subsumes {}" ,
799- pretty_print( & g, self . term_bank) ,
800- pretty_print( active_clause, self . term_bank) ,
801- ) ;
802- redundant_active. push ( active_clause. clone ( ) ) ;
803- }
804- }
805- redundant_active. iter ( ) . for_each ( |c| self . erase_active ( c) ) ;
825+ self . backward_subsumption ( & g) ;
806826
807827 let backward_simplified = backward_simplify ( & g, self ) ;
808828
0 commit comments