private modnode ConvertToAON(modnode m) //Исключает штрих Шеффера, стрелку Пирса, импликацию, эквивалентность и сложение по модулю 2.
        {
            modnode tl, tr;

            if (m.right != null)
            {
                m.right = ConvertToAON(m.right);
            }
            if (m.left != null)
            {
                m.left = ConvertToAON(m.left);
            }
            if (m.data == "/")
            {
                m.data = "V";
                m.Addl("!");
                m.Addr("!");
                return(m);
            }
            if (m.data == "|")
            {
                m.data = "&";
                m.Addl("!");
                m.Addr("!");
                return(m);
            }
            if (m.data == ">")
            {
                m.data = "V";
                m.Addl("!");
                return(m);
            }
            if (m.data == "=") //(x = y) == (!y V x) & (!x V y)
            {
                tl     = m.left.Copy();
                tr     = m.right.Copy();
                m.data = "&";
                m.Addl("V");
                m.left.left = tr;
                m.left.Addl("!");
                m.Addr("V");
                m.right.left = tl;
                m.right.Addl("!");
                return(m);
            }
            if (m.data == "+") //(x + y) == (y V x) & (!x V !y)
            {
                tl     = m.left.Copy();
                tr     = m.right.Copy();
                m.data = "&";
                m.Addl("V");
                m.left.left = tr;
                m.Addr("V");
                m.right.Addr("!");
                m.right.left = tl;
                m.right.Addl("!");
                return(m);
            }
            return(m);
        }
        private modnode Pars(modnode m) //Разбивает логическое выражение на атомы.
        {
            int sk = 0, j, k;

            char[] pr3 = { '/', '|' };
            int    p3  = m.data.IndexOfAny(pr3);

            if (p3 != -1)
            {
                for (int i = m.data.Length - 1; i >= 0; i--)
                {
                    if (sk == 0)
                    {
                        switch (m.data[i])
                        {
                        case '/':
                        {
                            m.Addl(m.data.Substring(0, i));
                            m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                            m.data  = "/";
                            m.left  = Pars(m.left);
                            m.right = Pars(m.right);
                            return(m);
                        }

                        case '|':
                        {
                            m.Addl(m.data.Substring(0, i));
                            m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                            m.data  = "|";
                            m.left  = Pars(m.left);
                            m.right = Pars(m.right);
                            return(m);
                        }
                        }
                    }
                    if (m.data[i] == ')')
                    {
                        sk++;
                    }
                    if (m.data[i] == '(')
                    {
                        sk--;
                    }
                }
            }
            if (m.data.Contains('='))
            {
                sk = 0;
                for (int i = m.data.Length - 1; i >= 0; i--)
                {
                    if ((sk == 0) && (m.data[i] == '='))
                    {
                        m.Addl(m.data.Substring(0, i));
                        m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                        m.data  = "=";
                        m.left  = Pars(m.left);
                        m.right = Pars(m.right);
                        return(m);
                    }
                    if (m.data[i] == ')')
                    {
                        sk++;
                    }
                    if (m.data[i] == '(')
                    {
                        sk--;
                    }
                }
            }
            if (m.data.Contains('>'))
            {
                sk = 0;
                for (int i = m.data.Length - 1; i >= 0; i--)
                {
                    if ((sk == 0) && (m.data[i] == '>'))
                    {
                        m.Addl(m.data.Substring(0, i));
                        m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                        m.data  = ">";
                        m.left  = Pars(m.left);
                        m.right = Pars(m.right);
                        return(m);
                    }
                    if (m.data[i] == ')')
                    {
                        sk++;
                    }
                    if (m.data[i] == '(')
                    {
                        sk--;
                    }
                }
            }
            char[] pr4 = { 'V', '+' };
            int    p4  = m.data.IndexOfAny(pr4);

            if (p4 != -1)
            {
                sk = 0;
                for (int i = m.data.Length - 1; i >= 0; i--)
                {
                    if (sk == 0)
                    {
                        switch (m.data[i])
                        {
                        case '+':
                        {
                            m.Addl(m.data.Substring(0, i));
                            m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                            m.data  = "+";
                            m.left  = Pars(m.left);
                            m.right = Pars(m.right);
                            return(m);
                        }

                        case 'V':
                        {
                            m.Addl(m.data.Substring(0, i));
                            m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                            m.data  = "V";
                            m.left  = Pars(m.left);
                            m.right = Pars(m.right);
                            return(m);
                        }
                        }
                    }
                    if (m.data[i] == ')')
                    {
                        sk++;
                    }
                    if (m.data[i] == '(')
                    {
                        sk--;
                    }
                }
            }
            if (m.data.Contains('&'))
            {
                sk = 0;
                for (int i = m.data.Length - 1; i >= 0; i--)
                {
                    if ((sk == 0) && (m.data[i] == '&'))
                    {
                        m.Addl(m.data.Substring(0, i));
                        m.Addr(m.data.Substring(i + 1, m.data.Length - i - 1));
                        m.data  = "&";
                        m.left  = Pars(m.left);
                        m.right = Pars(m.right);
                        return(m);
                    }
                    if (m.data[i] == ')')
                    {
                        sk++;
                    }
                    if (m.data[i] == '(')
                    {
                        sk--;
                    }
                }
            }
            if (m.data.StartsWith("!"))
            {
                m.Addr(m.data.Substring(1));
                m.data  = "!";
                m.right = Pars(m.right);
                return(m);
            }
            if (m.data.StartsWith("(") && m.data.EndsWith(")"))
            {
                m.data = m.data.Substring(1, m.data.Length - 2);
                m      = Pars(m);
                return(m);
            }
            if (m.data.StartsWith("$") || m.data.StartsWith("#"))
            {
                j = 2;
                if (m.data[1] >= 'a' && m.data[1] <= 'z')
                {
                    while (j < m.data.Length && m.data[j] >= '0' && m.data[j] <= '9')
                    {
                        j++;
                    }
                    m.Addr(m.data.Substring(j, m.data.Length - j));
                    m.data  = m.data.Substring(0, j);
                    m.right = Pars(m.right);
                }
                else
                {
                    correct = false;
                }
                return(m);
            }
            if (pred(m.data))
            {
                k = 1;
                string x;
                while (m.data[k] != '(')
                {
                    k++;
                }
                k++;
                while (k != m.data.Length)
                {
                    j = k;
                    while (m.data[j] != ',' && m.data[j] != ')')
                    {
                        j++;
                    }
                    x = m.data.Substring(k, j - k);
                    if (perems.IndexOf(x) == -1)
                    {
                        perems.Add(x);
                    }
                    k = j + 1;
                }
                return(m);
            }
            if (perem(m.data))
            {
                if (perems.IndexOf(m.data) == -1)
                {
                    perems.Add(m.data);
                }
                return(m);
            }
            correct = false;
            return(m);
        }
        private modnode NotDown(modnode m)//Продвижение отрацаний до атомов. Работает только с формулами приведёнными к базису и-или-не.
        {
            if (m.right == null)
            {
                return(m);
            }
            if (m.data == "!")
            {
                switch (m.right.data[0])
                {
                case '#':
                {
                    m.data       = "$" + m.right.data.Substring(1, m.right.data.Length - 1);
                    m.right.data = "!";
                    m.right      = NotDown(m.right);
                    return(m);
                }

                case '$':
                {
                    m.data       = "#" + m.right.data.Substring(1, m.right.data.Length - 1);
                    m.right.data = "!";
                    m.right      = NotDown(m.right);
                    return(m);
                }

                case 'V':
                {
                    m.data  = "&";
                    m.left  = m.right.left;
                    m.right = m.right.right;
                    m.Addl("!");
                    m.Addr("!");
                    m.right = NotDown(m.right);
                    m.left  = NotDown(m.left);
                    return(m);
                }

                case '&':
                {
                    m.data  = "V";
                    m.left  = m.right.left;
                    m.right = m.right.right;
                    m.Addl("!");
                    m.Addr("!");
                    m.right = NotDown(m.right);
                    m.left  = NotDown(m.left);
                    return(m);
                }

                case '!':
                {
                    return(m.right.right);
                }
                }
            }
            if (m.right != null)
            {
                m.right = NotDown(m.right);
            }
            if (m.left != null)
            {
                m.left = NotDown(m.left);
            }
            return(m);
        }