纯序言中的目标顺序

Order of Goals in Pure Prolog

我对序言还很陌生。据我所知,Pure Prolog 仅限于 Horn 子句。 这是一个非常简单的序言程序 -

 % student( Snr    , FirstName , LastName   , Semester ).
  student(  1000  , 'Anna'    , 'Arm'      , 'ti2'    ) .
  student(  1001  , 'Rita'    , 'Reich'    , 'ti2'    ) .
  student(  1002  , 'Peter'   , 'Reich'    , 'ti2'    ) .
  student(  1003  , 'Peter'   , 'Petersen' , 'ti7'    ) .


% course( Semester , Course     ) .
  course( 'ti2'    , 'Mathe2'   ) .
  course( 'ti2'    , 'Physics2' ) .
  course( 'ti7'    , 'pdv2'     ) .

 musttake(M,V,N,S,C) :- student(M,V,N,S),  course(S,C).

musttakereverse(M,V,N,S,C) :- course(S,C), student(M,V,N,S).

我的大学幻灯片说,即使我们在 Pure Prolog 的规则中颠倒目标的顺序,结果的顺序也不应该改变。在上面的代码中,我实现了 2 个规则。 musttakemusttakereverse 其中我只是改变了目标的顺序。因此,根据幻灯片,运行ning 时结果的顺序不应更改。 但是,当我 运行 代码时,它们以不同的顺序给出结果。(根据我的理解,上面的程序在 pure prolog 中)。

所以,我想知道

是不是真的

Change of orders in Goal does not change the order of the result in Pure Prolog code.

谢谢!

你是对的。

如果您使用查询

?-musttake(M,V,N,S,C).

目标student(M,V,N,S)通过第一个事实得到满足,然后course(S,C)通过第5个事实得到满足。如果我们跟踪 M 的演变,它将具有 1000 的值。

下一个可能的答案将来自调查最后一个 回溯点,它位于course(S,C)不是student(M,V,N,S)。通过第 6 个事实改变了 C 的值,但 M 的值没有改变,所以在第二个解决方案中 M 仍然是 1000。

如果您使用其他查询:

 ?-musttakereverse(M,V,N,S,C)

目标 course(S,C) 通过第 5 个事实得到满足,然后 目标 student(M,V,N,S) 通过第一个事实得到满足,这再次给出M取值1000,但下一个解法调查最后一个回溯点,也就是这次student(M,V,N,S),使用第2个事实,M取值为1001

Prolog 使用深度优先搜索并从上到下和从左到右对子句和目标进行排序,我只能假设您的幻灯片包含错字。 您可以阅读有关子句和目标排序的更多信息 here

这是一个最小的例子来说明 "order of the result",即生成的答案替换的顺序受子句中目标顺序的影响:

p(X) :- p123(X), p321(X), p213(X).

p123(1). p123(2). p123(3).

p321(3). p321(2). p321(1).

p213(2). p213(1). p213(3).

请注意,所有四个谓词都描述了完全相同的一组解决方案。在这种情况下,p/1 的精确顺序由第一个目标决定。

目标的顺序不影响解决方案的集合。那才是最有意思的属性.

最有趣的属性可能无法保留的是终止。通过交换目标,终止属性可能会受到影响。

然后,还有另一个保留的 属性,我承认,这不是很有趣:冗余 answers/solutions 的存在也被保留了。