unify() public method

public unify ( FOLNode x, FOLNode y ) : Term>.Dictionary
x FOLNode
y FOLNode
return Term>.Dictionary
Beispiel #1
0
        // END-InferenceProcedure
        //

        //
        // PRIVATE METHODS
        //

        /**
         * <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>
         */
        private List<List<ProofStepBwChGoal>> folbcask(FOLKnowledgeBase KB,
                BCAskAnswerHandler ansHandler, List<Literal> goals,
                Dictionary<Variable, Term> theta)
        {
            List<List<ProofStepBwChGoal>> thisLevelProofSteps = new List<List<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())
            {
                Clause r2 = KB.standardizeApart(r);
                // and thetaDelta <- UNIFY(q, qDelta) succeeds
                Dictionary<Variable, Term> thetaDelta = KB.unify(r2.getPositiveLiterals()
                        [0].getAtomicSentence(), qDelta.getAtomicSentence());
                if (null != thetaDelta)
                {
                    // new_goals <- [p1,...,pn|REST(goals)]
                    List<Literal> newGoals = new List<Literal>(r2
                            .getNegativeLiterals());
                    newGoals.AddRange(goals.Skip(1));
                    // answers <- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta,
                    // theta)) U answers
                    Dictionary<Variable, Term> composed = compose(KB, thetaDelta, theta);
                    List<List<ProofStepBwChGoal>> lowerLevelProofSteps = folbcask(
                            KB, ansHandler, newGoals, composed);

                    ansHandler.addProofStep(lowerLevelProofSteps, r2, qDelta,
                            composed);

                    thisLevelProofSteps.AddRange(lowerLevelProofSteps);
                }
            }

            // return answers
            return thisLevelProofSteps;
        }
Beispiel #2
0
        //
        // START-InferenceProcedure

        /**
         * <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>
         */
        public InferenceResult ask(FOLKnowledgeBase KB, Sentence query)
        {
            // Assertions on the type of queries this Inference procedure
            // supports
            if (!(query is AtomicSentence))
            {
                throw new ArgumentException(
                        "Only Atomic Queries are supported.");
            }

            FCAskAnswerHandler ansHandler = new FCAskAnswerHandler();

            Literal alpha = new Literal((AtomicSentence)query);

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

            // Ensure query is not already a know fact before
            // attempting forward chaining.
            List<Dictionary<Variable, Term>> 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())
                {
                    Clause impl2 = 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 (Dictionary<Variable, Term> theta in KB.fetch(invert(new List<Literal>(impl2
                            .getNegativeLiterals()))))
                    {
                        // q' <- SUBST(theta, q)
                        Literal qPrime = KB.subst(theta, impl.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(impl, qPrime, theta);
                            // theta <- UNIFY(q', alpha)
                            Dictionary<Variable, Term> theta2 = KB.unify(qPrime.getAtomicSentence(), alpha
                                    .getAtomicSentence());
                            // if theta is not fail then return theta
                            if (null != theta2)
                            {
                                foreach (Literal l in newSentences)
                                {
                                    Sentence s = null;
                                    if (l.isPositiveLiteral())
                                    {
                                        s = l.getAtomicSentence();
                                    }
                                    else
                                    {
                                        s = new NotSentence(l.getAtomicSentence());
                                    }
                                    KB.tell(s);
                                }
                                ansHandler.setAnswers(KB.fetch(alpha));
                                return ansHandler;
                            }
                        }
                    }
                }
                // add new to KB
                foreach (Literal l in newSentences)
                {
                    Sentence s = null;
                    if (l.isPositiveLiteral())
                    {
                        s = l.getAtomicSentence();
                    }
                    else
                    {
                        s = new NotSentence(l.getAtomicSentence());
                    }
                    KB.tell(s);
                }
            } while (newSentences.Count > 0);

            // return false
            return ansHandler;
        }