prologによる格子点の個数からの円周率の近似値の計算

  • Prolog Advent Calendar 2016 - Qiitaの3日目の記事です
  • 2015年07月に出た数学の課題をprologを使って解いてみました
  • これがはじめてのprologでした
  • 未だprolog初心者です

背景

格子点の個数を求め,\(\pi\)の近似値を計算せよ.という課題が2015年07月に数学の授業で出ました.

特に言語は指定されていなかったので,せっかくなのでこれまで実用してこなかったprologで解いてみました.

提出した後死蔵されていたので,Advent Calendarにて供養することにします.

ソースコード

swi-prolog向けに記述しています.

格子状に点を並べ,四角形と円の中に入った点の比率を計算することで円周率を計算しています.

prologを試してみたかったので,問題を解くのに必要ない記述も含んでいます.

実行結果

精度を指定して実行します.精度を上げるにつれて,再帰回数が増え,段々円周率に近似していきます.

?- piExp(1, Pi).
Pi = 4.0

?- piExp(2, Pi).
Pi = 3.732050807568877

?- piExp(3, Pi).
Pi = 3.584220045442658

?- piExp(4, Pi).
Pi = 3.4957090681024408

?- piExp(5, Pi).
Pi = 3.437048828883551

?- piExp(10000, Pi).
Pi = 3.141791477611329

言語以前に実用的なアルゴリズムではないため,速度は極めて遅いです.

prologに対する感想

これを書いてみてprolog面白いなあと思ったのは,

hypot(X, Y, R) :- nonvar(X), nonvar(Y), sqrt(X * X + Y * Y, R).
hypot(X, Y, R) :- nonvar(X), nonvar(R), sqrt(R * R - X * X, Y).
hypot(X, Y, R) :- nonvar(Y), nonvar(R), sqrt(R * R - Y * Y, X).

のように書けば,hypotの,どの変数を自由変数にしても,自由変数に答えが束縛されるという所でした.

要するにX, Y, Rのうち2点さえ既に束縛されていれば,同じ名前の述語で好きな箇所を求めることができるということです.理想上のprologでは\(cin, cos, tan\)などに対して\(asin, acos, atan2\)と逆を求める述語を定義する必要はありません.

難しい話は置いておいて,このインターフェイスでは,プログラマが覚える必要のある名前はぐっと減ります.

人間の記憶モデルとも大変相性が良いと思っていて,この仕組みを他の言語に取り込めたら面白そうだなあ,と当時から思っていました.うまく合体させるビジョンは全く浮かんでいません.頭のいい人がprologモデルを復興させてくれると嬉しいですね.