在prolog中绑定无序列表

时间:2017-02-23 03:33:28

标签: prolog swi-prolog

我对prolog有些新意,我正在试图找出如何在订单无关紧要时实现对列表元素的绑定。我在我的代码的最后几行中演示了这一点。这样做似乎微不足道,但它无法结合。

fh(Hand) :-
   is_card(R, _, C1),
   is_card(R, _, C2),
   is_card(R, _, C3),
   C1 \== C2,
   C2 \== C3,
   C1 \== C3,

   is_card(RR, _, D1),
   is_card(RR, _, D2),
   R \= RR,
   D1 \== D2,
   is_set(Hand),
   list_to_set([C1,C2,C3,D1,D2], Hand).

我很感激一些提示。 (隐藏的谓词名称和功能以防止剽窃)

2 个答案:

答案 0 :(得分:0)

阅读库(列表)中提供的文档,似乎对于您的用例,最好将一个集合表示为一个没有重复的排序列表,使用sort/2

这是我得到的:

?- A = [2,3,1],
   B = [1,1,2,3,2,3],
   sort(A, S),
   sort(B, S).
A = [2, 3, 1],
B = [1, 1, 2, 3, 2, 3],
S = [1, 2, 3].

sort(A, S)将确保S是一个与A具有相同元素的有序列表,sort(B, S)将确保如果从B创建一个集合,则它与A相同。

我发现is_set/1的实施可能与length(Set, Lenght), sort(Set, Sorted), length(Sorted, Len).相同,但我无法找到'$skip_list'的定义。但我明白了:

?- '$skip_list'(Len, [2,3,1], Tail).
Len = 3,
Tail = [].

答案 1 :(得分:0)

你可以用更严格的条件构建你的手,通过在它们上面下订单来建立独特的元素,而不仅仅是检查它们是不同的:

fh(Hand) :-
   is_card(R, _, C1),
   is_card(R, _, C2),
   is_card(R, _, C3),
   C1 @< C2,
   C2 @< C3,

   is_card(RR, _, D1),
   is_card(RR, _, D2),
   dif(R, RR),
   D1 @< D2.

这样,您就可以使用订购来构建您的牌手,这样您就不会有任何重复。由于您不关心订单是什么,因此订购特定订单不会影响要求并提供建立唯一性的方法。