假设我有一个谓词,用于查看某人是否有姐妹。
在我看来,有两种可能性:
1)有人使用sister(X,Y),所以用户想要所有与他们的姐妹在一起的人的列表。2)有人使用sister( person,Y),因此用户希望看到该用户的所有姐妹。
那么结果也可以是以下三种可能性之一:
1)找到了一个答案。2)找到多个答案。2)一无所获。
现在我可以用Prolog (伪代码)来做这件事了。
如果X和Y没有被替换并且找到了多个答案,则打印这个"All the sisters pair are“否则如果X和Y没有被替换并且找到一个答案,则打印这个”唯一的姐妹对是“否则如果X被替换并且找到了多个答案,则打印”Person1的姐妹是“
所以,这将是一个非常大的假设。有没有更干净的方法来处理这个问题?
罗洛夫
编辑1:
我是这样想的:
display_sisters(X,Y) :-
var(X),
var(Y),
setof (x-y,sisters_of(X,Y),Sisters),
<<check if Sisters is non-empty>>>
write "The sisters are" ,
<<print answers>>
display_sisters(X,Y) :-
var(X),
var(Y),
setof (x-y,sisters_of(X,Y),Sisters),
<<check if Sisters is empty>>>
write "There are no sisters" ,
发布于 2014-03-22 05:16:28
不,当没有答案或重复时,您会忘记说明要打印什么。
你的需求是非常具体的,代码会被细节搞得乱七八糟。一些Prolog提供了portray/1,但您应该将其应用于列表...
可以是通用的(使用setof/3以避免重复)
print_answers(Query, One, More, None) :-
Query =.. [Functor, A1, A2],
( nonvar(One) ; One = 'The only ~s of ~w is ~w' ),
( nonvar(More) ; More = 'All the ~ss pairs are ~w' ),
( nonvar(None) ; None = 'None ~s found' ),
( setof(A1-A2, Query, Answers)
-> ( Answers = [_]
-> format(One, [Functor, A1, A2])
; format(More, [Functor, Answers])
)
; format(None, [Functor])
).
这就产生了
sister(a,b).
sister(a,c).
?- print_answers(sister(a,X),_,_,_).
All the sisters pairs are [a-b,a-c]
?- print_answers(sister(a,b),_,_,_).
The only sister of a is b
但是imho不值得你去努力...
发布于 2014-03-22 20:50:57
如果我没理解错的话,你是在寻找非常具体的语言,并根据条件显示结果。@CapelliC的答案是使用format
和Prolog "if-then-else“模式将结果压缩成最简洁的谓词。
这里有一个稍微冗长的解决方案,没有使用format
,但使用了后面解释的"if-then-else“模式。也许这将使您朝着正确的方向迈出一步,但在您有机会研究了Prolog format
如何工作之后,请重新考虑@CapelliC的解决方案,以获得更一般的处理方法(可用于各种兄弟谓词)。(format
很像C中的printf
,但格式化符号不同。)
% Display all sister pairs
%
display_sisters(X, Y) :-
var(X), var(Y),
setof(X-Y, sisters_of(X, Y), Sisters),
length(Sisters, Number),
( Number =:= 0
-> write('No one has a sister')
; ( Number =:= 1
-> write('The only person with sister is: '),
write(Sisters)
; write('All the persons with sisters are: '),
write(Sisters)
)
), nl.
% Display sisters of a given person
%
display_sisters(X, Y) :-
nonvar(X), var(Y),
setof(Y, sisters_of(X, Y), Sisters),
length(Sisters, Number),
( Number =:= 0
-> write('Person '), write(X), write(' has no sister')
; ( Number =:= 1
-> write('The only sister '), write(X), write(' has is '),
write(Sisters)
; write('All of '), write(X), write('''s sisters are: '),
write(Sisters)
)
), nl.
这使得Prolog中的"if-then-else“结构得到了大量的使用。它可能没有它也可以完成,但它会变得更加冗长和有点麻烦。"if-then-else“有助于精简逻辑。
构造:
P1 -> P2.
将查询P1
,如果成功,则查询P2
。否则,它将失败。结合Prolog中的OR (;
),您可以执行"if-then-else":
P1 -> P2 ; P3.
如果P1
成功,则Prolog将继续执行P2
查询。否则,P1 -> P2
将失败,它将执行P3
(由于OR,;
)。由于运算符的优先级,如果在此构造中或其周围有多个语句,则需要使用括号。,
的优先级高于;
,;
高于->
。因此,更详细的模式将如下所示:
P1,
P2,
( P3 % Start of the if-then-else : P3 is the condition
-> P4, % P4, P5 are both in the true leg due to precedence of ','
P5
; P6, % P6, P7 are both the false leg due to precedence of ','
P7
),... % End of the if-then-else
在为答案显示的代码中,有另一个if-then-else作为"false“分支,因此它只有自己的分组:
...
( P1 % The condition
-> P2 % 'true' branch is P2
; ( P3 % 'false' branch is another if-then-else pattern
-> P4
; P5,
P6
)
)
当你想在Prolog中做更复杂的事情时,你需要学习它的其他内置功能("if-then-else",=../2
,format
等)。如果你通过@CapelliC的答案学习和工作,你会学到更多关于Prolog的知识。
https://stackoverflow.com/questions/22568157
复制相似问题