如何在 Prolog 中表达无穷大?

How to express infinity in Prolog?

我正在尝试使用 random/3

random(+L:int, +U:int, -R:int)

有什么东西可以用来表示无穷大吗?

例如:

random(0, Infinity, Random_Number).

是否可以通过随机实现?或者还有其他简单的选择吗?

P.S. 我在使用 sup ( Supremum ) 的地方制作了 clpfd 程序,但我没有使用 clpfd。

评论区的讨论真有趣。我对无限数和数学的不发达直觉告诉我:

可以使用一致表示法在物理计算机上表示的整数数量有限。所以就会有无穷多个其他整数无法表示。所以,如果你随机挑选任何个数字,你能在你的机器上表示它的概率是0。你不妨定义:

random_between(0, infinite, infinite).

Transfinite numbers 可能是 一个开始阅读的地方,但我能说谁呢。你需要 数学家 来解决这类问题,而不是编程行人。

也许你应该去https://math.stackexchange.com/问问?


关于你的问题:你可以用一个符号来表示无限的概念,例如原子infinite。然后你需要决定如何在你的代数中处理这个概念,并为它提供规则。上面的 random_between/3 只是一个例子。如需灵感,请查看 how floating point numbers handle infinity。

我认为评论中的讨论已经变得不太有用了。 David 是正确的,没有办法获得没有上限的 uniform 整数,但不清楚这是否是您想要的。绝对有办法从 偏斜 分布中获取无限随机整数,其中接近 0 的数字比远离 0 的数字更有可能,但 没有 整数,即使是 10000 万亿位的整数,也是不可能的。 (只要不超过Prolog的内存即可。)

这是一个简单的生成器。首先,随机长度列表:

random_length(List) :-
    random(P),
    (   P > 0.25
    ->  List = [_ | Tail],
        random_length(Tail)
    ;   List = [] ).

示例:

?- random_length(List).
List = [].

?- random_length(List).
List = [_2004, _2022, _2040, _2058, _2076].

?- random_length(List).
List = [].

?- random_length(List).
List = [_2004, _2022, _2040, _2058].

接下来,随机位的随机长度列表:

random_bit(Bit) :-
    random(P),
    (   P > 0.5
    ->  Bit = 1
    ;   Bit = 0 ).

random_bits(Bits) :-
    random_length(Bits),
    maplist(random_bit, Bits).

示例:

?- random_bits(Bits).
Bits = [0].

?- random_bits(Bits).
Bits = [1, 0, 1, 1, 0, 0].

?- random_bits(Bits).
Bits = [].

?- random_bits(Bits).
Bits = [0, 0, 0].

然后我们可以将这个位列表评估为一个数字,假设使用这种方法:

bits_value([], 0).
bits_value([Bit | Bits], Value) :-
    bits_value(Bits, TailValue),
    Value is TailValue * 2 + Bit.

示例:

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0],
Value = 3.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0],
Value = 2.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 1, 0],
Value = 24.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1],
Value = 2.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [],
Value = 0.

这些列表的长度没有限制,但往往很短,因此值相当低。我们可以修改 random_length 中的 0.25 因子,使更长的列表更有可能出现。例如,0.01:

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 0, 0, 0, 1, 0],
Value = 64.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0, 1, 1, 1, 0, 0, 0|...],
Value = 137345267061686159418.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0, 1, 1, 0, 0, 1, 0|...],
Value = 105607189397659.

?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 0, 1, 1],
Value = 104.

这里有很多可以修改的地方,例如,只包含零的列表不是很有用。您可以向此类列表添加一个“隐式 1”元素。您还可以将其中一位视为符号位以允许生成负数。您可以通过生成两个随机整数 PQ 并使用 P/Q 作为随机值来生成随机的、完全无界的有理数。等等。