Пример #1
0
        public object VisitQuantifiedSentence(QuantifiedSentence sentence,
                                              object arg)
        {
            ISentence quantified     = sentence.Quantified;
            var       universalScope = (ISet <Variable>)arg;

            // Skolemize: Skolemization is the process of removing existential
            // quantifiers by elimination. This is done by introducing Skolem
            // functions. The general rule is that the arguments of the Skolem
            // function are all the universally quantified variables in whose
            // scope the existential quantifier appears.
            if (Quantifiers.IsExists(sentence.Quantifier))
            {
                IDictionary <Variable, ITerm> skolemSubst = new Dictionary <Variable, ITerm>();
                foreach (Variable eVar in sentence.Variables)
                {
                    if (universalScope.Count > 0)
                    {
                        // Replace with a Skolem Function
                        var skolemFunctionName = parser.GetFOLDomain()
                                                 .AddSkolemFunction();
                        skolemSubst[eVar] = new Function(skolemFunctionName, new List <ITerm>((IEnumerable <ITerm>)universalScope));
                    }
                    else
                    {
                        // Replace with a Skolem Constant
                        String skolemConstantName = parser.GetFOLDomain()
                                                    .AddSkolemConstant();
                        skolemSubst[eVar] = new Constant(skolemConstantName);
                    }
                }

                ISentence skolemized = substVisitor.Subst(skolemSubst, quantified);
                return(skolemized.Accept(this, arg));
            }

            // Drop universal quantifiers.
            if (Quantifiers.IsForall(sentence.Quantifier))
            {
                // Add to the universal scope so that
                // existential skolemization may be done correctly
                universalScope.UnionWith(sentence.Variables);

                ISentence droppedUniversal = (ISentence)quantified.Accept(this, arg);

                // Enusre my scope is removed before moving back up
                // the call stack when returning
                foreach (var v in sentence.Variables)
                {
                    universalScope.Remove(v);
                }

                return(droppedUniversal);
            }

            // Should not reach here as have already
            // handled the two quantifiers.
            throw new InvalidOperationException("Unhandled Quantifier:" + sentence.Quantifier);
        }
Пример #2
0
        public object VisitNotSentence(NotSentence notSentence, object arg)
        {
            // CNF requires NOT (~) to appear only in literals, so we 'move ~
            // inwards' by repeated application of the following equivalences:
            ISentence negated = notSentence.Negated;

            // ~(~alpha) equivalent to alpha (double negation elimination)
            if (negated is NotSentence)
            {
                return(((NotSentence)negated).Negated.Accept(this, arg));
            }

            if (negated is ConnectedSentence)
            {
                ConnectedSentence negConnected = (ConnectedSentence)negated;
                ISentence         alpha        = negConnected.First;
                ISentence         beta         = negConnected.Second;
                // ~(alpha ^ beta) equivalent to (~alpha V ~beta) (De Morgan)
                if (Connectors.IsAnd(negConnected.Connector))
                {
                    // I need to ensure the ~s are moved in deeper
                    ISentence notAlpha = (ISentence)(new NotSentence(alpha)).Accept(
                        this, arg);
                    ISentence notBeta = (ISentence)(new NotSentence(beta)).Accept(
                        this, arg);
                    return(new ConnectedSentence(Connectors.Or, notAlpha, notBeta));
                }

                // ~(alpha V beta) equivalent to (~alpha ^ ~beta) (De Morgan)
                if (Connectors.IsOr(negConnected.Connector))
                {
                    // I need to ensure the ~s are moved in deeper
                    ISentence notAlpha = (ISentence)(new NotSentence(alpha)).Accept(
                        this, arg);
                    ISentence notBeta = (ISentence)(new NotSentence(beta)).Accept(
                        this, arg);
                    return(new ConnectedSentence(Connectors.And, notAlpha, notBeta));
                }
            }

            // in addition, rules for negated quantifiers:
            if (negated is QuantifiedSentence)
            {
                QuantifiedSentence negQuantified = (QuantifiedSentence)negated;
                // I need to ensure the ~ is moved in deeper
                ISentence notP = (ISentence)(new NotSentence(negQuantified
                                                             .Quantified)).Accept(this, arg);

                // ~ForAll x p becomes Exists x ~p
                if (Quantifiers.IsForall(negQuantified.Quantifier))
                {
                    return(new QuantifiedSentence(Quantifiers.Exists, negQuantified
                                                  .Variables, notP));
                }

                // ~Exists x p becomes ForAll x ~p
                if (Quantifiers.IsExists(negQuantified.Quantifier))
                {
                    return(new QuantifiedSentence(Quantifiers.ForAll, negQuantified
                                                  .Variables, notP));
                }
            }

            return(new NotSentence((ISentence)negated.Accept(this, arg)));
        }