Example #1
0
        /// <summary>
        /// Get subchain of chainkeys and words that satisfies the passed in condition
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        internal ChainMap GetSubChain(ChainCondition condition)
        {
            //If conditions won't be applied return original chains
            if (condition == null || condition == _alwaysTrueCondition ||
                (condition.WordCondition == null && condition.KeyCondition == null))
            {
                return(_chains);
            }

            ChainMap newMap      = new ChainMap();
            bool     valuesFound = false;

            foreach (ChainKey key in _chains.GetAllKeys())
            {
                if (condition.KeyCondition != null)
                {
                    if (condition.KeyCondition.Invoke(key))
                    {
                        foreach (string word in _chains.GetValues(key))
                        {
                            if (condition.WordCondition != null)
                            {
                                if (condition.WordCondition.Invoke(word))
                                {
                                    newMap.AddToChain(key, word);
                                    valuesFound = true;
                                }
                            }
                        }
                    }
                }
            }

            if (!valuesFound)
            {
                throw new Exceptions.NoPossibleElements("Chain map filter filtered everything out");
            }

            return(newMap);
        }
Example #2
0
        /// <summary>
        /// Generate a new sentece that contains a minimum number of non punctuation words
        /// This minimum number of words is not guaranteed, but it is a best try
        /// </summary>
        /// <param name="minLength">Minimum length of sentence.  Use 0 to indicate
        /// no minimum</param>
        /// <returns></returns>
        public string GenerateSentence(int minLength)
        {
            if (minLength < 0)
            {
                throw new Exceptions.InvalidArguments("Number of words generated must be positive");
            }

            if (minLength > Defs.MAX_SENTENCE_LENGTH)
            {
                throw new Exceptions.InvalidArguments("Minimum sentence length greater than default maximum of " +
                                                      Defs.MAX_SENTENCE_LENGTH);
            }

            StringBuilder sb = new StringBuilder();

            //Word generator should reset to beginning of a sentence if needed
            ChainCondition sentenceStartCondition = new ChainCondition(
                ck => IsSentenceEnd(ck.Words[ck.Words.Length - 1]) ||
                ck.Words[ck.Words.Length - 1] == null, w => !IsPunctuation(w));

            //redundant for clarity
            if (!_sentenceGenerator.SubchainsInitialized)
            {
                _sentenceGenerator.ResetSubchains(sentenceStartCondition, null);
            }
            else if (IsSentenceEnd(_sentenceGenerator.CurrentWord))
            {
                //We are already at the beginning of a new sentence
                //This is to try to optimize perfomance so that we don't do a reset more than necessary
                //A reset is an expensive operation as all chains need to be parsed
                _sentenceGenerator.GetNextWord(sentenceStartCondition.WordCondition, Defs.MAX_ITERATIONS);
            }

            if (!(sentenceStartCondition.KeyCondition(_sentenceGenerator.CurrKey) &&
                  (sentenceStartCondition.WordCondition(_sentenceGenerator.CurrentWord))))
            {
                _sentenceGenerator.ResetReadOnly();
            }

            int countWords;

            for (countWords = 0; countWords < Defs.MAX_SENTENCE_LENGTH; countWords++)
            {
                string nextWord = _sentenceGenerator.CurrentWord;

                if (!(countWords == 0 || IsPunctuation(nextWord)))
                {
                    //prepend space if not first word or punctuation
                    sb.Append(" ");
                    sb.Append(nextWord);
                }
                else if (countWords == 0)
                {
                    //capitalize first word
                    if (!string.IsNullOrEmpty(nextWord))
                    {
                        sb.Append(nextWord.Capitalize());
                    }
                }
                else
                {
                    sb.Append(nextWord);
                }

                //If we get to sentence end, we are done
                if (IsSentenceEnd(nextWord))
                {
                    break;
                }

                if (countWords < minLength)
                {
                    _sentenceGenerator.GetNextWord(w => !IsSentenceEnd(w), Defs.MAX_ITERATIONS);
                }
                else
                {
                    _sentenceGenerator.GetNextWord();
                }
            }

            if (countWords == Defs.MAX_SENTENCE_LENGTH)
            {
                //shouldn't get here, but if we do, put any random sentence end
                sb.Append(SentenceEnd.FirstOrDefault());
            }
            return(sb.ToString());
        }
Example #3
0
 /// <summary>
 /// Initialize pool of random keys
 /// The probability of picking a key is proportional to the number of values in the ChainMap
 /// </summary>
 public void Initialize()
 {
     _alwaysTrueCondition = new ChainCondition(p => true, p => true);
     _keys = CreateKeysArray(_chains, _alwaysTrueCondition.KeyCondition);
     _currentOnEndCondition = _alwaysTrueCondition;
 }
Example #4
0
 /// <summary>
 /// Reset word generator with same condition for initial chain as final chain
 /// </summary>
 /// <param name="initialCondition"></param>
 public void ResetSubchains(ChainCondition initialCondition)
 {
     Reset(initialCondition, null);
 }
Example #5
0
        /// <summary>
        /// Reset CurrentWord based on conditions
        /// </summary>
        /// <param name="keyCondition"> Condition for key of first word </param>
        /// <param name="onEndCondition"> Condition for new word after there are no more chains
        /// By default this is the same as @keyCondition   </param>
        private void Reset(ChainCondition initialCondition, ChainCondition onEndCondition)
        {
            ChainCondition realInitialConditions = initialCondition;

            //Set null conditions to always true conditions to simplify our code
            if (realInitialConditions == null)
            {
                realInitialConditions = _alwaysTrueCondition;
            }
            else
            {
                if (realInitialConditions.KeyCondition == null)
                {
                    realInitialConditions.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realInitialConditions.WordCondition == null)
                {
                    realInitialConditions.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainCondition realOnEndCondition = onEndCondition;

            //Set on end condition to start condition if it is null
            if (realOnEndCondition == null)
            {
                realOnEndCondition = realInitialConditions;
            }
            else
            {
                if (realOnEndCondition.KeyCondition == null)
                {
                    realOnEndCondition.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realOnEndCondition.WordCondition == null)
                {
                    realOnEndCondition.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainMap initialConditionMap;

            //Only generate subchains if we need to
            if (realInitialConditions != _alwaysTrueCondition)
            {
                initialConditionMap = GetSubChain(realInitialConditions);
            }
            else
            {
                initialConditionMap = Chains;
            }

            ChainKey[] initialConditionSubKeys = CreateKeysArray(initialConditionMap,
                                                                 _alwaysTrueCondition.KeyCondition);

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(initialConditionSubKeys);
            string   currWord;

            GetCandidate(initialConditionMap.GetValues(currKey), null, out currWord);

            if (realOnEndCondition != _alwaysTrueCondition)
            {
                //Verify on end map has valid elements.  If no exception is thrown we are good to go
                _onEndSubChains = GetSubChain(realOnEndCondition);
            }
            else
            {
                _onEndSubChains = initialConditionMap;
            }

            CurrentWord = currWord;
            _currKey    = currKey;
            _initialConditionSubChains = initialConditionMap;
            _initialConditionSubKeys   = initialConditionSubKeys;
            _currentOnEndCondition     = realOnEndCondition;
            SubchainsInitialized       = true;
        }
Example #6
0
        /// <summary>
        /// Generate a new sentece that contains a minimum number of non punctuation words
        /// This minimum number of words is not guaranteed, but it is a best try
        /// </summary>
        /// <param name="minLength">Minimum length of sentence.  Use 0 to indicate
        /// no minimum</param>
        /// <returns></returns>
        public string GenerateSentence(int minLength)
        {
            if (minLength < 0)
            {
                throw new Exceptions.InvalidArguments("Number of words generated must be positive");
            }

            if (minLength > Defs.MAX_SENTENCE_LENGTH)
            {
                throw new Exceptions.InvalidArguments("Minimum sentence length greater than default maximum of " +
                    Defs.MAX_SENTENCE_LENGTH);
            }

            StringBuilder sb = new StringBuilder();

            //Word generator should reset to beginning of a sentence if needed
            ChainCondition sentenceStartCondition = new ChainCondition(
                ck => IsSentenceEnd(ck.Words[ck.Words.Length - 1]) ||
                    ck.Words[ck.Words.Length-1] == null, w => !IsPunctuation(w)) ;

            //redundant for clarity
            if(!_sentenceGenerator.SubchainsInitialized)
            {
                _sentenceGenerator.ResetSubchains(sentenceStartCondition, null);

            }
            else if(IsSentenceEnd(_sentenceGenerator.CurrentWord))
            {
                //We are already at the beginning of a new sentence
                //This is to try to optimize perfomance so that we don't do a reset more than necessary
                //A reset is an expensive operation as all chains need to be parsed
                _sentenceGenerator.GetNextWord(sentenceStartCondition.WordCondition, Defs.MAX_ITERATIONS) ;
            }

            if(!(sentenceStartCondition.KeyCondition(_sentenceGenerator.CurrKey) &&
                 (sentenceStartCondition.WordCondition(_sentenceGenerator.CurrentWord))))
            {
                _sentenceGenerator.ResetReadOnly();
            }

            int countWords ;
            for(countWords = 0 ; countWords < Defs.MAX_SENTENCE_LENGTH ; countWords++)
            {
                string nextWord = _sentenceGenerator.CurrentWord;

                if(!(countWords == 0 || IsPunctuation(nextWord)))
                {
                    //prepend space if not first word or punctuation
                    sb.Append(" ") ;
                    sb.Append(nextWord) ;
                }
                else if (countWords == 0)
                {
                    //capitalize first word
                    if(!string.IsNullOrEmpty(nextWord))
                    {
                        sb.Append(nextWord.Capitalize()) ;
                    }
                }
                else
                {
                    sb.Append(nextWord) ;
                }

                //If we get to sentence end, we are done
                if(IsSentenceEnd(nextWord))
                {
                    break ;
                }

                if(countWords < minLength)
                {
                    _sentenceGenerator.GetNextWord(w => !IsSentenceEnd(w), Defs.MAX_ITERATIONS) ;
                }
                else
                {
                    _sentenceGenerator.GetNextWord() ;
                }
            }

            if(countWords == Defs.MAX_SENTENCE_LENGTH)
            {
                //shouldn't get here, but if we do, put any random sentence end
                sb.Append(SentenceEnd.FirstOrDefault()) ;
            }
            return sb.ToString();
        }
Example #7
0
 /// <summary>
 /// Reset using new initial and onEndCondition.  This requires quite a bit of CPU
 /// as all the chains are processed to get a valid subset for the initial and on end
 /// conditions
 /// </summary>
 public void ResetSubchains(ChainCondition initialCondition, ChainCondition onEndCondition)
 {
     Reset(initialCondition, onEndCondition);
 }
Example #8
0
        /// <summary>
        /// Reset CurrentWord based on conditions
        /// </summary>
        /// <param name="keyCondition"> Condition for key of first word </param>
        /// <param name="onEndCondition"> Condition for new word after there are no more chains
        /// By default this is the same as @keyCondition   </param>
        private void Reset(ChainCondition initialCondition, ChainCondition onEndCondition)
        {
            ChainCondition realInitialConditions = initialCondition;
            //Set null conditions to always true conditions to simplify our code
            if(realInitialConditions == null)
            {
                realInitialConditions = _alwaysTrueCondition;
            }
            else
            {
                if (realInitialConditions.KeyCondition == null)
                {
                    realInitialConditions.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realInitialConditions.WordCondition == null)
                {
                    realInitialConditions.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainCondition realOnEndCondition = onEndCondition ;
            //Set on end condition to start condition if it is null
            if(realOnEndCondition == null)
            {
                realOnEndCondition = realInitialConditions ;
            }
            else
            {
                if (realOnEndCondition.KeyCondition == null)
                {
                    realOnEndCondition.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realOnEndCondition.WordCondition == null)
                {
                    realOnEndCondition.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainMap initialConditionMap ;
            //Only generate subchains if we need to
            if(realInitialConditions != _alwaysTrueCondition)
              	{
                initialConditionMap = GetSubChain(realInitialConditions) ;
            }
            else
            {
                initialConditionMap = Chains;
            }

            ChainKey[] initialConditionSubKeys = CreateKeysArray(initialConditionMap,
                                                                 _alwaysTrueCondition.KeyCondition) ;

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(initialConditionSubKeys) ;
            string currWord ;
            GetCandidate(initialConditionMap.GetValues(currKey), null, out currWord) ;

            if(realOnEndCondition != _alwaysTrueCondition)
            {
                //Verify on end map has valid elements.  If no exception is thrown we are good to go
                _onEndSubChains = GetSubChain(realOnEndCondition) ;
            }
            else
            {
                _onEndSubChains = initialConditionMap;
            }

            CurrentWord = currWord;
            _currKey = currKey;
            _initialConditionSubChains = initialConditionMap ;
            _initialConditionSubKeys = initialConditionSubKeys;
            _currentOnEndCondition = realOnEndCondition;
            SubchainsInitialized = true ;
        }
Example #9
0
        /// <summary>
        /// Get subchain of chainkeys and words that satisfies the passed in condition
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        internal ChainMap GetSubChain(ChainCondition condition)
        {
            //If conditions won't be applied return original chains
            if(condition == null || condition == _alwaysTrueCondition ||
               (condition.WordCondition == null && condition.KeyCondition == null))
            {
                return _chains ;
            }

            ChainMap newMap = new ChainMap() ;
            bool valuesFound = false ;
            foreach(ChainKey key in _chains.GetAllKeys())
            {
                if(condition.KeyCondition != null)
                {
                    if(condition.KeyCondition.Invoke(key))
                    {
                        foreach(string word in _chains.GetValues(key))
                        {
                            if(condition.WordCondition != null)
                            {
                                if(condition.WordCondition.Invoke(word))
                                {
                                    newMap.AddToChain(key, word) ;
                                    valuesFound = true ;
                                }
                            }
                        }
                    }
                }
            }

            if(!valuesFound)
            {
                throw new Exceptions.NoPossibleElements("Chain map filter filtered everything out") ;
            }

            return newMap ;
        }
Example #10
0
 /// <summary>
 /// Reset word generator with same condition for initial chain as final chain
 /// </summary>
 /// <param name="initialCondition"></param>
 public void ResetSubchains(ChainCondition initialCondition)
 {
     Reset(initialCondition, null) ;
 }
Example #11
0
 /// <summary>
 /// Reset using new initial and onEndCondition.  This requires quite a bit of CPU
 /// as all the chains are processed to get a valid subset for the initial and on end
 /// conditions
 /// </summary>
 public void ResetSubchains(ChainCondition initialCondition, ChainCondition onEndCondition)
 {
     Reset(initialCondition, onEndCondition) ;
 }
Example #12
0
 /// <summary>
 /// Initialize pool of random keys
 /// The probability of picking a key is proportional to the number of values in the ChainMap
 /// </summary>
 public void Initialize()
 {
     _alwaysTrueCondition = new ChainCondition(p => true, p => true);
     _keys = CreateKeysArray(_chains, _alwaysTrueCondition.KeyCondition) ;
     _currentOnEndCondition = _alwaysTrueCondition ;
 }