0

私はadd2このように解決する述語を持っていますies(0)の後継者はどこですか01

?- add2(s(0)+s(s(0)), s(s(0)), Z).
Z = s(s(s(s(s(0)))))

?- add2(0, s(0)+s(s(0)), Z).
Z = s(s(s(0)))

?- add2(s(s(0)), s(0)+s(s(0)), Z).
Z = s(s(s(s(s(0)))))

等..

私はそのように機能する先行述語を追加しようとしています

?- add2(p(s(0)), s(s(0)), Z).
Z = s(s(0))

?- add2(0, s(p(0)), Z).
Z = 0

?- add2(p(0)+s(s(0)),s(s(0)),Z).
Z = s(s(s(0)))

?- add2(p(0), p(0)+s(p(0)), Z).
Z = p(p(0))

これを行う方法が見つからないようです。私のコードは以下です。

numeral(0).
numeral(s(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).
numeral(p(X)) :- numeral(X).


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


resolve(0,0).
resolve(s(X),s(Y)) :-
    resolve(X,Y).
resolve(p(X),p(Y)) :-
    resolve(X,Y).
resolve(X+Y,Z) :-
    resolve(X,RX),
    resolve(Y,RY),
    add(RX,RY,Z).

add2(A,B,C) :-
    resolve(A,RA),
    resolve(B,RB),
    add(RA,RB,C).
4

1 に答える 1

0

一般に、後続の算術演算との加算は、後続の項でもある形状0またはs(X)whereを持つ後続の項を処理することを意味しXます。これは、コードのこの部分によって完全に対処されます。

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

ここで、決定を下す必要があります。ここで前任者と追加項を で処理するか、add/3この述語をそれらを処理する別の述語でラップすることができます。でラップすることを選択したようadd/3ですadd2/3。その場合、ここで で構築したような還元項を作成する必要があります。その一部resolve/2の実装に同意します。

resolve(0,0).
resolve(s(X),s(Y)) :-
    resolve(X,Y).
resolve(X+Y,Z) :-
    resolve(X,RX),
    resolve(Y,RY),
    add(RX,RY,Z).

これはすべて良いです。今欠けているのは、p(X)用語を処理する方法です。add/3これを行う正しい方法は、 withを使用して、1 を差し引く方法が既にあることに注意することですs(0)

resolve(p(X), R) :-
    resolve(X, X1),
    add(s(0), R, X1).

つまり、X = Y - 1 を使用して X を計算する代わりに、X + 1 = Y を使用して X を計算しています。

入力が決して負でない場合、add2/3述語は機能します。

于 2019-10-14T21:06:10.650 に答える