Example #1
0
        public void AddClause(IClause clause)
        {
            if (clause == null)
            {
                return;
            }
            _satisfiedLiterals.Clear();

            if (clause.Head != null && clause.Head.Negated && clause.Body.Count > 0)
            {
                var newClause = new Clause(new Literal(clause.Head.NegatedValue()));
                foreach (var literal in clause.Body)
                {
                    newClause.Body.Add(new Literal(literal.NegatedValue()));
                }
                AddClause(newClause);
                return;
            }

            var headNode = clause.Head != null ? (_graph.GetNode(clause.Head.Value) ?? _graph.AddNode(clause.Head.Negated ? (ILogicNode) new ClauseNode(clause.Head.Value) : new LiteralNode(clause.Head.Value)).GetNode(clause.Head.Value)) : null;

            if (clause.Body.Count < 1)
            {
                if (headNode == null)
                {
                    throw new NullReferenceException("Clause Head is null");
                }
                headNode.Fact = true;
            }
            else if (clause.Body.Count == 1)
            {
                if (clause.Head == null)
                {
                    throw new NullReferenceException("Clause Head is null");
                }
                var literal = clause.Body.First();

                if (clause.Head.Value != literal.Value)
                {
                    var node = _graph.GetNode(literal.Value) ?? _graph.AddNode(literal.Negated ? (ILogicNode) new ClauseNode(literal.Value) : new LiteralNode(literal.Value)).GetNode(literal.Value);

                    if (_graph.GetEdge(headNode, node) == null)
                    {
                        _graph.AddEdge(new DirectedEdge <ILogicNode> (headNode, node));
                    }
                }
            }
            else if (clause.Body.Count > 1)
            {
                if (clause.Head != null)
                {
                    var literals = clause.Body.Where(literal => clause.Head.Value != literal.Value).ToList();
                    if (literals.Count > 0)
                    {
                        var clauseKey  = ClauseKey(literals);
                        var clauseNode = _graph.GetNode(clauseKey) ?? _graph.AddNode(new ClauseNode(clauseKey)).GetNode(clauseKey);

                        if (_graph.GetEdge(headNode, clauseNode) == null)
                        {
                            _graph.AddEdge(new DirectedEdge <ILogicNode> (headNode, clauseNode));
                        }

                        foreach (var literalNode in literals.Select(literal => _graph.GetNode(literal.Value) ?? _graph.AddNode(literal.Negated ? (ILogicNode) new ClauseNode(literal.Value) : new LiteralNode(literal.Value)).GetNode(literal.Value)).Where(literalNode => _graph.GetEdge(clauseNode, literalNode) == null))
                        {
                            _graph.AddEdge(new WeightedDirectedEdge <ILogicNode> (clauseNode, literalNode, 1));
                        }
                    }
                }
                else
                {
                    var disjointLiteralKey = DisjointLiteralKey(clause.Body);
                    var disjointLiteral    = _graph.GetNode(disjointLiteralKey) ?? _graph.AddNode(new LiteralNode(disjointLiteralKey)).GetNode(disjointLiteralKey);

                    foreach (var literalNode in clause.Body.Select(literal => _graph.GetNode(literal.Value) ?? _graph.AddNode(literal.Negated ? (ILogicNode) new ClauseNode(literal.Value) : new LiteralNode(literal.Value)).GetNode(literal.Value)).Where(literalNode => _graph.GetEdge(disjointLiteral, literalNode) == null))
                    {
                        _graph.AddEdge(new DirectedEdge <ILogicNode>(disjointLiteral, literalNode));
                    }
                }
            }

            var negated = clause.Head != null ? new Clause(new Literal(clause.Head.NegatedValue())) : new Clause();

            foreach (var dependency in clause.Body)
            {
                negated.Body.Add(new Literal(dependency.NegatedValue()));
            }
            AddNegatedClause(negated);

            if (headNode != null && negated.Head != null)
            {
                var negatedHeadNode = _graph.GetNode(negated.Head.Value);
                if (negatedHeadNode != null)
                {
                    if (headNode.Fact && negatedHeadNode.Fact)
                    {
                        throw new Exception("KB is inconsistent, " + headNode.Id + " and " + negatedHeadNode.Id + " are both facts!");
                    }

                    if (clause.Body.Count > 0)
                    {
                        var nodesA = clause.Body.Select(literal => _graph.GetNode(literal.Value));
                        var nodesB = clause.Body.Select(literal => _graph.GetNode(literal.NegatedValue()));
                        if (SharedAncestor(nodesA, nodesB))
                        {
                            Console.WriteLine("Adding " + clause.ToProperString() + " will cause conflict skipping clause...");
                            RemoveClause(clause);
                        }
                    }
                }
            }

            if (headNode != null && headNode.Fact)
            {
                FactFlow(headNode);
            }
            if (clause.Body.Count > 0)
            {
                foreach (var node in clause.Body.Select(literal => _graph.GetNode(literal.Value)).Where(node => node.Fact))
                {
                    FactFlow(node);
                }

                foreach (var node in clause.Body.Select(literal => _graph.GetNode(literal.NegatedValue())).Where(node => node.Fact))
                {
                    FactFlow(node);
                }
            }
        }