Iterator that goes from start of the chain.
Inheritance: IteratorBase
        /// <summary>
        /// Reorganizes source chain.
        /// </summary>
        /// <param name="source">
        /// Source chain.
        /// </param>
        /// <returns>
        /// <see cref="AbstractChain"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown if level is less than 0.
        /// </exception>
        public override AbstractChain Reorganize(AbstractChain source)
        {
            if (level < 0)
            {
                throw new InvalidOperationException("Markov chain level can't be less than 0");
            }

            if (level == 0)
            {
                return source;
            }

            var result = new BaseChain();
            result.ClearAndSetNewLength(source.GetLength() + level);
            for (int i = 0; i < source.GetLength(); i++)
            {
                result[i] = source[i];
            }

            var iterator = new IteratorStart(source, level, 1);
            iterator.Reset();
            iterator.Next();
            AbstractChain addition = iterator.Current();
            for (int i = 0; i < addition.GetLength(); i++)
            {
                result[source.GetLength() + i] = addition[i];
            }

            return result;
        }
        public void ReadWindowModeTest()
        {
            int length = 3;
            int step = 1;
            var iterator = new IteratorStart(chainToIterate, length, step);
            var message2 = new List<Chain>
                               {
                                   new Chain("121"),
                                   new Chain("213"),
                                   new Chain("133"),
                                   new Chain("331"),
                                   new Chain("312"),
                                   new Chain("121"),
                                   new Chain("212"),
                                   new Chain("122"),
                                   new Chain("223"),
                                   new Chain("231")
                               };

            int i = 0;
            while (iterator.Next())
            {
                var message1 = iterator.Current();
                Assert.AreEqual(message1, message2[i++]);
            }

            Assert.AreEqual(--i, 9);
        }
        /// <summary>
        /// The check recovery available.
        /// </summary>
        /// <param name="chain">
        /// Source sequence.
        /// </param>
        /// <param name="length">
        /// Length of L-gram.
        /// </param>
        /// <returns>
        /// true if chain is recoverable form L-grams.
        /// </returns>
        private bool CheckRecoveryAvailable(AbstractChain chain, int length)
        {
            var iterator = new IteratorStart(chain, length, 1);
            var alphabet = new Alphabet();

            while (iterator.Next())
            {
                if (alphabet.Contains(iterator.Current()))
                {
                    return false;
                }

                alphabet.Add(iterator.Current());
            }

            return true;
        }
        /// <summary>
        /// The divide.
        /// </summary>
        /// <param name="chain">
        /// The chain.
        /// </param>
        /// <returns>
        /// The <see cref="BaseChain"/>.
        /// </returns>
        public BaseChain Divide(BaseChain chain)
        {
            var firstChain = new ActualChain(chain);
            var stack = new Stack();
            stack.Push(firstChain);
            ArrayList list = alphabet.GetLengthList();
            do
            {
                var actChain = (ActualChain)stack.Pop();
                BaseChain chain4Check = actChain.Source;

                for (int i = list.Count - 1; i >= 0; i--)
                {
                    BaseChain word;
                    if (chain4Check.GetLength() >= (int)list[i])
                    {
                        var it = new IteratorStart(chain4Check, (int)list[i], 1);
                        it.Next();
                        word = (BaseChain)it.Current();
                    }
                    else
                    {
                        continue;
                    }

                    if (alphabet.Contains(word))
                    {
                        // solution is found
                        if (chain4Check.GetLength() == (int)list[i])
                        {
                            actChain.RemoveCharacter((int)list[i]);
                            return actChain.GetResult();
                        }

                        var newChain = (ActualChain)actChain.Clone();
                        newChain.RemoveCharacter((int)list[i]);
                        stack.Push(newChain);
                    }
                }
            }
            while (stack.Count > 0);
            return null;
        }
        public ActionResult Index(long[] matterIds, int length, bool congeneric, int notationId, int? languageId, int? translatorId)
        {
            return Action(() =>
            {
                if (matterIds.Length != 2)
                {
                    throw new ArgumentException("Count of selected matters must be 2.", "matterIds");
                }

                var firstMatterId = matterIds[0];
                var secondMatterId = matterIds[1];

                long firstSequenceId;
                if (db.Matter.Single(m => m.Id == firstMatterId).Nature == Nature.Literature)
                {
                    firstSequenceId = db.LiteratureSequence.Single(l => l.MatterId == firstMatterId &&
                                l.NotationId == notationId
                                && l.LanguageId == languageId
                                && ((translatorId == null && l.TranslatorId == null)
                                                || (translatorId == l.TranslatorId))).Id;
                }
                else
                {
                    firstSequenceId = db.CommonSequence.Single(c => c.MatterId == firstMatterId && c.NotationId == notationId).Id;
                }

                Chain firstLibiadaChain = sequenceRepository.ToLibiadaChain(firstSequenceId);

                long secondSequenceId;
                if (db.Matter.Single(m => m.Id == secondMatterId).Nature == Nature.Literature)
                {
                    secondSequenceId = db.LiteratureSequence.Single(l => l.MatterId == secondMatterId &&
                                l.NotationId == notationId
                                && l.LanguageId == languageId
                                && ((translatorId == null && l.TranslatorId == null)
                                                || (translatorId == l.TranslatorId))).Id;
                }
                else
                {
                    secondSequenceId = db.CommonSequence.Single(c => c.MatterId == secondMatterId && c.NotationId == notationId).Id;
                }

                Chain secondLibiadaChain = sequenceRepository.ToLibiadaChain(secondSequenceId);

                AbstractChain res1 = null;
                AbstractChain res2 = null;

                int i = 0;
                int j = 0;
                var firstIterator = new IteratorStart(firstLibiadaChain, length, 1);
                bool duplicate = false;
                while (!duplicate && firstIterator.Next())
                {
                    i++;
                    var firstTempChain = (Chain)firstIterator.Current();
                    var secondIterator = new IteratorStart(secondLibiadaChain, length, 1);
                    j = 0;
                    while (!duplicate && secondIterator.Next())
                    {
                        j++;
                        var secondTempChain = (Chain)secondIterator.Current();

                        if (congeneric)
                        {
                            for (int a = 0; a < firstTempChain.Alphabet.Cardinality; a++)
                            {
                                CongenericChain firstChain = firstTempChain.CongenericChain(a);
                                for (int b = 0; b < secondTempChain.Alphabet.Cardinality; b++)
                                {
                                    CongenericChain secondChain = secondTempChain.CongenericChain(b);
                                    if (!firstChain.Equals(secondChain) && CompareBuildings(firstChain.Building, secondChain.Building))
                                    {
                                        res1 = firstChain;
                                        res2 = secondChain;
                                        duplicate = true;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (!firstTempChain.Equals(secondTempChain) &&
                                CompareBuildings(secondTempChain.Building, firstTempChain.Building))
                            {
                                res1 = firstTempChain;
                                res2 = secondTempChain;
                                duplicate = true;
                            }
                        }
                    }
                }

                return new Dictionary<string, object>
                {
                    { "duplicate", duplicate },
                    { "firstSequenceName", db.Matter.Single(m => m.Id == firstMatterId).Name },
                    { "secondSequenceName", db.Matter.Single(m => m.Id == secondMatterId).Name },
                    { "res1", res1 },
                    { "res2", res2 },
                    { "pos1", i },
                    { "pos2", j }
                };
            });
        }
        public void GetThirdLevelChainTest()
        {
            matrix = new Matrix(testChain.Alphabet.Cardinality, 3);

            var reorganizer = new NullCycleSpaceReorganizer(2);
            testChain = (BaseChain)reorganizer.Reorganize(testChain);

            var it = new IteratorStart(testChain, 3, 1);
            while (it.Next())
            {
                var chain = it.Current();
                var arrayToTeach = new int[chain.GetLength()];
                for (var i = 0; i < chain.GetLength(); i++)
                {
                    arrayToTeach[i] = testChain.Alphabet.IndexOf(chain[i]);
                }

                matrix.Add(arrayToTeach);
            }

            var toGet = new int[1];

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(6, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(3, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(2, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet = new int[2];

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(3, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(2, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(2, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet = new int[3];

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(2, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"d");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(2, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"c");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(1, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"a");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"a");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"c");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));

            toGet[0] = testChain.Alphabet.IndexOf((ValueString)"d");
            toGet[1] = testChain.Alphabet.IndexOf((ValueString)"b");
            toGet[2] = testChain.Alphabet.IndexOf((ValueString)"b");
            Assert.AreEqual(0, matrix.FrequencyFromObject(toGet));
        }
        /// <summary>
        /// Removes character.
        /// </summary>
        /// <param name="length">
        /// The length.
        /// </param>
        public void RemoveCharacter(int length)
        {
            if (Source.GetLength() == length)
            {
                resultChain.Set(Source, actualLength);
                Source = null;
            }
            else
            {
                var it1 = new IteratorStart(Source, length, 1);
                it1.Next();
                resultChain.Set(it1.Current(), actualLength);
                var it2 = new IteratorEnd(Source, Source.GetLength() - length, 1);
                it2.Next();
                Source = (BaseChain)it2.Current();
            }

            actualLength++;
        }
 /// <summary>
 /// The get result.
 /// </summary>
 /// <returns>
 /// The <see cref="BaseChain"/>.
 /// </returns>
 public BaseChain GetResult()
 {
     var it = new IteratorStart(resultChain, actualLength, 1);
     it.Next();
     return (BaseChain)it.Current();
 }
        /// <summary>
        /// Teaches markov chain using provided sequence.
        /// </summary>
        /// <param name="chain">
        /// Sequence used for teaching.
        /// </param>
        /// <param name="method">
        /// Chain preprocessing method.
        /// </param>
        public virtual void Teach(BaseChain chain, TeachingMethod method)
        {
            var builder = new MatrixBuilder();
            var absMatrix = new IAbsoluteMatrix[HeterogeneityRank + 1];
            Alphabet = chain.Alphabet;
            for (int i = 0; i < HeterogeneityRank + 1; i++)
            {
                absMatrix[i] = (IAbsoluteMatrix)builder.Create(Alphabet.Cardinality, Rank);
            }

            SpaceReorganizer reorganizer = GetRebuilder(method);
            chain = (BaseChain)reorganizer.Reorganize(chain);

            var it = new IteratorStart(chain, Rank, 1);
            it.Reset();

            int k = 0;

            // filling matrixes
            while (it.Next())
            {
                ++k;
                int m = k % (HeterogeneityRank + 1);
                if (m == 0)
                {
                    m = HeterogeneityRank + 1;
                }

                BaseChain chainToTeach = (BaseChain)it.Current();
                var indexedChain = new int[Rank];
                for (int i = 0; i < Rank; i++)
                {
                    indexedChain[i] = chain.Alphabet.IndexOf(chainToTeach[i]);
                }

                absMatrix[m - 1].Add(indexedChain);
            }

            for (int i = 0; i < HeterogeneityRank + 1; i++)
            {
                ProbabilityMatrixes[i] = absMatrix[i].ProbabilityMatrix();
            }
        }