Exemple #1
0
        /// <summary>
        /// Ask the knowledge base if a given statement about the model is true, given what it knows.
        /// </summary>
        /// <param name="query"></param>
        /// <returns>True if the statement is known to be true, false if it is known to be false or cannot be determined.</returns>
        public bool Ask(Expression <Predicate <TModel> > query)
        {
            // NB: Very raw implementation - there are a number of possible performance improvements that could be made here
            // Will return to give them a go at some point..

            var queryAsCnf = new CNFExpression <TModel>(query);
            var clauses    = sentences.Append(queryAsCnf).SelectMany(s => s.Clauses).ToList();
            List <CNFClause <TModel> > newClauses = new List <CNFClause <TModel> >();

            while (true)
            {
                // TODO-PERFORMANCE: While this is how the source book writes the algorithm, its very inefficient -
                // we'll end up resolving the same clauses again and again. Need to improve this (and move this
                // implementation to the benchmarks project as a baseline).
                foreach (var ci in clauses)
                {
                    foreach (var cj in clauses)
                    {
                        var resolvents = CNFClause <TModel> .Resolve(ci, cj);

                        if (resolvents.IsEmpty)
                        {
                            return(true);
                        }

                        newClauses.Add(resolvents);
                    }
                }

                // if new ⊆ clauses then return false // need clause equality..
                clauses.AddRange(newClauses);
            }

            return(false);
        }
Exemple #2
0
        public void TestCNFClause()
        {
            CNFClause clause1 = new CNFClause(ClauseParser.Parse("a&b&c||d")),
                      clause2 = new CNFClause(ClauseParser.Parse("a=>(b&c||d&e)"));

            Console.WriteLine("{0}\n{1}", clause1.ToString(), clause2.ToString());
        }