O-Prologの仕様、覚書

  • 1
    いいね
  • 0
    コメント

はじめに

自作Prolog処理系のO-Prologについてその仕様などを文書化することにしました。O-PrologはISO-Prologを参考にしつつAZ-Prologのサブセットを目指して制作しているものです。この記述は甚だ中途半端なものですが、五月雨式に追加、詳細な記述を目指しております。

起動オプション

Windowsであればコマンドプロンプトよりoplと入力することにより起動します。Linuxであれば./oplで起動します。スタートアップファイルを読み込ませて起動する場合には -c でファイル名を与えます。


./ opl -c init.pl

対話的動作

起動すると|(縦棒)記号が表示されます。これがO-Prologのプロンプトです。この状態で受け取ったものは述語定義であると解釈してメモリに記憶されます。|に続いて?-と入力してから入力したものは処理系に対しての質問となります。いずれの場合には最後に .(ピリオド)記号が必要となります。質問の場合にはyesかnoかの結果が返されます。


| human(taro).

| ?- human(taro)).
yes

Prologコードをあらかじめエディタを使ってファイルにしておき、それを読み込む場合には次のようにします。

| ?- consult('init.pl').
yes
|

既に読み込み済みのコードを上書きをする場合にはreconsultを使います。
| ?- reconsult('init.pl').
yes

reconsultと入力するのは煩わしいのでリストで入力することも可能です。
| ?- ['init.pl'].
yes
|

これらにより読み込んだコードはlisting述語により表示することができます。
| ?-listing.
yes_or_no(X) :- repeat,write(yes or no >),read(X),X==yes;X==no,!.
yes
|

linux版には組み込みのCUIエディタがあります。CPUパワーの小さいラズパイでの編集を目的としています。詳細は下記を参照してください。
http://qiita.com/sym_num/items/4af619de02191c95e3b9

事実

太郎は人間であるという事実は述語として表現されます。

human(taro).

推論規則

人間は誤りを犯すものである、ということは推論規則として表現されます。次のような節となります。

節   ↓通称メダカ記号
error(X) :- human(X).
↑      ↑
頭部     本体部

大文字のアルファベットで始まる記号は変数として扱われます。

アトム

humanやtaroという記号はアトムと呼ばれます。アトムとして利用可能な文字はISO標準のものに加え、UnicodeまたはシフトJISが可能となっています。

アルファベット abcdefghijklmnopqrstuvwz ABCDEFGHIJKLMNOPQRSTUVWXYZ
特殊記号 #$&*+-/:.<=>?@^~\
数文字 1234567890

先頭はアルファベットである必要があります。
特殊記号を含むアトムである場合にはシングルクオートでくくる必要があります。

アトムにシングルクオートを含む場合には次のように記述します。
例 'I don''t know'

| ?- X = 'I don''t know'.
X = I don't know
yes
| 

独自拡張 Unicode(UTF8) またはシフトJIS 例 人間 太郎
Winodws版は初期設定はシフトJISです。Linux版はUnicodeです。
組込み述語 char_set/1により切り替えることができまs。
char_set(unicode). 以後Unicodeでの動作となります。
char_set(sjis).  以後シフトJISでの動作となります。

変数

先頭が大文字のアルファベットで始まるアトムは変数となります。

例 X Y A1 Bcd

先頭がアンダーバーで始まるアトムも変数となります。

例 _var _あれ

整数と浮動小数点数が扱えます。整数は無限多倍長整数(BIGNUM)が扱えます。

| ?- X is sin(3.14).
X = 0.001592652916486828
yes
| ?- Y is 3**100.
Y = 515377520732011331036461129765621272702107522001
yes
|

浮動小数点数には指数表示が可能です。
例 1.002E3

| ?- X is 1.002E3.
X = 1002.0
yes
| 

浮動小数点数は小数部を省略することはできません。
例 1. × 1.0 ○

| ?- X is 1.
X = 1
yes
| ?- X is 1.0.
X = 1.0
yes
| 

リスト

Lispと同様にリストが使えます。ドット記法は|(縦棒)で表現します。以下、Lispとの対比表です。

Prolog       Lisp
[1,2,3]     (1 2 3)
[1,2|3]     (1 2 . 3)
[1,2,[3,4]]  (1 2 (3 4))
[a|b]       (a . b)

演算子記号

次の記号が演算子として使用されています。

":-" "-->" "," "?-" "->" "/\" "=.." "==" "\==" "@<" "@=<" "@>" "@>="
"=:=" "=/=" "=\=" "<" "=<" ">"
">=" "<<" ">>" "**" "\\=" "^"
"=" "+" "-" "*" "//" "/" "."

演算子

:- 節を定義します。左側に頭部、右側に本体部の述語が入ります。
human(X) :- error(X).

?- 質問をします。続けて質問したい述語を記述します。
-? human(taro).

算術式

is述語を使った場合、右辺は評価計算され左辺にユニフィケーションします。この場合の算術式については下記の通りです。

定数

pi 円周率の近似値です。3.14159265358979

関数 数演算子

+ 加算
- 減算
* 乗算
/ 除算
// 整数除算
** 累乗
^ 累乗
abs(X) 絶対値
sin(X) 正弦
cos(X) 余弦
tan(X) 正接
asin(X) 正弦の逆関数
acos(X) 余弦の逆関数
atan(X) 正接の逆関数
exp(X) 指数関数
log(X) 対数関数(底はe)
floor(X) Xに最も近い整数
ceiling(X) 小数部の切り上げ
truncate(X) ゼロから近づいた時の最大の整数
float(X) 整数の浮動小数点数への変換
sign(X) 正負符号 プラスなら1、マイナスなら-1、ゼロなら0
sqrt(X) 平方根
round(X) まるめ
gcd(X,Y) 最大公約数
lcm(X,Y) 最小公倍数
mod(X,Y) 剰余
rem(X,y) 剰余
X /\ Y 論理積
X \/ Y 論理和
X xor Y 排他的論理和
X iand Y 包含的論理積

組込み述語

op
!

assert/1
述語、節をデータベースの最後に追加登録します。

| ?-assert(human(taro)).
yes
| ?-listing.
human(taro).
yes
| 

asserta/1
述語、節をデータベースの先頭に追加登録します。

assertz/1
assertと同じです。最後に追加登録します。

retractall/1
引数に与えられた述語をすべて削除します。

abolish/1
引数に与えられた述語、節を削除します。述語名とその引数の数をスラッシュ記号とともに渡します。

| foo(1).
| foo(2).
| ?-listing.
foo(1).
foo(2).
yes
| ?-abolish(foo/1).
yes
| ?-listing.
yes
| 

read/1
入力データを引数にユニファイします。入力の最後にはピリオドが必要です。

write/1
引数を画面表示します。

put
get
get

nl/0
画面表示で改行をします。

tab/1
引数に与えられた数だけスペースを表示します。

fail/0
常に失敗します。

once
not
true

halt/0
処理系を終了します。

abort/0
実行を中断してプロンプトに戻ります。

errorset
errormode
listing
functor
arg
debug
atom_length
atom_concat
findall
consult
reconsult
see
seen
tell
told
trace
notrace
spy
nospy
atom
integer/1
引数が整数のときに真、そうでなければ偽を返します。

float/1
引数が浮動小数点数であるときに真、そうでなければ偽を返します。

number/1
引数が数であるときに真、そうでなkれば偽を返します。

compound/1
引数が複合項であるときに真、そうでなければ偽を返します。

| ?-compound(human(taro)).
yes
| ?-compound([1,2,3]).
yes
| 

var/1
引数が未束縛の変数のときに真、そうでなければ偽を返します。

| ?- var(X).
yes
| ?- X is 3,var(X).
no
| 

nonvar/1
引数が未束縛の変数のときに偽、そうでなければ真を返します。

| ?-nonvar(X).
no
| ?- X is 3,nonvar(X).
X = 3.
yes
| 

atomic

list/1
引数がリストである場合には真、そうでなければ偽を返します。

| ?-list([1,2,3]).
yes
| 

length/2
第一引数のリストの長さを第二引数にユニファイします。

| ?-length([1,2,3],X).
X = 3
yes
| 

gbc/0 gbc/1
ガーベジコレクションを制御します。引数無しで呼ばれた場合にはガーベジコレクションを起動します。引数にnoを与えた場合にはガーベジコレクション起動時にメッセージを表示しなくなります。引数にyesを与えた場合にはガーベジコレクション起動時にメッセージを表示します。初期設定は表示するです。

| ?-gbc.
enter GBC free=9999739
exit  GBC free=9999751
yes
| ?-gbc(yes).
yes
| ?-gbc(no).
yes
| ?-gbc.
yes
| 

time/1
実行時間計測用の述語です。計測した述語を引数として与えます。

| ?-time(queens9).
[1,3,6,4,8,2,7,5,9]
...
[9,7,4,6,2,8,3,5,1]
Elapsed Time=0.135000 (second)
no
| 

char_set
char_code
atom_chars
atom_codes

name/2
アトムとリストとを相互に変換します。

| ?-name(abc,X).
X = [97,98,99]
yes
| ?-name(X,[97,98,99]).
X = abc
yes
| 

number_chars
number_cords

sexp/1
処理系のデバッグ用です。引数にyesを与えると述語や節をS式で表示します。noを与えると元に戻ります。

read_csv
append
member
retract
clause
between