public void testDecrement() { MixedRadixNumber mrn = new MixedRadixNumber(5, new int[] { 3, 2 }); int i = 0; while (mrn.decrement()) { i++; } Assert.AreEqual(i, mrn.getMaxAllowedValue()); }
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 <FOLNode> 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); }