예제 #1
0
        /// <summary>
        /// <code>
        /// function FOL-BC-ASK(KB, goals, theta) returns a set of substitutions
        ///   input: KB, a knowledge base
        ///          goals, a list of conjuncts forming a query (theta already applied)
        ///          theta, the current substitution, initially the empty substitution {}
        /// </code>
        /// </summary>
        /// <param name="KB"></param>
        /// <param name="ansHandler"></param>
        /// <param name="goals"></param>
        /// <param name="theta"></param>
        /// <returns></returns>
        private IList <IList <ProofStepBwChGoal> > Folbcask(FOLKnowledgeBase KB,
                                                            BCAskAnswerHandler ansHandler, IList <Literal> goals,
                                                            IDictionary <Variable, ITerm> theta)
        {
            var thisLevelProofSteps = new List <IList <ProofStepBwChGoal> >();

            // local variables: answers, a set of substitutions, initially empty

            // if goals is empty then return {theta}
            if (goals.Count == 0)
            {
                thisLevelProofSteps.Add(new List <ProofStepBwChGoal>());
                return(thisLevelProofSteps);
            }

            // qDelta <- SUBST(theta, FIRST(goals))
            Literal qDelta = KB.Subst(theta, goals[0]);

            // for each sentence r in KB where
            // STANDARDIZE-APART(r) = (p1 ^ ... ^ pn => q)
            foreach (Clause r in KB.GetAllDefiniteClauses())
            {
                var standardizedR = KB.StandardizeApart(r);
                // and thetaDelta <- UNIFY(q, qDelta) succeeds
                IDictionary <Variable, ITerm> thetaDelta = KB.Unify(standardizedR.GetPositiveLiterals()[0].AtomicSentence, qDelta.AtomicSentence);
                if (null != thetaDelta)
                {
                    // new_goals <- [p1,...,pn|REST(goals)]
                    var newGoals = new List <Literal>(standardizedR.GetNegativeLiterals());
                    newGoals.AddRange(goals.Skip(1));
                    // answers <- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta,
                    // theta)) U answers
                    IDictionary <Variable, ITerm>      composed             = this.Compose(KB, thetaDelta, theta);
                    IList <IList <ProofStepBwChGoal> > lowerLevelProofSteps = this.Folbcask(
                        KB, ansHandler, newGoals, composed);

                    ansHandler.AddProofStep(lowerLevelProofSteps, standardizedR, qDelta,
                                            composed);

                    thisLevelProofSteps.AddRange(lowerLevelProofSteps);
                }
            }

            // return answers
            return(thisLevelProofSteps);
        }
예제 #2
0
        public IInferenceResult Ask(FOLKnowledgeBase kb, ISentence alpha)
        {
            // clauses <- the set of clauses in CNF representation of KB ^ ~alpha
            ISet <Clause> clauses = new HashedSet <Clause>();

            foreach (Clause c in kb.GetAllClauses())
            {
                var standardizedC = kb.StandardizeApart(c);
                standardizedC.SetStandardizedApartCheckNotRequired();
                clauses.UnionWith(standardizedC.GetFactors());
            }
            ISentence notAlpha = new NotSentence(alpha);
            // Want to use an answer literal to pull
            // query variables where necessary
            Literal         answerLiteral          = kb.CreateAnswerLiteral(notAlpha);
            ISet <Variable> answerLiteralVariables = kb
                                                     .CollectAllVariables(answerLiteral.AtomicSentence);
            Clause answerClause = new Clause();

            if (answerLiteralVariables.Count > 0)
            {
                ISentence notAlphaWithAnswer = new ConnectedSentence(Connectors.Or,
                                                                     notAlpha, answerLiteral.AtomicSentence);
                foreach (Clause c in kb.ConvertToClauses(notAlphaWithAnswer))
                {
                    var standardizedC = kb.StandardizeApart(c);
                    standardizedC.SetProofStep(new ProofStepGoal(standardizedC));
                    standardizedC.SetStandardizedApartCheckNotRequired();
                    clauses.UnionWith(standardizedC.GetFactors());
                }

                answerClause.AddLiteral(answerLiteral);
            }
            else
            {
                foreach (Clause c in kb.ConvertToClauses(notAlpha))
                {
                    var standardizedC = kb.StandardizeApart(c);
                    standardizedC.SetProofStep(new ProofStepGoal(standardizedC));
                    standardizedC.SetStandardizedApartCheckNotRequired();
                    clauses.UnionWith(standardizedC.GetFactors());
                }
            }

            var ansHandler = new TFMAnswerHandler(answerLiteral,
                                                  answerLiteralVariables, answerClause, this.MaxQueryTime);

            // new <- {}
            ISet <Clause> newClauses = new HashedSet <Clause>();
            ISet <Clause> toAdd      = new HashedSet <Clause>();
            // loop do
            int noOfPrevClauses = clauses.Count;

            do
            {
                if (Tracer != null)
                {
                    Tracer.StepStartWhile(clauses, clauses.Count, newClauses
                                          .Count);
                }

                newClauses.Clear();

                // for each Ci, Cj in clauses do
                Clause[] clausesA = new Clause[clauses.Count];
                clausesA = clauses.ToArray();
                // Basically, using the simple T)wo F)inger M)ethod here.
                for (int i = 0; i < clausesA.Length; i++)
                {
                    Clause cI = clausesA[i];
                    if (null != Tracer)
                    {
                        Tracer.StepOuterFor(cI);
                    }
                    for (int j = i; j < clausesA.Length; j++)
                    {
                        Clause cJ = clausesA[j];

                        if (null != Tracer)
                        {
                            Tracer.StepInnerFor(cI, cJ);
                        }

                        // resolvent <- FOL-RESOLVE(Ci, Cj)
                        ISet <Clause> resolvents = cI.BinaryResolvents(cJ);

                        if (resolvents.Count > 0)
                        {
                            toAdd.Clear();
                            // new <- new <UNION> resolvent
                            foreach (Clause rc in resolvents)
                            {
                                toAdd.UnionWith(rc.GetFactors());
                            }

                            if (null != Tracer)
                            {
                                Tracer.StepResolved(cI, cJ, toAdd);
                            }

                            ansHandler.CheckForPossibleAnswers(toAdd);

                            if (ansHandler.IsComplete())
                            {
                                break;
                            }

                            newClauses.UnionWith(toAdd);
                        }

                        if (ansHandler.IsComplete())
                        {
                            break;
                        }
                    }
                    if (ansHandler.IsComplete())
                    {
                        break;
                    }
                }

                noOfPrevClauses = clauses.Count;

                // clauses <- clauses <UNION> new
                clauses.UnionWith(newClauses);

                if (ansHandler.IsComplete())
                {
                    break;
                }

                // if new is a <SUBSET> of clauses then finished
                // searching for an answer
                // (i.e. when they were added the # clauses
                // did not increase).
            } while (noOfPrevClauses < clauses.Count);

            if (null != Tracer)
            {
                Tracer.StepFinished(clauses, ansHandler);
            }

            return(ansHandler);
        }
예제 #3
0
        public IInferenceResult Ask(FOLKnowledgeBase KB, ISentence alpha) 
        {
            ISet<Clause> sos = new HashedSet<Clause>();
            ISet<Clause> usable = new HashedSet<Clause>();

            // Usable set will be the set of clauses in the KB,
            // are assuming this is satisfiable as using the
            // ISet of Support strategy.
            //foreach (var standardizedC in KB.GetAllClauses().Select(c => KB.StandardizeApart(c)))
            foreach (var standardizedC in KB.GetAllClauses())
            {
                standardizedC.SetStandardizedApartCheckNotRequired();
                usable.UnionWith(standardizedC.GetFactors());
            }

            // Ensure reflexivity axiom is added to usable if using paramodulation.
            if (this.UseParamodulation) 
            {
                // Reflexivity Axiom: x = x
                var reflexivityAxiom = new TermEquality(new Variable("x"), new Variable("x"));
                var reflexivityClause = new Clause();
                reflexivityClause.AddLiteral(new Literal(reflexivityAxiom));
                reflexivityClause = KB.StandardizeApart(reflexivityClause);
                reflexivityClause.SetStandardizedApartCheckNotRequired();
                usable.Add(reflexivityClause);
            }

            ISentence notAlpha = new NotSentence(alpha);
            // Want to use an answer literal to pull
            // query variables where necessary
            var answerLiteral = KB.CreateAnswerLiteral(notAlpha);
            var answerLiteralVariables = KB
                    .CollectAllVariables(answerLiteral.AtomicSentence);
            var answerClause = new Clause();

            if (answerLiteralVariables.Count > 0) {
                ISentence notAlphaWithAnswer = new ConnectedSentence(Connectors.Or,
                        notAlpha, answerLiteral.AtomicSentence);
               // foreach (var standardizedC in
              //      KB.ConvertToClauses(notAlphaWithAnswer).Select(KB.StandardizeApart))
                  foreach (var standardizedC in
                      KB.ConvertToClauses(notAlphaWithAnswer))
                   {
                       Clause c = KB.StandardizeApart(standardizedC);
                       c.SetProofStep(new ProofStepGoal(c));
                       c.SetStandardizedApartCheckNotRequired();
                       sos.UnionWith(c.GetFactors());
                   }

                answerClause.AddLiteral(answerLiteral);
            } 
            else 
            {
                //foreach (var standardizedC in
                //    KB.ConvertToClauses(notAlpha).Select(KB.StandardizeApart)) 
                foreach (var standardizedC in
                    KB.ConvertToClauses(notAlpha))
                {
                    Clause c = KB.StandardizeApart(standardizedC);
                    c.SetProofStep(new ProofStepGoal(c));
                    c.SetStandardizedApartCheckNotRequired();
                    sos.UnionWith(standardizedC.GetFactors());
                }
            }

            // Ensure all subsumed clauses are removed
            usable.ExceptWith(SubsumptionElimination.FindSubsumedClauses(usable));
            sos.ExceptWith(SubsumptionElimination.FindSubsumedClauses(sos));

            var ansHandler = new OTTERAnswerHandler(answerLiteral,
                    answerLiteralVariables, answerClause, this.MaxQueryTime);

            var idxdClauses = new IndexedClauses(LightestClauseHeuristic, sos, usable);

            return this.Otter(ansHandler, idxdClauses, sos, usable);
        }
예제 #4
0
        /// <summary>
        /// <code>
        /// function FOL-FC-ASK(KB, alpha) returns a substitution or false
        ///   inputs: KB, the knowledge base, a set of first order definite clauses
        ///           alpha, the query, an atomic sentence
        /// </code>
        /// </summary>
        /// <param name="KB"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public IInferenceResult Ask(FOLKnowledgeBase KB, ISentence query)
        {
            // Assertions on the type of queries this Inference procedure
            // supports
            if (!(query is IAtomicSentence))
            {
                throw new ArgumentOutOfRangeException("query", "Only Atomic Queries are supported.");
            }

            var ansHandler = new FCAskAnswerHandler();

            var alpha = new Literal((IAtomicSentence)query);

            // local variables: new, the new sentences inferred on each iteration
            IList <Literal> newSentences = new List <Literal>();

            // Ensure query is not already a know fact before
            // attempting forward chaining.
            ISet <IDictionary <Variable, ITerm> > answers = KB.Fetch(alpha);

            if (answers.Count > 0)
            {
                ansHandler.AddProofStep(new ProofStepFoChAlreadyAFact(alpha));
                ansHandler.SetAnswers(answers);
                return(ansHandler);
            }

            // repeat until new is empty
            do
            {
                // new <- {}
                newSentences.Clear();
                // for each rule in KB do
                // (p1 ^ ... ^ pn => q) <-STANDARDIZE-VARIABLES(rule)
                foreach (Clause impl in KB.GetAllDefiniteClauseImplications())
                {
                    var standardizedImpl = KB.StandardizeApart(impl);
                    // for each theta such that SUBST(theta, p1 ^ ... ^ pn) =
                    // SUBST(theta, p'1 ^ ... ^ p'n)
                    // --- for some p'1,...,p'n in KB
                    foreach (IDictionary <Variable, ITerm> theta in KB.Fetch(this.Invert(standardizedImpl.GetNegativeLiterals())))
                    {
                        // q' <- SUBST(theta, q)
                        Literal qPrime = KB.Subst(theta, standardizedImpl.GetPositiveLiterals()[0]);
                        // if q' does not unify with some sentence already in KB or
                        // new then do
                        if (!KB.IsRenaming(qPrime) &&
                            !KB.IsRenaming(qPrime, newSentences))
                        {
                            // add q' to new
                            newSentences.Add(qPrime);
                            ansHandler.AddProofStep(standardizedImpl, qPrime, theta);
                            // theta <- UNIFY(q', alpha)

                            // if theta is not fail then return theta
                            if (KB.Unify(qPrime.AtomicSentence, alpha.AtomicSentence) != null)
                            {
                                foreach (Literal l in newSentences)
                                {
                                    ISentence s;
                                    if (l.IsPositiveLiteral())
                                    {
                                        s = l.AtomicSentence;
                                    }
                                    else
                                    {
                                        s = new NotSentence(l.AtomicSentence);
                                    }
                                    KB.tell(s);
                                }
                                ansHandler.SetAnswers(KB.Fetch(alpha));
                                return(ansHandler);
                            }
                        }
                    }
                }
                // add new to KB
                foreach (Literal l in newSentences)
                {
                    ISentence s;
                    if (l.IsPositiveLiteral())
                    {
                        s = l.AtomicSentence;
                    }
                    else
                    {
                        s = new NotSentence(l.AtomicSentence);
                    }
                    KB.tell(s);
                }
            } while (newSentences.Count > 0);

            // return false
            return(ansHandler);
        }