---
title: ichiban/prolog の紹介
tags:  #go #golang #prolog  
author: [佐伯](https://image.docswell.com/user/h-saeki)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/KE4W158RJ1.jpg?width=480
description: Go Connect #17でLTしたスライドです（2026/09/16）。 https://gotalk.connpass.com/event/398016/
published: September 17, 26
canonical: https://image.docswell.com/s/h-saeki/K8NQR1-2026-09-17-092556
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/KE4W158RJ1.jpg)

ichiban/prolog
の紹介
2026/09/16 Go Connect LT
佐伯


# Page. 2

![Page Image](https://bcdn.docswell.com/page/L71YGW2VJG.jpg)

はじめまして！ 技術書典でこんなの出してる人です


# Page. 3

![Page Image](https://bcdn.docswell.com/page/G7WGK6R3E2.jpg)

今日伝えたいこと
ichiban/prologという便利ライブラリ紹介
Goの上でPrologが動くようになります！


# Page. 4

![Page Image](https://bcdn.docswell.com/page/4JZLZYRGE3.jpg)

昔々：システム開発では、データベースが主役だった


# Page. 5

![Page Image](https://bcdn.docswell.com/page/YE6WZDRQEV.jpg)

昔々：データベースが主役だった


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GE5MW382E4.jpg)

昔：アプリケーションが徐々に主役に


# Page. 7

![Page Image](https://bcdn.docswell.com/page/9729QZK1JR.jpg)

今：アプリケーションが主役


# Page. 8

![Page Image](https://bcdn.docswell.com/page/DJY4WRN47M.jpg)

今々：AIによる実装の半自動化/高速化
コードベースの調査コストが安い / 実装コストが安い
一方で、&quot;vibe documenting&quot;には苦労？


# Page. 9

![Page Image](https://bcdn.docswell.com/page/V7NY9DX6E8.jpg)

ずっと居続けたもの＝ドメイン


# Page. 10

![Page Image](https://bcdn.docswell.com/page/YJ9P2G8R73.jpg)

の手続きで書いてたけど、ドメイン表現！
SQL


# Page. 11

![Page Image](https://bcdn.docswell.com/page/GJ8D5V8GJD.jpg)

ドメイン層にドメイン表現！ Testable！


# Page. 12

![Page Image](https://bcdn.docswell.com/page/LJLMY5RXER.jpg)

ドメインの設計（説明）をミスるか、実装（表現方法）をミスる
のが怖い
理解/説明を間違う⇒設計ミス
実装（表現）を間違う⇒バグ


# Page. 13

![Page Image](https://bcdn.docswell.com/page/47MYN3R37W.jpg)

特に、ドキュメントが課題
ドキュメント向けの強力な静的解析/IDEがない
markdown lint等はあるが、設計ミスを検知はできない
デバッグ実行できない（頭の中で机上デバッグはできるが）
ドキュメントは動かない
最近だと、AIがそれっぽい嘘や長々と薄い文章を書く（AI Slop！）
コードには修正履歴コメントもたくさん書かれて、品質低下していく
ドメインの確認については人間が目視でがんばるしかない（？）


# Page. 14

![Page Image](https://bcdn.docswell.com/page/P7R9DQRRE9.jpg)

そこで、プロトタイピング（試作・仮説実験）
ドキュメント通りに、本当に動くのか
早く「こいつ動くぞ！」したい
概要設計とか基本設計の段階で試したい
後工程で失敗すると手戻りコストが大きい
ドメインの理解を確かめたい
間違っているなら早く改善したい
ドメインエキスパート（有識者）に聞く前に自分でも確認したい


# Page. 15

![Page Image](https://bcdn.docswell.com/page/PJXQ15RY7X.jpg)

みんな大好きGoで試作
愚直にif/else/forするしかない（これはこれでGoらしくて良き）
ドキュメントにGoのExampleコードを貼ってもいい
samber/loのようなコレクション操作ライブラリに頼ってGoらしさを諦めるか
は開発メンバーのプログラミング遍歴による
ただし、ネストが深いと表現が詳細設計寄りになる
早期リターン
関数分割
メソッド化
構造体検討
package検討


# Page. 16

![Page Image](https://bcdn.docswell.com/page/3JK926R4JD.jpg)

ドメインは手続きではなく、関係を記述したい
その日人類は思い出した
「関係を表すなら、論理型プログラミング言語があるね」
Goはいいぞ！ でも、Prologもいいぞ！


# Page. 17

![Page Image](https://bcdn.docswell.com/page/LE3W468DE5.jpg)

たとえば、トランプのハート（ハーツ）のルールを記述する
% スートの定義
suit(h). suit(d). suit(c). suit(s).
% ランクの強さを数値化 (2が最弱、Aが最強)
rank_value(2, 2).
rank_value(3, 3).
% ... 中略 ...
rank_value(j, 11).
rank_value(q, 12).
rank_value(k, 13).
rank_value(a, 14).
% カードの強さ比較 (同じスートの場合のみ意味を持つ)
is_stronger(card(Suit, Rank1), card(Suit, Rank2)) :rank_value(Rank1, Val1),
rank_value(Rank2, Val2),
Val1 &gt; Val2.


# Page. 18

![Page Image](https://bcdn.docswell.com/page/8EDKQVM27G.jpg)

手札からカードを出すときのルール
% プレイヤーがカードを出せるかの判定
% can_play(手札, 台札(リード), 出そうとしているカード)
% ケース1: 自分がリードの場合（台札がない）、手札にあるなら何でも出せる
can_play(Hand, nil, Card) :member(Card, Hand).
% ケース2: 台札があり、台札と同じスートを持っている場合 (マストフォロー)
% 出すカードは台札と同じスートでなければならない
can_play(Hand, card(LeadSuit, _), card(PlayerSuit, Rank)) :member(card(PlayerSuit, Rank), Hand), % 手札にあること
has_suit(Hand, LeadSuit),
% 手札にリードスートがある
PlayerSuit == LeadSuit.
% 出すカードがリードスートと一致する
% ケース3: 台札があり、台札と同じスートを持っていない場合
% 手札にあるカードなら何でも出せる (スート不一致でOK)
can_play(Hand, card(LeadSuit, _), card(PlayerSuit, Rank)) :member(card(PlayerSuit, Rank), Hand), % 手札にあること
\+ has_suit(Hand, LeadSuit).
% 手札にリードスートがない (否定)


# Page. 19

![Page Image](https://bcdn.docswell.com/page/V7PKLVRLJ8.jpg)

ルール判定のヘルパー述語
% ヘルパー: 手札の中に指定されたスートがあるか確認
has_suit([], _) :- fail.
has_suit([card(S, _)|_], TargetSuit) :- S == TargetSuit, !.
has_suit([_|Rest], TargetSuit) :- has_suit(Rest, TargetSuit).


# Page. 20

![Page Image](https://bcdn.docswell.com/page/2JVVQZR6JQ.jpg)

業務判断のうち、大事なところ＝ドメイン
ドメインを（AIにお願いして）plファイルに書いたら
処理系で動かす
例）SWI-Prolog
例）今日紹介するichiban/prolog
1 ?- consult([&#039;c:/hoge/prolog-go/internal/rules/hearts.pl&#039;]).
true.


# Page. 21

![Page Image](https://bcdn.docswell.com/page/5EGLW4M2JL.jpg)

の実行例
SWI-Prolog
2 ?- can_play([card(s,q), card(h,3), card(c,9), card(c,5)], card(c,2), C).
C = card(c, 9) ;
C = card(c, 5) ;
false.
3 ?- findall(C,
|
can_play([card(s,q), card(h,3), card(c,9), card(c,5)],
|
card(c,2), C),
|
Cs).
Cs = [card(c, 9), card(c, 5)].
手札が Q 3 9 5で、台札に 2が出ているとき、何を出せるか？
9か 5を出せる
バックトラッキングで全列挙してくれる
;セミコロンで次の解を見られる or findallでリストにまとめる


# Page. 22

![Page Image](https://bcdn.docswell.com/page/4JQY3GR97P.jpg)

ichiban/prolog
で、Prologを動かせるライブラリ
Go
https://github.com/ichiban/prolog
準拠のPrologが動く
SWI-Prologには固有の方言があったりするので、移植時は互換性に注意
ISO


# Page. 23

![Page Image](https://bcdn.docswell.com/page/K74W15QRE1.jpg)

と組み合わせるとそのままゲームになる
GoTH(Go/Templ/Htmx)
ドキュメント→pl試作→plのままGoにオン（ichiban/prologに感謝）
→if-else頑張らなくても動く（pl処理を呼び出すラッパーは書く必要あるけど）


# Page. 24

![Page Image](https://bcdn.docswell.com/page/LJ1YGWPVEG.jpg)

まとめ
ドキュメント上のドメイン記述補助～実装でPrologという選択肢がある
ichiban/prologというライブラリを使うとGoでPrologが動く
シビアなパフォーマンス要求にはProlog部分をGoで書き直しが必要かも


