ChatGPTにUMLクラス図を作図してもらう（Ph2 派生のほか、集約とか）

# はじめに
Mermaidのソースコードの代わりに日本語記述のロジック仕様記述言語が間接的なソースコードになるとうれしいなというお話の続きです。前回の記事 [Ph1 ロジック仕様記述言語 の構文の仕込み](https://qiita.com/mylifewithviolin/items/dd33d6b35d003b60b8f7)では、意外とすんなり派生関係まで漕ぎつけました。

## この記事内容の作業目的
自作ロジック仕様記述言語Re:Mindの構文仕様をAIに学習してもらい、UMLクラス図を作図してもらうことから、日本語ロジック仕様記述言語がUMLクラス図の間接的なソースコードになりうるか検討します。

## この記事内容の保証
※この記事にはAIが自動生成した情報が含まれます。AIが自動生成して書かれた内容の妥当性は保証されません。

# 実行結果
ChatGPTにご提示いただいたMermaidのソースコードでエラーのない状態は、都度Qiita上でイメージ描画するようにしています。

## ChatGPT3.5
私：
こんにちは！あなたは先日のUMLのクラス図の作図について覚えていますか？
ChatGPT：
>こんにちは！はい、UMLのクラス図の作成について覚えています。クラス図に関する質問や作図のサポートが必要であれば、どのようなお手伝いができますか？

私：
これから、わたしが考案した日本語ロジック仕様記述言語Re:Mind リマインド のクラスの記述ルールの続きを説明します。
このセッション内で覚えておいていただくことは可能ですか？

ChatGPT：
>もちろんです！Re:Mind リマインドのクラスの記述ルールについて続きを説明してください。どのようなルールや概念について知りたいのでしょうか？お手伝いできることがあればお伝えください。

私：
主にクラスのインスタンスに関わる記述ルールで、前回の続きは下記のとおりです。

クラスのインスタンス宣言
```remind:
    ・メンバーの取り扱い方 メンバー取り扱い方法
```
・クラスのインスタンス名は同じ主旨の別名としてください。
・コンストラクタにオーバーロードがある場合は、かっこ内に引数を記述します。

クラスのインスタンスの変数操作
```remind:
    □年齢 = メンバー取り扱い方法.年齢
    □メンバー取り扱い方法.年齢 = 年齢
```
・クラスのインスタンス名の装飾子は半角ドットです。

クラスのインスタンスの関数実行
```remind:
    □年齢 = メンバー取り扱い方法.メンバーの年齢を取得する(名前,特待区分)
    □メンバー取り扱い方法.メンバーの年齢を設定する(名前,特待区分)
```
・クラスのインスタンス名の装飾子は半角ドットです。

・値を返す関数の場合、全角記号の四角□に続いて、戻り値を受け取る変数名を記述し、半角等号に続いてクラスのインスタンス名と関数名を半角ドットを挟んで記述します。
・続いて半角かっこを設け、型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・値を返さない関数の場合、全角記号の四角□に続いて関数名を記述し、半角かっこを設け、型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。

ChatGPT：
>了解しました！Re:Mind リマインドのクラスのインスタンスに関する記述ルールについて、クラスのインスタンス宣言、変数操作、関数実行についての詳細を説明いたします。
>
>クラスのインスタンス宣言
>クラスのインスタンスを宣言する際のルールは以下の通りです：

```remind:
    ・メンバーの取り扱い方 メンバー取り扱い方法
```
>クラスのインスタンス名は、同じ主旨の別名として設定します。
>クラスのコンストラクタにオーバーロードがある場合、かっこ内に引数を記述します。

例:
```remind:
    ・クラス名 インスタンス名
    ・クラス名 インスタンス名(引数1, 引数2)
```

私：
ありがとうございます。素晴らしいです。では、下記のRe:Mindのクラス定義のソースコードをMermaidのクラス図のソースコードに変換してください。
```remind:
   ▽class 取り扱い方

        ・変数ブール値 取り扱い区分
    
        ▽ブール値 取り扱い区分を取得する()
            □取り扱い区分を 返す
        △
    
        ▽取り扱い区分を設定する(bool 区分)
             □取り扱い区分=区分
        △

    △
    
    ▽class メンバーの取り扱い方 : 取り扱い方

        ・変数整数 年齢
        ・変数文字列 名前
        ・変数ブール値 特待区分
        ・グループの取り扱い方 グループ1("A")
        ・グループの取り扱い方 グループ2("B")
    
        ▽整数 メンバーの年齢を取得する(string 名前,bool 区分)
             //todo
            □(齢)を 返す
        △
    
        ▽メンバーの年齢を設定する(string 名前,bool 区分)
             //todo
        △

    △
    
    ▽class グループの取り扱い方 : 取り扱い方

        ・変数文字列 グループコード
        ・変数ブール値 特待区分
        
        ▽グループの取り扱い方(string コード)
             □グループコード=コード
        △
        
        ▽整数 グループの特待区分を取得する()
            □特待区分を 返す
        △
    
        ▽グループの特待区分を設定する(bool 区分)
             □特待区分=区分
        △

    △
```
ChatGPT：
>Re:Mindのクラス定義をMermaidのクラス図のソースコードに変換します。以下が変換されたソースコードです。

```:mermaid
classDiagram

class "取り扱い方" {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class "メンバーの取り扱い方" as メンバー取り扱い方法 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class "グループの取り扱い方" as グループ取り扱い方法 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
```
>このMermaidのクラス図のソースコードでは、Re:Mindのクラス定義がクラス図として表現されています。各クラスの属性やメソッドが正確に反映されています。必要に応じてカスタマイズやスタイリングを追加することができます。


私：
ありがとうございます。Mermaidエディタが下図のエラーを返しました。
```:mermaid
Error: Parse error on line 3:
...lassDiagramclass "取り扱い方" { + 取り扱い区分:
---------------------^
Expecting 'MINUS', 'UNICODE_TEXT', 'NUM', 'ALPHA', 'BQUOTE_STR', got 'STR'
```

ChatGPT：
>申し訳ありません、エラーが発生しました。Mermaidのクラス図ではクラス名に日本語を使用する場合、エラーが発生することがあります。代替案として、クラス名を英語に変更するか、エラーを回避するために特別な設定を行う必要があります。
以下はクラス名を英語に変更した場合のMermaidのクラス図のソースコードです：

```:mermaid
classDiagram

class "取り扱い方" {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class "メンバーの取り扱い方" as MemberHandling {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class "グループの取り扱い方" as GroupHandling {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- MemberHandling
取り扱い方 <|-- GroupHandling
```

>このソースコードでは、クラス名を英語に変更しています。変更後のクラス名を使用することで、エラーを回避できます。
日本語文字列をダブルクオーテーションで囲むことは、通常のMermaidのクラス図のソースコードでは問題ありません。Mermaidは基本的にクラス名や属性をクォーテーションで囲むことを許容しています。
前回のエラーは、Mermaidがクラス名に日本語を含む場合に、正しく解釈できなかった可能性が高いです。一般的には、英語のクラス名を使用することで問題を回避できますが、日本語のクラス名を使用したい場合は、Mermaidのバージョンや設定に依存する可能性があります。したがって、問題が解決しない場合は、Mermaidのバージョンを確認し、設定を調整してみることを検討してください。


私：
あなたがおっしゃることはよくわかります。アクティビティ図は半角かっこなどの識別子を含む場合はダブルクオーテーションで囲いましたね。
しかし、とりあえずダブルクオーテーションを除いて、無駄な「as」もとるとエラーはなくなり正常に描画できるようになりましたよ。
```:mermaid
classDiagram

class 取り扱い方 {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class メンバーの取り扱い方 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class グループの取り扱い方 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
```

```mermaid:
classDiagram

class 取り扱い方 {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class メンバーの取り扱い方 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class グループの取り扱い方 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
```
ChatGPT：
>素晴らしいです！問題が解決し、正常に描画できるようになったようですね。ダブルクオーテーションを除いて、無駄な "as" も削除することで、Mermaidのクラス図のソースコードがよりシンプルで正確になりました。これでクラス図が適切に表現されています。


私：
メンバー取り扱い方法の中で変数となっているグループ取り扱い方法の扱いの記述を追加してください。

ChatGPT：
>理解しました。メンバー取り扱い方法内でのグループ取り扱い方法の記述を追加します。

```:mermaid
classDiagram

class 取り扱い方 {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class メンバーの取り扱い方 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class グループの取り扱い方 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
メンバー取り扱い方法 -- グループの取り扱い方
```
メンバー取り扱い方法がグループ取り扱い方法を持つようになりました。これで変更点を反映したクラス図が完成しました。質問があればどうぞお知らせください。


```mermaid:
classDiagram

class 取り扱い方 {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class メンバーの取り扱い方 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class グループの取り扱い方 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
メンバー取り扱い方法 -- グループの取り扱い方
```

私：
Aggregation（集約）なので、Link（線）ではない方がよいです。
ChatGPT：
>理解しました。Aggregation（集約）関係を示すために、Link（線）ではなく、ダイヤモンド記号（◇）を使用します。修正を加えたクラス図を以下に示します。

```:mermaid
classDiagram

class 取り扱い方 {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class メンバーの取り扱い方 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class グループの取り扱い方 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
メンバー取り扱い方法 --◇ グループの取り扱い方
```
>修正を加え、Aggregation（集約）関係を示すために◇ダイヤモンド記号を使用しました。これで変更点を反映したクラス図が完成しました。何か他のご質問があれば、どうぞお知らせください。


私：
ありがとうございます。Mermaidエディタが下図のエラーを返しました。
```:mermaid
Error: Lexical error on line 29. Unrecognized text.
...取り扱い方法メンバー取り扱い方法 --◇ グループの取り扱い方
```
Aggregation（集約）関係を示すために◇ダイヤモンド記号を描画させるMermaidのソースコードは小文字のoのようでした。
```:mermaid
メンバー取り扱い方法 <--o グループの取り扱い方
```

# おわりに
生成AIにいろいろやってもらうのは自然言語で対話しつつ形式言語のソースコードを調整していく形になりますが、今回、前回の単純なクラス図に比べて、やはり若干のもたつきがありました。ロジック仕様記述言語からMermaidへのトランスコンパイラという処理系はクラス図の実装としても成り立つ気がしますが、今回は完成前で中断。

今回の最終状態
ちょっとまだ変ですが、いったん撤収です。インスタンス名とクラス名の扱いが少々混線してますね。
```mermaid:
classDiagram

class 取り扱い方 {
  + 取り扱い区分: ブール値
  + 取り扱い区分を取得する(): ブール値
  + 取り扱い区分を設定する(区分: ブール値): void
}

class メンバーの取り扱い方 {
  + 年齢: 整数
  + 名前: 文字列
  + 特待区分: ブール値
  + グループ1: グループの取り扱い方
  + グループ2: グループの取り扱い方
  + メンバーの年齢を取得する(名前: string, 区分: bool): 整数
  + メンバーの年齢を設定する(名前: string, 区分: bool): void
}

class グループの取り扱い方 {
  + グループコード: 文字列
  + 特待区分: ブール値
  + グループの取り扱い方(コード: string): void
  + グループの特待区分を取得する(): 整数
  + グループの特待区分を設定する(区分: bool): void
}

取り扱い方 <|-- メンバー取り扱い方法
取り扱い方 <|-- グループ取り扱い方法
メンバー取り扱い方法 <--o グループの取り扱い方
```
# 参考リンク

https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94

https://qiita.com/mylifewithviolin/items/127a963be816f91b4c84