Module MdlPublic
    Public Structure TValue
        Public Orig As String
        Public Dest As String
        Public Sub New(ByVal pOrig As String, ByVal pDest As String)
            Orig = pOrig
            Dest = pDest
        End Sub
    End Structure
    Public Structure TEquation
        Public Params As TValue()
        Public Result As String
        Public Sub New(ByVal pParams As TValue(), ByVal pExpr As String)
            Dim lStr As String
            Dim i As Integer
            ReDim Params(pParams.GetUpperBound(0))
            pParams.Copy(pParams, Params, pParams.Length)
            Do
                For i = 1 To Params.GetUpperBound(0)
                    If Params(i - 1).Orig.Length < Params(i).Orig.Length Then
                        lStr = Params(i - 1).Orig
                        Params(i - 1).Orig = Params(i).Orig
                        Params(i).Orig = lStr
                        lStr = Params(i - 1).Dest
                        Params(i - 1).Dest = Params(i).Dest
                        Params(i).Dest = lStr
                        i = 0
                        Exit For
                    End If
                Next
            Loop While i = 0

            For i = 0 To Params.GetUpperBound(0)
                pExpr = pExpr.Replace(Params(i).Orig, Params(i).Dest)
            Next

            Result = CalcBooleanExpression(pExpr)
        End Sub
    End Structure
    Public Function CalcBooleanExpression(ByVal pStr As String) As String
        Dim lStr As String = pStr.Replace("*", ".")
        Dim i As Integer
        Dim lValues() As TValue = {New TValue("(0)", "0"), New TValue("(1)", "1"), New TValue("/1", "0"), New TValue("/0", "1"), New TValue("0.1", "0"), New TValue("0.0", "0"), New TValue("1.0", "0"), New TValue("1.1", "1"), New TValue("0-0", "0"), New TValue("0-1", "1"), New TValue("1-0", "1"), New TValue("1-1", "0"), New TValue("0+0", "0"), New TValue("0+1", "1"), New TValue("1+0", "1"), New TValue("1+1", "1")}
        Do
            pStr = lStr
            For i = 0 To lValues.GetUpperBound(0)
                lStr = lStr.Replace(lValues(i).Orig, lValues(i).Dest)
                If lStr <> pStr Then
                    'Debug.WriteLine(pStr + " -> " + lStr)
                    Exit For
                End If
            Next
        Loop While lStr <> pStr
        Return lStr
    End Function

    Public Function CalcBoolTablExpParam(ByVal pStr As String) As TEquation()
        Dim lEquations As TEquation()
        Dim lValues As TValue()
        Dim lTStr As String()
        Dim lStr1 As String
        Dim lStr2 As String
        Dim i As Integer
        Dim j As Integer
        Dim k As Integer
        Dim lQueue As New System.Collections.Queue
        Dim lValName As New System.Collections.ArrayList

        pStr = pStr.ToLower

        lStr1 = pStr
        lStr1 = lStr1.Replace("+", ";")
        lStr1 = lStr1.Replace("-", ";")
        lStr1 = lStr1.Replace("*", ";")
        '        lStr1 = lStr1.Replace("0", ";")
        'lStr1 = lStr1.Replace("1", ";")
        lStr1 = lStr1.Replace(".", ";")
        lStr1 = lStr1.Replace("/", ";")
        lStr1 = lStr1.Replace("(", ";")
        lStr1 = lStr1.Replace(")", ";")
        lStr1 = lStr1.Replace(" ", ";")

        lStr2 = lStr1
        Do
            lStr1 = lStr2
            lStr2 = lStr1.Replace(";;", ";")
        Loop While lStr2 <> lStr1

        lTStr = lStr2.Replace(";", " ").Trim.Split(" ".Chars(0))


        For i = 0 To lTStr.GetUpperBound(0)
            lQueue.Enqueue(lTStr(i))
        Next

        Do While lQueue.Count > 0
            lStr1 = CType(lQueue.Dequeue, String).Trim
            If lStr1 <> "" Then
                For i = 0 To lValName.Count - 1
                    If lStr1 = CType(lValName.Item(i), String) Then
                        lStr1 = ""
                        Exit For
                    End If
                Next
            End If
            If lStr1 <> "" Then lValName.Add(lStr1)
        Loop


        ReDim lEquations(CInt(2 ^ lValName.Count - 1))
        ReDim lValues(lValName.Count - 1)

        For i = 0 To lValName.Count - 1
            lValues(i).Orig = CType(lValName.Item(i), String)
            lValues(i).Dest = "1"
        Next

        For i = 0 To lEquations.GetUpperBound(0)
            k = 1
            For j = lValues.GetUpperBound(0) To 0 Step -1
                If k = 1 Then
                    If lValues(j).Dest = "1" Then
                        lValues(j).Dest = "0"
                    Else
                        k = 0
                        lValues(j).Dest = "1"
                    End If
                End If
            Next

            lEquations(i) = New TEquation(lValues, pStr)
        Next

        System.GC.Collect()

        Return lEquations
    End Function

End Module
