private void CalculateFactors(ISet <Clause> parentFactors) { nonTrivialFactors = new HashedSet <Clause>(); IDictionary <Variable, ITerm> theta = new Dictionary <Variable, ITerm>(); var lits = new List <Literal>(); for (var i = 0; i < 2; i++) { lits.Clear(); if (i == 0) { // Look at the positive literals lits.AddRange(positiveLiterals); } else { // Look at the negative literals lits.AddRange(negativeLiterals); } for (int x = 0; x < lits.Count; x++) { for (int y = x + 1; y < lits.Count; y++) { var litX = lits[x]; var litY = lits[y]; theta.Clear(); IDictionary <Variable, ITerm> substitution = _unifier.Unify( litX.AtomicSentence, litY.AtomicSentence, theta); if (substitution != null) { var posLits = new List <Literal>(); var negLits = new List <Literal>(); if (i == 0) { posLits.Add(_substVisitor.Subst(substitution, litX)); } else { negLits.Add(_substVisitor.Subst(substitution, litX)); } posLits.AddRange(from pl in this.positiveLiterals where pl != litX && pl != litY select _substVisitor.Subst(substitution, pl)); negLits.AddRange(from nl in this.negativeLiterals where nl != litX && nl != litY select _substVisitor.Subst(substitution, nl)); // Ensure the non trivial factor is standardized apart _standardizeApart.GetStandardizeApartResult(posLits, negLits, _saIndexical); Clause c = new Clause(posLits, negLits); c.SetProofStep(new ProofStepClauseFactor(c, this)); if (this.Immutable) { c.Immutable = true; } if (!this.IsStandardizedApartCheckRequired()) { c.SetStandardizedApartCheckNotRequired(); } if (parentFactors == null || !parentFactors.Contains(c)) { c.CalculateFactors(this.nonTrivialFactors); this.nonTrivialFactors.UnionWith(c.GetFactors()); } } } } } factors = new HashedSet <Clause>(); // Need to add self, even though a non-trivial // factor. See: slide 30 // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture10.pdf // for example of incompleteness when // trivial factor not included. factors.Add(this); factors.UnionWith(nonTrivialFactors); }
// Note: Applies binary resolution rule and factoring // Note: returns a set with an empty clause if both clauses // are empty, otherwise returns a set of binary resolvents. public ISet <Clause> BinaryResolvents(Clause othC) { ISet <Clause> resolvents = new HashedSet <Clause>(); // Resolving two empty clauses // gives you an empty clause if (IsEmpty() && othC.IsEmpty()) { resolvents.Add(new Clause()); return(resolvents); } // Ensure Standardized Apart // Before attempting binary resolution othC = this.SaIfRequired(othC); var allPosLits = new List <Literal>(); var allNegLits = new List <Literal>(); allPosLits.AddRange(this.positiveLiterals); allPosLits.AddRange(othC.positiveLiterals); allNegLits.AddRange(this.negativeLiterals); allNegLits.AddRange(othC.negativeLiterals); var trPosLits = new List <Literal>(); var trNegLits = new List <Literal>(); var copyRPosLits = new List <Literal>(); var copyRNegLits = new List <Literal>(); for (int i = 0; i < 2; i++) { trPosLits.Clear(); trNegLits.Clear(); if (i == 0) { // See if this clauses positives // unify with the other clauses // negatives trPosLits.AddRange(this.positiveLiterals); trNegLits.AddRange(othC.negativeLiterals); } else { // Try the other way round now trPosLits.AddRange(othC.positiveLiterals); trNegLits.AddRange(this.negativeLiterals); } // Now check to see if they resolve IDictionary <Variable, ITerm> copyRBindings = new Dictionary <Variable, ITerm>(); foreach (var pl in trPosLits) { foreach (var nl in trNegLits) { copyRBindings.Clear(); if (null != _unifier.Unify(pl.AtomicSentence, nl.AtomicSentence, copyRBindings)) { copyRPosLits.Clear(); copyRNegLits.Clear(); var found = false; foreach (var l in allPosLits) { if (!found && pl.Equals(l)) { found = true; continue; } copyRPosLits.Add(_substVisitor.Subst(copyRBindings, l)); } found = false; foreach (Literal l in allNegLits) { if (!found && nl.Equals(l)) { found = true; continue; } copyRNegLits.Add(_substVisitor.Subst(copyRBindings, l)); } // Ensure the resolvents are standardized apart var renameSubstitituon = _standardizeApart .GetStandardizeApartResult(copyRPosLits, copyRNegLits, _saIndexical); var c = new Clause(copyRPosLits, copyRNegLits); c.SetProofStep(new ProofStepClauseBinaryResolvent(c, this, othC, copyRBindings, renameSubstitituon)); if (this.Immutable) { c.Immutable = true; } if (!this.IsStandardizedApartCheckRequired()) { c.SetStandardizedApartCheckNotRequired(); } resolvents.Add(c); } } } } return(resolvents); }