private bool IsGroupMintermsAvilableInArray(SKarnaughGroup group, bool[] Arr)
        {
            int[] mintermsIndexes = GetMintermsIndexes(GetMintermsInsideGroup(group));
            int   ArrayLen        = Arr.GetLength(0);

            //
            if (ArrayLen == 0)
            {
                return(false);
            }
            // - - -
            foreach (int index in mintermsIndexes)
            {
                if (index < ArrayLen)
                {
                    if (Arr[index] == true)
                    {
                        continue;
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }
            return(true);
        }
        private bool IsGroupAvilableInFunctionMinterms(SKarnaughGroup group)
        {
            CMinterm[] groupMinterms       = GetMintermsInsideGroup(group); // Get minterms inside 'group' parameter
            int        groupMintermsLength = groupMinterms.GetLength(0);

            // Controler Code
            if (m_minterms.GetLength(0) == 0)
            {
                return(false);
            }
            // - - -

            for (int i = 0; i < groupMintermsLength; i++)
            {
                if (m_minterms[groupMinterms[i].GetDecimalIndex()].BoolValue)
                {
                    continue; // Minterm found in array ! we must find next minterm in array
                }
                else
                {
                    return(false); // One of minterms NOT found in array , method must return false.
                }
            }
            // 'for' loop is finished . all minterms in group parameter are in function minterms.
            return(true);
        }
        public static string GetGroupString(SKarnaughGroup group, char[] letters)
        {
            ArrayList groupChars = new ArrayList();

            int[] mintermIndexes    = GetMintermsIndexes(GetMintermsInsideGroup(group));
            int   firstMintermIndex = mintermIndexes[0];
            int   indexesCount      = mintermIndexes.GetLength(0);
            int   equalityResult    = firstMintermIndex;
            byte  lettersCount      = (byte)letters.GetLength(0);
            bool  flag;

            // Group string for group RectGroup_16
            if ((group.Type == EGroupTypes.RectGroup_16 && lettersCount == 4) || (group.Type == EGroupTypes.RectGroup_8_Hor && lettersCount == 3))
            {
                return("1 (True)");
            }
            // Find bits in minterms that are equal (bits with same height)
            for (byte i = 0; i < lettersCount; i++)
            {
                flag = true;
                for (int j = 1; j < indexesCount; j++)
                {
                    if (BinaryManip.GetBitValue(firstMintermIndex, i)
                        != BinaryManip.GetBitValue(mintermIndexes[j], i))
                    {
                        flag = false;
                        break;
                    }
                }
                BinaryManip.SetBitValue(ref equalityResult, i, flag);
            }
            // - - -

            // Produce group string
            for (byte i = 0; i < lettersCount; i++)
            {
                if (BinaryManip.GetBitValue(equalityResult, i))
                {
                    string tmpStr;
                    if (BinaryManip.GetBitValue(firstMintermIndex, i))
                    {
                        tmpStr = letters[lettersCount - i - 1].ToString();
                    }
                    else
                    {
                        tmpStr = letters[lettersCount - i - 1].ToString() + "\'";
                    }

                    groupChars.Add(tmpStr);
                }
            }
            groupChars.Reverse();
            // - - -

            // Return all strings
            string[] str = (string[])groupChars.ToArray(typeof(string));
            return(string.Concat(str));
        }
        private void InsertGroupMintermsToArray(SKarnaughGroup group, bool[] ArrayToInsert)
        {
            int[] Indexes = GetMintermsIndexes(GetMintermsInsideGroup(group));

            foreach (int i in Indexes)
            {
                ArrayToInsert[i] = true;
            }
        }
        public static string GetMintermString(int mintermIndex, char[] letters)
        {
            SKarnaughGroup group = new SKarnaughGroup();

            group.Type     = EGroupTypes.SingleMinterm;
            group.Location = mintermIndex;

            return(GetGroupString(group, letters));
        }
        private void ctlKarnaughTable_Paint(object sender, PaintEventArgs e)
        {
            Graphics g             = e.Graphics;
            Point    point1        = new Point();
            Point    point2        = new Point();
            Point    point3        = new Point();
            int      mintermsCount = 16;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            if (m_objKarnaugh == null)
            {
                mintermsCount = 16;
            }
            else if (m_objKarnaugh.GetTableType() == EKarnaughTableType.Karnaugh3Var)
            {
                mintermsCount = 8;
            }


            #region Draw Table Border
            m_borderPen.Color = m_borderColor;
            g.DrawRectangle(m_borderPen, new Rectangle(new Point(0, 0), new System.Drawing.Size(this.Width - 1, this.Height - 1)));
            #endregion

            #region Draw Table Frame
            int X1 = m_innerTableRegion.Left;
            int Y1 = m_innerTableRegion.Top;
            int X2 = m_innerTableRegion.Right;
            int Y2 = m_innerTableRegion.Bottom;

            // Draw rows
            int currentCellBottom;
            g.DrawLine(m_framePen, X1, Y1, X2, Y1);
            for (int i = 0; i < m_rowsCount; i++)
            {
                currentCellBottom = GetCellLocation(i, 0).Bottom;
                g.DrawLine(m_framePen, X1, currentCellBottom, X2, currentCellBottom);
            }

            // Draw cols
            int currentCellRight;
            g.DrawLine(m_framePen, X1, Y1, X1, Y2);
            for (int i = 0; i < m_colsCount; i++)
            {
                currentCellRight = GetCellLocation(0, i).Right;
                g.DrawLine(m_framePen, currentCellRight, Y1, currentCellRight, Y2);
            }

            #endregion

            if (ShowMintermsIndex)
            {
                #region Draw Minterm Indexses

                for (int i = 0; i < mintermsCount; i++)
                {
                    // Draw minterm indexes in cells
                    point1 = GetMintermLocation(i).Location;
                    TextRenderer.DrawText(g, i.ToString(), m_mintemIndexFont, point1, m_mintermIndexColor);
                }
                #endregion
            }

            if (ShowLables)
            {
                #region Draw lables

                const int SPC = 5;
                char[]    chrLetters;
                char      chr;

                #region Draw binary lables

                for (int i = 0; i < m_colsCount; i++)
                {
                    point1.X = m_cellsLocation_Hor[i].Left + (m_cellsLocation_Hor[i].Width - m_lableBitsSize.Width) / 2;
                    point1.Y = m_innerTableRegion.Top - m_lableBitsSize.Height;
                    TextRenderer.DrawText(g, m_strLableBits_Cols[i], m_lableBitsFont, point1, m_lableBitsColor);
                }

                for (int i = 0; i < m_rowsCount; i++)
                {
                    point1.X = m_innerTableRegion.Left - m_lableBitsSize.Width;
                    point1.Y = m_cellsLocation_Ver[i].Top + (m_cellsLocation_Ver[i].Height - m_lableBitsSize.Height) / 2;;
                    TextRenderer.DrawText(g, m_strLableBits_Rows[i], m_lableBitsFont, point1, m_lableBitsColor);
                }


                #endregion

                #region Draw brackets && table letters

                if (m_objKarnaugh == null)
                {
                    chrLetters = new char[4] {
                        'A', 'B', 'C', 'D'
                    }
                }
                ;
                else
                {
                    chrLetters = m_objKarnaugh.TableLetters;
                }

                // Bracket for letter A
                point1.X = m_innerTableRegion.Left - m_lableBitsSize.Width - SPC;
                point1.Y = (m_innerTableRegion.Top + m_innerTableRegion.Bottom) / 2;
                point2.X = point1.X;
                point2.Y = m_innerTableRegion.Bottom;
                g.DrawLine(m_bracketPen, point1, point2);

                point3.X = point1.X - m_lableSize.Width;
                point3.Y = (point2.Y + point1.Y - m_lableSize.Height) / 2;
                TextRenderer.DrawText(g, chrLetters[0].ToString(), m_lableFont, point3, m_lableColor);


                // Bracket for letter C
                point1.X = m_cellsLocation_Hor[2].Left;
                point1.Y = m_innerTableRegion.Top - m_lableBitsSize.Height - SPC;
                point2.X = m_cellsLocation_Hor[3].Right;
                point2.Y = point1.Y;
                g.DrawLine(m_bracketPen, point1, point2);

                point3.X = (point2.X + point1.X - m_lableSize.Width) / 2;
                point3.Y = point1.Y - m_lableSize.Height;
                chr      = m_rowsCount == 2 ? chrLetters[1] : chrLetters[2];
                TextRenderer.DrawText(g, chr.ToString(), m_lableFont, point3, m_lableColor);



                // Bracket for letter D
                point1.X = m_cellsLocation_Hor[1].Left;
                point1.Y = m_innerTableRegion.Bottom + SPC * 2;
                point2.X = m_cellsLocation_Hor[3].Left;
                point2.Y = point1.Y;
                g.DrawLine(m_bracketPen, point1, point2);

                point3.X = (point1.X + point2.X - m_lableSize.Width) / 2;
                point3.Y = point2.Y;
                chr      = m_rowsCount == 2 ? chrLetters[2] : chrLetters[3];
                TextRenderer.DrawText(g, chr.ToString(), m_lableFont, point3, m_lableColor);

                if (m_rowsCount == 4)
                {
                    // Bracket for letter B
                    point1.X = m_innerTableRegion.Right + SPC * 2;
                    point1.Y = m_cellsLocation_Ver[1].Top;
                    point2.X = point1.X;
                    point2.Y = m_cellsLocation_Ver[3].Top;
                    g.DrawLine(m_bracketPen, point1, point2);

                    point3.X = point2.X + SPC;
                    point3.Y = (point2.Y + point1.Y - m_lableSize.Height) / 2;
                    TextRenderer.DrawText(g, chrLetters[1].ToString(), m_lableFont, point3, m_lableColor);
                }
                #endregion

                #region Draw DIAGONAL line && row and col headers

                point1.X = m_innerTableRegion.Left - 20;
                point1.Y = m_innerTableRegion.Top - 20;
                // Set location of col headers
                point2.X = point1.X - m_lableSize.Width;
                point2.Y = point1.Y + m_lableSize.Height / 2;
                // Set location of row headers
                point3.X = point1.X + m_lableSize.Width / 2;
                point3.Y = point1.Y - m_lableSize.Height / 2;

                g.DrawLine(m_framePen, point1, m_innerTableRegion.Location);

                TextRenderer.DrawText(g, chrLetters[0].ToString() + chrLetters[1].ToString(), m_lableFont, point2, m_lableColor);
                string strRowHeader = m_rowsCount == 2 ? chrLetters[2].ToString() : chrLetters[2].ToString() + chrLetters[3].ToString();
                TextRenderer.DrawText(g, strRowHeader, m_lableFont, point3, m_lableColor);

                #endregion
                #endregion
            }

            #region Draw minterm values  && Specify Groups Visualy

            if (m_objKarnaugh != null)
            {
                #region Draw minterm values
                string    strBool = "0";
                Rectangle tmp;
                bool      currentMintermValue;

                for (int i = 0; i < mintermsCount; i++)
                {
                    tmp                 = GetMintermLocation(i);
                    point1.X            = tmp.Left + tmp.Width / 2 - 10;
                    point1.Y            = tmp.Top + tmp.Height / 2 - 10;
                    currentMintermValue = m_objKarnaugh.GetMintermValue(i);

                    if (currentMintermValue && m_showValue1)
                    {
                        strBool = "1";
                        m_generalBrush.Color = m_mintermValueColor;
                        g.DrawString(strBool, m_mintermValueFont, m_generalBrush, point1);
                    }
                    else if (currentMintermValue == false && m_showValue0)
                    {
                        strBool = "0";
                        m_generalBrush.Color = Color.FromArgb(100, m_mintermValueColor);
                        g.DrawString(strBool, m_mintermValueFont, m_generalBrush, point1);
                    }
                }
                #endregion

                if (m_specifyGroupsVisualy)
                {
                    #region Specify Groups Visualy

                    SKarnaughGroup[] groups = m_objKarnaugh.GetFunctionGroups();
                    foreach (SKarnaughGroup group in groups)
                    {
                        SpecifyGroupVisualy(group, g);
                    }
                    #endregion
                }
            }
            else
            {
                // Show a group temprory (to help to developers to set color property of groups easily)
                SKarnaughGroup myGroup = new SKarnaughGroup();
                myGroup.Location = 0;
                myGroup.Type     = EGroupTypes.SingleMinterm;

                SpecifyGroupVisualy(myGroup, g);
            }
            #endregion
        }
        private void SpecifyGroupVisualy(SKarnaughGroup group, Graphics g)
        {
            Point[] points1;
            Point[] points2;
            Point[] points3;
            Point[] points4;

            System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();

            Rectangle[] drawRegions      = GetGroupRegions(group);
            int         drawRegionsCount = drawRegions.GetLength(0);
            int         Spc_HOR          = 20;
            int         Spc_VER          = 15;
            int         Dest_To_Reg      = m_innerTableRegion.Left / 2;

            if (drawRegionsCount == 1)
            {
                points1 = new Point[2];
                int middle_X = (drawRegions[0].Left + drawRegions[0].Right) / 2;
                Spc_HOR = 10;
                Spc_VER = 10;

                #region Set rectangular shape points (for around a cell)

                points1[0].X = drawRegions[0].Left + Spc_HOR;
                points1[0].Y = drawRegions[0].Top + Spc_VER;

                points1[1].X = drawRegions[0].Right - Spc_HOR;
                points1[1].Y = drawRegions[0].Bottom - Spc_VER;
                #endregion

                path.AddEllipse(points1[0].X, points1[0].Y, points1[1].X - points1[0].X, points1[1].Y - points1[0].Y);
                path.StartFigure();
            }
            else if (drawRegionsCount == 2)
            {
                points1 = new Point[4];
                points2 = new Point[4];

                #region Set curve points (for around two groups)

                if (drawRegions[0].Left == drawRegions[1].Left)
                {
                    // We have two HORIZONTAL group
                    #region Set top group points

                    points1[0].X = drawRegions[0].Left + Spc_HOR;
                    points1[0].Y = m_innerTableRegion.Top - Dest_To_Reg;

                    points1[1].X = (int)(drawRegions[0].Left + Spc_HOR);
                    points1[1].Y = (int)(drawRegions[0].Bottom - Spc_VER);

                    points1[2].X = (int)(drawRegions[0].Right - Spc_HOR);
                    points1[2].Y = points1[1].Y;

                    points1[3].X = points1[2].X;
                    points1[3].Y = points1[0].Y;
                    #endregion

                    #region Set bottom group points
                    points2[0].X = points1[0].X;
                    points2[0].Y = drawRegions[1].Bottom + Dest_To_Reg;

                    points2[1].X = points1[1].X;
                    points2[1].Y = (int)(drawRegions[1].Top + Spc_VER);

                    points2[2].X = points1[2].X;
                    points2[2].Y = points2[1].Y;

                    points2[3].X = points1[3].X;
                    points2[3].Y = points2[0].Y;
                    #endregion
                }
                else
                {
                    // We have two VERTICAL group

                    #region Set left group points

                    points1[0].X = m_innerTableRegion.Left - Dest_To_Reg;
                    points1[0].Y = drawRegions[0].Top + Spc_VER;

                    points1[1].X = (int)(drawRegions[0].Right - Spc_HOR);
                    points1[1].Y = (int)(drawRegions[0].Top + Spc_VER);

                    points1[2].X = points1[1].X;
                    points1[2].Y = (int)(drawRegions[0].Bottom - Spc_VER);

                    points1[3].X = points1[0].X;
                    points1[3].Y = drawRegions[0].Bottom - Spc_VER;
                    #endregion


                    #region Set right group points

                    points2[0].X = m_innerTableRegion.Right + Dest_To_Reg;
                    points2[0].Y = points1[0].Y;

                    points2[1].X = (int)(drawRegions[1].Left + Spc_HOR);
                    points2[1].Y = points1[1].Y;

                    points2[2].X = points2[1].X;
                    points2[2].Y = points1[2].Y;

                    points2[3].X = points2[0].X;
                    points2[3].Y = points1[2].Y;
                    #endregion
                }
                #endregion

                path.AddCurve(points1, 0.2f);
                path.StartFigure();
                path.AddCurve(points2, 0.2f);
            }
            else
            {
                points1 = new Point[3];
                points2 = new Point[3];
                points3 = new Point[3];
                points4 = new Point[3];

                #region Set curve points (for around four groups)

                // Group 1
                points1[0].X = m_innerTableRegion.Left - Dest_To_Reg;
                points1[0].Y = drawRegions[0].Bottom - Spc_VER;

                points1[1].X = drawRegions[0].Right - Spc_HOR;  //drawRegions[0].Right- Spc_HOR ;
                points1[1].Y = drawRegions[0].Bottom - Spc_VER; //points1[0].Y;

                points1[2].X = drawRegions[0].Right - Spc_HOR;
                points1[2].Y = m_innerTableRegion.Top - Dest_To_Reg;

                // Group 2
                points2[0].X = drawRegions[1].Right + Dest_To_Reg;
                points2[0].Y = points1[0].Y;

                points2[1].X = drawRegions[1].Left + Spc_HOR;
                points2[1].Y = points1[1].Y;

                points2[2].X = drawRegions[1].Left + Spc_HOR;
                points2[2].Y = points1[2].Y;

                // Group 3
                points3[0].X = points1[0].X;
                points3[0].Y = drawRegions[2].Top + Spc_VER;

                points3[1].X = points1[1].X;
                points3[1].Y = drawRegions[2].Top + Spc_VER;

                points3[2].X = points1[2].X;
                points3[2].Y = drawRegions[2].Bottom + Dest_To_Reg;

                // Group 4
                points4[0].X = points2[0].X;
                points4[0].Y = points3[0].Y;

                points4[1].X = points2[1].X;
                points4[1].Y = points3[1].Y;

                points4[2].X = points2[2].X;
                points4[2].Y = points3[2].Y;
                #endregion

                path.AddCurve(points1);
                path.StartFigure();
                path.AddCurve(points2);
                path.StartFigure();
                path.AddCurve(points3);
                path.StartFigure();
                path.AddCurve(points4);
            }

            // Draw with high quality
            g.DrawPath(m_groupSpecifyerPen, path);
            //
        }
        private Rectangle[] GetGroupRegions(SKarnaughGroup group)
        {
            Rectangle[] reg;

            if (group.Type == EGroupTypes.RectGroup_4 && group.Location == 10)
            {
                #region We must return 4 region
                reg    = new Rectangle[4];
                reg[0] = GetMintermLocation(0);
                reg[1] = GetMintermLocation(2);
                reg[2] = GetMintermLocation(8);
                reg[3] = GetMintermLocation(10);

                #endregion
            }
            else if ((group.Location % 4 == 2 && (group.Type == EGroupTypes.LinerGroup_2_Hor ||
                                                  group.Type == EGroupTypes.RectGroup_4 ||
                                                  group.Type == EGroupTypes.RectGroup_8_Ver)) ||
                     ((group.Location >= 8 && group.Location <= 11) && (group.Type == EGroupTypes.LinerGroup_2_Ver ||
                                                                        group.Type == EGroupTypes.RectGroup_4 ||
                                                                        group.Type == EGroupTypes.RectGroup_8_Hor)))
            {
                #region We must return 2 region
                reg = new Rectangle[2];
                SKarnaughGroup g1, g2;
                Rectangle[]    reg1;
                Rectangle[]    reg2;
                switch (group.Type)
                {
                case EGroupTypes.RectGroup_8_Ver:
                    g1.Type     = g2.Type = EGroupTypes.LinerGroup_4_Ver;
                    g1.Location = 0;
                    g2.Location = 2;

                    reg1 = GetGroupRegions(g1);
                    reg2 = GetGroupRegions(g2);

                    reg[0] = reg1[0];
                    reg[1] = reg2[0];
                    break;

                case EGroupTypes.RectGroup_8_Hor:
                    g1.Type     = g2.Type = EGroupTypes.LinerGroup_4_Hor;
                    g1.Location = 0;
                    g2.Location = 8;

                    reg1 = GetGroupRegions(g1);
                    reg2 = GetGroupRegions(g2);

                    reg[0] = reg1[0];
                    reg[1] = reg2[0];
                    break;

                case EGroupTypes.RectGroup_4:
                    if (group.Location == 2 || group.Location == 6 || group.Location == 14)
                    {
                        g1.Type     = g2.Type = EGroupTypes.LinerGroup_2_Ver;
                        g1.Location = group.Location - 2;
                        g2.Location = group.Location;

                        reg1 = GetGroupRegions(g1);
                        reg2 = GetGroupRegions(g2);

                        reg[0] = reg1[0];
                        reg[1] = reg2[0];
                    }
                    else if (group.Location == 8 || group.Location == 9 || group.Location == 11)
                    {
                        g1.Type     = g2.Type = EGroupTypes.LinerGroup_2_Hor;
                        g1.Location = group.Location - 8;
                        g2.Location = group.Location;

                        reg1 = GetGroupRegions(g1);
                        reg2 = GetGroupRegions(g2);

                        reg[0] = reg1[0];
                        reg[1] = reg2[0];
                    }

                    break;

                case EGroupTypes.LinerGroup_2_Hor:
                    g1.Type     = g2.Type = EGroupTypes.SingleMinterm;
                    g1.Location = group.Location - 2;
                    g2.Location = group.Location;

                    reg1 = GetGroupRegions(g1);
                    reg2 = GetGroupRegions(g2);

                    reg[0] = reg1[0];
                    reg[1] = reg2[0];
                    break;

                case EGroupTypes.LinerGroup_2_Ver:
                    g1.Type     = g2.Type = EGroupTypes.SingleMinterm;
                    g1.Location = group.Location - 8;
                    g2.Location = group.Location;

                    reg1 = GetGroupRegions(g1);
                    reg2 = GetGroupRegions(g2);

                    reg[0] = reg1[0];
                    reg[1] = reg2[0];
                    break;
                }
                #endregion
            }
            else
            {
                #region We must return 1 region
                Rectangle currentRegion;
                int[]     mintermIndexes = CKarnaughTable.GetMintermsIndexes(CKarnaughTable.GetMintermsInsideGroup(group));
                int       regionsCount   = mintermIndexes.GetLength(0);
                reg = new Rectangle[1];

                reg[0] = GetMintermLocation(mintermIndexes[0]);
                for (int i = 1; i < regionsCount; i++)
                {
                    currentRegion = GetMintermLocation(mintermIndexes[i]);
                    if (currentRegion.Left < reg[0].Left)
                    {
                        reg[0].X = currentRegion.Left;
                    }
                    if (currentRegion.Top < reg[0].Top)
                    {
                        reg[0].Y = currentRegion.Top;
                    }
                    if (currentRegion.Right > reg[0].Right)
                    {
                        reg[0].Width = currentRegion.Right - reg[0].Left;
                    }
                    if (currentRegion.Bottom > reg[0].Bottom)
                    {
                        reg[0].Height = currentRegion.Bottom - reg[0].Top;
                    }
                }
                #endregion
            }


            return(reg);
        }
 private string GetGroupString(SKarnaughGroup group)
 {
     return(GetGroupString(group, m_tableLetters));
 }
        public SKarnaughGroup[] GetFunctionGroups()
        {
            int functionMintermsCount = m_minterms.GetLength(0);

            bool[]         functionMintermsValues = new bool[functionMintermsCount];
            bool[]         coveredMinterms        = new bool[functionMintermsCount];
            SKarnaughGroup group          = new SKarnaughGroup();
            ArrayList      functionGroups = new ArrayList();
            int            RowsCount;


            // Map function minterms to a boolean array
            for (int i = 0; i < functionMintermsCount; i++)
            {
                functionMintermsValues[i] = m_minterms[i].BoolValue ? true : false;
            }
            // - - -

            #region Search for "RectGroup_16" group
            if (functionMintermsCount == 16)
            {
                group.Type     = EGroupTypes.RectGroup_16;
                group.Location = 0;

                if (IsGroupAvilableInFunctionMinterms(group))
                {
                    functionGroups.Add(group);
                    return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                }
            }
            #endregion

            RowsCount = m_tableType == EKarnaughTableType.Karnaugh3Var ? 1 : 4;

            #region Search for "RectGroup_8_Hor" groups
            group.Type = EGroupTypes.RectGroup_8_Hor;
            for (int i = 0; i < RowsCount; i++)
            {
                group.Location = i * 4;
                if (IsGroupAvilableInFunctionMinterms(group))
                {
                    if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                    {
                        InsertGroupMintermsToArray(group, coveredMinterms);
                        functionGroups.Add(group);
                    }
                    if (IsContentEqual(functionMintermsValues, coveredMinterms))
                    {
                        return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                    }
                }
            }
            #endregion

            #region Search for "RectGroup_8_Ver" groups
            if (functionMintermsCount == 16)
            {
                group.Type = EGroupTypes.RectGroup_8_Ver;
                for (int i = 0; i <= 3; i++)
                {
                    group.Location = i;
                    if (IsGroupAvilableInFunctionMinterms(group))
                    {
                        if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                        {
                            InsertGroupMintermsToArray(group, coveredMinterms);
                            functionGroups.Add(group);
                        }
                        if (IsContentEqual(functionMintermsValues, coveredMinterms))
                        {
                            return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                        }
                    }
                }
            }
            #endregion

            RowsCount = m_tableType == EKarnaughTableType.Karnaugh3Var ? 2 : 4;

            #region Search for "LinerGroup_4_Hor" groups
            group.Type = EGroupTypes.LinerGroup_4_Hor;
            for (int i = 0; i < RowsCount; i++)
            {
                group.Location = i * 4;
                if (IsGroupAvilableInFunctionMinterms(group))
                {
                    if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                    {
                        InsertGroupMintermsToArray(group, coveredMinterms);
                        functionGroups.Add(group);
                    }
                    if (IsContentEqual(functionMintermsValues, coveredMinterms))
                    {
                        return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                    }
                }
            }
            #endregion

            #region Search for "LinerGroup_4_Ver" groups
            if (functionMintermsCount == 16)
            {
                group.Type = EGroupTypes.LinerGroup_4_Ver;
                for (int i = 0; i <= 3; i++)
                {
                    group.Location = i;
                    if (IsGroupAvilableInFunctionMinterms(group))
                    {
                        if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                        {
                            InsertGroupMintermsToArray(group, coveredMinterms);
                            functionGroups.Add(group);
                        }
                        if (IsContentEqual(functionMintermsValues, coveredMinterms))
                        {
                            return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                        }
                    }
                }
            }
            #endregion

            RowsCount = m_tableType == EKarnaughTableType.Karnaugh3Var ? 1 : 4;

            #region Search for "RectGroup_4" groups
            group.Type = EGroupTypes.RectGroup_4;
            for (int i = 0; i < RowsCount; i++)
            {
                for (int j = 0; j <= 3; j++)
                {
                    group.Location = i * 4 + j;
                    if (IsGroupAvilableInFunctionMinterms(group))
                    {
                        if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                        {
                            InsertGroupMintermsToArray(group, coveredMinterms);
                            functionGroups.Add(group);
                        }
                        if (IsContentEqual(functionMintermsValues, coveredMinterms))
                        {
                            return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                        }
                    }
                }
            }
            #endregion

            RowsCount = m_tableType == EKarnaughTableType.Karnaugh3Var ? 2 : 4;

            #region Search for "LinerGroup_2_Hor" groups
            group.Type = EGroupTypes.LinerGroup_2_Hor;
            for (int i = 0; i < RowsCount; i++)
            {
                for (int j = 0; j <= 3; j++)
                {
                    group.Location = i * 4 + j;
                    if (IsGroupAvilableInFunctionMinterms(group))
                    {
                        if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                        {
                            InsertGroupMintermsToArray(group, coveredMinterms);
                            functionGroups.Add(group);
                        }
                        if (IsContentEqual(functionMintermsValues, coveredMinterms))
                        {
                            return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                        }
                    }
                }
            }

            #endregion

            RowsCount = m_tableType == EKarnaughTableType.Karnaugh3Var ? 1 : 4;

            #region Search for "LinerGroup_2_Ver" groups
            group.Type = EGroupTypes.LinerGroup_2_Ver;
            for (int i = 0; i < RowsCount; i++)
            {
                for (int j = 0; j <= 3; j++)
                {
                    group.Location = i * 4 + j;
                    if (IsGroupAvilableInFunctionMinterms(group))
                    {
                        if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                        {
                            InsertGroupMintermsToArray(group, coveredMinterms);
                            functionGroups.Add(group);
                        }
                        if (IsContentEqual(functionMintermsValues, coveredMinterms))
                        {
                            return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                        }
                    }
                }
            }
            #endregion

            RowsCount = m_tableType == EKarnaughTableType.Karnaugh3Var ? 2 : 4;

            #region Search for "SingleMinterm" groups
            group.Type = EGroupTypes.SingleMinterm;
            for (int i = 0; i < RowsCount; i++)
            {
                for (int j = 0; j <= 3; j++)
                {
                    group.Location = i * 4 + j;
                    if (IsGroupAvilableInFunctionMinterms(group))
                    {
                        if (!IsGroupMintermsAvilableInArray(group, coveredMinterms))
                        {
                            InsertGroupMintermsToArray(group, coveredMinterms);
                            functionGroups.Add(group);
                        }
                        if (IsContentEqual(functionMintermsValues, coveredMinterms))
                        {
                            return((SKarnaughGroup[])functionGroups.ToArray(typeof(SKarnaughGroup)));
                        }
                    }
                }
            }
            #endregion

            return(new SKarnaughGroup[0]);
        }
        public static CMinterm[] GetMintermsInsideGroup(SKarnaughGroup group)
        {
            CMinterm[] neighbors      = new CMinterm[0];
            int[]      mintermIndexes = new int[0];

            switch (group.Type)
            {
            case EGroupTypes.RectGroup_16:
                #region RectGroup_16
                neighbors = new CMinterm[16];
                for (int i = 0; i < 16; i++)
                {
                    neighbors[i] = new CMinterm(i);
                }

                break;
                #endregion

            case EGroupTypes.RectGroup_8_Hor:
                #region RectGroup_8_Hor
                neighbors = new CMinterm[8];
                for (int i = 0; i < 8; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                if (group.Location >= 0 && group.Location <= 3)
                {
                    mintermIndexes = new int[8] {
                        0, 1, 2, 3, 4, 5, 6, 7
                    }
                }
                ;                                                               // Array of minterm indexes
                else if (group.Location >= 4 && group.Location <= 7)
                {
                    mintermIndexes = new int[8] {
                        4, 5, 6, 7, 12, 13, 14, 15
                    }
                }
                ;                                                                   // Array of minterm indexes
                else if (group.Location >= 8 && group.Location <= 11)
                {
                    mintermIndexes = new int[8] {
                        8, 9, 10, 11, 0, 1, 2, 3
                    }
                }
                ;                                                                 // Array of minterm indexes
                else if (group.Location >= 12 && group.Location <= 15)
                {
                    mintermIndexes = new int[8] {
                        12, 13, 14, 15, 8, 9, 10, 11
                    }
                }
                ;                                                                     // Array of minterm indexes

                for (int i = 0; i < 8; i++)
                {
                    neighbors[i].SetIndex(mintermIndexes[i]);
                }

                break;
                #endregion

            case EGroupTypes.RectGroup_8_Ver:
                #region RectGroup_8_Ver
                neighbors = new CMinterm[8];
                for (int i = 0; i < 8; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                switch (group.Location % 4)
                {
                case 0:
                    mintermIndexes = new int[8] {
                        0, 4, 12, 8, 1, 5, 13, 9
                    };                                                                // Array of minterm indexes
                    break;

                case 1:
                    mintermIndexes = new int[8] {
                        1, 5, 13, 9, 3, 7, 15, 11
                    };                                                                 // Array of minterm indexes
                    break;

                case 2:
                    mintermIndexes = new int[8] {
                        2, 6, 14, 10, 0, 4, 12, 8
                    };                                                                 // Array of minterm indexes
                    break;

                case 3:
                    mintermIndexes = new int[8] {
                        3, 7, 15, 11, 2, 6, 14, 10
                    };                                                                  // Array of minterm indexes
                    break;
                }

                for (int i = 0; i < 8; i++)
                {
                    neighbors[i].SetIndex(mintermIndexes[i]);
                }

                break;
                #endregion

            case EGroupTypes.RectGroup_4:
                #region RectGroup_4

                neighbors = new CMinterm[4];
                for (int i = 0; i < 4; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                switch (group.Location)
                {
                case 0:
                    mintermIndexes = new int[4] {
                        0, 1, 4, 5
                    };                                                  // Array of minterm indexes
                    break;

                case 1:
                    mintermIndexes = new int[4] {
                        1, 3, 5, 7
                    };                                                  // Array of minterm indexes
                    break;

                case 2:
                    mintermIndexes = new int[4] {
                        2, 0, 4, 6
                    };                                                  // Array of minterm indexes
                    break;

                case 3:
                    mintermIndexes = new int[4] {
                        3, 2, 7, 6
                    };                                                  // Array of minterm indexes
                    break;

                case 4:
                    mintermIndexes = new int[4] {
                        4, 5, 12, 13
                    };                                                    // Array of minterm indexes
                    break;

                case 5:
                    mintermIndexes = new int[4] {
                        5, 7, 13, 15
                    };                                                    // Array of minterm indexes
                    break;

                case 6:
                    mintermIndexes = new int[4] {
                        6, 4, 12, 14
                    };                                                    // Array of minterm indexes
                    break;

                case 7:
                    mintermIndexes = new int[4] {
                        7, 6, 15, 14
                    };                                                    // Array of minterm indexes
                    break;

                case 8:
                    mintermIndexes = new int[4] {
                        8, 9, 0, 1
                    };                                                  // Array of minterm indexes
                    break;

                case 9:
                    mintermIndexes = new int[4] {
                        9, 11, 1, 3
                    };                                                   // Array of minterm indexes
                    break;

                case 10:
                    mintermIndexes = new int[4] {
                        10, 8, 0, 2
                    };                                                   // Array of minterm indexes
                    break;

                case 11:
                    mintermIndexes = new int[4] {
                        11, 10, 3, 2
                    };                                                    // Array of minterm indexes
                    break;

                case 12:
                    mintermIndexes = new int[4] {
                        12, 13, 8, 9
                    };                                                    // Array of minterm indexes
                    break;

                case 13:
                    mintermIndexes = new int[4] {
                        13, 15, 9, 11
                    };                                                     // Array of minterm indexes
                    break;

                case 14:
                    mintermIndexes = new int[4] {
                        14, 12, 8, 10
                    };                                                     // Array of minterm indexes
                    break;

                case 15:
                    mintermIndexes = new int[4] {
                        15, 14, 11, 10
                    };                                                      // Array of minterm indexes
                    break;
                }

                for (int i = 0; i < 4; i++)
                {
                    neighbors[i].SetIndex(mintermIndexes[i]);
                }

                break;
                #endregion

            case EGroupTypes.LinerGroup_4_Hor:
                #region LinerGroup_4_Hor
                neighbors = new CMinterm[4];
                for (int i = 0; i < 4; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                if (group.Location >= 0 && group.Location <= 3)
                {
                    mintermIndexes = new int[4] {
                        0, 1, 2, 3
                    }
                }
                ;                                                   // Array of minterm indexes
                else if (group.Location >= 4 && group.Location <= 7)
                {
                    mintermIndexes = new int[4] {
                        4, 5, 6, 7
                    }
                }
                ;                                                   // Array of minterm indexes
                else if (group.Location >= 8 && group.Location <= 11)
                {
                    mintermIndexes = new int[4] {
                        8, 9, 10, 11
                    }
                }
                ;                                                     // Array of minterm indexes
                else if (group.Location >= 12 && group.Location <= 15)
                {
                    mintermIndexes = new int[4] {
                        12, 13, 14, 15
                    }
                }
                ;                                                       // Array of minterm indexes

                for (int i = 0; i < 4; i++)
                {
                    neighbors[i].SetIndex(mintermIndexes[i]);
                }

                break;
                #endregion

            case EGroupTypes.LinerGroup_4_Ver:
                #region LinerGroup_4_Ver
                neighbors = new CMinterm[4];
                for (int i = 0; i < 4; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                switch (group.Location % 4)
                {
                case 0:
                    mintermIndexes = new int[4] {
                        0, 4, 12, 8
                    };                                                   // Array of minterm indexes
                    break;

                case 1:
                    mintermIndexes = new int[4] {
                        1, 5, 13, 9
                    };                                                   // Array of minterm indexes
                    break;

                case 2:
                    mintermIndexes = new int[4] {
                        2, 6, 14, 10
                    };                                                    // Array of minterm indexes
                    break;

                case 3:
                    mintermIndexes = new int[4] {
                        3, 7, 15, 11
                    };                                                    // Array of minterm indexes
                    break;
                }

                for (int i = 0; i < 4; i++)
                {
                    neighbors[i].SetIndex(mintermIndexes[i]);
                }

                break;
                #endregion

            case EGroupTypes.LinerGroup_2_Hor:
                #region LinerGroup_2_Hor
                neighbors = new CMinterm[2];
                for (int i = 0; i < 2; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                switch (group.Location % 4)
                {
                case 0:
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location + 1);
                    break;

                case 1:
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location + 2);
                    break;

                case 2:
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location - 2);
                    break;

                case 3:
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location - 1);
                    break;
                }

                break;
                #endregion

            case EGroupTypes.LinerGroup_2_Ver:
                #region LinerGroup_2_Ver
                neighbors = new CMinterm[2];
                for (int i = 0; i < 2; i++)
                {
                    neighbors[i] = new CMinterm();
                }

                if (group.Location >= 0 && group.Location <= 3)
                {
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location + 4);
                }
                else if (group.Location >= 4 && group.Location <= 7)
                {
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location + 8);
                }
                else if (group.Location >= 8 && group.Location <= 11)
                {
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location - 8);
                }
                else     // (group.Location >= 12 && group.Location <= 15)
                {
                    neighbors[0].SetIndex(group.Location);
                    neighbors[1].SetIndex(group.Location - 4);
                }

                break;
                #endregion

            case EGroupTypes.SingleMinterm:
                #region SingleMinterm
                neighbors    = new CMinterm[1];
                neighbors[0] = new CMinterm();

                neighbors[0].SetIndex(group.Location);
                break;
                #endregion
            }

            return(neighbors);
        }