3

Prologで考えるのに苦労しています。この記述の誤りは次のとおりです。

numberList([], 0).
numberList([H|T], Limit) :-
    H is Limit,
    numberList(T, Limit - 1).

をお願いします。

?- numberList(X,Limit).

[Limit, Limit-1 ... 1]Limit の特定の値に対する唯一の解として決定する、つまり

?- numberList(X, 100).

お譲りいたしX = [100, 99, 98, ..., 1].ます。

私の推測では、これが機能しないという私の理解にはかなり問題があると思います。私がやろうとしていることの解決策を必ずしも求めているわけではありません。最初の試みが間違っている理由を理解したいだけです。

4

2 に答える 2

3

ここには 2 つの主な問題が潜んでいます。

1- 適切な場所で統一と算術演算を取得するのに問題がある

2-入力を十分にチェックしていません

1- について の注意(is)/2は、算術を実行するために使用されます。ここでは、たとえば、 を減算1Limitます。(is)/2変数を既に評価された算術式に統一するために使用することはできますが、使用すべきではありません。(=)/2優先する必要があります(統合)。

2 についての注意事項 - 演算子を正しく設定しても、プログラムはループします。それについては後で詳しく説明します。

オペレーターを自分で切り替えるだけではあまり得策がないため、正しい方法は次のとおりです。

numberList([], 0).
numberList([Limit|T], Limit) :-
    NewLimit is Limit - 1,
    numberList(T, NewLimit).

ここで、2 番目の節の先頭で暗黙的に統一を使用していることがわかります。別の言い方をすると、次のようになります。

numberList([], 0).
numberList([H|T], Limit) :-
    H = Limit,
    NewLimit is Limit - 1,
    numberList(T, NewLimit).

しかし、このプログラムを試してみるとわかるように、正しい解を見つけますが、別の解を求めるとループします;

その理由は、初心者の目には見つけにくいかもしれません。Prolog が成功して解を返した場合、実行中に残された選択ポイントを探索することによってのみ、新しい解を見つけることができます。ここで、残された唯一の選択ポイントは が である場合Limitです0。したがって、その場合、最初の節ではなく 2 番目の節を試行し、到達するまでループしますNegativeInfinity。悲しいことに、そこに着くまでの距離がかなり長いため、前にオーバーフローします。この問題の解決策は、2 番目の句にガードを追加して、Limitそれよりも大きい必要があることを指定する0か、最初の句にカットを追加するか、さらに良い方法で両方を行うことです。自分でやるのが苦手な方はご相談ください!

于 2012-05-10T18:03:07.107 に答える
0

「Limit - 1」は関数呼び出しと考えられており、C言語などでは機能します。プロローグに「減算関数を見つけて、それを制限変数と 1 で呼び出す」ように要求/命令しています。「Limit - 1」を関数呼び出し結果としてPrologに理解させようとしているのですが、Prologは「Limit - 1」を複合項subtract(Limit,1)として理解しており、一階論理からの述語です

「H is Limit」これも関数呼び出しと考えられる

プロローグには機能がない(???)、クレームはC-ピープルにとって大きな壁だと思います。関数 (C など、数学など) の代わりに、Prolog には述語 (述語論理、一次など) があります。

関数は、マイクロプロセッサに命令するコマンドです。代わりに、述語は「マイクロプロセッサの目で見る」ためにマイクロプロセッサにデータを提示し、マイクロプロセッサにデータを提示して認識します。

述語は世界の一部を記述し、その世界のオブジェクト間のいくつかの関係を記述し、マイクロプロセッサはそれらの関係を検証しようとします。マイクロプロセッサは、それらの関係が実際に存在することを証明しようとします。これらの関係は、その知識の中で複数回存在する可能性があるため、マイクロプロセッサは複数の結果を返すことができます (別名、非決定論)。

Prolog はすばらしいプログラミング言語です。おそらく、すばらしい記述言語、すばらしいパターン認識言語、すばらしい推論/演繹言語 (単純な推論/演繹、それは一種の「人工知能」ではなく、デジタル電子論理のような推論/演繹) を書くべきですゲート) . 以前は熱心な Visual Studio プログラマーでしたが、ここ数年 Prolog を勉強しています。

C 言語などは Commanding 用で、Prolog 言語などは Describeing 用です。

于 2015-01-26T17:27:39.047 に答える