/// <summary>
        /// Obtém os implicantes usados na expressão lógica.
        /// </summary>
        /// <param name="data">Os dados de entrada.</param>
        /// <returns>O conjunto de implicantes.</returns>
        private ImplicantLine[] GetUsedDataImplicants(BooleanMinimalFormInOut data)
        {
            var result = new List <ImplicantLine>();

            for (int i = 0; i < data.Count; ++i)
            {
                var combination = data[i];
                if (combination.LogicOutput == EBooleanMinimalFormOutStatus.ON)
                {
                    var implicantLine = new ImplicantLine()
                    {
                        LineCombination = combination.LogicInput
                    };

                    implicantLine.TableTuples.Add(i);
                    result.Add(implicantLine);
                }
            }

            return(result.ToArray());
        }
        /// <summary>
        /// Processa a lista de implicantes.
        /// </summary>
        /// <param name="implicantsList">A lista de implicantes a serem processados.</param>
        /// <returns>O resultado do processamento.</returns>
        private List <ImplicantLine> ProcessPrimeImplicantsList(List <List <ImplicantLine> > implicantsList)
        {
            var combinationEqualityComparer = new ImplicantLineEqualityComparer();
            var result = new List <ImplicantLine>();

            if (implicantsList.Count > 0)
            {
                var innerImplicantList = implicantsList;
                while (innerImplicantList.Count > 1)
                {
                    var groupedImplicantsList = new List <List <ImplicantLine> >();
                    var currentCombination    = innerImplicantList[0];
                    for (int i = 1; i < innerImplicantList.Count; ++i)
                    {
                        var nextCombination    = innerImplicantList[i];
                        var tempImplicantsList = new List <ImplicantLine>();
                        for (int j = 0; j < currentCombination.Count; ++j)
                        {
                            var upperPrimeImplicantCandidate = currentCombination[j];
                            var haveNotFoundReduction        = true;
                            for (int k = 0; k < nextCombination.Count; ++k)
                            {
                                var lowerPrimeImplicantCandidate = nextCombination[k];
                                var processedCombination         = default(LogicCombinationBitArray);
                                if (upperPrimeImplicantCandidate.LineCombination.TryToGetReduced(
                                        lowerPrimeImplicantCandidate.LineCombination,
                                        out processedCombination))
                                {
                                    var implicantLineToAdd = new ImplicantLine()
                                    {
                                        LineCombination = processedCombination
                                    };

                                    foreach (var logicComb in upperPrimeImplicantCandidate.TableTuples)
                                    {
                                        implicantLineToAdd.TableTuples.Add(logicComb);
                                    }

                                    foreach (var logicComb in lowerPrimeImplicantCandidate.TableTuples)
                                    {
                                        implicantLineToAdd.TableTuples.Add(logicComb);
                                    }

                                    tempImplicantsList.Add(implicantLineToAdd);
                                    haveNotFoundReduction = false;
                                }
                            }

                            if (haveNotFoundReduction)
                            {
                                if (!result.Contains(upperPrimeImplicantCandidate, combinationEqualityComparer))
                                {
                                    result.Add(upperPrimeImplicantCandidate);
                                }
                            }
                        }

                        if (tempImplicantsList.Count > 0)
                        {
                            groupedImplicantsList.Add(tempImplicantsList);
                        }

                        currentCombination = nextCombination;
                    }

                    // O último grupo não é passível de ser simplificado
                    var last = innerImplicantList[innerImplicantList.Count - 1];
                    for (int i = 0; i < last.Count; ++i)
                    {
                        var lastValue = last[i];
                        if (!result.Contains(lastValue, combinationEqualityComparer))
                        {
                            result.Add(lastValue);
                        }
                    }

                    innerImplicantList = groupedImplicantsList;
                }

                if (innerImplicantList.Any())
                {
                    var lastGroup = innerImplicantList[0];
                    foreach (var combination in lastGroup)
                    {
                        if (!result.Contains(combination, combinationEqualityComparer))
                        {
                            result.Add(combination);
                        }
                    }
                }
            }

            return(result);
        }