2009年7月6日月曜日

【LPN】5 Arithmetic


* 5 Arithmetic
** 1 Arithmetic in Prolog
- この本では整数しかやらないよ。
- こんな感じ。
?- 8 is 6+2.
true.

?- 8 is 6 + 2.
true.

?- is(8,+(6,2)).
true.

?- X is 6+2.
X = 8.

?-
- (is 8 (+ 6 2))でもよかったじゃん、と思う。まあ
それはPAIPで、ということで。

** 2 A Closer Look
- +-*/などは単なるfunctorである。
?- X = 3+2.
X = 3+2.

?-
これは単なるUnification。それは=/2が統制してい
る。
- 計算を統さどるのはis。
- isは逆演算はできない点に注意。

?- X is 6+2.
X = 8.

?- 6+2 is X.
ERROR: is/2: Arguments are not sufficiently instantiated

?- X = 2, Y is X*3.
X = 2,
Y = 6.

?- Y = 6, Y is X*3.
ERROR: is/2: Arguments are not sufficiently instantiated
?-

** 3 Arithmetic and Lists
- len/2の実装。
- accumulaterの導入。accLen/3、leng/2。
- 末尾再帰の効用の紹介。

** 4 Comparing Integers
- =:= Common Lispの=みたいなもの。
- =\= Common Lispの\=みたいなもの。
- 比較演算子はinstantiationsを実施しない。
?- X < 3.
ERROR: ?-
- あ、なるほど。制御構造のPrologでの表現はこんな
感じ。

accMax([H|T],A,Max) :-
H > A, accMax(T,H,Max);
H =< A, accMax(T,A,Max).
accMax([],A,A).

** 5 Exercise
- Exercise 5.1.
- 1. X = 3*4.
X = 3*4.
- 2. X is 3*4.
X = 12.
- 3. 4 is X.
ERROR.
- 4. X = Y.
X = Y.
- 5. 3 is 1+2.
true.
- 6. 3 is +(1,2).
true.
- 7. 3 is X+2.
ERROR.
- 8. X is 1+2.
X = 3.
- 9. 1+2 is 1+2.
true.
おお、間違えた。これfail。
isの左引数はis的評価をしないのか。
- 10. is(X,+(1,2)).
X = 3.
- 11. 3+2 = +(3,2).
true.
- 12. *(7,5) = 7*5.
true.
- 13. *(7,+(3,2)) = 7*(3+2).
true.
- 14. *(7,(3+2)) = 7*(3+2).
true.
- 15. 7*3+2 = *(7,+(3,2)).
fail.
- 16. *(7,(3+2)) = 7*(+(3,2)).
true.

- Exercise 5.2.
increment(M,N) :- N is M + 1.
sum(M,N,Sum) :- Sum is M + N.

- Exercise 5.3.
addone([],[]).
addone([H1|T1],[H2|T2]) :-
H2 is H1 + 1, addone(T1,T2).

- 油断するとすぐに手続きから考えてしまう。成立す
べき様子というか条件を考えて素直にそれを記述す
べし。

** 6 Practical Session
- 1
accMin([H|T],A,Min) :-
H < A, accMin(T,H,Min);
H >= A, accMin(T,A,Min).
accMin([],A,A).

- 2

scalarMult(_,[],[]).
scalarMult(N,[LH|LT],[RH|RT]) :-
RH is N * LH, scalarMult(N,LT,RT).

- 3

dot([],[],0).
dot([Ha|Ta],[Hb|Tb],A) :-
Anew is A + Ha * Hb, dot(Ta,Tb,Anew).

だとうまくいかない。accumulatorを使うとうまくいく。

dot_acc([],[],A,A).
dot_acc([Ha|Ta],[Hb|Tb],A,R) :-
Anew is A + Ha * Hb, dot_acc(Ta,Tb,Anew,R).
dot(Va,Vb,Result) :-
dot_acc(Va,Vb,0,Result).

なぜかというと、accumulatorをつかうとisの右引数のA
が具体的な数値になるから。


Lisp -> Lisper
Ruby -> Rubyist
Python -> Pythonista
Prolog -> Prologger?, Prologician? ???

こつこつ。

0 件のコメント: