private void calculateFactors(ISet <Clause> parentFactors) { nonTrivialFactors = CollectionFactory.CreateSet <Clause>(); IMap <Variable, Term> theta = CollectionFactory.CreateInsertionOrderedMap <Variable, Term>(); ICollection <Literal> lits = CollectionFactory.CreateQueue <Literal>(); for (int i = 0; i < 2; ++i) { lits.Clear(); if (i == 0) { // Look at the positive literals lits.AddAll(positiveLiterals); } else { // Look at the negative literals lits.AddAll(negativeLiterals); } for (int x = 0; x < lits.Size(); x++) { for (int y = x + 1; y < lits.Size(); y++) { Literal litX = lits.Get(x); Literal litY = lits.Get(y); theta.Clear(); IMap <Variable, Term> substitution = _unifier.unify( litX.getAtomicSentence(), litY.getAtomicSentence(), theta); if (null != substitution) { ICollection <Literal> posLits = CollectionFactory.CreateQueue <Literal>(); ICollection <Literal> negLits = CollectionFactory.CreateQueue <Literal>(); if (i == 0) { posLits.Add(_substVisitor.subst(substitution, litX)); } else { negLits.Add(_substVisitor.subst(substitution, litX)); } foreach (Literal pl in positiveLiterals) { if (pl == litX || pl == litY) { continue; } posLits.Add(_substVisitor.subst(substitution, pl)); } foreach (Literal nl in negativeLiterals) { if (nl == litX || nl == litY) { continue; } negLits.Add(_substVisitor.subst(substitution, nl)); } // Ensure the non trivial factor is standardized apart IMap <Variable, Term> renameSubst = _standardizeApart .standardizeApart(posLits, negLits, _saIndexical); Clause c = new Clause(posLits, negLits); c.setProofStep(new ProofStepClauseFactor(c, this, litX, litY, substitution, renameSubst)); if (isImmutable()) { c.setImmutable(); } if (!isStandardizedApartCheckRequired()) { c.setStandardizedApartCheckNotRequired(); } if (null == parentFactors) { c.calculateFactors(nonTrivialFactors); nonTrivialFactors.AddAll(c.getFactors()); } else { if (!parentFactors.Contains(c)) { c.calculateFactors(nonTrivialFactors); nonTrivialFactors.AddAll(c.getFactors()); } } } } } } factors = CollectionFactory.CreateSet <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.AddAll(nonTrivialFactors); }
private bool checkSubsumes(Clause othC, IMap <string, ICollection <Literal> > thisToTry, IMap <string, ICollection <Literal> > othCToTry) { bool subsumes = false; ICollection <Term> thisTerms = CollectionFactory.CreateQueue <Term>(); ICollection <Term> othCTerms = CollectionFactory.CreateQueue <Term>(); // Want to track possible number of permuations ICollection <int> radices = CollectionFactory.CreateQueue <int>(); foreach (string literalName in thisToTry.GetKeys()) { int sizeT = thisToTry.Get(literalName).Size(); int sizeO = othCToTry.Get(literalName).Size(); if (sizeO > 1) { // The following is being used to // track the number of permutations // that can be mapped from the // other clauses like literals to this // clauses like literals. // i.e. n!/(n-r)! // where n=sizeO and r =sizeT for (int i = 0; i < sizeT; ++i) { int r = sizeO - i; if (r > 1) { radices.Add(r); } } } // Track the terms for this clause foreach (Literal tl in thisToTry.Get(literalName)) { thisTerms.AddAll(tl.getAtomicSentence().getArgs()); } } MixedRadixNumber permutation = null; long numPermutations = 1L; if (radices.Size() > 0) { permutation = new MixedRadixNumber(0, radices); numPermutations = permutation.GetMaxAllowedValue() + 1; } // Want to ensure none of the othCVariables are // part of the key set of a unification as // this indicates it is not a legal subsumption. ISet <Variable> othCVariables = _variableCollector .collectAllVariables(othC); IMap <Variable, Term> theta = CollectionFactory.CreateInsertionOrderedMap <Variable, Term>(); ICollection <Literal> literalPermuations = CollectionFactory.CreateQueue <Literal>(); for (long l = 0L; l < numPermutations; l++) { // Track the other clause's terms for this // permutation. othCTerms.Clear(); int radixIdx = 0; foreach (string literalName in thisToTry.GetKeys()) { int sizeT = thisToTry.Get(literalName).Size(); literalPermuations.Clear(); literalPermuations.AddAll(othCToTry.Get(literalName)); int sizeO = literalPermuations.Size(); if (sizeO > 1) { for (int i = 0; i < sizeT; ++i) { int r = sizeO - i; if (r > 1) { // If not a 1 to 1 mapping then you need // to use the correct permuation int numPos = permutation.GetCurrentNumeralValue(radixIdx); Literal lit = literalPermuations.Get(numPos); literalPermuations.Remove(lit); othCTerms.AddAll(lit.getAtomicSentence().getArgs()); radixIdx++; } else { // is the last mapping, therefore // won't be on the radix othCTerms.AddAll(literalPermuations.Get(0).getAtomicSentence().getArgs()); } } } else { // a 1 to 1 mapping othCTerms.AddAll(literalPermuations.Get(0) .getAtomicSentence().getArgs()); } } // Note: on unifier // unifier.unify(P(w, x), P(y, z)))={w=y, x=z} // unifier.unify(P(y, z), P(w, x)))={y=w, z=x} // Therefore want this clause to be the first // so can do the othCVariables check for an invalid // subsumes. theta.Clear(); if (null != _unifier.unify(thisTerms, othCTerms, theta)) { bool containsAny = false; foreach (Variable v in theta.GetKeys()) { if (othCVariables.Contains(v)) { containsAny = true; break; } } if (!containsAny) { subsumes = true; break; } } // If there is more than 1 mapping // keep track of where I am in the // possible number of mapping permutations. if (null != permutation) { permutation.Increment(); } } return(subsumes); }
public void addLiteral(Literal literal) { literals.Add(literal); }