Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 如何处理一个谓词和多个答案?_Prolog - Fatal编程技术网

Prolog 如何处理一个谓词和多个答案?

Prolog 如何处理一个谓词和多个答案?,prolog,Prolog,假设我有一个谓词,用来判断某人是否有姐妹 在我看来,还有两种可能性: 1) 有人使用sister(X,Y),因此用户需要一个所有与其姐妹在一起的人的列表。 2) 某人使用sister(Person,Y),因此用户希望看到该人的所有姐妹 那么结果也可以是三种可能性之一: 1) 找到了一个答案。 2) 找到了多个答案。 2) 什么也没找到 现在我可以在Prolog(伪代码)中实现这一点 如果X和Y不存在,并且找到了多个答案,则打印“所有姐妹对都存在” 其他的 如果X和Y不存在,并且找到了一个答案,则

假设我有一个谓词,用来判断某人是否有姐妹

在我看来,还有两种可能性:

1) 有人使用sister(X,Y),因此用户需要一个所有与其姐妹在一起的人的列表。 2) 某人使用sister(Person,Y),因此用户希望看到该人的所有姐妹

那么结果也可以是三种可能性之一:

1) 找到了一个答案。 2) 找到了多个答案。 2) 什么也没找到

现在我可以在Prolog(伪代码)中实现这一点

如果X和Y不存在,并且找到了多个答案,则打印“所有姐妹对都存在” 其他的 如果X和Y不存在,并且找到了一个答案,则打印“这对中唯一的姐妹是” 否则,如果X被替换并找到多个答案,则打印“1个人的姐妹是”

所以,这将是一个非常大的如果。 有没有更干净的方法来处理这个问题

罗洛夫

编辑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" , 
显示(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
   )
)