我对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).
我很感激一些提示。 (隐藏的谓词名称和功能以防止剽窃)
答案 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.
这样,您就可以使用订购来构建您的牌手,这样您就不会有任何重复。由于您不关心订单是什么,因此订购特定订单不会影响要求并提供建立唯一性的方法。