예제 #1
0
        protected List <ReteNode> Commonize(List <ReteNode> exist)
        {
            bool changed = true;

            //на каждой итерации цикла множество уменьшается на 1 элемент, либо остаётся неизменным
            //если множество осталось неизменным, то алгоритм заканчивает работу
            while (changed)
            {
                changed = false; // на каждой итерации проверяем обновилось ли множество
                for (int i = 0; i < exist.Count; i++)
                {
                    for (int j = i + 1; j < exist.Count; j++)                         //для каждой пары [i, j]
                    {
                        ReteNode commonOutput = null;                                 //пытаемся найти общего наследника
                        if (exist[i].HasCommonOutputWith(exist[j], out commonOutput)) //если наследник существует
                        {
                            exist.RemoveAt(j);                                        //удаляем кандидатов из множества
                            exist.RemoveAt(i);
                            exist.Add(commonOutput);                                  //вставляем найденного наследника
                            changed = true;
                            break;
                        }
                    }
                    if (changed == true)
                    {
                        break;                  //если множество изменилось, то переходим к следующей итерации
                    }
                }
            }
            return(exist);
        }
예제 #2
0
 /// <summary>
 /// Удаляет факт из сети с корнем к текущем ноде.
 /// </summary>
 /// <param name="fact">Удаляемый факт.</param>
 /// <param name="parent">Текущий родитель.</param>
 public virtual void RemoveFact(IData fact, ReteNode parent)
 {
     foreach (var output in outputs)
     {
         output.RemoveFact(fact, this);
     }
 }
예제 #3
0
 /// <summary>
 /// Добавляет новое правило в сеть.
 /// </summary>
 /// <param name="statement">Новое правило.</param>
 /// <param name="parent">Текущий родитель.</param>
 /// <param name="end">Конечный нод сети.</param>
 public virtual void AddStatement(ProductionRule statement, ReteNode parent, AgendaNode end)
 {
     foreach (var output in outputs)
     {
         output.AddStatement(statement, this, end);
     }
 }
예제 #4
0
 /// <summary>
 /// Удаляет факт из сети с корнем к текущем ноде.
 /// </summary>
 /// <param name="fact">Удаляемый факт.</param>
 /// <param name="parent">Текущий родитель.</param>
 public override void RemoveFact(IData fact, ReteNode parent)
 {
     alphaMemory.Remove(fact);
     if (alphaMemory.Count == 0) //выполнимых фактов не осталось
     {
         base.RemoveFact(fact, this);
     }
 }
예제 #5
0
        /// <summary>
        /// Сливает текущий нод с заданным.
        /// </summary>
        /// <param name="node">Второй нод.</param>
        /// <returns>Возвращает новый экземпляр <see cref="ExpertSystemShell.KnowledgeBases.ProductionModel.ReteNode"/>,
        /// который является наследником двух заданных нодов.</returns>
        public virtual ReteNode Merge(ReteNode node)
        {
            BetaNode result = new BetaNode();

            result.inputs[0] = this;
            result.inputs[1] = node;
            return(result);
        }
예제 #6
0
 /// <summary>
 /// Добавляет новое правило в сеть.
 /// </summary>
 /// <param name="statement">Новое правило.</param>
 /// <param name="parent">Текущий родитель.</param>
 /// <param name="end">Конечный нод сети.</param>
 public override void AddStatement(ProductionRule statement, ReteNode parent, AgendaNode end)
 {
     if (this.outputs.Count == 0)
     {
         this.outputs.Add(new BetaMemoryNode());
         this.outputs[0].Inputs.Add(this);
     }
     base.AddStatement(statement, parent, end);
 }
예제 #7
0
 /// <summary>
 /// Добавляет новое правило в сеть.
 /// </summary>
 /// <param name="statement">Новое правило.</param>
 /// <param name="parent">Текущий родитель.</param>
 /// <param name="end">Конечный нод сети.</param>
 public override void AddStatement(ProductionRule statement, ReteNode parent, AgendaNode end)
 {
     if (!this.outputs.Any((a) => { return(a is BetaMemoryNode); }))
     {
         this.outputs.Add(new BetaMemoryNode());
         this.outputs.Last().Inputs.Add(this);
     }
     base.AddStatement(statement, this, end);
 }
예제 #8
0
        /// <summary>
        /// Пропускает факт через сеть с корнем в текущем ноде.
        /// </summary>
        /// <param name="fact">Факт.</param>
        /// <param name="parent">Текущий родитель.</param>
        public override void AddFact(IData fact, ReteNode parent)
        {
            var clonedPred = predicate.Copy();

            clonedPred.SetVariable(fact.Name, fact);
            if (clonedPred.Calculate().Equals(true))
            {
                alphaMemory.Add(fact);
                base.AddFact(fact, this);
            }
        }
예제 #9
0
 /// <summary>
 /// Изменяет значение заданного факта в текущей сети.
 /// </summary>
 /// <param name="oldValue">Старое значение факта.</param>
 /// <param name="newValue">Новое значение факта.</param>
 /// <param name="parent">Текущий родитель.</param>
 public virtual void ChangeFact(IData oldValue, IData newValue, ReteNode parent)
 {
     foreach (var output in outputs)
     {
         output.RemoveFact(oldValue, this);
     }
     foreach (var output in outputs)
     {
         output.AddFact(newValue, this);
     }
 }
예제 #10
0
        /// <summary>
        /// Удаляет факт из сети с корнем к текущем ноде.
        /// </summary>
        /// <param name="fact">Удаляемый факт.</param>
        /// <param name="parent">Текущий родитель.</param>
        public override void RemoveFact(IData fact, ReteNode parent)
        {
            BetaMemoryNode bmn = (BetaMemoryNode)parent;

            foreach (var item in bmn.BetaMemory)
            {
                if (!ready.Contains(item))
                {
                    ready.Remove(item);
                }
            }
        }
예제 #11
0
 /// <summary>
 /// Добавляет новое правило в сеть.
 /// </summary>
 /// <param name="statement">Новое правило.</param>
 /// <param name="parent">Текущий родитель.</param>
 /// <param name="end">Конечный нод сети.</param>
 public override void AddStatement(ProductionRule statement, ReteNode parent, AgendaNode end)
 {
     if (outputs[0] == null)
     {
         outputs[0] = end;
         end.Inputs.Add(this);
     }
     if (!betaMemory.Contains(statement.Name))
     {
         betaMemory.Add(statement.Name);
     }
     base.AddStatement(statement, parent, end);
 }
예제 #12
0
        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);
            }
        }
예제 #13
0
        /// <summary>
        /// Сливает текущий нод с заданным.
        /// </summary>
        /// <param name="node">Второй нод.</param>
        /// <returns>
        /// Возвращает новый экземпляр <see cref="ExpertSystemShell.KnowledgeBases.ProductionModel.ReteNode" />,
        /// который является наследником двух заданных нодов.
        /// </returns>
        public override ReteNode Merge(ReteNode node)
        {
            ReteNode result = base.Merge(node);

            this.outputs.Add(result);
            if (node is AlphaNode)
            {
                node.Outputs.Add(result);
            }
            else
            {
                node.Outputs.Add(result);
            }
            return(result);
        }
예제 #14
0
 /// <summary>
 /// Определяет, есть ли у текущего и заданного нода общий потомок.
 /// </summary>
 /// <param name="node">Второй нод.</param>
 /// <param name="ouput">Наследник.</param>
 /// <returns>Возвращает <c>true</c>, если найден наследник, иначе - <c>false</c>.</returns>
 public bool HasCommonOutputWith(ReteNode node, out ReteNode ouput)
 {
     foreach (var n1 in this.outputs)
     {
         foreach (var n2 in node.outputs)
         {
             if (n1 == n2)
             {
                 ouput = n1;
                 return(true);
             }
         }
     }
     ouput = null;
     return(false);
 }
예제 #15
0
        /// <summary>
        /// Пропускает факт через сеть с корнем в текущем ноде.
        /// </summary>
        /// <param name="fact">Факт.</param>
        /// <param name="parent">Текущий родитель.</param>
        public override void AddFact(IData fact, ReteNode parent)
        {
            var other      = inputs[0] == parent ? inputs[1] : inputs[0];
            var otherAlpha = other as AlphaNode;

            if (otherAlpha != null && otherAlpha.AlphaMemory.Any())
            {
                IsActive = true;
                base.AddFact(fact, parent);
            }
            var otherBeta = other as BetaNode;

            if (otherBeta != null && otherBeta.IsActive)
            {
                IsActive = true;
                base.AddFact(fact, parent);
            }
        }
예제 #16
0
 public override void AddStatement(ProductionRule statement, ReteNode parent, AgendaNode end)
 {
     AddStatement(statement.Condition, statement, end);
 }