private void calculateFactors(List<Clause> parentFactors) { nonTrivialFactors = new List<Clause>(); Dictionary<Variable, Term> theta = new Dictionary<Variable, Term>(); List<Literal> lits = new List<Literal>(); for (int 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++) { Literal litX = lits[x]; Literal litY = lits[y]; theta.Clear(); Dictionary<Variable, Term> substitution = _unifier.unify(litX .getAtomicSentence(), litY.getAtomicSentence(), theta); if (null != substitution) { List<Literal> posLits = new List<Literal>(); List<Literal> negLits = new List<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 _standardizeApart.standardizeApart(posLits, negLits, _saIndexical); Clause c = new Clause(posLits, negLits); c.setProofStep(new ProofStepClauseFactor(c, this, null, null, null, null)); if (isImmutable()) { c.setImmutable(); } if (!isStandardizedApartCheckRequired()) { c.setStandardizedApartCheckNotRequired(); } if (null == parentFactors) { c.calculateFactors(nonTrivialFactors); nonTrivialFactors.AddRange(c.getFactors()); } else { if (!parentFactors.Contains(c)) { c.calculateFactors(nonTrivialFactors); nonTrivialFactors.AddRange(c.getFactors()); } } } } } } factors = new List<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.AddRange(nonTrivialFactors); }
private bool checkSubsumes(Clause othC, Dictionary<String, List<Literal>> thisToTry, Dictionary<String, List<Literal>> othCToTry) { bool subsumes = false; List<Term> thisTerms = new List<Term>(); List<Term> othCTerms = new List<Term>(); // Want to track possible number of permuations List<int> radixs = new List<int>(); foreach (String literalName in thisToTry.Keys) { int sizeT = thisToTry[literalName].Count; int sizeO = othCToTry[literalName].Count; 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) { radixs.Add(r); } } } // Track the terms for this clause foreach (Literal tl in thisToTry[literalName]) { List<Term> folNodes = tl.getAtomicSentence().getArgs(); foreach (FOLNode n in folNodes) { thisTerms.Add((Term)n); } } } MixedRadixNumber permutation = null; long numPermutations = 1L; if (radixs.Count > 0) { permutation = new MixedRadixNumber(0, radixs); 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. List<Variable> othCVariables = _variableCollector .collectAllVariables(othC); Dictionary<Variable, Term> theta = new Dictionary<Variable, Term>(); List<Literal> literalPermuations = new List<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.Keys) { int sizeT = thisToTry[literalName].Count; literalPermuations.Clear(); literalPermuations.AddRange(othCToTry[literalName]); int sizeO = literalPermuations.Count; 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[numPos]; literalPermuations.Remove(lit); foreach (FOLNode arg in lit.getAtomicSentence().getArgs()) { othCTerms.Add((Term)arg); } radixIdx++; } else { // is the last mapping, therefore // won't be on the radix foreach (FOLNode arg in literalPermuations[0].getAtomicSentence().getArgs()) { othCTerms.Add((Term)arg); } } } } else { // a 1 to 1 mapping foreach (FOLNode arg in literalPermuations[0].getAtomicSentence().getArgs()) { othCTerms.Add((Term)arg); } } } // 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(); List<FOLNode> termNodes = new List<FOLNode>(); foreach (Term t in thisTerms) { termNodes.Add((FOLNode)t); } List<FOLNode> othCNodes = new List<FOLNode>(); foreach (Term t in othCTerms) { othCNodes.Add((FOLNode)t); } if (null != _unifier.unify(termNodes, othCNodes, theta)) { bool containsAny = false; foreach (Variable v in theta.Keys) { 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); }