不要回溯单一论点

时间:2013-12-17 19:52:48

标签: prolog

我有一个谓词,给定一个列表,为这个列表创建一个分区(即它分成两部分)。因此,该谓词可以生成多个解决方案。

对于分区的每个部分,我将生成所有可能的排列。

然后对于这些排列,我会做一些测试。

假设以下内容:

:- generatePartition(List, A, B),
   permutation(A,Perm1),
   permutation(B, Perm2),
   test(Perm1),
   test(Perm2).

这里的要点是,如果Perm1的测试成功,那么这是我唯一需要的Perm1

如果接下来,Perm2的测试失败,我想尝试Perm2的每个可能的排列。如果它们都失败了我立即想要一个新的分区。我不想为A生成不同的排列。

我尝试了以下内容(为剪辑添加了某种范围):

:- generatePartition(List, A, B),
   permutation(A,Perm1),
   permutation(B, Perm2),
   (
       test(Perm1),!
   ),
   test(Perm2).

这有什么可能的解决方案吗?我今天在这个上打破了我的大脑:)

1 个答案:

答案 0 :(得分:2)

您可以使用IF-THEN构造实现此目的:

:- generatePartition(List, A, B),
   (   permutation(A,Perm1),
       test(Perm1)             % just one Perm1 for which test succeeds
   ->
       permutation(B, Perm2),
       test(Perm2)             % all the Perm2 such that test succeeds
   ).

通常,您可以通过创建辅助命名谓词并使用它而不是代码块来创建范围。然后你可以在辅助谓词中使用cut。

但是已经有一个谓词once/1,正如评论中[user:false]所指出的那样:

:- generatePartition(List, A, B),
   once( (permutation(A,Perm1), test(Perm1)) ),
   permutation(B, Perm2),
   test(Perm2).