2

我知道这里有题目的标题:反映人们坐在圆桌旁的序言程序

但我需要一个不同的解决方案,更简单。

所以我有这个问题,4个人围坐在一张方桌旁。

我们知道他们的名字。有人是骨科医生,有人是牙医,有人是外科医生,有人是儿科医生。

我们有一个知识库,您将在代码中看到。

我们必须找到儿科医生的名字。

我的程序找到了它,但没有打印代表桌子上座位的列表的所有四种可能组合。

table(List):-
    length(List,4),
    member(convive(argiro,_,female),List),
    member(convive(georgia,_,female),List),
    member(convive(basilis,_,male),List),
    member(convive(dimitris,_,male),List),
    left(convive(_,dentist,_),convive(argiro,_,female),List),
    oppo(convive(_,surgeon,_),convive(basilis,_,male),List),
    next(convive(georgia,_,female),convive(dimitris,_,male),List),
    left(convive(_,_,female),convive(_,orthopedist,_),List),
    member(convive(_,pediatrecian,_),List).

left(X,Y,ConLs):-append(_,[X,Y|_],ConLs).

left(X,Y,ConLs):-prefix(X,ConLs),last(ConLs,Y).

next(X,Y,ConLs):-left(X,Y,ConLs).

next(X,Y,ConLs):-append(_,[Y,X|_],ConLs).

next(X,Y,ConLs):-prefix(Y,ConLs),last(ConLs,X).

oppo(X,Y,ConLs):-next(X,Z,ConLs),next(Z,Y,ConLs),X\==Y.

在终端上我得到:

?- 表(列表),成员(convive(姓名,儿科,_),列表)。

列表 = [convive(basilis, 牙医, 男性), convive(argiro, 儿科医师, 女性), convive(格鲁吉亚, 外科医生, 女性), convive(dimitris, 骨科医生, 男性)], Name = argiro ;

列表 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科,女性)],名称 = argiro;

错误的。

如您所见,我得到了名字,但只有 2 个可能的列表代表每个人的座位。还应该有:

List = [convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科,女性),convive(格鲁吉亚,外科医生,女性)]

List = [convive(argiro, 儿科医师, 女性), convive(格鲁吉亚, 外科医生, 女性), convive(dimitris, 骨科医生, 男性), convive(basilis, 牙医, 男性)]

我已经使用了线条

left(X,Y,ConLs):-prefix(X,ConLs),last(ConLs,Y).

next(X,Y,ConLs):-prefix(Y,ConLs),last(ConLs,X).

但是,他们什么也没做,如果我删除它们,我会得到相同的结果。

更新

table(List):-
length(List,4),
member(convive(argiro,_,female),List),
member(convive(georgia,_,female),List),
member(convive(basilis,_,male),List),
member(convive(dimitris,_,male),List),
left(convive(_,dentist,_),convive(argiro,_,female),List),
oppo(convive(_,surgeon,_),convive(basilis,_,male),List),
next(convive(georgia,_,female),convive(dimitris,_,male),List),
left(convive(_,_,female),convive(_,orthopedist,_),List),
member(convive(_,pediatrecian,_),List).

left(X,Y,ConLs):-append(_,[X,Y|_],ConLs).

left(X,Y,ConLs):-prefix(X,ConLs),last(ConLs,Y).

next(X,Y,ConLs):-left(X,Y,ConLs);left(Y,X,ConLs).

%next(X,Y,ConLs):-append(_,[Y,X|_],ConLs).

next(X,Y,ConLs):-prefix(Y,ConLs),last(ConLs,X).

%oppo(X,Y,ConLs):-next(X,Z,ConLs),next(Z,Y,ConLs),X\==Y.

oppo(X,Y,[X,_,Y,_]).

oppo(X,Y,[Y,_,X,_]).

oppo(X,Y,[_,X,_,Y]).

oppo(X,Y,[_,Y,_,X]).

所以,oppo/3 似乎在给定的列表上运行良好

?- 表(列表)、oppo(convive(argiro、儿科、女性)、姓名、列表)。

List = [convive(basilis, 牙医, 男性), convive(argiro, 儿科医师, 女性), convive(格鲁吉亚, 外科医生, 女性), convive(dimitris, 骨科医生, 男性)],

姓名 = convive(dimitris, 骨科医生, 男性) ;

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名 = convive(dimitris, 骨科医生, 男性) ;

错误的。


left/3 似乎在做与我首先要解决的事情相同的事情,它适用于 argiro 为 2 且 georgia 为 3 的列表,这是一个简单的情况,但在第二个列表中你可以见上面的 oppo/3 结果,其中 argiro 是第 4 号,georgia 是第 1 号,它应该看到 georgia 再次在 argiro 的左侧,但没有。

?- 表(列表),(convive(argiro,儿科,女性),姓名,列表)。

List = [convive(basilis, 牙医, 男性), convive(argiro, 儿科医师, 女性), convive(格鲁吉亚, 外科医生, 女性), convive(dimitris, 骨科医生, 男性)],

姓名 = convive(格鲁吉亚,外科医生,女性);

错误的。


现在 next/3 返回一些非常令人不安的结果。我不知道该怎么做,我是Prolog的新手。有些还可以,但有些似乎将整个数组作为结果,有些说 List = Name。

前三个结果没问题,第四个和 left/3 一样,它看不到列表中的第一个在最后一个的旁边,所以它返回一个空数组。

这里发生了什么?

?- 表(列表),下一个(convive(argiro,儿科,女性),姓名,列表)。

List = [convive(basilis, 牙医, 男性), convive(argiro, 儿科医师, 女性), convive(格鲁吉亚, 外科医生, 女性), convive(dimitris, 骨科医生, 男性)],

姓名 = convive(格鲁吉亚,外科医生,女性);

List = [convive(basilis, 牙医, 男性), convive(argiro, 儿科医师, 女性), convive(格鲁吉亚, 外科医生, 女性), convive(dimitris, 骨科医生, 男性)],

姓名 = convive(basilis, 牙医, 男性) ;

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名 = convive(basilis, 牙医, 男性) ;

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

名称 = [] ;

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名= [convive(格鲁吉亚,外科医生,女性)];

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性)];

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性)];

列表 = 名称,

姓名 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)];

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

名称 = [] ;

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名= [convive(格鲁吉亚,外科医生,女性)];

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性)];

List = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)],

姓名 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性)];

列表 = 名称,

姓名 = [convive(格鲁吉亚,外科医生,女性),convive(dimitris,骨科医生,男性),convive(basilis,牙医,男性),convive(argiro,儿科医师,女性)];

错误的。

更新

所以我了解到 prefix/2 与字符串一起使用,例如, prefix(x,[x,y,z]).返回 false。这就是它不起作用的原因,这解释了 next/3 中的结果,但我的问题仍然没有解决。

还有其他方法可以让 left 和 next 与列表的第一部分和最后一部分一起工作吗?

4

1 回答 1

0

我敢打赌罪魁祸首是\==in oppo,因为这些谓词在这里以生成方式使用。试着摆脱它。只需手动编码四种可能性就足够了 - 毕竟,您的列表长度固定且非常短:

oppo(X,Y,[X,_,Y,_]).
.....

next/3如果编码为对 . 的两个调用的析取,则更容易/更清晰left/3

left/3其本身而言,您也可以从您ConLs

circle_up(Ls,Circle):- head(A,Ls), append(Ls,[A],Circle).

Circle在一个简单的调用中使用append来完成left/3. 这假设定义

head(A,L):- L=[A|_].
于 2017-05-29T11:30:40.513 回答