Gemini Advancedでコーディングを試す 3
以前の投稿でGemini Advancedのコーディング能力を試している.今回はGemini Advancedの創造能力を試してみたい.
プロンプトと出力結果は下記.
Pythonで言語学に関する興味深いシミュレーションを行うコードを書いて.
エラーが出ないように自分で点検して.
import random
# --- 定数 ---
# シミュレーションで使用する音素の定義(単純化のため1文字のローマ字で表現)
VOWELS = ['a', 'i', 'u', 'e', 'o']
CONSONANTS = ['k', 's', 't', 'n', 'h', 'm', 'y', 'r', 'w', 'g', 'z', 'd', 'b', 'p'] # 清音の子音
ALL_PHONEMES = VOWELS + CONSONANTS
# 各音変化イベントの発生確率 (各単語、各世代で適用されるかどうかの独立した確率)
# これらの確率を調整することで、変化の速さや種類をコントロールできます。
PROB_VOWEL_SHIFT = 0.10 # 母音が別の母音に変わる確率
PROB_CONSONANT_SHIFT = 0.10 # 子音が別の子音に変わる確率
PROB_DELETION = 0.05 # 音素が1つ脱落する確率
PROB_INSERTION = 0.05 # 新しい音素が1つ挿入される確率
PROB_METATHESIS = 0.03 # 隣り合う2つの音素が入れ替わる(音位転換)確率
# PROB_ASSIMILATION = 0.02 # (発展課題) 同化現象の確率
# PROB_DISSIMILATION = 0.02 # (発展課題) 異化現象の確率
# --- ヘルパー関数 ---
def get_phonemes_from_word(word_str):
"""
単語文字列を音素のリストに変換します。
このシミュレーションでは、簡単のため単語は1文字1音素のアルファベットで構成されると仮定します。
例: "yama" -> ['y', 'a', 'm', 'a']
"""
return list(word_str)
def word_from_phonemes(phonemes_list):
"""音素のリストを単語文字列に戻します。"""
return "".join(phonemes_list)
# --- 音変化のコア関数 ---
def shift_vowel(phonemes):
"""単語内のランダムな母音を別の母音に変化させます。"""
vowel_indices = [i for i, p in enumerate(phonemes) if p in VOWELS]
if not vowel_indices:
return phonemes # 母音がなければ何もしない
idx_to_change = random.choice(vowel_indices)
current_vowel = phonemes[idx_to_change]
possible_new_vowels = [v for v in VOWELS if v != current_vowel]
if not possible_new_vowels: # 万が一、他の母音がない場合(VOWELSが1要素の場合など)
return phonemes
phonemes[idx_to_change] = random.choice(possible_new_vowels)
return phonemes
def shift_consonant(phonemes):
"""単語内のランダムな子音を別の子音に変化させます。"""
consonant_indices = [i for i, p in enumerate(phonemes) if p in CONSONANTS]
if not consonant_indices:
return phonemes # 子音がなければ何もしない
idx_to_change = random.choice(consonant_indices)
current_consonant = phonemes[idx_to_change]
possible_new_consonants = [c for c in CONSONANTS if c != current_consonant]
if not possible_new_consonants: # 万が一、他の子音がない場合
return phonemes
phonemes[idx_to_change] = random.choice(possible_new_consonants)
return phonemes
def delete_phoneme(phonemes):
"""単語内からランダムな音素を1つ削除します。ただし単語が1音素のみの場合は削除しません。"""
if len(phonemes) > 1:
idx_to_delete = random.randrange(len(phonemes))
del phonemes[idx_to_delete]
return phonemes
def insert_phoneme(phonemes):
"""単語内のランダムな位置に、ランダムな新しい音素を1つ挿入します。"""
insert_idx = random.randrange(len(phonemes) + 1) # 単語の前後を含む任意の位置
new_phoneme = random.choice(ALL_PHONEMES)
phonemes.insert(insert_idx, new_phoneme)
return phonemes
def metathesis(phonemes):
"""単語内の隣り合う2つの音素をランダムに入れ替えます(音位転換)。"""
if len(phonemes) >= 2:
idx1 = random.randrange(len(phonemes) - 1) # N-1までのインデックスを選ぶ
idx2 = idx1 + 1
phonemes[idx1], phonemes[idx2] = phonemes[idx2], phonemes[idx1]
return phonemes
# --- 単語進化のメイン関数 ---
def evolve_word(word_phonemes):
"""
単一の単語(音素リスト形式)を、定義された確率に基づいて1世代進化させます。
複数の音変化が同じ世代で同じ単語に起こりえます。
"""
# 変更は元のリストのコピーに対して行う
evolved_ph = list(word_phonemes)
if random.random() < PROB_VOWEL_SHIFT:
evolved_ph = shift_vowel(evolved_ph)
if random.random() < PROB_CONSONANT_SHIFT:
evolved_ph = shift_consonant(evolved_ph)
if random.random() < PROB_DELETION:
evolved_ph = delete_phoneme(evolved_ph)
if random.random() < PROB_INSERTION:
# 挿入は単語が極端に短くなるのを防ぐため、また長大化も促すため、確率を少し考える
# 例えば、現在の単語長が短い場合は挿入確率を少し上げるなど、工夫も可能
evolved_ph = insert_phoneme(evolved_ph)
if random.random() < PROB_METATHESIS:
evolved_ph = metathesis(evolved_ph)
return evolved_ph
# --- シミュレーション実行関数 ---
def run_linguistic_simulation(initial_word_strings, num_generations, num_daughter_languages=1):
"""
言語の音変化シミュレーションを実行します。
Args:
initial_word_strings (list): シミュレーション開始時の単語のリスト (例: ["sora", "yama"])
num_generations (int): シミュレーションを行う世代数。
num_daughter_languages (int): 同じ祖語から分岐させる娘言語の数。
Returns:
dict: 各娘言語の、各世代における単語リストの履歴。
形式: {
"Language_1": {0: [祖語1, 祖語2,...], 1: [変化後1, 変化後2,...], ...},
"Language_2": {0: [祖語1, 祖語2,...], 1: [変化後1, 変化後2,...], ...},
...
}
"""
simulation_history = {}
# 初期単語を音素リストに変換 (全言語共通の祖語)
proto_phonemes_list = [get_phonemes_from_word(word) for word in initial_word_strings]
for lang_idx in range(num_daughter_languages):
lang_name = f"Language_{lang_idx + 1}"
simulation_history[lang_name] = {}
current_phonemes_list = [list(ph) for ph in proto_phonemes_list] # 祖語リストをコピーして使用
for gen in range(num_generations + 1): # 0世代目(祖語)からnum_generations世代目まで
# 現在の単語リストを文字列として記録
current_words_str = [word_from_phonemes(ph_list) for ph_list in current_phonemes_list]
simulation_history[lang_name][gen] = current_words_str
# 最終世代では進化させない
if gen < num_generations:
next_gen_phonemes_list = []
for phonemes in current_phonemes_list:
evolved_ph = evolve_word(phonemes) # phonemes は既にリストなのでコピー不要
next_gen_phonemes_list.append(evolved_ph)
current_phonemes_list = next_gen_phonemes_list
return simulation_history
# --- メイン実行ブロック ---
if __name__ == "__main__":
# --- シミュレーションのパラメータ設定 ---
# 祖語の単語リスト (1文字1音素の小文字アルファベットで記述)
# 例: 日本語の単語をローマ字表記で "yama", "kawa", "ame", "sora", "hito"
# ラテン語風の祖語 "aqua" (水), "terra" (地), "ventus" (風), "ignis" (火)
INITIAL_WORDS = ["proto", "lingua", "verbum", "sonus", "mutatio"]
GENERATIONS = 30 # シミュレーションする世代数
NUM_LANGUAGES = 3 # 分岐させる娘言語の数
print(f"--- 言語進化シミュレーション開始 ---")
print(f"祖語: {', '.join(INITIAL_WORDS)}")
print(f"世代数: {GENERATIONS}")
print(f"分岐する娘言語の数: {NUM_LANGUAGES}\n")
history = run_linguistic_simulation(INITIAL_WORDS, GENERATIONS, NUM_LANGUAGES)
# 結果の表示
for lang_name, lang_history in history.items():
print(f"--- {lang_name} の進化 ---")
if lang_name == "Language_1" or NUM_LANGUAGES == 1:
print(f" Generation 0 (祖語): {', '.join(lang_history[0])}")
else:
# 2つ目以降の言語では、0世代目は共通の祖語であることを示す
print(f" Generation 0 (祖語より分岐): {', '.join(lang_history[0])}")
for gen in range(1, GENERATIONS + 1): # 1世代目から表示
words_at_gen = lang_history[gen]
print(f" Generation {gen}: {', '.join(words_at_gen)}")
print("\n")
print("--- シミュレーション終了 ---")
print("\n考察ポイント:")
print("- 同じ祖語から出発しても、ランダムな変化により異なる語形の娘言語が生まれる様子。")
print("- 音の脱落や挿入により、単語の長さが世代を経るごとに変化する様子。")
print("- 母音や子音の質的変化(例: 'a' -> 'o', 'k' -> 'g'など)が蓄積する様子。")
print("- 音位転換のような、比較的稀だが言語変化で見られる現象もシミュレートされています。")
print("- 各種確率パラメータを変更すると、進化の速度や傾向が変わります。")
print("\n発展的なアイデア:")
print("- 特定の音変化に方向性や条件(例: 特定の音環境で変化しやすいなど)を導入する。")
print("- 単語の意味変化のモデルは含まれていませんが、追加するとより複雑なシミュレーションが可能です。")
print("- アナロジー(類推)による形態変化をモデル化する。")
print("- より現実に近い音素体系や音変化規則(例: グリムの法則のようなもの)を導入する。")
Output
— 言語進化シミュレーション開始 —
祖語: proto, lingua, verbum, sonus, mutatio
世代数: 30
分岐する娘言語の数: 3
— Language_1 の進化 —
Generation 0 (祖語): proto, lingua, verbum, sonus, mutatio
Generation 1: proto, lingue, varbum, snous, metatio
Generation 2: proto, lingue, varbum, snous, metatio
Generation 3: proto, lingue, varbum, snous, metato
Generation 4: proto, lingue, varbum, snous, metato
Generation 5: proto, lisgue, varbum, snaus, metato
Generation 6: prato, lisgue, vurbum, smnaus, metato
Generation 7: prato, lisgue, vurbum, smmaus, metato
Generation 8: prato, lisgue, vurbum, smmaus, meano
Generation 9: prato, lisgue, vurbum, smmaus, meano
Generation 10: prato, lisgue, vurbmu, smmaus, meano
Generation 11: prato, lisgue, vurdmu, smmaus, meeno
Generation 12: prato, lisgue, vurdmu, smmaus, meeno
Generation 13: prpato, lisgue, vurdmu, smmaus, meeno
Generation 14: prpato, lisgue, vurdmu, smmaus, meeno
Generation 15: prpato, lisgue, vurdmu, smmaus, meeno
Generation 16: mprpato, lisgue, vurdmu, smmaus, meeno
Generation 17: mprpato, lisgui, vurdmu, smmaus, meeno
Generation 18: mprpato, lisguu, vurdmu, smmauk, meeno
Generation 19: mprwato, lisguu, vurdmu, smmauk, meeno
Generation 20: mprwatoo, lisguu, vurdme, sdauk, meeno
Generation 21: pprwatoo, lisguu, vurdme, sdaak, geeno
Generation 22: pprwatoo, lisguu, vurdme, skaak, geeno
Generation 23: pprwatoo, lisguu, vumdme, skauk, geeno
Generation 24: pprwatoo, lyisguu, vumdme, skauk, geeno
Generation 25: pprwatoo, lyisguu, vumdme, skauk, geeno
Generation 26: pprwitoo, ylasguu, vumdme, skauk, geeono
Generation 27: psrwitoi, ylasguu, vumdme, skauk, neeono
Generation 28: psrwitoi, ylamguu, vumdme, skauk, neeono
Generation 29: psrwitoi, ylamguu, vumdme, skauk, peeeno
Generation 30: psrwitii, ylamguu, vumdme, sauk, peeeno
— Language_2 の進化 —
Generation 0 (祖語より分岐): proto, lingua, verbum, sonus, mutatio
Generation 1: proto, lingua, verbum, sonus, mutatio
Generation 2: proto, ilnpua, verbum, sonus, mutatio
Generation 3: proto, ilnpua, verbum, sanus, mutatio
Generation 4: proto, ilnpua, vergum, sanus, mutatio
Generation 5: proto, ilnpua, vergum, snus, mitatio
Generation 6: proto, ilnpua, vergum, snus, mipatio
Generation 7: proto, ilnpua, vergaum, snas, mipiutio
Generation 8: proto, ilnpua, vergaum, snas, mimiutio
Generation 9: prsoto, ilnpua, vergaum, snas, mimiutio
Generation 10: prsoto, ilnpua, vergaump, snas, mimiutio
Generation 11: prsoto, ilnpua, vergaump, snas, mimiutio
Generation 12: prsoto, olnpua, vergaump, snas, mamiutio
Generation 13: prsoto, olnkua, vergaump, snas, mamiutio
Generation 14: pksoto, olnkua, vergaump, sans, mamiusio
Generation 15: pksto, onkua, vepigaump, sams, mamiusio
Generation 16: pksto, onkua, vepigaump, sams, mamiusio
Generation 17: pkstyo, onkua, vepigaumtp, sams, mamiusio
Generation 18: pkstyo, onkua, vepigaumtp, sams, mamiusio
Generation 19: pkstyo, onkua, vzepigaumtp, sams, tamiusio
Generation 20: pkstyi, onkua, vzepigaumtp, sams, tamiusio
Generation 21: pkstyi, onkua, vzepigaumtp, sams, tamiubio
Generation 22: pkstyi, nkua, vzepiguamtp, sams, tamiubio
Generation 23: pkstyi, knia, vzepiguamtp, sams, tamiubio
Generation 24: pstyi, knia, vzepigamtp, sams, tamibio
Generation 25: pstyi, knia, vzepigamtp, sams, tamibio
Generation 26: psnyi, knia, vzepigamtp, soms, tamibio
Generation 27: psnyi, knia, vzepigamtp, boms, tamibio
Generation 28: psnyi, knia, vzepigamtp, boms, tamiibo
Generation 29: psnbi, kniea, vzepigamtp, boms, taiiso
Generation 30: psnbi, knoea, vzepigamtp, boms, taiiso
— Language_3 の進化 —
Generation 0 (祖語より分岐): proto, lingua, verbum, sonus, mutatio
Generation 1: proyo, lingua, verbum, sonus, muhtatio
Generation 2: proyo, lingua, verbum, sones, muhkatio
Generation 3: nroyo, lingua, verbum, sones, muhkatio
Generation 4: nroyo, lingui, verbum, sones, muhkatio
Generation 5: nrobno, lingui, verbum, sones, muhkatio
Generation 6: nrobno, lingui, verbum, sones, mukkatio
Generation 7: nrobni, lingui, verbum, sones, mukkatio
Generation 8: nrobni, lingui, verbum, sones, munkkatio
Generation 9: nrobni, lingui, verbum, sones, munkkatio
Generation 10: nrobi, lingui, varbum, donens, munkkato
Generation 11: nrubi, lingui, varbum, donens, umnkkato
Generation 12: nrubi, lingui, varbum, donens, umnkkato
Generation 13: nrubi, lingui, varbum, wonens, amnkkato
Generation 14: nrubi, lingui, varbum, wonens, amnkkato
Generation 15: nrubod, lingui, vatbum, wonens, amnkkato
Generation 16: nrubod, lingui, vtbom, wonens, amnkkato
Generation 17: nrubod, lingui, vtbom, wonens, amnkkato
Generation 18: nrubod, lkingai, vtbom, wonens, amnkkato
Generation 19: nruboy, lkisgai, vtbim, wonens, amnnkata
Generation 20: nrusoy, lkisgai, vtbim, wonins, amnnkata
Generation 21: nrusoy, lkisgai, vtbim, wononn, amnnkata
Generation 22: nruoy, lkisgai, vtbim, woonn, amnnkata
Generation 23: nroy, lkisgai, vtbim, woonn, amnnbata
Generation 24: nroy, lkisgai, vtbim, woozn, amnnbata
Generation 25: ngoy, lkisgai, vtbim, woozn, apmnnbata
Generation 26: ngoy, lkisgai, vtbim, woazn, apmnnbata
Generation 27: ngoy, lkisgai, vtbam, woazn, apmnnbata
Generation 28: ngoy, lkisgain, vtbam, woazn, apmnnhata
Generation 29: ngoy, lkisgain, vtbam, woazn, apmnnhata
Generation 30: ngoy, lkisgiin, vtbom, woazn, apmnnhata
— シミュレーション終了 —
考察ポイント:
- 同じ祖語から出発しても、ランダムな変化により異なる語形の娘言語が生まれる様子。
- 音の脱落や挿入により、単語の長さが世代を経るごとに変化する様子。
- 母音や子音の質的変化(例: ‘a’ -> ‘o’, ‘k’ -> ‘g’など)が蓄積する様子。
- 音位転換のような、比較的稀だが言語変化で見られる現象もシミュレートされています。
- 各種確率パラメータを変更すると、進化の速度や傾向が変わります。
発展的なアイデア:
- 特定の音変化に方向性や条件(例: 特定の音環境で変化しやすいなど)を導入する。
- 単語の意味変化のモデルは含まれていませんが、追加するとより複雑なシミュレーションが可能です。
- アナロジー(類推)による形態変化をモデル化する。
- より現実に近い音素体系や音変化規則(例: グリムの法則のようなもの)を導入する。