8
?- permutation([A,B,C],Z).
Z = [A, B, C] ;
Z = [A, C, B] ;
Z = [B, A, C] ;
Z = [B, C, A] ;
Z = [C, A, B] ;
Z = [C, B, A] ;
false.

理にかなっています。の順列に取り組むことができ[A,B,C]、その順列には と同じ要素が含まれている[A,B,C]ため、これらの要素に対して行うことはすべて、元のリストに適用されます。

今:

?- findall(X, permutation([A,B,C], X), Z).
Z = [[_G1577, _G1580, _G1583], [_G1565, _G1568, _G1571], [_G1553, _G1556, _G1559], [_G1541, _G1544, _G1547], [_G1529, _G1532, _G1535], [_G1517, _G1520, _G1523]].

どうして??findall/3ではなく、完全に無関係な変数を含むリストが表示されるのはなぜA,B,Cですか? のリストはZ互いに関連していないため、実際に得られる結果は長さ 3 の 6 つのランダムなリストであり、これは私が照会したものとはまったく異なります。

この動作により、次のようなばかげた結果が得られます。

?- findall(X, permutation([A,B,C],X), Z), A = 1.
A = 1,
Z = [[_G1669, _G1672, _G1675], [_G1657, _G1660, _G1663], [_G1645, _G1648, _G1651], [_G1633, _G1636, _G1639], [_G1621, _G1624, _G1627], [_G1609, _G1612, _G1615]].

これは、論理的な観点からは意味がありません。

これが実際には関係型の純粋な論理述語ではないことは理解してfindall/3いますが、これがここに示されている動作をどのように正当化するのかわかりません。

したがって、私の質問は次のとおりです。

  • この動作が述語に選ばれたのはなぜですか?

  • この動作が実際に私が望むものよりも好ましい一般的な状況はありますか?

  • 私が望む動作で のバージョンを実装する方法はfindall/3?

4

3 に答える 3

4

最後の質問の解決策。

?- setof(X,permutation([A,B,C],X),Z).
Z = [[A, B, C], [A, C, B], [B, A, C], [B, C, A], [C, A, B], [C, B, A]].

sicstus の findall の説明を見ると、

findall(?Template,:Goal,?Bag) ISO Bag は、Prolog によって検出された、Goal のすべての証明における Template のインスタンスのリストです。リストの順序は、証明が見つかった順序に対応します。リストは空の場合があり、すべての変数は存在量化されていると見なされます。これは、findall/3 の各呼び出しが 1 回だけ成功し、Goal 内の変数がバインドされないことを意味します。普遍的に数量化された変数の管理を回避すると、かなりの時間とスペースを節約できます。

したがって、存在量化はfindallのこの望ましくない動作を作成すると思います。

于 2017-06-23T19:31:03.440 に答える
3
?- findall(X, permutation([A,B,C],X), Z), A = 1.

このクエリでは、Prolog はリスト [A,B,C] の要素のすべての順列を見つけますが、Prolog は変数 A、B、C をインスタンス化できないため、得られる匿名変数は次のようになります。

Z = [[_G1669, _G1672, _G1675], [_G1657, _G1660, _G1663], [_G1645, _G1648, _G1651], [_G1633, _G1636, _G1639], [_G1621, _G1624, _G1627], [_G1609, _G1612, _G1615]].

一方、最初に変数 A、B、および C をインスタンス化すると、異なる結果が得られます。

?- A=1, B=2, C=3, findall(X, permutation([A,B,C],X), Z).
A = 1,
B = 2,
C = 3,
Z = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

findall(X, permutation([A,B,C],X), Z), A = 1.これは、Prolog が最初に条件を解決しようとするため、findall(X, permutation([A,B,C],X), Z)以前はクエリで発生しませんでした。A = 1

于 2017-06-23T19:30:47.657 に答える