* 9 A Closer Look at Terms
** 1 Comparing Terms
- ==/2はCommon Lispのeqみたいなニュアンスかな。
?- a == a.
true.
?- a == b.
fail.
?- a == 'a'.
true.
?- X == Y.
fail.
?- X=Y.
X = Y.
?- a = X, a == X.
X = a.
?-
- ふむ、eval、、、ではなくunifyされたobjectsを
eq、、、じゃなく==は等価性チェックする。
- ただ、==はtrue/failだけでなく、unifyされている
ときは、unification(binding)を返しているな。な
んか気になる。
- \==/2の導入。
** 2 Terms with a Special Notation
- Arithmetic terms
?- (2 =:= 3) == =:=(2,3).
true.
?- 2 =:= 3 == =:=(2,3).
ERROR: Syntax error: Operator priority clash
ERROR: 2 =:=
ERROR: ** here **
ERROR: 3 == =:=(2,3) .
?-
- なるほど。
- List as terms
?- .(a,[]) == [a].
true.
?- .(a,.(b,[])) == [a,b].
true.
?-
- おお、consだ!会いたかったよ、cons。こんなに小
さくなっちゃって。。。
** 3 Examining Terms
- Types of Terms
- termsの型を調べる述語たち。
- The structure of Terms
?- functor(f(a,b),F,A).
F = f,
A = 2.
?-
- おお、functorとarityも取れるのね。
?- functor(T,hoge,1).
T = hoge(_G240).
- 構成もしてくれる、と。
- complex termに対する型判定述語は自分で作る。
complexterm(X) :-
nonvar(X),
functor(X,_,A),
A > 0.
- arg : 引数に対するアクセス。
- =.. : complex termsのfunctorとargsをリストで返
す。univと呼ばれる。
- atom_codes/2にてatomとstringの相互変換ができる。
** 4 Operators
- ?-というのはprefix operatorだったのか。
- precedenceが大きいものが主たる(:外側の)functor
になる。+と*でいうと+の方が優先度が大きいので
2 + 3 * 4.
は、
+(2,*(3,4)).
になる。優先度が高い = 結合度が低い、かな。
- operatorsとpredicatesが同義語なのかそうでないの
かがわからない。先々わかるかな。
- precedenceが同じoperatorsが存在する場合どうなる
か。それはoperatorsのassociativityという概念/機
構によって振る舞いがきまる。
- 例えば、+は左結合性をもっている(left
associative)。
- 左結合性をは何か?
- まずexpressionsのprecedenceの概念がある。それは
そのexpressionの主functorのprecedenceである。さ
て、左結合性とは、infix operatorsなのでそもそも
引数は左右の2つなのだが、左にいれるexpressionは
自身と同じprecedenceでもよいが、右にいれる
expressionは自身より低くないといけない。これに
よって、
2 + 3 + 4.
は、
+(+(2,3),4).
というように曖昧さなく解釈される。ためす。
?- 2 + 3 + 4 = +(+(2,3),4).
true.
?- 2 + 3 + 4 = +(2,+(3,4)).
fail.
なお、これは内側のoperatorが+でなくても(同じで
なくても)適用される。
- ==, =:= は同じprecedenceを持ち、かつ
non-associtiveである。すなわち、左右引数双方と
も自身よりもprecedenceが低い必要がある。そのた
め、
2 =:= 3 == =:=(2,3).
が、
==((2 =:= 3),=:=(2,3)).
なのか、
=:=(2,==(3,=:=(2,3))).
なのかをPrologは自動判定できない。
- Defining operators
- operatorsというのは、operatorとして構文定義され
たpredicatesのことのようだな。逆に言うと、op
operatorが定義するのは構文だけで、それの意味と
いうかその演算の結果がどうなるかは通常のqueryと
同じであるということ。
?- assert(kill(marcellus,zed)).
true.
?- kill(X,zed).
X = marcellus.
?- assert((is_dead(X) :- kill(_,X))).
true.
?- is_dead(zed).
true.
?- op(500,xf,is_dead).
true.
?- zed is_dead.
true.
?- is_dead zed.
ERROR: Syntax error: Operator expected
ERROR: is_dead
ERROR: ** here **
ERROR: zed .
?-
** 5 Exercise
- Exercise 9.1.
- 12 is 2*6.
true.
- 14 =\= 2*6.
true.
- 14 = 2*7.
true. /* 正しくはfail。unifyは計算しない。term
の種類が違う。*/
- 14 == 2*7.
fail.
- 14 \== 2*7.
true.
- 14 =:= 2*7.
true.
- [1,2,3|[d,e]] == [1,2,3,d,e].
true.
- 2+3 == 3+2.
fail.
- 2+3 =:= 3+2.
true.
- 7-2 =\= 9-2.
true.
- p == 'p'.
true.
- p =\= 'p'.
fail. /* 正しくはERROR.数字じゃないので計算で
きない */
- vicent == VAR.
fail
- vincent=VAR,VAR==vincent.
true.
- Exercise 9.2.
- .(a,.(b,.(c,[]))) = [a,b,c].
true.
- .(a,.(b,.(c,[]))) = [a,b|c].
fail
- .(.(a,[]),.(b,[]),.(.(c,[]),[])) = X.
ERROR. /* 最外の.の引数が3つ。*/
お、ERRORにならない。そうか'.'/3が定義されるの
か!
- .(a,.(b,.(.(c,[]),[]))) = [a,b|[c]].
fail. /* [a,b,[c]] */
- Exercise 9.3.
complexterm(X) :-
nonvar(X),
functor(X,_,A),
A > 0.
termtype(Term,atom) :-
atom(Term).
termtype(Term,number) :-
number(Term).
termtype(Term,constant) :-
atomic(Term).
termtype(Term,variable) :-
var(Term).
termtype(Term,simple_term) :-
atomic(Term);
var(Term).
termtype(Term,comprex_term) :-
complexterm(Term).
termtype(_,term).
- Exercise 9.4.
groundterm(X) :-
atomic(X), nonvar(X).
groundterm(X) :-
nonvar(X),
X = [H|T],
groundterm(H),
groundterm(T).
groundterm(X) :-
complexterm(X),
'=..'(X,[functor|Args]),
groundterm(Args).
- Exercise 9.5.
- うー。operatorの結合めんどくさい。S式でいいじゃん。
X is_a witch
is_a(X,witch).
harry and ron and hermione are friends
are(and(harry,and(ron,haermione)),friends)
harry is_a wizard and likes quidditch
illegal.
dubledore is_a famous wizard
is_a(dubledore,famous(wizard)).
** 6 Practical Session
- pretty printer
pptree(T) :- ppt(T,0).
ppt(T,I) :-
atomic(T),tab(I),write(T).
ppt(T,I) :-
complexterm(T),
'=..'(T,[Functor,Single]),
tab(I),write(Functor),write('('),write(Single),write(')').
ppt(T,I) :-
complexterm(T),
'=..'(T,[Functor,Left,Right]),
tab(I),write(Functor),write('('),nl,
NewI is I + 2,
ppt(Left,NewI),nl,
ppt(Right,NewI),write(')').
- propositional logic formulas
:- op(200,fx,not).
:- op(300,xfy,implies).
さすがに体調が悪くなってきた。
仕事との両立が難しいのか、体が弱いのか。
こつこつ。