/// <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); } }
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); }
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); }
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; }
/// <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(); }