Prolog 如何处理一个谓词和多个答案?
假设我有一个谓词,用来判断某人是否有姐妹 在我看来,还有两种可能性: 1) 有人使用sister(X,Y),因此用户需要一个所有与其姐妹在一起的人的列表。 2) 某人使用sister(Person,Y),因此用户希望看到该人的所有姐妹 那么结果也可以是三种可能性之一: 1) 找到了一个答案。 2) 找到了多个答案。 2) 什么也没找到 现在我可以在Prolog(伪代码)中实现这一点 如果X和Y不存在,并且找到了多个答案,则打印“所有姐妹对都存在” 其他的 如果X和Y不存在,并且找到了一个答案,则打印“这对中唯一的姐妹是” 否则,如果X被替换并找到多个答案,则打印“1个人的姐妹是” 所以,这将是一个非常大的如果。 有没有更干净的方法来处理这个问题 罗洛夫 编辑1: 我这样想:Prolog 如何处理一个谓词和多个答案?,prolog,Prolog,假设我有一个谓词,用来判断某人是否有姐妹 在我看来,还有两种可能性: 1) 有人使用sister(X,Y),因此用户需要一个所有与其姐妹在一起的人的列表。 2) 某人使用sister(Person,Y),因此用户希望看到该人的所有姐妹 那么结果也可以是三种可能性之一: 1) 找到了一个答案。 2) 找到了多个答案。 2) 什么也没找到 现在我可以在Prolog(伪代码)中实现这一点 如果X和Y不存在,并且找到了多个答案,则打印“所有姐妹对都存在” 其他的 如果X和Y不存在,并且找到了一个答案,则
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" ,
显示(X,Y):-
var(X),
var(Y),
集合(x-y,姐妹(x,y),姐妹),
>
写“姐妹们是”,
显示姐妹(X,Y):-
var(X),
var(Y),
集合(x-y,姐妹(x,y),姐妹),
>
写“没有姐妹”,
没有,而且当没有答案或重复答案时,您会忘记说要打印什么
您的需求非常具体,代码会被细节弄得乱七八糟。
有些序言使/1可用,但您应该将其应用于列表
可以是通用的(使用setof/3避免重复)
这就产生了
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不值得付出努力…如果我正确理解了这个问题,那么您将根据条件寻找非常具体的语言和结果显示@Capelical的答案是使用
格式和序言“if-then-else”模式将结果压缩成最简洁的谓词
这里有一个更详细的解决方案,不使用格式
,而是使用后面解释的“if-then-else”模式。也许这将使您朝着正确的方向迈出一步,但在您有机会研究Prolog格式的工作原理之后,请重新考虑@capelical的解决方案,以获得更一般的处理方法(可用于各种同级谓词)。(format
与C中的printf
非常相似,但格式化符号不同。)
这在Prolog中大量使用了“if-then-else”构造。也许没有它也可以完成,但它会变得更加冗长和有点麻烦。“if-then-else”有助于浓缩逻辑
结构:
P1 -> P2.
将查询P1
,如果成功,则查询P2
。否则,它将失败。结合Prolog中的OR(;
),可以执行“if-then-else”:
如果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”,“if-then-else”,“code>=../2
,格式
,等等)。如果你通过@capelical的答案学习和工作,你会学到更多关于Prolog的知识。你说的“substained”是指“实例化”吗?是的,很抱歉我弄糊涂了。我认为答案是可行的,但我是一个初学者,这个脚本是远远超过我可以咀嚼。
P1 -> P2 ; P3.
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
...
( P1 % The condition
-> P2 % 'true' branch is P2
; ( P3 % 'false' branch is another if-then-else pattern
-> P4
; P5,
P6
)
)