/// <summary>
        /// Creates solvers in this object from clauses in a knowledge base
        /// </summary>
        public async Task LoadFromKnowledgeBase(IKnowledgeBase knowledge, Func<IClause, ISolver> solverForClause = null)
        {
            if (knowledge == null) throw new ArgumentNullException("knowledge");

            // By default, use the simple single clause solver
            if (solverForClause == null)
            {
                solverForClause = clause => new SimpleSingleClauseSolver(clause, this);
            }

            // Fetch the clauses from the knowledge base
            var clauses = await knowledge.GetClauses();

            // Fill the dictionary
            var solvers = clauses.Select(clause => new { Key = clause.Implies.UnificationKey, Solver = solverForClause(clause) });

            foreach (var solver in solvers)
            {
                if (solver.Key == null) continue;

                List<ISolver> solversForKey;
                if (!_solverForUnificationKey.TryGetValue(solver.Key, out solversForKey))
                {
                    solversForKey = new List<ISolver>();
                    _solverForUnificationKey.Add(solver.Key, solversForKey);
                }

                solversForKey.Add(solver.Solver);
            }
        }
Example #2
0
        public ListKnowledgeBase(IClause newClause, IKnowledgeBase next)
        {
            if (newClause == null) throw new ArgumentNullException("newClause");
            if (next == null) throw new ArgumentNullException("next");

            _clause = newClause;
            _next = CreateKnowledgeList(next);
        }
Example #3
0
        public static SearchResult Search(AbstractNode initialNode, IKnowledgeBase kb)
        {
            var frontier = new PriorityQueue<AbstractNode>();
            var explored = new List<AbstractState>();
            var statesSearched = 0; //Bliver kun brugt af os af ren interesse
            var end = initialNode.Target;
            frontier.Add(initialNode);
            explored.Add(initialNode.State);

            while (frontier.Count > 0)
            {
                // Chooses the lowest-cost node in the frontier
                var currentNode = frontier.Pop();
                statesSearched++;
                if (currentNode.State.Equals(end))
                    return new SearchResult(currentNode, statesSearched, true);

                var actions = kb.ActionsForNode(currentNode);
            //Explore /expand the current node
                foreach (var action in actions)
                {
                    var child = kb.Resolve(currentNode, action, end);
                    //System.Console.WriteLine("Frontier.Count: " + frontier.Count);

                    if (!explored.Contains(child.State) && !frontier.Contains(child))
                    {
                        explored.Add(child.State);
                        frontier.Add(child);

                    }
                    else if(true)
                    {
                        for (int i = 0; i < frontier.Count; i++)
                        {
                            var frontierNode = frontier[i];
                            if (frontierNode.State.Equals(child.State) && frontierNode.PathCost > child.PathCost)
                            {
                                frontier[i] = child;
                                break;
                            }
                        }
                    }
                }
            }

            return new SearchResult(null, statesSearched, false);
        }
Example #4
0
        private ListKnowledgeBase CreateKnowledgeList(IKnowledgeBase notList)
        {
            var result = notList as ListKnowledgeBase;
            if (result != null)
            {
                return result;
            }

            result = null;
            foreach (var clause in notList.GetClauses().Result)
            {
                result = new ListKnowledgeBase(clause, result);
            }

            return result;
        }
Example #5
0
        /// <summary>
        /// Compiles a knowledge base into a bytecode program
        /// </summary>
        public async Task Compile(IKnowledgeBase knowledge)
        {
            if (knowledge == null) throw new ArgumentNullException("knowledge");

            _compiled = null;
            _literals = null;

            // Fetch the clauses and group them by their predicate
            var predicateList = (await knowledge.GetClauses())
                .GroupBy(clause => clause.Implies.UnificationKey);

            // Compile each clause in turn
            foreach (var predicate in predicateList)
            {
                // So we can call this predicate, store the location of its first instruction
                _predicateLocation[predicate.Key] = _program.Count;
                _program.Label(predicate.Key);

                var clauseList = predicate.ToArray();
                for (var clauseNum = 0; clauseNum < clauseList.Length; ++clauseNum)
                {
                    var clause = clauseList[clauseNum];

                    // Label this position
                    var thisClause = Tuple.Create(predicate.Key, clauseNum);
                    _program.Label(thisClause);

                    // Add a backtracking point if there are multiple definitions of this clause
                    if (clauseList.Length > 1)
                    {
                        var nextClause = Tuple.Create(predicate.Key, clauseNum + 1);

                        if (clauseNum == 0)
                        {
                            // First clause uses TryMeElse
                            _program.WriteWithLabel(Operation.TryMeElse, nextClause);
                        }
                        else if (clauseNum == clauseList.Length-1)
                        {
                            // Last one uses TrustMe
                            _program.Write(Operation.TrustMe);
                        }
                        else
                        {
                            // Other clauses use RetryMeElse
                            _program.WriteWithLabel(Operation.RetryMeElse, nextClause);
                        }
                    }

                    // Compile the clause itself
                    clause.Compile(_program);

                    // Final instruction is 'proceed'
                    _program.Write(Operation.Proceed);
                }
            }

            // Bind any calls to within the program that come from the same knowledgebase
            _program.BindCalls(predicate => predicate);

            _maxVariableIndex = _program.GetMaxVariableIndex();
        }