示例#1
0
 /// <summary>
 /// Означивание переменной
 /// </summary>
 private void SetValue(Variables variable)
 {
     //если переменная не означена, то ее нет в _workMemory
     if (WorkMemory.All(x => x.Variable != variable))
     {
         //если переменная запрашиваемая, то выводим форму с вопросом
         if (variable.VarTypes.Name == "Запрашиваемая")
         {
             var askForm = new FormAsk(_es, variable);
             if (askForm.ShowDialog() == DialogResult.OK)
             {
                 //означиваем переменную, т.е. заносим ее в рабочую память
                 Values answer = askForm.GivenAnswer;
                 WorkMemory.Add(new WorkMemory {
                     Variable = variable, Value = answer, HasBeenAsked = true
                 });
             }
         }
         //если переменная выводимая или выводимо-запрашиваемая, рекурсивно доказываем подцель
         else
         {
             ProveGoal(variable);
         }
     }
     //если переменная означена, то выводим форму с вопросом, если эта переменная выводимо-запрашиваемая
     //и про нее раньше не спрашивали
     else if (variable.VarTypes.Name == "Выводимо-запрашиваемая" &&
              !WorkMemory.Single(x => x.Variable == variable).HasBeenAsked)
     {
         //спрашиваем
         var askForm = new FormAsk(_es, variable);
         if (askForm.ShowDialog() == DialogResult.OK)
         {
             //означиваем переменную, т.е. заносим ее в рабочую память
             Values answer = askForm.GivenAnswer;
             var    wm     = WorkMemory.Single(x => x.Variable == variable);
             wm.HasBeenAsked = true;
             wm.Value        = answer;
         }
     }
 }
示例#2
0
        private Values ProveGoal(Variables varToProve)
        {
            //Строим горячий набор правил
            var   r             = _es.Conclusions.Where(x => x.VariableID == varToProve.Id);
            var   hotSetOfRules = r.Select(rr => rr.Rules).OrderBy(x => x.Number).ToList();
            Rules workedRule    = null;
            int   ruleNum       = 0;

            while (ruleNum < hotSetOfRules.Count() && workedRule == null)
            {
                var rule = hotSetOfRules[ruleNum];
                //факты из посылки текущего правила
                var listOfVariablesInFact = _es.Facts.Where(x => x.RuleID == rule.Id).OrderBy(x => x.Number);
                //означиваем посылку
                bool goodRule = true;
                int  i        = 0;
                while (i < listOfVariablesInFact.Count() && goodRule)
                {
                    var fact     = listOfVariablesInFact.ToList()[i];
                    var variable = fact.Variables;
                    //означиваем переменную
                    SetValue(variable);
                    //теперь, когда переменная означена, проверяем, совпадает ли ее значение со значением в правиле
                    //если совпадает, то все ок
                    //если не совпадает, переходим на следующее правило
                    var    ss = WorkMemory.SingleOrDefault(x => x.Variable == variable);
                    Values v1 = ss == null ? null : ss.Value;
                    var    v2 = fact.Values;
                    if (v1 != v2)
                    {
                        goodRule = false;
                    }
                    i++;
                }
                if (goodRule) //все ок, правило срабатывает
                {
                    workedRule = rule;
                }
                else //правило не сработало, берем следующее
                {
                    ruleNum++;
                }
            }
            //если есть сработавшее правило, то означиваем заключение
            //заносим в рабочую память все переменные и значения из заключения правила
            if (workedRule != null)
            {
                var listOfVariablesInConclusion = _es.Conclusions.Where(x => x.RuleID == workedRule.Id).
                                                  Select(x => x.Variables);
                foreach (var variableC in listOfVariablesInConclusion)
                {
                    WorkMemory.Add(new WorkMemory
                    {
                        Variable = variableC,
                        Value    = _es.Conclusions.Single(x => x.RuleID == workedRule.Id &&
                                                          x.Variables == variableC).Values,
                        HasBeenAsked = false
                    });
                }
                //поясняем
                //1) Имя правила
                var rName = workedRule.Name;
                //2) Список посылок в виде "Переменная = значение"
                var factList =
                    _es.Facts.Where(x => x.Rules == workedRule).Select(x => x.Variables.Name + " = " + x.Values.Name);
                //3) список заключений
                var concList =
                    _es.Conclusions.Where(x => x.Rules == workedRule).Select(
                        x => x.Variables.Name + " = " + x.Values.Name);
                //4) Объяснение
                var exp = workedRule.Explain;
                AddToExplanation(rName, factList, concList, exp);
            }
            //Ищем ответ
            var coolAnswer = WorkMemory.SingleOrDefault(x => x.Variable == varToProve);

            if (coolAnswer != null)
            {
                return(coolAnswer.Value);
            }
            if (varToProve.VarTypes.Name != "Выводимая")
            {
                var fquestion = new FormAsk(_es, varToProve);
                if (fquestion.ShowDialog() == DialogResult.OK)
                {
                    Values answer = fquestion.GivenAnswer;
                    WorkMemory.Add(new WorkMemory {
                        Variable = varToProve, Value = answer, HasBeenAsked = true
                    });
                    return(answer);
                }
            }
            //throw new ArgumentException("Ответ не найден");
            return(null);
        }