2013-03-09 93 views
0

我只是无法理解我与prolog有关的这个问题。只是刚刚开始,但我似乎无法找到一种方法来查明对象是否是唯一的。继承人我的代码:我怎么知道一个对象是否是唯一的

/* (Student Name, Student Number)*/ 
Student(stuart, 11234). 
Student(ross, 11235). 
Student(rose, 11236). 
Student(stuart, 11237). 

我怎么能找出一个学生是否是独一无二的。以Stuart为例,有两个学生叫Stuart,所以Stuart并不是唯一的。我怎么能写一个程序来判断另一个学生是否叫斯图尔特。

我试过在这上面花了这么多小时,但我似乎无法控制原来的斯图尔特而不是其他斯图尔特,因为我不能排除我正在寻找的那个如果其独特的话。

感谢您的帮助。

回答

2

与数据库例如,这可以做

​​

,因为它产生

?- 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(计数,学生(S,_) 1)来自库(集合),但是这个库目前在内部建立一个列表,那么你可以考虑彼得的答案更容易实现。

+0

谢谢,我敢肯定,这是一种方法来做到这一点\ +,但我想你的解决方案处理它罚款:) – user1816481 2013-03-13 16:23:34

1

关于你的代码的一些评论。这不是一个事实:

Student(Ross). 

这是两个不同的事实(在SWI-Prolog的,至少):

student(ross). 
student('Ross'). 

换句话说,谓词名称必须以小写字母开始,标识出发用大写字母表示变量,而不是原子。您可以将任何字符串放在单引号中,使其成为有效的原子。

现在,这是不利的,目前还不清楚你的目标是什么。你将如何处理你的独特的学生?你怎么知道第一个是你正在寻找的那个,而不是第二个?为什么不使用学生号码(至少在你的例子中两个斯图尔特似乎有不同的数字)?

+0

感谢您抽出一些时间来解决我的问题。是的,你说我的代码无效。这只是一个如何做独特的事情的例子。我想知道你是否可以用一种方式来表示学生是否独一无二。是的,我可以使用学生号码,但我真的很想知道一种方式,我可以告诉别人是否是独一无二的。我将要对独特的学生做什么,告诉它是否唯一 – user1816481 2013-03-09 17:56:24

2

可能有相当多的解决这个问题的方法,但我会做这种方式:

% a student has a name and a number 
student(stuart, 11234). 
student(ross, 11235). 
student(rose, 11236). 
student(stuart, 11237). 

这段代码说“找一个列表的长度相同的学生姓名的号码”,然后“让伯爵一样的列表的长度”:

% a student name is unique (appears once and only once) is the 
% number_students count is 1 
unique_student(Name) :- 
    number_students(Name, 1). 
012:

% 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此谓词只会是真实的

测试:

12 ?- unique_student(ross). 
true. 

13 ?- unique_student(rose). 
true. 

14 ?- unique_student(bob). 
false. 

15 ?- unique_student(stuart). 
false. 

这是解决问题的一种简单的方法,但因为你不能说这样的话是不是很大 Prolog的解决方案“给我一个独特的学生姓名”,并得到一个列表所有独特的名字。

+0

+1 @CapelliC答案。这比我的好多了! – 2013-03-10 12:16:13

+0

虽然仍然是一个很好的答案,感谢您的帮助:) – user1816481 2013-03-13 16:23:59

相关问题