我无法理解这个与prolog有关的问题。才开始,但我似乎无法找到一种方法来确定一个对象是否是唯一的。继承我的代码:
/* (Student Name, Student Number)*/
Student(stuart, 11234).
Student(ross, 11235).
Student(rose, 11236).
Student(stuart, 11237).
我怎样才能知道学生是否独一无二。以斯图尔特为例,有两名学生名叫斯图尔特,因此斯图尔特并不是独一无二的。我怎么能写一个程序来判断它的另一个学生是否叫斯图尔特。
我已经尝试过花了这么多时间,但我似乎无法理解与最初的斯图尔特而不是其他斯图亚特打交道,因为我无法排除我试图找出的那个如果它的独特之处。
感谢您的帮助。
答案 0 :(得分:2)
可能有很多方法可以解决这个问题,但我会这样做:
% a student has a name and a number
student(stuart, 11234).
student(ross, 11235).
student(rose, 11236).
student(stuart, 11237).
此代码显示“查找与姓名学生人数相同的列表”,然后“使计数与列表长度相同”:
% for every student name there is an associated count of how many times
% that name appears
number_students(Name, Count) :-
findall(_, student(Name, _), Students),
length(Students, Count).
只有number_students为1:
时,此谓词才会成立% a student name is unique (appears once and only once) is the
% number_students count is 1
unique_student(Name) :-
number_students(Name, 1).
测试:
12 ?- unique_student(ross).
true.
13 ?- unique_student(rose).
true.
14 ?- unique_student(bob).
false.
15 ?- unique_student(stuart).
false.
这是一个解决问题的简单方法,但它不是一个伟大的 Prolog解决方案,因为你不能说“给我一个独特的学生名字”这样的东西,并获得所有的独特的名字。
答案 1 :(得分:2)
使用您的数据库示例,可以执行
unique(S) :-
student(S, N), \+ (student(S, M), M \= N).
因为它产生
?- unique(S).
S = ross ;
S = rose ;
false.
通常,Prolog的目标是解决方案的存在。然后关于基数的预测需要来自“不纯”的支持。该语言的一部分:nb_setarg当我们需要有效跟踪基数时,它是我们最好的朋友。
使用这样的metapredicate:
%% count_solutions(+Goal, ?C)
%
% adapted from call_nth/2 for http://stackoverflow.com/a/14280226/874024
%
count_solutions(Goal, C) :-
State = count(0, _), % note the extra argument which remains a variable
( Goal,
arg(1, State, C1),
C2 is C1 + 1,
nb_setarg(1, State, C2),
fail
; arg(1, State, C)
).
:- meta_predicate count_solutions(0, ?).
你可以在不考虑第二个参数的情况下解决问题
unique(S) :-
student(S, _), count_solutions(student(S, _), 1).
同一个谓词可以使用库(聚合)中的aggregate_all(count,student(S,_),1),但是这样的库目前在内部构建一个列表,那么你可以认为Peter的答案更容易实现。 / p>
答案 2 :(得分:1)
您对代码的一些评论。这不是事实:
Student(Ross).
这是两个不同的事实(至少在SWI-Prolog中):
student(ross).
student('Ross').
换句话说,谓词名称必须以小写字母开头,以大写字母开头的标识符表示变量,而不是原子。您可以将任何字符串放在单引号中,使其成为有效的原子。
现在已经解决了这个问题,目前还不清楚你的目标是什么。你和你这个独特的学生有什么关系?你怎么知道第一个是你正在寻找的那个,而不是第二个?为什么不使用学号呢(至少在你的例子中,两个Stuarts似乎有不同的数字)?