Пример #1
0
        /// <summary>
        /// This method can be executed several times, it returns the same if the probability has not been updated between the calls
        /// </summary>
        public void RecalculateProbForEachAnswer()
        {
            if (ProbChange != -1)
            {
                //UncertainFact provided only with ProbChange (not fixed list of probabilities)

                probabilitiesForEachPossibleAnswer[0] = SharedHelper.IncreaseProb(ProbVariable.RefValue.ProbOf(e => e == true), -ProbChange);

                probabilitiesForEachPossibleAnswer[1] = ProbVariable.RefValue.ProbOf(e => e == true).Value; //get the current value

                probabilitiesForEachPossibleAnswer[2] = SharedHelper.IncreaseProb(ProbVariable.RefValue.ProbOf(e => e == true), ProbChange);

                //UnityEngine.Debug.LogWarning("Recalculate answers probabilities for " + this.Name + ": " + probabilitiesForEachPossibleAnswer[0] + " " + probabilitiesForEachPossibleAnswer[1] + " " + probabilitiesForEachPossibleAnswer[2]);
            }
            else
            {
                SharedHelper.LogWarning("Prob change requested for " + Name + ", but this question is with fixed probabilities");
            }

            #region debug
            if (probabilitiesForEachPossibleAnswer.Sum() == 0)
            {
                SharedHelper.LogError("Probabilities are all 0!!! for " + Name);
            }
            #endregion
        }
Пример #2
0
        public bool AdjustProbVariablesDuringPlanning(int bufferedInteractionsCount)
        {
            bool regenerate = false;

            //1. About bot
            //exclude this action because there are no items for it
            if (ProbVariables.Bot.PrSharePureFactInfoAboutBot[(int)PV.Current].Value != 0 && KorraModelHelper.GetItemsLeftForSubCategory(ActionsEnum.SharePureFactInfoAboutBot, ItemProviders) == 0)
            {
                //adjust pure facts probabilities: disable AboutBot and boost AboutUser

                ProbVariables.Bot.PrSharePureFactInfoAboutBot[(int)PV.Current] = Prob(0);
                SharedHelper.LogWarning("Disabled all pure facts about bot, because there were no items.");

                //we re-inforce AboutUser so that it is stronger than Suggestion action
                if (ProbVariables.Bot.PrAskPureFactQuestionAboutUser[(int)PV.Current].Value > 0)
                {
                    ProbVariables.Bot.PrAskPureFactQuestionAboutUser[(int)PV.Current] = ProbVariables.Bot.PrAskPureFactQuestionAboutUser[(int)PV.Increased];
                }

                regenerate = true;
            }

            //2. About User
            //exclude this action because there are no items for it
            if (ProbVariables.Bot.PrAskPureFactQuestionAboutUser[(int)PV.Current].Value != 0 && KorraModelHelper.GetItemsLeftForSubCategory(ActionsEnum.AskPureFactQuestionAboutUser, ItemProviders) == 0)
            {
                //adjust pure facts probabilities: disable AboutUser and boost AboutBot

                ProbVariables.Bot.PrAskPureFactQuestionAboutUser[(int)PV.Current] = Prob(0);
                SharedHelper.Log("Disabled all pure facts about user, because there were no items.");

                //we re-inforce AboutBot so that it is stronger than Suggestion action
                if (ProbVariables.Bot.PrSharePureFactInfoAboutBot[(int)PV.Current].Value > 0)
                {
                    ProbVariables.Bot.PrSharePureFactInfoAboutBot[(int)PV.Current] = ProbVariables.Bot.PrSharePureFactInfoAboutBot[(int)PV.Increased];
                }

                regenerate = true;
            }

            //3. Suggestions
            //if there are no Pure or Uncertain facts left then we boost suggestions
            bool noFactsLeft = (ProbVariables.Bot.PrAskPureFactQuestionAboutUser[(int)PV.Current].Value == 0 && ProbVariables.Bot.PrSharePureFactInfoAboutBot[(int)PV.Current].Value == 0);

            if (noFactsLeft && ProbVariables.Bot.PrMakeSuggestion[(int)PV.Current] != ProbVariables.Bot.PrMakeSuggestion[(int)PV.Default])
            {
                ProbVariables.Bot.PrMakeSuggestion[(int)PV.Current] = ProbVariables.Bot.PrMakeSuggestion[(int)PV.Default];
                SharedHelper.Log("All pure facts used. PrMakeSuggestion changed to: " + ProbVariables.Bot.PrMakeSuggestion[(int)PV.Current]);
            }

            //Keep suggestions decreased if there are more pure facts
            if (!noFactsLeft && ProbVariables.Bot.PrMakeSuggestion[(int)PV.Current] != ProbVariables.Bot.PrMakeSuggestion[(int)PV.Descreased])
            {
                SharedHelper.Log("PrMakeSuggestion changed decreased.");
                ProbVariables.Bot.PrMakeSuggestion[(int)PV.Current] = ProbVariables.Bot.PrMakeSuggestion[(int)PV.Descreased];
            }

            return(regenerate);
        }
Пример #3
0
        public bool Process(bool isPureFactUpdated, TimeSpan timeSinceStart, IKorraAIModel model)
        {
            //SharedHelper.LogWarning("Inside music trigger");

            // We increase the music suggestions after a fixed amount of time
            if (timeSinceStart.TotalMinutes > MinutesIncreaseMusic) // && !IncreaseDistributionSuggestMusicDone)
            {
                executedCount = executedCount + 1;

                ProbVariables.Bot.PrSuggestListenToSong = Prob(0.35);
                SharedHelper.LogWarning("PrSuggestListenToSong updated to: " + ProbVariables.Bot.PrSuggestListenToSong.Value);
            }

            return(false); //no re-sampling
        }
Пример #4
0
        //public static void SetAsPlanned(string name)
        //{
        //    for (int i = 0; i < list.Count; i++)
        //    {
        //        if (list[i].Name == name)
        //        {
        //            //UnityEngine.Debug.Log("Set to used true: " + list[i].Name);
        //            list[i].IsPlanned = true;
        //            return;
        //        }
        //    }

        //    SharedHelper.LogError("Pure Fact Name not found in SetAsUsed!");
        //}

        public void SetValue(string Name, string Value)
        {
            foreach (var item in items)
            {
                PureFact f = (PureFact)item;
                if (f.Name == Name)
                {
                    SharedHelper.LogWarning("Set as answered: " + f.Name + " with value: '" + Value + "'");
                    f.Value      = Value;
                    f.IsAnswered = true;

                    return;
                }
            }
        }
Пример #5
0
        //public static PureFact GetByName(string name)
        //{
        //    foreach (var q in list)
        //    {
        //        if (q.Name == name)
        //        {
        //            return q;
        //        }
        //    }

        //    SharedHelper.LogError("GetFacfByName: Pure Fact Name '" + name + "'not found");

        //    return null;
        //}

        //public static void RemovePlannedFlagForAllPureFacts()
        //{
        //    for (int i = 0; i < list.Count; i++)
        //    {
        //        list[i].IsPlanned = false;
        //    }
        //}

        /// <summary>
        /// Used to delete answers that are invalid after validation: ex. age is not a valid number
        /// </summary>
        public void DropAnswer(string Name)
        {
            foreach (var item in items)
            {
                PureFact f = (PureFact)item;
                if (f.Name == Name)
                {
                    SharedHelper.LogWarning("DropAnswer: " + f.Name);
                    f.Value      = "";
                    f.IsAnswered = false;
                    f.IsUsed     = false;
                    return;
                }
            }
        }
Пример #6
0
        public static void PrintSummary()
        {
            string result = "";
            int    i      = 0;

            foreach (var key in CategoryNInter.Keys)
            {
                i++;
                result += "|" + key + ": " + CategoryNInter[key] + Environment.NewLine;
            }
            SharedHelper.LogWarning("Interactions statistics: " + Environment.NewLine + result);

            TimeSpan time = TimeSpan.FromSeconds(TimeForecast());

            SharedHelper.Log("Time (hh:mm) forecast scheduled interactions will take: " + time.ToString(@"hh\:mm"));
        }
Пример #7
0
        public Item GetItem()
        {
            Item[] q;

            q = items.Where(j => j.IsUsed == false && j.IsPlanned == false).ToArray();

            if (q.Length > 0)
            {
                Item s = q.ElementAt(r.Next(0, q.Count()));

                return(s);
            }
            else
            {
                //SharedHelper.LogError("No items for category: " + example.Category + example.SubCategory);

                if (IsAllowedResetUsageOnEmptyCategory())
                {
                    SharedHelper.LogWarning("No items for category: " + example.Category + example.SubCategory + " have been reset. They are all set to unused now.");

                    foreach (Item item in items)
                    {
                        if (item.IsUsed == true)
                        {
                            item.IsUsed    = false;
                            item.IsPlanned = false;
                        }
                    }

                    //after adding items, choose one
                    q = items.Where(j => j.IsUsed == false && j.IsPlanned == false).ToArray();

                    if (q.Length > 0)
                    {
                        Item s = q.ElementAt(r.Next(0, q.Count()));

                        return(s);
                    }
                }

                return(null);
            }
        }
Пример #8
0
        public CommItem?Process(IKorraAIModel model)
        {
            #region Get Fact Manager
            PureFacts pfManager = (PureFacts)model.ItemProviders.SingleOrDefault(x => x is PureFacts);
            if (pfManager == null)
            {
                SharedHelper.LogError("No manager in Facts Manager in MoviesModelUpdateTrigger.");
                return(null);
            }
            #endregion

            var    context = model.GetContext();
            string text    = "";

            PureFact factLikesVideoGames = (PureFact)pfManager.GetByName("UserLikesVideoGames");
            PureFact factThinksVideoGameIsGoodPresent = (PureFact)pfManager.GetByName("UserThinksVideoGameIsGoodPresent");
            PureFact userAge = (PureFact)pfManager.GetByName("UserAge");
            PureFact userSex = (PureFact)pfManager.GetByName("UserSex");

            if (factLikesVideoGames == null || factThinksVideoGameIsGoodPresent == null || userAge == null || userSex == null)
            {
                SharedHelper.LogError("factJob or factWatchedMovieYesterday is NULL in MoviesModelUpdateTrigger.");
            }

            bool UserLikesVideoGamesAnswered = factLikesVideoGames.IsAnswered;
            bool UserThinksVideoGameIsGoodPresentAnswered = factThinksVideoGameIsGoodPresent.IsAnswered;

            bool userAgeAnswered = userAge.IsAnswered;
            bool userSexAnswered = userSex.IsAnswered;

            if (!UserLikesVideoGamesAnswered)
            {
                return(null);
            }

            bool UserLikesVideoGamesAnsweredYES = context.BasePhrases.IsYes(factLikesVideoGames.Value); //only if answered

            //Calcualte 3 differerent surprises:

            //1. surprise because statistically people from this sex and age like computer games
            //Should like Video Games, but user answered No
            if (userAgeAnswered && userSexAnswered &&
                factLikesVideoGames.IsAnswered &&
                !UserLikesVideoGamesAnsweredYES //DOES NOT LIKE VIDEO GAMES
                )
            {
                int  Age    = Convert.ToInt32(userAge.Value);
                bool IsMale = userSex.Value.ToLower() == phrases.Male().ToLower();

                var likesVideoGamesInferred = BernoulliF(ProbVariables.User.playsGames(Age, IsMale)); //our estimation based on Age and Sex

                //Threshold check
                if (likesVideoGamesInferred.ProbOf(e => e == true).Value > 0.8)
                {
                    SharedHelper.LogWarning("VG S1 surprise inferred.");
                    text          = phrases.SurpriseVideoGames(1, false); //second parameter is not used
                    executedCount = executedCount + 1;

                    return(new CommItem
                    {
                        Category = ActionsEnum.MakeGeneralStatement,
                        Name = "ExpressVideoGamesSurprise",

                        TextToSay = text,
                        FacialExpression = FaceExp.SurpriseOnStartTalking,
                    });
                }
                else
                {
                    SharedHelper.LogWarning("No VG S1 surprise, because it is below threshold.");
                }
            }

            if (!UserThinksVideoGameIsGoodPresentAnswered)
            {
                return(null);
            }
            bool UserThinksVideoGameIsGoodPresentYES = context.BasePhrases.IsYes(factThinksVideoGameIsGoodPresent.Value); //only if answered

            //2. Surprise
            //Thinks games are good present - YES
            //Likes games in general - NO
            //surprise: LikesGames rendered more than 70% positive, but still answered NO by user
            //backward inference
            if (UserLikesVideoGamesAnswered &&
                !UserLikesVideoGamesAnsweredYES &&  //DOES NOT LIKE VIDEO GAMES
                UserThinksVideoGameIsGoodPresentAnswered &&
                UserThinksVideoGameIsGoodPresentYES //LIKES VG AS PRESENT
                )
            {
                var conditionThinksVideogameIsGoodPresent = ProbVariables.User.VideoGameModel.ConditionHard(e => e.ThinksVideogameIsGoodPresent);

                //for this query we are not using Age and Sex, because we already know that the user LikesVideoGames (answered by the user)
                double probLikesGamesConditionedOnThinksGamesAreGoodPresentInferred = conditionThinksVideogameIsGoodPresent.ProbOf(e => e.LikesVideoGames).Value;

                SharedHelper.LogWarning("S2 probLikesGamesConditionedOnThinksGamesAreGoodPresent: " + probLikesGamesConditionedOnThinksGamesAreGoodPresentInferred);

                //Threshold check
                if (probLikesGamesConditionedOnThinksGamesAreGoodPresentInferred > 0.6)
                {
                    SharedHelper.LogWarning("VG S2 surprise inferred.");
                    bool IsLikesGamesFirstAnswered = factLikesVideoGames.LastUpdated < factThinksVideoGameIsGoodPresent.LastUpdated;
                    text          = phrases.SurpriseVideoGames(2, IsLikesGamesFirstAnswered);
                    executedCount = executedCount + 1;

                    return(new CommItem
                    {
                        Category = ActionsEnum.MakeGeneralStatement,
                        Name = "ExpressVideoGamesSurprise",

                        TextToSay = text,
                        IsReactionToUser = true,
                        FacialExpression = FaceExp.SurpriseOnStartTalking,
                    });
                }
                else
                {
                    SharedHelper.LogWarning("No VG S2 surprise, because it is below threshold.");
                }
            }

            // 3. Surprise
            //Thinks games are a good present - NO
            //Likes games in general - YES
            //surprise: ThinkGamesGoodPresent rendered more than 70% positive, but still answered NO by user
            if (UserLikesVideoGamesAnswered &&
                UserThinksVideoGameIsGoodPresentAnswered &&
                UserLikesVideoGamesAnsweredYES &&     //LIKES VIDEO GAMES
                !UserThinksVideoGameIsGoodPresentYES) //DOES NOT LIKE VG AS PRESENT
            {
                //TODO: it should not be here, but attached to the item
                //THIS IS NEEDED FOR THE INFERRENCE BELOW ON: probThinksVideoGameIsGoodPresentInferred
                if (UserLikesVideoGamesAnsweredYES)
                {
                    ProbVariables.User.LikesVideoGames = BernoulliF(Prob(0.98));
                }

                var probThinksVideoGameIsGoodPresentInferred = ProbVariables.User.VideoGameModel.ProbOf(e => e.ThinksVideogameIsGoodPresent).Value;

                SharedHelper.LogWarning("S3 probThinksVideoGameIsGoodPresent: " + probThinksVideoGameIsGoodPresentInferred);

                //Threshold check
                if (probThinksVideoGameIsGoodPresentInferred >= 0.7)
                {
                    SharedHelper.LogWarning("VG S3 surprise inferred.");
                    bool IsLikesGamesFirstAnswered = factLikesVideoGames.LastUpdated < factThinksVideoGameIsGoodPresent.LastUpdated;
                    text          = phrases.SurpriseVideoGames(3, IsLikesGamesFirstAnswered);
                    executedCount = executedCount + 1;

                    return(new CommItem
                    {
                        Category = ActionsEnum.MakeGeneralStatement,
                        Name = "ExpressVideoGamesSurprise",

                        TextToSay = text,
                        FacialExpression = FaceExp.SurpriseOnStartTalking,
                    });
                }
                else
                {
                    SharedHelper.LogWarning("No VG S3 surprise, because it is below threshold.");
                }
            }

            return(null);
        }
Пример #9
0
        public void ReGenerateMainSequence(ref Queue <CommItem> Interactions, ItemManager[] p_providers)
        {
            this.providers = p_providers;

            #region debug planned
            string availableItems = "Available items before sampling:\n";
            foreach (var manager in providers)
            {
                availableItems += "Available items for : " + manager.ToString() + " (" + manager.AvailableItems() + ")\n";
                if (!manager.AreAllUnPlanned())
                {
                    SharedHelper.LogError("Flag planned not removed for: " + manager.ToString());
                }
            }

            if ((JokesProvider.GetAll().Where(x => x.IsPlanned == false)).Count() != JokesProvider.GetAll().Count())
            {
                SharedHelper.LogError("Flag planned not removed for: JokeProvider ");
            }
            int availableJokes = JokesProvider.GetAll().Where(x => x.IsPlanned == false && x.IsUsed == false).Count();
            availableItems += "Available items for : " + "JokeProvider" + " (" + availableJokes + ")\n";
            SharedHelper.LogWarning(availableItems);
            #endregion

            PureFacts pfManager = (PureFacts)providers.SingleOrDefault(x => x is PureFacts);
            if (pfManager == null)
            {
                SharedHelper.LogError("No PureFact manager in ReGenerateMainSequence.");
            }

            //Creates a distribution over "EasilyOffended", IsRomanticJoke
            dists.InitJokesDistribution((PureFact)pfManager.GetByName("EasilyOffended"), false, true);

            //Interactions are built newely generated suggestions and actions
            allSuggestions = GenerateSuggestions();
            allActions     = GenerateActions();

            while (allActions.Count > 0 && allSuggestions.Count > 0)
            {
                if (this.AdjFunc(Interactions.Count))
                {
                    allActions = GenerateActions();
                }

                //==================================================================================================

                CommItem citem = new CommItem();
                citem.Category = allActions.Dequeue();

                //SharedHelper.Log("action: " + action);

                string suggestion = "";
                if (citem.Category == ActionsEnum.MakeSuggestion)
                {
                    suggestion = allSuggestions.Dequeue();
                }
                citem.SubCategory = suggestion;

                //Correction
                if (citem.Category == ActionsEnum.AskPureFactQuestionAboutUser)
                {
                    citem.Category = ActionsEnum.PureFact; citem.SubCategory = ActionsEnum.AskPureFactQuestionAboutUser;
                }
                if (citem.Category == ActionsEnum.SharePureFactInfoAboutBot)
                {
                    citem.Category = ActionsEnum.PureFact; citem.SubCategory = ActionsEnum.SharePureFactInfoAboutBot;
                }

                #region Process All
                ItemManager manager = providers.SingleOrDefault(x => x.Is(citem));

                if (manager != null && !(manager is PureFacts))  //TODO: to be improved
                {
                    Item item = manager.GetItem();
                    if (item != null)
                    {
                        manager.SetAsPlanned(item.Name);
                        citem = new CommItem(item);

                        if (manager is SongsProvider)
                        {
                            citem.TextToSay = ((Song)item).Name;
                        }

                        if (manager is MoviesProvider)
                        {
                            citem.TextToSay = phrases.MovieAnnouncement((Movie)item);
                        }

                        //if (manager is SportsProvider)
                        //    SharedHelper.Log("Sport item added in Joi sampler: " + citem.TextToSay);

                        InteractionsStat.AddScheduledInteraction(citem.Category + citem.SubCategory);
                        //SharedHelper.LogWarning("Added " + citem.Category + citem.SubCategory + " with text: " + citem.TextToSay);
                    }
                    else
                    {
                        InteractionsStat.AddMissingInteraction(citem.Category + citem.SubCategory);
                        SharedHelper.LogWarning("Not enough " + citem.Category + citem.SubCategory + " during planning.");
                    }
                }
                #endregion
                else
                {
                    #region Set Suggestion
                    if (citem.Category == ActionsEnum.MakeSuggestion)
                    {
                        //string suggestion = allSuggestions.Dequeue();

                        //SharedHelper.Log("suggestion: " + suggestion);

                        #region set joke
                        if (suggestion == SuggestionsEnum.TellJoke)
                        {
                            //the fact that joke has bee planned, does not mean it has been executed

                            Joke joke = dists.NextJoke();

                            if (joke != null)
                            {
                                citem = new CommItem(joke);

                                //Planned is handled by "dists"
                                //It gives a distribution from all unplanned and unused

                                JokesProvider.SetJokeAsPlanned(joke.Name);

                                //joke.IsPlanned = true;
                                //citem.Name = joke.Name;
                                //citem.TextToSay = joke.Text;
                                //citem.SubCategory = suggestion;
                                citem.IsJokePureFact   = joke.IsPureFact; //these jokes come from the PureFacts collection
                                citem.UIAnswer         = joke.PureFactUI;
                                citem.FacialExpression = joke.FaceExpression;

                                InteractionsStat.AddScheduledInteraction(SuggestionsEnum.TellJoke);
                            }
                            else
                            {
                                citem.TextToSay = "__nointeraction__";
                                //UnityEngine.Debug.LogWarning("Not enough jokes during planning.");
                                InteractionsStat.AddMissingInteraction(SuggestionsEnum.TellJoke);
                            }
                        }
                        #endregion

                        #region set Go Out
                        if (suggestion == SuggestionsEnum.GoOut)
                        {
                            citem.TextToSay = phrases.GoOutAnnoucement();
                            InteractionsStat.AddScheduledInteraction(SuggestionsEnum.GoOut);
                        }
                        #endregion

                        //#region set Watch movie
                        //if (suggestion == SuggestionsEnum.WatchMovie)
                        //{
                        //    Movie movie = MoviesProvider.Get();
                        //    if (movie != null)
                        //    {
                        //        movie.IsPlanned = true;
                        //        //citem.Name = movie.Name;
                        //        //citem.TextToSay = phrases.MovieAnnouncement(movie);
                        //        citem = new CommItem(movie);

                        //        //UnityEngine.Debug.LogWarning("Movie scheduled: " + citem.TextToSay);
                        //        InteractionsStat.AddScheduledInteraction(SuggestionsEnum.WatchMovie);
                        //    }
                        //    else
                        //    {
                        //        citem.TextToSay = "__nointeraction__";
                        //        SharedHelper.LogWarning("Not enough movies during planning.");
                        //        InteractionsStat.AddMissingInteraction(SuggestionsEnum.WatchMovie);
                        //    }
                        //}
                        //#endregion

                        #region set Weather forecast
                        if (suggestion == SuggestionsEnum.TellWeatherForecast)
                        {
                            citem.TextToSay = "The weather forecast should be good."; //TODO not translated
                        }
                        #endregion

                        //#region set Song
                        //if (suggestion == SuggestionsEnum.ListenToSong)
                        //{
                        //    //the fact that song has bee planned, does not mean it has been executed
                        //    Song song = SongsProvider.GetSong();
                        //    if (song != null)
                        //    {
                        //        song.IsPlanned = true;
                        //        citem.Name = song.Name;
                        //        citem.TextToSay = song.Name;

                        //        InteractionsStat.AddScheduledInteraction(SuggestionsEnum.ListenToSong);
                        //    }
                        //    else
                        //    {
                        //        citem.TextToSay = "__nointeraction__";
                        //        SharedHelper.LogWarning("Not enough songs during planning.");
                        //        InteractionsStat.AddMissingInteraction(SuggestionsEnum.ListenToSong);
                        //    }
                        //}
                        //#endregion
                        //else
                        //#region set Go to gym
                        //if (suggestion == SuggestionsEnum.DoSport)
                        //{
                        //    ItemManager manager = providers.Single(x => x.Is(citem));

                        //    if (manager == null) SharedHelper.LogWarning("Manager is null");

                        //    Sport sport = (Sport)manager.GetItem();
                        //    if (sport != null)
                        //    {
                        //        manager.SetAsPlanned(sport.Name);
                        //        citem = new CommItem(sport);

                        //        InteractionsStat.AddScheduledInteraction(SuggestionsEnum.DoSport);
                        //    }
                        //    else
                        //    {
                        //        citem.TextToSay = "__nointeraction__";
                        //        SharedHelper.LogWarning("Not enough sports during planning.");
                        //        InteractionsStat.AddMissingInteraction(SuggestionsEnum.DoSport);
                        //    }
                        //}
                        //#endregion
                    } //end action suggestions
                    #endregion
                    else if (citem.Category == ActionsEnum.AskUncertanFactQuestion)
                    {
                        //the actual question is selected at run time
                        citem.TextToSay  = "###place holder for UncertanFactQuestion";
                        citem.IsPureFact = false;

                        InteractionsStat.AddScheduledInteraction(ActionsEnum.AskUncertanFactQuestion);
                    }
                    else if (citem.SubCategory == ActionsEnum.AskPureFactQuestionAboutUser) //ABOUT USER
                    {
                        int pfabul = PureFactsAboutUserLeftCount();

                        if (pfabul > 0)
                        {
                            PureFact sf = pfManager.GetPureFactAbouUser();

                            if (sf == null)
                            {
                                SharedHelper.LogError("There are pure facts about the user left, but no pure fact has been selected.");
                            }
                            else
                            {
                                citem.TextToSay = sf.Question;
                                //SharedHelper.Log("q name: " + q [0].Name);
                                citem.Name       = sf.Name;
                                citem.IsPureFact = true;

                                pfManager.SetAsPlanned(sf.Name);

                                citem.UIAnswer = sf.UI;
                            }
                            InteractionsStat.AddScheduledInteraction(citem.Category + citem.SubCategory);
                        }
                        else
                        {
                            InteractionsStat.AddMissingInteraction(citem.Category + citem.SubCategory);
                        }
                    }
                    else if (citem.SubCategory == ActionsEnum.SharePureFactInfoAboutBot) //ABOUT BOT
                    {
                        int pfabbl = PureFactsAboutBotLeftCount();

                        if (pfabbl > 0)
                        {
                            PureFact sf = GetPureFactAbouBot();
                            if (sf == null)
                            {
                                SharedHelper.LogError("There are pure facts about the bot left, but no pure fact has been selected.");
                            }
                            else
                            {
                                //SharedHelper.Log("Found " + Actions.SharePureFactInfoAboutBot + ": " + q.Length.ToString());
                                citem.TextToSay  = sf.Acknowledgement;
                                citem.IsPureFact = true;
                                citem.Name       = sf.Name;

                                pfManager.SetAsPlanned(sf.Name);
                            }
                            InteractionsStat.AddScheduledInteraction(citem.Category + citem.SubCategory);
                        }
                        else
                        {
                            InteractionsStat.AddMissingInteraction(citem.Category + citem.SubCategory);
                        }
                    }
                    else if (citem.Category == ActionsEnum.ChangeVisualAppearance)
                    {
                        citem.TextToSay = context.BasePhrases.ChangeClothesAnnouncement();
                        InteractionsStat.AddScheduledInteraction(ActionsEnum.ChangeVisualAppearance);
                    }
                    else if (citem.Category == ActionsEnum.ExpressMentalState)
                    {
                        //choose mental state to share using a distribution (uniform?)
                        //currently only one state is processed
                        string selectedMentalState = "InAGoodMood";

                        if (selectedMentalState == "InAGoodMood")
                        {
                            //Take into account the: ProbVariables.Bot.InAGoodMood;
                            //class Statement where the constructor takes prob variable as or UncertainFact
                            //or just phrase that internally takes into account current values of the prob variable and other normal variables
                            citem.TextToSay = "###place holder for InAGoodMood";
                        }

                        InteractionsStat.AddScheduledInteraction(ActionsEnum.ExpressMentalState);
                    }
                    else
                    {
                        SharedHelper.LogError("Unknown action: " + citem.Category);
                    }
                }

                #region Add interaction item to queue

                if (string.IsNullOrEmpty(citem.TextToSay))
                {
                    SharedHelper.LogError("Text is empty! Action was: " + citem.Category + "|" + citem.SubCategory);
                }
                else
                {
                    Interactions.Enqueue(citem);
                }

                #endregion

                #region debug
                PureFact[] LeftPureFacts = (from item in pfManager.GetAll()
                                            let pf = (PureFact)item
                                                     where (pf.Type == PureFactType.AboutBot || pf.Type != PureFactType.AboutUser) &&
                                                     pf.IsPlanned == false && pf.IsUsed == false
                                                     select pf).ToArray();

                //if (!Flags.DecreaseDistributionOfAskPureFactQuestionAboutUserDone && Interactions.Count > 45 && (LeftPureFacts.Length - PersistentData.PureFactsLoadedOnStartup()) > 0)
                //    KorraBaseHelper.LogError("All pure facts should have been already planned. Left not used pure facts: " + LeftPureFacts.Length);

                #endregion
            }
        }