22
33import java .util .ArrayList ;
44import java .util .HashMap ;
5+ import java .util .HashSet ;
56import java .util .LinkedHashSet ;
67import java .util .List ;
78import java .util .Map ;
@@ -153,8 +154,8 @@ public void setClauseSimplifier(ClauseSimplifier clauseSimplifier) {
153154 //
154155 // START-InferenceProcedure
155156 public InferenceResult ask (FOLKnowledgeBase KB , Sentence alpha ) {
156- Set <Clause > sos = new LinkedHashSet <Clause >();
157- Set <Clause > usable = new LinkedHashSet <Clause >();
157+ Set <Clause > sos = new HashSet <Clause >();
158+ Set <Clause > usable = new HashSet <Clause >();
158159
159160 // Usable set will be the set of clauses in the KB,
160161 // are assuming this is satisfiable as using the
@@ -164,7 +165,6 @@ public InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha) {
164165 c .setStandardizedApartCheckNotRequired ();
165166 usable .addAll (c .getFactors ());
166167 }
167- usable .removeAll (SubsumptionElimination .findSubsumedClauses (usable ));
168168
169169 // Ensure reflexivity axiom is added to usable if using paramodulation.
170170 if (isUseParamodulation ()) {
@@ -206,14 +206,21 @@ public InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha) {
206206 }
207207 }
208208
209+ // Ensure all subsumed clauses are removed
210+ usable .removeAll (SubsumptionElimination .findSubsumedClauses (usable ));
211+ sos .removeAll (SubsumptionElimination .findSubsumedClauses (sos ));
212+
209213 OTTERAnswerHandler ansHandler = new OTTERAnswerHandler (answerLiteral ,
210214 answerLiteralVariables , answerClause , maxQueryTime );
211215
212- return otter (ansHandler , sos , usable );
216+ IndexedClauses idxdClauses = new IndexedClauses (
217+ getLightestClauseHeuristic (), sos , usable );
218+
219+ return otter (ansHandler , idxdClauses , sos , usable );
213220 }
214221
215222 // END-InferenceProcedure
216- //
223+ //
217224
218225 /**
219226 * <pre>
@@ -223,7 +230,7 @@ public InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha) {
223230 * </pre>
224231 */
225232 private InferenceResult otter (OTTERAnswerHandler ansHandler ,
226- Set <Clause > sos , Set <Clause > usable ) {
233+ IndexedClauses idxdClauses , Set <Clause > sos , Set <Clause > usable ) {
227234
228235 getLightestClauseHeuristic ().initialSOS (sos );
229236
@@ -234,11 +241,13 @@ private InferenceResult otter(OTTERAnswerHandler ansHandler,
234241 if (null != clause ) {
235242 // * move clause from sos to usable
236243 sos .remove (clause );
237- usable .add (clause );
238244 getLightestClauseHeuristic ().removedClauseFromSOS (clause );
245+ usable .add (clause );
239246 // * PROCESS(INFER(clause, usable), sos)
240- process (ansHandler , infer (clause , usable ), sos , usable );
247+ process (ansHandler , idxdClauses , infer (clause , usable ), sos ,
248+ usable );
241249 }
250+
242251 // * until sos = [] or a refutation has been found
243252 } while (sos .size () != 0 && !ansHandler .isComplete ());
244253
@@ -251,7 +260,7 @@ private InferenceResult otter(OTTERAnswerHandler ansHandler,
251260 */
252261 private Set <Clause > infer (Clause clause , Set <Clause > usable ) {
253262 Set <Clause > resultingClauses = new LinkedHashSet <Clause >();
254-
263+
255264 // Remember to resolve with self
256265 Set <Clause > resolvents = clause .binaryResolvents (clause );
257266 for (Clause rc : resolvents ) {
@@ -279,8 +288,9 @@ private Set<Clause> infer(Clause clause, Set<Clause> usable) {
279288 }
280289
281290 // procedure PROCESS(clauses, sos)
282- private void process (OTTERAnswerHandler ansHandler , Set <Clause > clauses ,
283- Set <Clause > sos , Set <Clause > usable ) {
291+ private void process (OTTERAnswerHandler ansHandler ,
292+ IndexedClauses idxdClauses , Set <Clause > clauses , Set <Clause > sos ,
293+ Set <Clause > usable ) {
284294
285295 // * for each clause in clauses do
286296 for (Clause clause : clauses ) {
@@ -308,14 +318,15 @@ private void process(OTTERAnswerHandler ansHandler, Set<Clause> clauses,
308318 if (!sos .contains (clause ) && !usable .contains (clause )) {
309319 for (Clause ac : clause .getFactors ()) {
310320 if (!sos .contains (ac ) && !usable .contains (ac )) {
311- sos .add (ac );
312- getLightestClauseHeuristic ().addedClauseToSOS (ac );
321+ idxdClauses .addClause (ac , sos , usable );
322+
323+ // * if clause has one literal then look for unit
324+ // refutation
325+ lookForUnitRefutation (ansHandler , idxdClauses , ac ,
326+ sos , usable );
313327 }
314328 }
315329 }
316-
317- // * if clause has one literal then look for unit refutation
318- lookForUnitRefutation (ansHandler , clause , sos , usable );
319330 }
320331
321332 if (ansHandler .isComplete ()) {
@@ -325,7 +336,8 @@ private void process(OTTERAnswerHandler ansHandler, Set<Clause> clauses,
325336 }
326337
327338 private void lookForUnitRefutation (OTTERAnswerHandler ansHandler ,
328- Clause clause , Set <Clause > sos , Set <Clause > usable ) {
339+ IndexedClauses idxdClauses , Clause clause , Set <Clause > sos ,
340+ Set <Clause > usable ) {
329341
330342 Set <Clause > toCheck = new LinkedHashSet <Clause >();
331343
@@ -362,8 +374,7 @@ private void lookForUnitRefutation(OTTERAnswerHandler ansHandler,
362374 // LightestClauseHeuristic to loop continuously
363375 // on the same pair of objects.
364376 if (!sos .contains (t ) && !usable .contains (t )) {
365- sos .add (t );
366- getLightestClauseHeuristic ().addedClauseToSOS (t );
377+ idxdClauses .addClause (t , sos , usable );
367378 }
368379 }
369380
@@ -374,6 +385,90 @@ private void lookForUnitRefutation(OTTERAnswerHandler ansHandler,
374385 }
375386 }
376387
388+ class IndexedClauses {
389+ private LightestClauseHeuristic lightestClauseHeuristic = null ;
390+ // Group the clauses by their # of literals.
391+ private Map <Integer , Set <Clause >> clausesGroupedBySize = new HashMap <Integer , Set <Clause >>();
392+ // Keep track of the min and max # of literals.
393+ private int minNoLiterals = Integer .MAX_VALUE ;
394+ private int maxNoLiterals = 0 ;
395+
396+ public IndexedClauses (LightestClauseHeuristic lightestClauseHeuristic ,
397+ Set <Clause > sos , Set <Clause > usable ) {
398+ this .lightestClauseHeuristic = lightestClauseHeuristic ;
399+ Set <Clause > allClauses = new HashSet <Clause >();
400+ allClauses .addAll (sos );
401+ allClauses .addAll (usable );
402+ for (Clause c : allClauses ) {
403+ indexClause (c );
404+ }
405+ }
406+
407+ public void addClause (Clause c , Set <Clause > sos , Set <Clause > usable ) {
408+ // Perform forward subsumption elimination
409+ boolean addToSOS = true ;
410+ for (int i = minNoLiterals ; i < c .getNumberLiterals (); i ++) {
411+ Set <Clause > fs = clausesGroupedBySize .get (i );
412+ if (null != fs ) {
413+ for (Clause s : fs ) {
414+ if (s .subsumes (c )) {
415+ addToSOS = false ;
416+ break ;
417+ }
418+ }
419+ }
420+ if (!addToSOS ) {
421+ break ;
422+ }
423+ }
424+
425+ if (addToSOS ) {
426+ sos .add (c );
427+ lightestClauseHeuristic .addedClauseToSOS (c );
428+ indexClause (c );
429+ // Perform backward subsumption elimination
430+ Set <Clause > subsumed = new HashSet <Clause >();
431+ for (int i = c .getNumberLiterals () + 1 ; i <= maxNoLiterals ; i ++) {
432+ subsumed .clear ();
433+ Set <Clause > bs = clausesGroupedBySize .get (i );
434+ if (null != bs ) {
435+ for (Clause s : bs ) {
436+ if (c .subsumes (s )) {
437+ subsumed .add (s );
438+ if (sos .contains (s )) {
439+ sos .remove (s );
440+ lightestClauseHeuristic
441+ .removedClauseFromSOS (s );
442+ }
443+ usable .remove (s );
444+ }
445+ }
446+ bs .removeAll (subsumed );
447+ }
448+ }
449+ }
450+ }
451+
452+ //
453+ // PRIVATE METHODS
454+ //
455+ private void indexClause (Clause c ) {
456+ int size = c .getNumberLiterals ();
457+ if (size < minNoLiterals ) {
458+ minNoLiterals = size ;
459+ }
460+ if (size > maxNoLiterals ) {
461+ maxNoLiterals = size ;
462+ }
463+ Set <Clause > cforsize = clausesGroupedBySize .get (size );
464+ if (null == cforsize ) {
465+ cforsize = new HashSet <Clause >();
466+ clausesGroupedBySize .put (size , cforsize );
467+ }
468+ cforsize .add (c );
469+ }
470+ }
471+
377472 class OTTERAnswerHandler implements InferenceResult {
378473 private Literal answerLiteral = null ;
379474 private Set <Variable > answerLiteralVariables = null ;
@@ -392,13 +487,13 @@ public OTTERAnswerHandler(Literal answerLiteral,
392487 //
393488 this .finishTime = System .currentTimeMillis () + maxQueryTime ;
394489 }
395-
490+
396491 //
397492 // START-InferenceResult
398493 public boolean isPossiblyFalse () {
399494 return !timedOut && proofs .size () == 0 ;
400495 }
401-
496+
402497 public boolean isTrue () {
403498 return proofs .size () > 0 ;
404499 }
@@ -488,7 +583,7 @@ public boolean isAnswer(Clause aClause) {
488583 }
489584 if (addNewAnswer ) {
490585 proofs .add (new ProofFinal (aClause .getProofStep (),
491- answerBindings ));
586+ answerBindings ));
492587 }
493588 isAns = true ;
494589 }
0 commit comments