static void Main(string[] args) { Clauses C = new Clauses(); //add KB to Clauses in CNF form C.Add(new List <string> { "a", "!b" }); //a+!b C.Add(new List <string> { "b", "!c", "!d" }); //b+!c+!d C.Add(new List <string> { "b", "c", "!d" }); //b+c+!d C.Add(new List <string> { "d" }); //d //CHANGE THIS LINE TO CHECK OTHER LITERALS List <string> formula = new List <string>() { "!b" }; //define as CNF, KB:=a --> formula/clause = !a to proof nonsatisfaction, Console.WriteLine(C.Print() + " =: " + formula[0]); //Console.ReadLine(); //bool enumerates = Algorithm.linearResolution(C, new List<string>(formula)); bool enumerates = Algorithm.Astar(C, formula); Console.WriteLine("KB := !" + C.Print(formula) + " is " + enumerates.ToString()); Console.ReadLine(); }
public List <Node> getChildren() { List <Node> children = new List <Node>(); for (int i = 0; i < Kb.allClauses.Count; i++) { if (canSolve(Kb.allClauses[i])) { var clause1 = new List <string>(Kb.allClauses[i]); var clause2 = new List <string>(ResolvedClause); var solvedClause = Algorithm.resolutionRule(clause1, clause2, out int heuristic); //Kb.allClauses.Add(solvedClause); var tempKb = new Clauses { allClauses = new List <List <string> >(Kb.allClauses) }; tempKb.allClauses.Add(ResolvedClause); //Need to add pathCost var node = new Node() { Kb = tempKb, //I wonder if it works, since syntax is a bit weird xD parent = this, ResolvedClause = solvedClause, Cost = Cost + heuristic }; children.Add(node); } } return(children); }
//it is like Uniform cost search, but we have an ordered queue //path cost is set in problem class.. // algo from Book: figure 3.14 public static Boolean Astar(Clauses kb, List <string> formula) { //Node node = new Node(problem.initial(), null, null, 0); var node = new Node { Kb = kb, ResolvedClause = formula, Cost = 0 }; List <Node> frontier = new List <Node>(); //priority queue frontier.Add(node); List <Node> expanded = new List <Node>(); var index = 0; while (frontier.Any()) { frontier.OrderBy(x => x.Cost); //orders frontier in ascending order node = frontier[0]; //picks the one with lowest value Console.WriteLine(node.Kb.Print() + " =: " + node.Kb.Print(node.ResolvedClause)); //Console.WriteLine("current node: " + node.State().print()); if (node.Kb.allClauses.Count == 0 || frontier.Exists(x => x.ResolvedClause.Count() == 0)) { return(true); } frontier.Remove(node); expanded.Add(node); foreach (Node child in node.getChildren()) { //if child state not in frontier and not in expanded if ((!frontier.Exists(x => x.Kb == child.Kb))) { if (!expanded.Exists(x => x.Kb == child.Kb)) { frontier.Add(child); } } else//here we know that chil is in frontier, as above if failed. { //if node already exist in frontier, but child can reach it wirh less cost, then replace node in frontier. int i = frontier.FindIndex(x => x.Kb == child.Kb); if (frontier[i].Cost > child.Cost) { frontier[i] = child; } } } } Console.WriteLine("\n" + "Frontier is empty, no solution found."); return(false); //if frontier is empty }