简体   繁体   English

列表中的Prolog唯一值

[英]Prolog unique value in list

I learing Prolog language for exam at college and I don't know how to create function which: check unique values in list. 我在大学期间使用Prolog语言进行考试,但我不知道如何创建函数:检查列表中的唯一值。 I mean, if each value in list are unique function return true, otherwise return false. 我的意思是,如果列表中的每个值都是唯一函数,则返回true,否则返回false。 eg. 例如。

[1,2,3,5] - true
[1,2,2,4] - false

Header for this function is uniqueValues(X) X - mean list. 该函数的标题是uniqueValues(X)X-均值列表。 I really don't know this language and if anyone can explain me how to create this function will be great. 我真的不懂这种语言,如果有人可以向我解释如何创建此功能,那将是很好的。 Thanks in advence for help 感谢您的帮助

Not knowing Prolog, this is going to be a bit of a haul, but let's give it a shot. 不了解Prolog,这有点麻烦,但是让我们尝试一下。 In Prolog, functions work by recursion rather than iteration. 在Prolog中,函数通过递归而不是迭代来工作。 For list processing, this means (in general) you have to decide how to handle the empty list and how to handle an element in front of some other list. 对于列表处理,这通常意味着您必须决定如何处理空列表以及如何处理其他列表前面的元素。 So first, you need to make a decision about the empty list. 因此,首先,您需要对空白列表做出决定。

unique([]).

This says "empty lists are unique." 这说“空列表是唯一的”。 This is a helpful property. 这是一个有用的属性。

The recursive case assumes that you already know how to handle the rest of the list. 递归情况假设您已经知道如何处理列表的其余部分。 In "ordinary" recursive list processing predicates like this, you tend to have this kind of structure: 在像这样的“普通”递归列表处理谓词中,您倾向于具有这种结构:

foo([X|Xs]) :- /* do something with X */, foo(Xs).

The foo(Xs) there is saying, "and run this same thing on whatever's left." 那里的foo(Xs)说,“然后在剩下的任何东西上运行同样的东西。” So the question we have to ask is, how do we know if a list that starts with X and ends with Xs is unique? 因此,我们要问的问题是,如何知道以X开头和以Xs结尾的列表是否唯一? Well, we can make sure that X is unique my ensuring it doesn't occur else where in the list. 好吧,我们可以确保X是唯一的,并确保它不会出现在列表中的其他位置。 Like this: 像这样:

unique([X|Xs]) :- \+ memberchk(X, Xs).

Consider your example [1,2,3,4] . 考虑您的示例[1,2,3,4] The first time in, X = 1 and Xs = [2,3,4]. 第一次进入,X = 1,Xs = [2,3,4]。 \\+ means "not" in Prolog, and memberchk/2 tells you whether something is in a list. \\+在Prolog中表示“不是”, memberchk/2告诉您列表中是否包含某些内容。 So memberchk(1, [2,3,4]) will fail and the \\+ will turn that failure into success. 因此memberchk(1, [2,3,4])将失败,而\\+会将失败变为成功。 This is good! 很好! Also, with [1,2,1] , X will equal 1 and Xs will equal [2,1], the memberchk/2 will succeed, and then be negated into a failure. 同样,对于[1,2,1] ,X等于1,Xs等于[2,1], memberchk/2将成功,然后被否定为失败。 This is probably what we want! 这可能就是我们想要的!

Putting that together with the recursive call, you get this for the entire predicate: 将其与递归调用结合在一起,就可以得到整个谓词:

unique([]).
unique([X|Xs]) :- \+ memberchk(X, Xs), unique(Xs).
  1. Empty lists are unique. 空列表是唯一的。
  2. Lists that are not empty ([X|Xs]) are unique if: 在以下情况下,不为空的列表([X | Xs])是唯一的:
    1. Xs does not contain X, and Xs不包含X,并且
    2. Xs is also unique Xs也很独特

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM