Example #1
0
        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);
        }
Example #2
0
        private bool CheckSubsumes(Clause othC, IDictionary <string, IList <Literal> > thisToTry, IDictionary <string, IList <Literal> > othCToTry)
        {
            bool subsumes = false;

            var thisTerms = new List <ITerm>();
            var othCTerms = new List <ITerm>();

            // Want to track possible number of permuations
            var 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 (var tl in thisToTry[literalName])
                {
                    thisTerms.AddRange(tl.AtomicSentence.GetArgs().Cast <ITerm>());
                }
            }

            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.
            var othCVariables      = _variableCollector.CollectAllVariables(othC);
            var theta              = new Dictionary <Variable, ITerm>();
            var literalPermuations = new List <Literal>();

            for (var l = 0L; l < numPermutations; l++)
            {
                // Track the other clause's terms for this
                // permutation.
                othCTerms.Clear();
                var radixIdx = 0;
                foreach (string literalName in thisToTry.Keys)
                {
                    var sizeT = thisToTry[literalName].Count;
                    literalPermuations.Clear();
                    literalPermuations.AddRange(othCToTry[literalName]);
                    var sizeO = literalPermuations.Count;

                    if (sizeO > 1)
                    {
                        for (var i = 0; i < sizeT; i++)
                        {
                            var 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);
                                othCTerms.AddRange(literalPermuations[numPos].AtomicSentence.GetArgs().Cast <ITerm>());
                                literalPermuations.RemoveAt(numPos);
                                radixIdx++;
                            }
                            else
                            {
                                // is the last mapping, therefore
                                // won't be on the radix
                                othCTerms.AddRange(literalPermuations[0].AtomicSentence.GetArgs().Cast <ITerm>());
                            }
                        }
                    }
                    else
                    {
                        // a 1 to 1 mapping
                        othCTerms.AddRange(literalPermuations[0].AtomicSentence.GetArgs().Cast <ITerm>());
                    }
                }

                // 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((IFOLNode)thisTerms, (IFOLNode)othCTerms, theta))
                {
                    var containsAny = theta.Keys.Any(othCVariables.Contains);
                    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);
        }
Example #3
0
        // 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);
        }