private void RequestVariable(InferenceContext context) { var requestTask = VariableRequester.Invoke(context.Goal); var configuredTaskAwaitable = requestTask.ConfigureAwait(true); var configuredTaskAwaiter = configuredTaskAwaitable.GetAwaiter(); var answerFact = configuredTaskAwaiter.GetResult(); context.Resolved.Add(answerFact); context.Result = answerFact; WorkingMemory.ResolvedFacts.Add(answerFact); WorkingMemory.Log(answerFact, true); }
public Fact Deduce(Variable goal) { WorkingMemory = new WorkingMemory { Goal = goal }; var context = new InferenceContext() { Goal = goal, RulesToDeduce = GetRulesToDeduceVariable(goal), }; WorkingMemory.InferenceStack.Push(context); WorkingMemory.Log(goal); while (WorkingMemory.InferenceStack.Count > 0) { if (WorkingMemory.TriggeredRules.Count > MaxTriggeredRules) { WorkingMemory.Log("Превышен лимит попыток вывода правил"); break; } context = WorkingMemory.InferenceStack.Pop(); if (context.Goal.VariableKind == VariableKind.Requested) { RequestVariable(context); continue; } //if (context.RuleToDeduce == null) //{ // if (context.RulesToDeduce.Count == 0) // { // if (context.Result == null && WorkingMemory.InferenceStack.Count > 0) // { // WorkingMemory.InferenceStack.Peek().RuleToDeduce = null; // WorkingMemory.InferenceStack.Peek().FactToCheck = null; // } // continue; // } // context.RuleToDeduce = context.RulesToDeduce.Dequeue(); // WorkingMemory.TriggeredRules.Add(context.RuleToDeduce); // WorkingMemory.Log(context.RuleToDeduce); //} //if (context.FactsToCheck.Count == 0) //{ // context.FactsToCheck = new Queue<Fact>(context.RuleToDeduce.Premise); //} //context.FactToCheck = context.FactsToCheck.Dequeue(); if (context.FactsToCheck.Count > 0) { context.FactToCheck = context.FactsToCheck.Pop(); } else { if (context.RulesToDeduce.Count > 0) { context.RuleToDeduce = context.RulesToDeduce.Dequeue(); context.FactsToCheck = new Stack <Fact>(context.RuleToDeduce.Premise); context.FactToCheck = context.FactsToCheck.Pop(); WorkingMemory.TriggeredRules.Add(context.RuleToDeduce); WorkingMemory.Log(context.RuleToDeduce); } else { if (WorkingMemory.InferenceStack.Count > 0) { WorkingMemory.InferenceStack.Peek().FactsToCheck.Pop(); } continue; } } var resolvedFact = WorkingMemory .ResolvedFacts .FirstOrDefault(f => f.Variable == context.FactToCheck.Variable); if (resolvedFact == null) { var newContext = new InferenceContext() { Goal = context.FactToCheck.Variable, RulesToDeduce = GetRulesToDeduceVariable(context.FactToCheck.Variable), }; context.FactsToCheck.Push(context.FactToCheck); WorkingMemory.InferenceStack.Push(context); WorkingMemory.InferenceStack.Push(newContext); WorkingMemory.Log(newContext.Goal); } else { if (resolvedFact.Value == context.FactToCheck.Value) { if (context.FactsToCheck.Count == 0) { var resolved = context.RuleToDeduce.Conclusion; context.Resolved.AddRange(resolved); context.Result = resolved.FirstOrDefault(f => f.Variable == context.Goal); WorkingMemory.FiredRules.Add(context.RuleToDeduce); WorkingMemory.ResolvedFacts.AddRange(resolved); WorkingMemory.Log(context.RuleToDeduce, true); WorkingMemory.Log(resolved); context.RuleToDeduce = null; } else { WorkingMemory.InferenceStack.Push(context); } context.FactToCheck = null; } else { context.FactToCheck = null; context.RuleToDeduce = null; WorkingMemory.InferenceStack.Push(context); } } } DeduceEnded?.Invoke(context.Result); WorkingMemory.Result = context.Result; return(WorkingMemory.Result); }