Prolog,如何在write()中显示多个输出

时间:2011-09-08 14:11:15

标签: prolog

go :-   match(Mn,Fn),
        write('--Matching Result--'),
        nl,
        write(Mn),
        write(' match with '),
        write(Fn),
        match(Mn1,Fn1).


person(may,female,25,blue).
person(rose,female,20,blue).
person(hock,male,30,blue).
person(ali,male,24,blue).
match(Mn,Fn):-person(Fn,'female',Fage,Fatt),
person(Mn,'male',Mage,Matt),
Mage>=Fage,
Fatt=Matt.

嗨,这是我的代码...但它只能显示1个输出...但匹配中有3对匹配(X,Y)。如何在我的go函数中显示它们。

谢谢

3 个答案:

答案 0 :(得分:11)

如果您强制回溯,通常输入;(例如在SWI Prolog中),您就可以获得所有匹配。但是你也看到你得到了不必要的输出true。这是因为go中的最后一个条款是match(Mn1,Fn1)。该子句成功执行三次并绑定变量Mn1,Fn1,但只输出true,因为在该子句之后没有write()。第四次match(Mn1,Fn1)失败,通过回溯,你回到匹配的第一个句子match(Mn,Fn),输出匹配等。

您肯定不希望出现此行为。您应该删除match(Mn1,Fn1)中的最后一个条款go。现在,按;即可获得3个匹配,而中间没有任何输出true

但你可能想要的是该程序进行回溯。要实现这一点,您只需要通过添加false作为最后一个句子来强制回溯。要获得正确的输出格式,请使用以下程序。最后一句go2.被添加到最后获得true

go2 :- write('--Matching Result--'), nl,
    match(Mn,Fn),
    write(Mn), write(' match with '), write(Fn), nl,
    fail.
go2.

此技术称为故障驱动循环

答案 1 :(得分:3)

如果您有任何谓词有多个结果且想要查找所有结果,则应使用findall/3

例如,在您的情况下,您可以执行以下操作:

findall([X,Y], match(X,Y),L).

L将是一个列表,其中包含以[X,Y]格式满足匹配(X,Y)的所有X,Y。 例如,假设:

match(m1,f1).
match(m2,f2).

结果将是L = [[m1,f1],[m2,f2]]

请注意,您可以根据需要定义格式,例如您可以写:

findall(pair(X,Y), match(X,Y), L).
L = [ pair(m1,f1), pair(m2,f2) ]

findall( X, match(X,Y), L).
L = [ m1, m2]

findall( 42, match(X,Y), L).
L = [42, 42]

然后你必须在列表上递归才能打印出来。

但是,如果你想找到一个结果,运行一些代码,然后继续你可以使用forall / 2:

forall(match(X,Y), my_print(X,Y).

答案 2 :(得分:-1)

Prolog是一种懒惰的语言。这意味着一旦找到使问题成立的条件,它就会停止。这将是第一场比赛。

如果您的代码正在运行(我还没有尝试过),那么您应该尝试在prolog检查器中运行match - 这样的语句:match(X,Y)

prolog检查员将返回所有状态并为您打印。