Exemple #1
0
        public CNF ConvertToCNF(ISentence aSentence)
        {
            // I)mplications Out:
            ISentence implicationsOut = (ISentence)aSentence.Accept(
                new ImplicationsOut(), null);

            // N)egations In:
            ISentence negationsIn = (ISentence)implicationsOut.Accept(
                new NegationsIn(), null);

            // S)tandardize variables:
            // For sentences like:
            // (ForAll x P(x)) V (Exists x Q(x)),
            // which use the same variable name twice, change the name of one of the
            // variables.
            ISentence saQuantifiers = (ISentence)negationsIn.Accept(
                new StandardizeQuantiferVariables(substVisitor),
                new HashSet <Variable>());

            // Remove explicit quantifiers, by skolemizing existentials
            // and dropping universals:
            // E)xistentials Out
            // A)lls Out:
            ISentence andsAndOrs = (ISentence)saQuantifiers.Accept(
                new RemoveQuantifiers(parser), new HashSet <Variable>());

            // D)istribution
            // V over ^:
            ISentence orDistributedOverAnd = (ISentence)andsAndOrs.Accept(
                new DistributeOrOverAnd(), null);

            // O)perators Out
            return((new CNFConstructor()).Construct(orDistributedOverAnd));
        }
Exemple #2
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);
        }
        // Note: The set guarantees the order in which they were
        // found.
        public ISet <Variable> CollectAllVariables(ISentence sentence)
        {
            ISet <Variable> variables = new HashedSet <Variable>();

            sentence.Accept(this, variables);

            return(variables);
        }
Exemple #4
0
        public CNF Construct(ISentence orDistributedOverAnd)
        {
            var ad = new ArgData();

            orDistributedOverAnd.Accept(this, ad);

            return(new CNF(ad.Clauses));
        }
Exemple #5
0
        public object VisitConnectedSentence(ConnectedSentence sentence, object arg)
        {
            ArgData   ad     = (ArgData)arg;
            ISentence first  = sentence.First;
            ISentence second = sentence.Second;

            first.Accept(this, arg);
            if (Connectors.IsAnd(sentence.Connector))
            {
                ad.Clauses.Add(new Clause());
            }
            second.Accept(this, arg);

            return(sentence);
        }
Exemple #6
0
        public object VisitQuantifiedSentence(QuantifiedSentence sentence, object arg)
        {
            ISet <Variable> seenSoFar = (ISet <Variable>)arg;

            // Keep track of what I have to subst locally and
            // what my renamed variables will be.
            IDictionary <Variable, ITerm> localSubst = new Dictionary <Variable, ITerm>();
            IList <Variable> replVariables           = new List <Variable>();

            foreach (Variable v in sentence.Variables)
            {
                // If local variable has be renamed already
                // then I need to come up with own name
                if (seenSoFar.Contains(v))
                {
                    var sV = new Variable(quantifiedIndexical.GetPrefix()
                                          + quantifiedIndexical.GetNextIndex());
                    localSubst[v] = sV;
                    // Replacement variables should contain new name for variable
                    replVariables.Add(sV);
                }
                else
                {
                    // Not already replaced, this name is good
                    replVariables.Add(v);
                }
            }

            // Apply the local subst
            ISentence subst = substVisitor.Subst(localSubst, sentence.Quantified);

            // Ensure all my existing and replaced variable
            // names are tracked
            seenSoFar.UnionWith(replVariables);

            var sQuantified = (ISentence)subst.Accept(this, arg);

            return(new QuantifiedSentence(sentence.Quantifier, replVariables,
                                          sQuantified));
        }
Exemple #7
0
        public object VisitNotSentence(NotSentence notSentence, object arg)
        {
            ISentence negated = notSentence.Negated;

            return(new NotSentence((ISentence)negated.Accept(this, arg)));
        }
Exemple #8
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)));
        }
 private static void CollectAllVariables(ISentence s, IList <Variable> vars)
 {
     s.Accept(_collectAllVariables, vars);
 }
Exemple #10
0
 public IList <Predicate> GetPredicates(ISentence s)
 {
     return((IList <Predicate>)s.Accept(this, new List <Predicate>()));
 }
Exemple #11
0
 /// <summary>
 /// Note: Refer to Artificial Intelligence A Modern Approach (3rd Edition): page 323
 /// </summary>
 /// <param name="theta">a substitution.</param>
 /// <param name="aSentence">the substitution has been applied to.</param>
 /// <returns>a new Sentence representing the result of applying the substitution theta to aSentence.</returns>
 public ISentence Subst(IDictionary <Variable, ITerm> theta, ISentence aSentence)
 {
     return((ISentence)aSentence.Accept(this, theta));
 }