Prolog:找到所有但只保存一些解决方案

Prolog: findall but to save only some solutions

我找到了 that for swi-prolog it exists findnsols,但是它对我不起作用。

我的 predicate generate_color(Color) 生成随机颜色。

当我尝试调用它 N 次并将执行的值保存在列表中时,我总是得到一个结果而不是很多。

findnsols(3, Color, generate_color(Color),Colors).

Colors = ["# 4c4b43"].

findnsols(3, Color, generate_color(Color),Colors).

Colors = ["# 158955"].

findnsols (300, Color, generate_color (Color), Colors).

Colors = ["# 5d67e1"].

有谁知道我可以在列表中获得我想要的 Nsolutions 的任何方法吗?

预期输出:

findnsols(3, Color, generate_color(Color),Colors).

Colors = ["# 5d67e1", "# 4c4b43", "# 158955"].

我假设 generate_color 只有 returns 一种颜色(即,您不能在给出第一个解决方案后按 ;)。

因此,findnsols 不起作用,因为它基于 回溯,即再次输入您的目标并尝试找到进一步的解决方案。

我建议采用类似于以下的解决方案:

length(Colors, 10), maplist(generate_color, Colors).

这定义了一个长度为 10 的列表 Colors,其中所有条目必须对应于 generate_color(有关更多信息,请参阅 maplist


相关范例:

random 生成 单个随机数 .

?- findnsols(3, N, random(0, 100, N), Rands).
Rands = [33].

?- length(Rands, 10), maplist(random(0,100), Rands).
Rands = [85, 92, 81, 66, 98, 15, 74, 95, 56|...].

要有一个生成多种随机颜色的谓词, 这还不够:
(0x 语法来自 ISO 核心标准,以 16 为基数的整数表示法)

generate_color(Color) :-
   random(0, 0xFFFFFF, Color).

如果你调用上面的方法,它只会生成一个解决方案:
(不在浏览器中使用,仅显示以 10 为基数的整数)

?- generate_color(Color).
Color = 8649520.

如果你想制作无限发电机, 你必须放置 repeat/0:

generate_color(Color) :-
   repeat,
   random(0, 0xFFFFFF, Color).

然后它的工作原理如下:

?- generate_color(Color).
Color = 4282662 ;
Color = 13523844 ;
Color = 511176 ;
Etc..

除了使用repeat/0,您还可以编程generate_color/1
尾递归得到它 return 多个解决方案。

编辑 2021 年 9 月 4 日:
在 SWI-Prolog 中,您可以使用 format/2 转换为基数 16,
获得可以在浏览器中使用的东西:

?- generate_color(Color), format('#~|~`0t~16r~6+', [Color]).
#415926
C = 4282662 ;
#ce5b84
C = 13523844 ;
#07ccc8
C = 511176.
Etc..