6

最近 Prolog を始めたので、いくつかの単純なタスクに Prolog を使用してきましたが、以下の簡単な例のような forall ループ内で member を使用することに疑問を抱き始めました。

forall(member(A,[1,2,3,4]), print(A)).

このようなことを行う場合、forall が呼び出されるたびにリスト内の要素を同じ順序で処理するというのは常に本当ですか? 次のようなことを言って強制する必要がありますか?

A = [1,2,3,4], sort(A, B), forall(member(C,B), print(C)).

私が最初に行った小さな調査から、それは member/2 の動作に帰着すると推測していますが、SWI-Prolog の Web サイトにある関数のドキュメントは非常に簡潔です。しかし、確実ではありませんが、常に同じ順序で要素を抽出すると言って正しい道を進んでいる可能性があることを私に感じさせた member/2 に関する決定論について言及しています。

誰かがこれについて保証や説明をしてくれますか?

4

3 に答える 3

4

Prolog での非決定性とは、複数の解を持つ可能性のある述語を単に指します。明らかに、member/2そのような述語です。これは、計算が予測不能になることを心配する必要があるという意味ではありません。Prolog には明確に定義された計算規則があり、これは基本的に、代替ソリューションが深さ優先、左から右の方法で探索されることを示しています。したがって、目標は予想される順序 1、2、3、4 でmember(X,[1,2,3,4])解を生成します。X

リスト [1,2,3,4] を並べ替えても、(Prolog の標準用語順序に従って) 既に並べ替えられているため、違いはありません。

についての注意forall/2: 一部のプロローグはこれを定義していますが、実際には「ループ」ではないため、おそらくあなたが想像するほど有用ではありません。各反復で印刷の副作用のみを実行するため、例で使用できます。他のほとんどの目的では、次のような再帰パターンに慣れておく必要があります。

print_list([]).
print_list([X|Xs]) :- print(X), print_list(Xs).
于 2014-02-04T19:16:14.920 に答える
0

厳密に言えば、いくつかのレベルで SWI には保証がありません。

1mo、それは、member/2またはforall/2それらを再定義できるため、まさにこの方法で実行されます。

?- [user].
member(X,X).
|: % user://1 compiled 0.00 sec, 2 clauses
true.

?- forall(member(A,[1,2,3,4]), print(A)).
[1,2,3,4]
true.

ただし、関心のあるすべての詳細をカバーするプロローグのプロローグmember/2で定義されています。これは標準機能のみに依存しているため、代わりに書く方が安全です。そのような定義はないため、何が「正しい」動作であるかを判断するのは困難です。forall(A,B)\+ (A, \+B)forall/2

2do、その SWI は標準準拠になります。ドキュメントを読むと、標準準拠についての自己宣言 (SICStus Prolog など) がないことに気付くでしょう。実際に\+ (A, \+B)は、次の例のように完全に準拠しているわけではありません。nonconforming

?-  \+ ( C= !, \+ (C,fail;writeq(nonconforming))).
于 2014-02-03T16:48:10.707 に答える