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);
 }