public IList <QueryResponse> FindModels() { Stack <ModelState> stack = new Stack <ModelState>(); var initialFluentValues = FluentsHelper.InitializeFluents(_extractionResult.Fluents.Count).ToList(); initialFluentValues.RemoveAll( x => !ObservationHelper.ValidateModelWithObservation(x, 0, _extractionResult, _scenarioId)); _queryExecutors = QueriesHelper.CreateQueryExecutors(_queries, initialFluentValues, _scenarioId); foreach (var fluents in initialFluentValues) { ProcessModel(new ModelState { Time = 0, Fluents = fluents, Action = null, OcclussionFluents = null }, stack); stack.Clear(); } return(_queryExecutors.Select(x => x.GetResponse()).ToList()); }
private bool ProcessModel(ModelState state, Stack <ModelState> stack) { //Validate model with observations from scenario if (!ObservationHelper.ValidateModelWithObservation(state.Fluents, state.Time, _extractionResult, _scenarioId)) { return(false); } List <int> occlussionInNextMoment = new List <int>(); //Check actions if (state.Action != null) //action is invoking { //Find all matching action results var results = state.Action.Results.Where(r => r.Delay + state.Action.StartTime == state.Time); foreach (var actionResult in results.ToList()) { //check if result is satisfied if (!ExpressionHelper.IsExpressionTrue(actionResult.Result, state.Fluents)) { return(false); } state.Action.Results.Remove(actionResult); } if (!state.Action.Results.Any()) //all results have been applied -> action finish { state.Action = null; } else { occlussionInNextMoment = FluentsHelper.GetFluentsInOcclusion(state.Action); //set occlusion } } //there is a method ActionHelper.GetActionToBePerformed. Use it! var actionId = ActionHelper.GetActionToStart(_extractionResult, _scenarioId, state.Time, state.Fluents, _invokedActions); if (!actionId.HasValue || (actionId >= 0 && state.Action != null)) { return(false); //error - multiple action to invoke } if (actionId.Value >= 0) //start new action { var results = ActionHelper.CanActionBePerformed(_extractionResult.Sentences, actionId.Value, state.Fluents, state.Time, _endTime); if (results.Item1) { state.Action = results.Item2; //start action occlussionInNextMoment = FluentsHelper.GetFluentsInOcclusion(state.Action); var actionDuration = results.Item2.Results.Max(x => x.Delay); var invoked = ActionHelper.FindInvokedActions(_extractionResult, actionId.Value, actionDuration, state.Fluents, state.Time); foreach (var i in invoked) { if (!_invokedActions.TryGetValue(i.Item2, out int a)) { _invokedActions.Add(i.Item2, i.Item1); } else { if (a != i.Item1) { return(false); //error - to many invokes } } } } else { return(false); //powinniśmy wykonać akcję, ale nie udało się } } stack.Push(state); //Generate children - only fluents in occlusion can differ! if (state.Time < _endTime) { //if occlusion is empty - nothing changes it is only one child if (!occlussionInNextMoment.Any()) { var r = ProcessModel(new ModelState() { Fluents = state.Fluents, OcclussionFluents = occlussionInNextMoment, Time = state.Time + 1, Action = state.Action?.Clone() }, stack); if (r) { stack.Pop(); } return(r); } foreach (var fluents in FluentsHelper.InitializeFluentsWithOcclusion(state.Fluents, occlussionInNextMoment)) { var r = ProcessModel(new ModelState() { Fluents = fluents, Time = state.Time + 1, OcclussionFluents = occlussionInNextMoment, Action = state.Action?.Clone() }, stack); if (r) { stack.Pop(); } } return(true); } else { var modelStack = new Stack <ModelState>(stack.ToArray()); ValidModel model = new ValidModel(modelStack, _extractionResult.Fluents.Count); foreach (var queryExecutor in _queryExecutors) { queryExecutor.CheckModel(model); } _modelSaver?.SaveModel(model); return(true); } }