エレファント・ビジュアライザー調査記録

ビジュアルプログラミングで数式の変形を表すことを考えていくブロクです。

人工知能的代数学(5)

交換子の計算

以前引用した交換子の計算をするプログラムを作成しました。これは ChatGPT で「文字列を逆順にして、大文字を小文字に、小文字を大文字に変換したものを取得するプログラムを書いてください」と「文字列の中に「大文字とその文字の小文字」か「小文字とその文字の大文字」が連続しているときその二文字を削除することを繰り返して、そのようなパターンが含まれない文字列に変換したものを取得するプログラムを書いてください」と入力して得られた関数を使って、クラスのサンプルを元に、ChatGPT を使って Python の情報を得ながら作成しました。

class GroupExp:
    def __init__(self, exp, struct_exp = None):
        self.exp = exp
        if struct_exp is not None:
            self.struct_exp = struct_exp
        else:
            if exp == "":
                self.struct_exp = ("const", "e")
            else:
                self.struct_exp = ("const", exp)

    def __add__(self, other):
        # 積
        if isinstance(other, GroupExp):
            result_str = self.remove_opposite_case_pairs(self.exp + other.exp)
            return GroupExp(result_str, self.prod_struct(other))
        raise TypeError("Operand must be a GroupExp")

    def __sub__(self, other):
        # 逆元との積
        if isinstance(other, GroupExp):
            return self + - other
        raise TypeError("Operand must be a GroupExp")

    def __neg__(self):
        # 逆元
        result_str = self.reverse_and_swapcase(self.exp)
        return GroupExp(result_str, self.inv_struct())

    def __mul__(self, other):
        # 交換子
        if isinstance(other, GroupExp):
            return (- self - other + self + other).replace_struct(self.com_struct(other))
        raise TypeError("Operand must be a GroupExp")

    def __pow__(self, other):
        # 共役
        if isinstance(other, GroupExp):
            return (- other + self + other).replace_struct(self.conj_struct(other))
        raise TypeError("Operand must be a GroupExp")

    def prod_struct(self, other):
        # 積の構造
        return ("prod", self.struct_exp, other.struct_exp)

    def inv_struct(self):
        # 逆元の構造
        return ("inv", self.struct_exp)

    def com_struct(self, other):
        # 交換子の構造
        return ("com", self.struct_exp, other.struct_exp)

    def conj_struct(self, other):
        # 共役の構造
        return ("conj", self.struct_exp, other.struct_exp)

    def replace_struct(self, struct_exp):
        # 構造を置き換える
        return GroupExp(self.exp, struct_exp)

    def __str__(self):
        return self.exp

    def __repr__(self):
        return f"GroupExp({self.exp})"
    
    def reverse_and_swapcase(self, text):
        # 文字列を逆順にする
        reversed_text = text[::-1]
        # 大文字と小文字を入れ替える
        swapped_text = reversed_text.swapcase()
        return swapped_text
    
    def remove_opposite_case_pairs(self, text):
        # 文字列の中で大文字とその文字の小文字、または小文字とその文字の大文字が
        # 連続しているペアを削除します。
    
        i = 0
        while i < len(text) - 1:
            # 現在の文字と次の文字を比較
            current = text[i]
            next_char = text[i + 1]
        
            # 大文字と小文字の組み合わせ、またはその逆を検出
            if (current.lower() == next_char.lower() and
                current.islower() != next_char.islower()):
                # このペアを削除するために、前と次を繋げてスライス
                text = text[:i] + text[i + 2:]
                # 削除されたので、再度この位置からチェック
                i = max(0, i - 1)
            else:
                # 削除がない場合は、次に進む
                i += 1
    
        return text

def tex_print(s):
    if len(s) == 2:
        struct_type, x = s
        if struct_type == "const":
            return x
        elif struct_type == "inv":
            return tex_print(x) + "^{-1}"
    if len(s) == 3:
        struct_type, x, y = s
        if struct_type == "prod":
            return tex_print(x) + tex_print(y)
        elif struct_type == "com":
            return "[" + tex_print(x) + ", " + tex_print(y) + "]"
        elif struct_type == "conj":
            return tex_print(x) + "^{" + tex_print(y) + "}"

def equation_print(x, y):
    print(str(x) + " = " + str(y))
    if (str(x) == str(y)):
        print("一致しました")
        print(tex_print(x.struct_exp) + " = " + tex_print(y.struct_exp))
    else:
        print("違います")

e = GroupExp("")
x = GroupExp("x")
y = GroupExp("y")
z = GroupExp("z")

# x^y = x[x, y]
equation_print(x ** y, x + x * y)

# [y, x] = [x, y]^-1
equation_print(y * x, - (x * y))

# [xy,z] = [x,z]^y[y,z]
equation_print((x + y) * z, (x * z) ** y + y * z)

# [x,yz] = [x,z][x,y]^z
equation_print(x * (y + z), x * z + (x * y) ** z)

# [x,y^−1] = [y,x]^y^−1
equation_print(x * (-y), (y * x) ** (-y))

# [x^−1,y] = [y,x]^x^−1
equation_print((-x) * y, (y * x) ** (-x))

# [[x,y^−1],z]^y[[y,z^−1],x]^z[[z,x^−1],y]^x = e
equation_print(((x * (-y)) * z) ** y + ((y * (-z)) * x) ** z + ((z * (-x)) * y) ** x, e)

# [[x,y],z^x][[z,x],y^z][[y,z],x^y] = e
equation_print((x * y) * (z ** x) + (z * x) * (y ** z) + (y * z) * (x ** y), e)

# [x,y]^z = [x^z, y^z]
equation_print((x * y) ** z, (x ** z) * (y ** z))
結果

Yxy = Yxy
一致しました
 x^{y} = x[x, y]
YXyx = YXyx
一致しました
 [y, x] = [x, y]^{-1}
YXZxyz = YXZxyz
一致しました
 [xy, z] = [x, z]^{y}[y, z]
XZYxyz = XZYxyz
一致しました
 [x, yz] = [x, z][x, y]^{z}
XyxY = XyxY
一致しました
 [x, y^{-1}] = [y, x]^{y^{-1}}
xYXy = xYXy
一致しました
 [x^{-1}, y] = [y, x]^{x^{-1}}
=
一致しました
 [[x, y^{-1}], z]^{y}[[y, z^{-1}], x]^{z}[[z, x^{-1}], y]^{x} = e
=
一致しました
 [[x, y], z^{x}][[z, x], y^{z}][[y, z], x^{y}] = e
ZXYxyz = ZXYxyz
一致しました
 [x, y]^{z} = [x^{z}, y^{z}]