4

Prolog で CLP がどのように機能するかについて、私は非常に混乱しています。利点を理解するのが難しいだけでなく (特定のケースではそれを理解できますが、それらを一般化するのは難しいと思います)、さらに重要なことに、再帰述語を正しく記述する方法をほとんど理解できません。次のうち、CLP(R) の方法で正しい形式はどれですか?

factorial(0, 1).
factorial(N, F):- {
  N > 0,
  PrevN = N - 1,
  factorial(PrevN, NewF),
  F = N * NewF}.

また

factorial(0, 1).
factorial(N, F):- {
  N > 0,
  PrevN = N - 1,
  F = N * NewF},
  factorial(PrevN, NewF).

言い換えれば、いつ制約外にコードを書くべきかわかりません。PrevN私には、最初のケースの方がより論理的に見えるでしょうNewFしかし、それが本当なら、再帰関数の制約の外側で述語を使用することがどのような場合に役立つかを知りたいです。

4

1 に答える 1

5

あなたの投稿には重複する質問や問題がいくつかあります。おそらく多すぎて、1 つの投稿で完全に満足できるように首尾一貫して対処することはできません。

したがって、最初にいくつかの一般原則を述べ、次に、それに基づいて、投稿したコードについていくつかの具体的なコメントを述べたいと思います。

まず、あなたのケースで最も重要だと思うことを述べたいと思います。

LP ⊆ CLP

これは単純に、CLP が論理プログラミング (LP)のスーパーセットと見なすことができることを意味します。それが適切なスーパーセットと見なされるかどうか、または実際に、それらを同じ概念を示すと見なすことがさらに理にかなっている場合は、多少議論の余地があります. 私の個人的な見解では、制約のないロジック プログラミングは制約がある場合よりもはるかに理解しにくく、使いにくいものです。非常に最初の Prolog システムでさえも制約がdif/2あり、その本質的な組み込み述語 (=)/2が「制約」の概念に完全に適合していることを考えると、境界が存在する場合、境界は少なくともいくらか人工的に見え、それを示唆しています。 :

LP≒CLP

いずれにせよ、CLP (あらゆる種類の) を扱う際の重要な概念は、制約が predicate として利用可能 あり、他のすべての述語と同様に Prolog プログラムで使用されるということです。

したがって、目標を持っているかどうかfactorial(N, F){ N > 0 }、少なくとも原則としては同じ概念です。どちらも何か が成り立つことを意味します。

構文に注意してください。CLP(ℛ) 制約の形式{ C }は {}(C)で、接頭辞表記になっています。

ゴールfactorial(N, F)はCLP(ℛ) 制約ではないことに注意してください! 次のこともありません。

?- { factorial(N, F) }.
エラー: 未処理の例外: type_error({factorial(_3958,_3960)},...)

したがって、CLP(ℛ) 制約でも{ factorial(N, F) }ありません!

したがって、最初の例は、この理由だけでは機能しません。(さらに、句 head: に構文エラーがあるfactorial (ため、これもまったくコンパイルされません。)

制約ソルバーの操作を学習したら、それが提供する述語を確認してください。たとえば、CLP(ℛ) は、および他のいくつかの述語を提供し、浮動小数点数について保持される関係を記述するため{}/1の専用の構文を備えています(この場合)。

他の制約ソルバーは、それぞれのドメインのエンティティを記述するための独自の述語を提供します。たとえば、CLP(FD) は整数について推論するための述語をいくつか提供します。任意のProlog 用語について推論できます。等々。(#=)/2dif/2

プログラマーの観点からは、これはProlog システムの他の述語を使用するのとまったく同じです。原則として、すべて同じです。

のような目標list_length(Ls, L)は、「リストの長さは です」と読むことができ Lsます L

のような目標は次のよう{ X = A + B }に読むことができます: 数はと の合計X等しい. たとえば、CLP(Q) を使用している場合、この場合は有理数について話していることは明らかです。AB

2番目の例では、句の本体はフォームの結合(A, B)であり、Aは CLP(ℛ) 制約でありB、フォームのゴールですfactorial(PrevN, NewF)

要点: CLP(ℛ) 制約目標です! 見てみな:

?- write_canonical({a,b,c})。
{','(a,','(b,c))}
真実。

したがって、エクスポートする述語の 1 つである{}/1fromを使用しているだけです。library(clpr)

あなたはその通りでPrevNありNewF 、制約に属しています。ただし、浮動小数点数を推論するために CLP(ℛ) が実装するミニ言語factorial(PrevN, NewF)の一部ではありません。したがって、この目標を CLP(ℛ) 固有の部分に組み込むことはできません。

プログラマーの観点から見ると、CLP の主な魅力は、 「通常の」論理プログラミングに完全にシームレスに溶け込み、実際にはほとんど区別できない点です。制約は単なる述語であり、次のように書き留められます。他のすべての目標。

ライブラリ述語に「制約」というラベルを付けるかどうかは、ほとんど違いはありません。すべての述語は制約と見なすことができます。これは、回答を制約することしかできず、緩和することはできないためです。

あなたが投稿した両方の例は再帰的であることに注意してください! それはまったく問題ありません。実際、再帰述語は、今後制約を使用する状況の大部分になる可能性があります。

ただし、factorialの具体的なケースでは、Prolog システムのCLP(FD)制約の方が適している可能性があります。これは、完全に 整数に関する推論に専念しているためです。

于 2017-01-10T10:09:36.837 に答える