Help us understand the problem. What is going on with this article?

PrologによるPrologインタプリタ

More than 1 year has passed since last update.

はじめに

O-Prologのテストを兼ねて、PrologでPrologインタプリタを書くということをしてみました。お遊びです。本格的なものではありません。

超手抜きバージョン

%prolog in prolog

pp :- 
    repeat,
    nl,write(': ?- '),
    read(X),
    (X=halt -> abort;true),
    (call(X) -> write(yes);write(no)),
    fail.

LispでLispインタプリタを記述する場合、evalを使っていいのなら、それはとても容易いことです。(print (eval (read))) で済んでしまいます。同様にPrologのresolveの部分をcall/1を使っていいのなら、上記のようなコードになります。しかし、これではつまりません。

少し手を加えて

call/1を自前で書いてみます。組込み述語は処理系のものを呼び出すことにします。predicate_property/2で判別しています。O-Prologの場合にはbuilt_inを返すようになっています。(このあたりはISO-Prologの規格でも曖昧なようで、各種処理系によってばらつきがあります)

組込述語ではないユーザー定義の述語だった場合には、その定義された節をclause/2を使って呼び出します。そしてその本体部をmy_callで実行します。

連言と選言も自前で処理することにしました。

%prolog in prolog

pp :- 
    repeat,
    nl,write(': ?- '),
    read(X),
    (X=halt -> abort;true),
    (my_call(X) -> write(yes);write(no)),
    fail.

%builtin
my_call(X) :-
    predicate_property(X,built_in),
    call(X).
%user predicate
my_call(X) :-
    predicate_property(X,dynamic),
    clause(X,true),
    write(X),
    get_char(D), %discard EOL
    get_char(Z),
    (\+(Z = ';') -> true;fail).
%user clause
my_call(X) :-
    predicate_property(X,dynamic),
    clause(X,Y),
    Y \= true,
    my_call(Y),
    write(X),
    get_char(D), %discard EOL
    get_char(Z),
    (\+(Z = ';') -> true;fail).
%variable
my_call(X) :-
    var(X),
    call(X).
%conjunction
my_call((X,Y)) :-
    call(X),
    my_call(Y).
%disjunction
my_call((X;Y)) :-
    call(X),!.
my_call((X;Y)) :-
    call(Y).

動作

ちょっと表示がおかしいところもあるますが、それっぽく動作するようにはなりました。

O-Prolog Ver 1.19(hiromi)
| ?- ['prolog.pl'].
yes
| ?- pp.

: ?- assert(human(taro)).
yes
: ?- assert(human(jiro)).
yes
: ?- human(X).
human(taro);
human(jiro);
no
: ?- assert((error(X) :- human(X))).
yes
: ?- error(jiro).
error(jiro)
yes
: ?- halt.
| 

改良、拡張

my_callの部分をいろいろ書き換えると面白いと思います。Prolog処理系の動作について興味をもっていただけたら嬉しいです。

sym_num
LALの笹川です。よろしくお願いします。
http://eisl.kan-be.com/
fukuokaex
エンジニア/企業向けにElixirプロダクト開発・SI案件開発を支援する福岡のコミュニティ
https://fukuokaex.fun/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away