5

このプロローグクエリがそのように機能する理由を誰かが説明してくれますか? 定義は次のとおりです。

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

これを考えると:

?-  add(succ(succ(succ(0))),  succ(succ(0)),  R).

クエリのトレースは次のとおりです。

Call:  (6)  add(succ(succ(succ(0))),  succ(succ(0)),  R) 

Call:  (7)  add(succ(succ(0)),  succ(succ(0)),  _G648) 

Call:  (8)  add(succ(0),  succ(succ(0)),  _G650) 

Call:  (9)  add(0,  succ(succ(0)),  _G652) 

Exit:  (9)  add(0,  succ(succ(0)),  succ(succ(0))) 

Exit:  (8)  add(succ(0),  succ(succ(0)),  succ(succ(succ(0)))) 

Exit:  (7)  add(succ(succ(0)),  succ(succ(0)), 
                                              succ(succ(succ(succ(0))))) 

Exit:  (6)  add(succ(succ(succ(0))),  succ(succ(0)), 
                                                succ(succ(succ(succ(succ(0))))))

そのチュートリアルで私を最も混乱させたのは、最初の引数で succ が取り除かれ、再帰するという事実でした。ただし、再帰中、R は成功を収めます...どうやって?! また、最初の出口 (9) のゼロはどこから来ますか? 私はプロローグが初めてで、宿題のために言語を理解しようとしています。どんな助けでも大歓迎です。

注: 興味のある方のために、このチュートリアルへのリンクはhttp://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse9です。

4

3 に答える 3

4

あなたが提示したクエリを解決しようとしてインタープリターが実行するアクションが表示さcallれます。その後、トレースによって実際に行われた作業の詳細が明らかになり、履歴の観点から見ることができます。exitverbs

Prolog が規則 (a call) を選択しなければならない場合name、与えられた (いわゆる) を使用し、規則の先頭にある各引数functorを試行します。unify次に、通常、Prolog はarity選択のために 、つまり引数の数も考慮すると言います。

Unificationbindingsは 2 つの項を「等しくする」試みであり、注目に値する結果は変数のいわゆるものです。変数が で始まる名前であることは既にご存じでしょうUppercase。このような名前は、ルールで指定されていない値を識別します。つまりplaceholders、引数用です。混乱を避けるために、Prolog がトレースを表示するとき、変数の名前を変更して変数を識別できるようにしていidentitiesます。

次に、そのような_G648シンボルがトレースに表示されます。それらは、呼び出されたゴールのまだインスタンス化さRれていない引数、つまりとのためにとどまりますZ。R は一意 (最上位の呼び出しでのみ発生) であるため、この Prolog は親切にユーザー フレンドリな名前を保持しますが、Z はプログラムに由来し、複数回発生する可能性があり、その後名前が変更されました。

このクエリに答えるには

?-  add(succ(succ(succ(0))),  succ(succ(0)),  R).

プロローグの最初のマッチング試行

add(0,Y,Y). 

succ(succ(succ(0)) を 0 にすることはできないため失敗します。

add(succ(X),Y,succ(Z)) :- add(X,Y,Z).

したがって、これらのバインディングを解決する必要があります (呼び出し元の項の左側)。

succ(succ(succ(0))) = succ(X)
succ(succ(0)) = Y
R = Z

X が になる理由がわかります。また、証明する新しい目標があります。つまり、バインディングが確立されたばかりsucc(succ(0))のルール本体です。add(X,Y,Z)

add(成功(成功(0))、成功(成功(0))、_G648)

など... X になり0、ゴールが一致するまで

add(0,Y,Y).

Zすると Y は succ(succ(0)) になり、注目すべきは呼び出しルールで値を与えることです。

HTH

于 2012-04-25T06:37:18.723 に答える
1

「最初の出口 (9) のゼロはどこから来ますか?」

呼び出しは、 の最初の引数が 0 の場合、2 番目と 3 番目が同じであるadd(0, succ(succ(0)), _G652)ことを示す最初の節で統一されています。addこの特定の状況では、変数_G652は になりsucc(succ(0))ます。

「しかし、再帰中に、R は成功を収めます...どうやって?!」

これは、2 番目の条項を適用した結果です。succこの句は、最初の引数から最初に削除し、次に再帰的に呼び出し、最後に、この再帰呼び出しから返される 3 番目の引数にadd別の「レイヤー」を追加することを (大まかに) 述べています。succ

述語addは、ペアノ算術における加算の直接実装に他なりません: http://en.wikipedia.org/wiki/Peano_axioms#Addition

于 2012-04-25T06:14:16.877 に答える