



aho(X,Z) :- A =.. [plus,1,X,Z], call(A),print(Z).

?- aho(4,Z). 5 Z = 5

「call/1」 は、 引数をゴールとして、実行を行う。

「=.. 『(=..)/2』」は =..の右辺(正確には第2引数)のリストの、

先頭の要素を、 ファンクタとして、 残りの要素を、 引数として、 項(term)を生成して、左辺の変数(正確には第1引数)にバインドする。



map(_,[]) :-!. map(F,L) :- !,select(A,L,LR), X =.. [F,A], call(X), map(F,LR).

baka(X) :- print(X),nl.

?- map(baka,[a,b,c,d]). a b c d

このmap/2は、 第2引数のリストの要素を1つづつ順番に、

第1引数(のアトムをファンクターとする)の述語に適用します。

:- dynamic(aaa/1).

asserta(aaa(1)). aaa(1)という節が定義できる。データベースの先頭に。 retract(aaa(1)). aaa(1)という(パターンにマッチした)節が削除される。 retract(aaa(_)). aaa(_)に最初にマッチした節が削除される。 retractall(aaa(_)). aaa(_)にマッチしたすべての節が削除される。

looop(0). looop(X) :- print(X),nl,X1 is X - 1, looop(X1). % ?-looop(5). 5 4 3 2 1

-- 昔風、素朴なevalを、なんとなくC言語のようなもので記述した。 -- eval(関数) { : 関数をどんどん実行する : if(関数呼び出しに出会った) eval(新しい関数); 残りを実行 : } --

-- テイル・リカーシブなevalを、なんとなくC言語のようなもので記述した。 -- eval(関数) { eval_loop: : 関数をどんどん実行する : if(関数呼び出しに出会った){ if(新しい関数呼び出しの後に、仕事はある?){ 今evalしている情報を、スタックへ退避 } プログラムカウンタ=新しい関数; goto eval_loop; } ※1 残りを実行 : ※2 if(スタック!=空){ スタックから、情報を戻す goto eval_loop; } } --

aaa1 :- bbb(X),ddd(X). aaa2 :- bbb(X),!,ddd(X). bbb(a). bbb(b). bbb(c). bbb(d). ddd(X) :- print(X),read(Y),X == Y.

-- カットの入れ方の典型例 a) 単純な手続き (先頭にカットを入れる) subroutine1(X) :- !, XX is X + 1, print(XX). b) 条件判断がある時 (条件判断が終わったところで、カット) condSubr(X) :- XX is X + 2, XX == 3,!,print('One'). condSubr(X) :- !,print('not One'). 上を、C言語の if() ... else... で書くと、 condSubr(X) { XX = X + 2; if(XX == 3) printf("One"); else printf("not One"); } c) if()..else if()..else if()... の例 condSubr(0) :- !,print('Zero'). condSubr(1) :- !,print('One'). condSubr(2) :- !,print('Two'). condSubr(X) :- X < 0,!,print('minus'). condSubr(X) :- !,print('too much'). 上を、C言語の if() ... else... で書くと、 if(X == 0) printf("Zero"); else if(X == 1) printf("One"); else if(X == 2) printf("Two"); else if(X < 0) printf("minus"); else printf("too much"); Prologは、「==」の条件判断と呼び出しが、同時にできて、強力〜♪ --