0

n=s(s(...s(0)...)) (単に n= s^n(0)) と考えてみましょう。2 つの整数の除算を計算するプログラムをどのように作成できますか? つまり、 s^(n//m) (除算の定義) です。何か案は?たとえば、次のような質問があるとします。

?-divide(s(s(s(s(0)))),s(0),D). 

私は次のコードを書きました:

 nat(0).
 nat(s(X)) :- nat(X).
 divide(0,_,D) :- D is 0.
 divide(s(X),s(Y),D) :- divide(X,Y,D). 
4

3 に答える 3

1

あなたの述語divide/3は、x と y が数値の場合、次の方程式が成り立つと誤って想定しています: (x-1)/(y-1) = x/y
反例: (16-1)/(4-1) = 5 16/4 = 4とは異なります

よく知られている加算述語に基づいて述語を作成しようとしているようです。

add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

しかし、除算は加法演算ではなく乗法演算です。問題を解決する可能な方法は、除算を反復減算と考えることです (乗算は反復加算であるため)。あなたの述語は自然数に基づいているため、質問に書いたように整数除算を実装する必要があります。

于 2015-05-02T14:34:22.217 に答える
0
s(0).
s(X):- X.

plus(0, Y, Y).
plus(s(X), Y, s(Z)):- plus(X , Y , Z).

minus(A, B, C) :- plus(C, B, A).

divide(_, 0, 0).
divide(0, _ , 0).
divide(X, s(0), X).
divide(A, B, s(N)) :- minus(A, B, R), divide(R, B, N).

例:

| ?- divide(s(s(s(0))), s(0), N).

N = s(s(s(0))) ?

yes
| ?- divide(s(s(s(s(0)))), s(s(0)), N).

N = s(s(0)) ?

yes

この解決法は明らかに、4/2 や 6/3 などの完全除算に対してのみ機能します。ペアノの数を使用して自然数しか表現できないためです。

于 2016-10-17T04:41:44.957 に答える
0

古い投稿ですが、同じ割り当てがあります。答えは次のとおりです。

%nat:Is X natural?,nat2:Is X,Y naturals?
nat(0).
nat(s(X)) :- nat(X).
nat2(0,s(Y)) :- nat(Y).
nat2(s(X),s(Y)) :- nat2(X,Y). 

%Summary of X+Y=Z
sum(X,0,X) :- nat(X).
sum(X,s(Y),s(Z)) :- sum(X,Y,Z).

%Minus of X-Y=Z is same as Y+Z=X
minus(X,Y,Z) :- sum(Y,Z,X). 

%Multiplication of X*Y,add X+0(Z) Y times(recursive)
mult(X,0,0).
mult(X,s(Y),D):-mult(X,Y,Z), sum(X,Z,D).

%Divide,check special occasions,add to W the s(0)(1) recursive.
divide(X,Y,D) :- div(X,Y,D,_).
div(s(X),0,undefined,_).
div(0,s(Y),0,_).
div(0,0,undefined,_).
div(X,Y,0,X) :- X \== 0,Y \== 0,nat2(X,Y).
div(X,Y,D,L) :- X \== 0,Y \== 0,minus(X,Y,Z),div(Z,Y,W,L),sum(W,s(0),D).
于 2017-05-12T15:41:06.123 に答える