Prolog毕达哥拉斯三重态

Prolog pythagorean triplet

我正在尝试使用序言解决项目欧拉问题 9。我是一个 100% 的 prolog 新手,我现在只是想了解基础知识。

我正在尝试使用 findall 来获取所有加起来等于 1000 的三元组,但我真的无法理解语法。

我希望的是这样的:

pythag_trip(A, B, C, D) :- D is (A * A) + (B * B) + (C * C).
one_thou_pythag(A, B, C) :- pythag_trip(A, B, C, 1000).
product_trip(A, B, C, D) :- D is A * B * C.
findall([A, B, C], one_thou_pythag(A, B, C) , Bag)).
writeln(Bag).

我知道这不起作用,因为它说 Bag 未实例化。但是也有一些我不了解这门语言的基础知识。

1:我能做到吗?一次有多个移动件?我能找到所有满足条件的三胞胎吗?我需要像使用 clpfd 一样完全不同吗?

2:在我放置 Bag 的最后一个参数中应该发生什么?

3:是否可以创建数据类型?我在想,如果我必须找到某种方法来自己生成所有可能性,那么创建一个三元组集类型和一个运算来获得它们的毕达哥拉斯三元组和可能会很好

基本上是那些问题,如果有人有提示,我可以使用一些指向正确方向的东西

抱歉,我不回答你的问题。在我看来,您尝试的不是类似序言的方法。

你应该尝试从逻辑上解决它。

把这道题从上到下做一遍。 我们想要 3 个数字之和为 1000。

between(1,1000,A), between(A,1000,B), between(B,1000,C), C is 1000-A-B.

在那种情况下,我们将对它们进行排序,我们不会进行排列。

让我们更进一步。我们希望它们是毕达哥拉斯三重态。

between(1,1000,A), between(A,1000,B), between(B,1000,C), C is 1000-A-B, is_triplet(A,B,C).

但是我们没有is_triplet/3谓词,所以让我们创建它

is_triplet(A,B,C) :- D is C*C - A*A -B*B, D=0.

实际上就是这样。

所以让我们总结一下

is_triple(A, B, C) :- D is C*C - A*A - B*B, D = 0.
triplet(A,B,C) :- between(1,1000,A), between(A,1000,B), C is 1000-A-B, between(B,1000,C), C is 1000-A-B, is_triple(A,B,C). 

当您致电 triplet(A,B,C) 时,您应该会得到答复。

请注意一件事,最后我将 C is 1000-A-B 换成了 between(B,1000,C)。它使程序更快,试着想一想为什么。