给定知识库的 Prolog 难题 - 不工作
Prolog puzzle with given Knowledge Base - Not Working
我知道这里有主题标题:A prolog program that reflects people sitting at a round table
但我需要一个不同的解决方案,更简单。
所以我遇到了这个问题,4 个人坐在一个正方形周围 table。
我们知道他们的名字。
有人是骨科医生,有人是牙医,有人是外科医生,有人是儿科医生。
我们有一个知识库,您将在代码中看到它。
而且我们必须找到儿科医生的名字。
我的程序找到了它,但没有打印代表 table 上的座位的列表的所有四种可能组合。
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.
在终端上我得到:
?- table(List),member(convive(Name,pediatrecian,_),List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = argiro ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = argiro ;
false.
如您所见,我得到了名字,但只有 2 个可能的列表代表每个人的座位。还应该有:
List = [convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female)]
List = [convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)]
我用过台词
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 似乎在给定的列表上运行良好
?- table(List), oppo(convive(argiro,pediatrecian,female),Name,List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(dimitris, orthopedist, male) ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = convive(dimitris, orthopedist, male) ;
false.
left/3 似乎在做我首先要解决的同样的事情,它在 argiro 为 2 且 georgia 为 3 的列表中起作用,这是一个简单的情况, 但是在上面 oppo/3 结果中可以看到的第二个列表中,argiro 是第 4 位,georgia 是第 1 位,它应该看到 georgia 再次位于 argiro 的左侧,但没有。
?- table(List), left(convive(argiro,pediatrecian,female),Name,List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(georgia, surgeon, female) ;
false.
现在 next/3 returns 一些非常令人不安的结果。我不知道该怎么做,我是 Prolog 的新手。有些没问题,但有些似乎将整个数组作为结果,有些说 List = Name.
前三个结果还可以,第四个和left/3一样,看不到列表中的第一个紧挨着最后一个所以它 returns 一个空数组。
这里发生了什么?
?- table(List), next(convive(argiro,pediatrecian,female),Name,List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(georgia, surgeon, female) ;
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(basilis, dentist, male) ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = convive(basilis, dentist, male) ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)] ;
List = Name,
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)] ;
List = Name,
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)] ;
false.
更新
所以我了解到 prefix/2 适用于字符串,例如,
prefix(x,[x,y,z]).
returns 错误。
这就是它不起作用的原因,这解释了 next/3 中的结果,但我的问题仍然没有解决。
还有其他方法可以使 left 和 next 与列表的第一部分和最后一部分一起工作吗?
我敢打赌罪魁祸首是 oppo
中的 \==
,因为这些谓词在这里以生成方式使用。尝试摆脱它。只需手动编码四种可能性就足够了——毕竟你的列表是固定长度的,而且非常短:
oppo(X,Y,[X,_,Y,_]).
.....
next/3
如果编码为对 left/3
.
的两次调用的析取,则更容易/更清晰
对于 left/3
本身,您还可以通过
从您的 ConLs
围成一个圆圈
circle_up(Ls,Circle):- head(A,Ls), append(Ls,[A],Circle).
并在对 append
的一次简单调用中使用 Circle
来完成 left/3
的定义。这假设定义
head(A,L):- L=[A|_].
我知道这里有主题标题:A prolog program that reflects people sitting at a round table
但我需要一个不同的解决方案,更简单。
所以我遇到了这个问题,4 个人坐在一个正方形周围 table。
我们知道他们的名字。 有人是骨科医生,有人是牙医,有人是外科医生,有人是儿科医生。
我们有一个知识库,您将在代码中看到它。
而且我们必须找到儿科医生的名字。
我的程序找到了它,但没有打印代表 table 上的座位的列表的所有四种可能组合。
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.
在终端上我得到:
?- table(List),member(convive(Name,pediatrecian,_),List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)], Name = argiro ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)], Name = argiro ;
false.
如您所见,我得到了名字,但只有 2 个可能的列表代表每个人的座位。还应该有:
List = [convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female)]
List = [convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)]
我用过台词
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 似乎在给定的列表上运行良好
?- table(List), oppo(convive(argiro,pediatrecian,female),Name,List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(dimitris, orthopedist, male) ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = convive(dimitris, orthopedist, male) ;
false.
left/3 似乎在做我首先要解决的同样的事情,它在 argiro 为 2 且 georgia 为 3 的列表中起作用,这是一个简单的情况, 但是在上面 oppo/3 结果中可以看到的第二个列表中,argiro 是第 4 位,georgia 是第 1 位,它应该看到 georgia 再次位于 argiro 的左侧,但没有。
?- table(List), left(convive(argiro,pediatrecian,female),Name,List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(georgia, surgeon, female) ;
false.
现在 next/3 returns 一些非常令人不安的结果。我不知道该怎么做,我是 Prolog 的新手。有些没问题,但有些似乎将整个数组作为结果,有些说 List = Name.
前三个结果还可以,第四个和left/3一样,看不到列表中的第一个紧挨着最后一个所以它 returns 一个空数组。
这里发生了什么?
?- table(List), next(convive(argiro,pediatrecian,female),Name,List).
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(georgia, surgeon, female) ;
List = [convive(basilis, dentist, male), convive(argiro, pediatrecian, female), convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)],
Name = convive(basilis, dentist, male) ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = convive(basilis, dentist, male) ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)] ;
List = Name,
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male)] ;
List = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)],
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male)] ;
List = Name,
Name = [convive(georgia, surgeon, female), convive(dimitris, orthopedist, male), convive(basilis, dentist, male), convive(argiro, pediatrecian, female)] ;
false.
更新
所以我了解到 prefix/2 适用于字符串,例如,
prefix(x,[x,y,z]).
returns 错误。
这就是它不起作用的原因,这解释了 next/3 中的结果,但我的问题仍然没有解决。
还有其他方法可以使 left 和 next 与列表的第一部分和最后一部分一起工作吗?
我敢打赌罪魁祸首是 oppo
中的 \==
,因为这些谓词在这里以生成方式使用。尝试摆脱它。只需手动编码四种可能性就足够了——毕竟你的列表是固定长度的,而且非常短:
oppo(X,Y,[X,_,Y,_]).
.....
next/3
如果编码为对 left/3
.
对于 left/3
本身,您还可以通过
ConLs
围成一个圆圈
circle_up(Ls,Circle):- head(A,Ls), append(Ls,[A],Circle).
并在对 append
的一次简单调用中使用 Circle
来完成 left/3
的定义。这假设定义
head(A,L):- L=[A|_].