protected bool FindNode(Expression expression, out AlphaNode node) { Stack <AlphaNode> stack = new Stack <AlphaNode>(); node = null; IData sampleFact = expression.GetFact(); foreach (var n in outputs) { stack.Push((AlphaNode)n); } while (stack.Count > 0) { AlphaNode currNode = stack.Pop(); if (currNode.Predicate.IsFact()) { IData fact = currNode.Predicate.GetFact(); if (fact.Equals(sampleFact)) { node = currNode; return(true); } } foreach (var n in currNode.Outputs) { AlphaNode child = n as AlphaNode; if (child != null) { stack.Push(child); } } } return(false); }
protected void AddAndMerge(IEnumerable <Expression> conditions, ProductionRule statement, AgendaNode end) { List <ReteNode> exist = new List <ReteNode>(); //список уже существующих нодов List <ReteNode> add = new List <ReteNode>(); // список новых нодов foreach (var c in conditions) //находим уже сущеcтвующие Alpha ноды { AlphaNode n = null; if (FindNode(c, out n)) // если нод существует, то добавляем его к списку существующих { exist.Add(n); } else { AlphaNode n1 = new AlphaNode(); //иначе создаём новый n1.Predicate = c; n1.Inputs[0] = this; //связываем его с корнем this.outputs.Add(n1); add.Add(n1); //добавляем его в список новых нодов } } exist = Commonize(exist); //находим наиболее общих наследников foreach (var n in add) //теперь всё в одном списке { exist.Add(n); } while (exist.Count > 1) //объединяем всё, что осталось { ReteNode n1 = exist[0]; ReteNode n2 = exist[1]; exist.RemoveAt(0); exist.RemoveAt(0); ReteNode unuion = n1.Merge(n2); exist.Add(unuion); } BetaMemoryNode bm = (BetaMemoryNode)exist[0].Outputs.FirstOrDefault((a) => { return(a is BetaMemoryNode); }); if (bm == null) { bm = new BetaMemoryNode(); bm.Outputs[0] = end; bm.Inputs.Add(exist[0]); exist[0].Outputs.Add(bm); } if (!bm.BetaMemory.Contains(statement.Name)) { bm.BetaMemory.Add(statement.Name); } }