从剩余目标中获取价值

时间:2018-04-02 20:41:54

标签: prolog clpfd

如果我有X #> 3. Prolog将给出剩余目标X in 4..sup.。如何将X中的一个可能值指定为sup?任何随机值都足够了。

2 个答案:

答案 0 :(得分:2)

在SWI-Prolog中,您可以使用秘密选项random_value(Seed)获取随机值分配。 看到这个:How does `random_variable `random_value` work in SWI-Prolog's labeling/2?



    :- use_module(library(clpfd)).

    random_labeling_test(A):-
        A in 1..5,
        labeling([random_value(332)],[A]).



    ?- random_labeling_test(A).
    A = 5 ;
    A = 1 ;
    A = 2 ;
    A = 4 ;
    A = 3.

332没有意义。将随机种子放入here.current毫秒经常使用。

我不确定这个选项是否安全。

但在你的情况下,这不起作用,因为上限是无限的。这是合理的。

在ECLiPSe中,使用indomaindelete可以完全控制标记变量选择和赋值选择。 看到这个:http://eclipseclp.org/doc/tutorial/tutorial088.html

答案 1 :(得分:1)

解决此问题的一种天真方法是使用这样的谓词:

enumeration(Z) :-
        length(_, N),
        enumeration_(N, Z).

enumeration_(N, N).
enumeration_(N0, N) :- N #= -N0.

您现在可以按如下方式解决您的任务:

?- X #> 3, enumeration(X).
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 .

优点:

  • 一个非常简单的解决方案
  • 轻松到不同的Prolog系统。

缺点:

  • 可能非常

示例:

?- X #> 2^100, enumeration(X).
[waiting...]

为了提高效率,您需要考虑变量的实际

至少有两种方法可以做到这一点:

(a)使用求解器的反射谓词

反射谓词让您可以将变量的实际作为Prolog术语提供。

例如,如果可用,您可以使用 fd_inf/2 来获取受约束变量域的 infimum

?- X #> 3, fd_inf(X, Inf).
Inf = 4,
X in 4..sup.

您可以将其用作枚举的起点。我把这作为挑战。

有关其反射谓词的详细信息,请参阅Prolog系统手册。

(b)检查剩余目标

或者,您可以将剩余目标视为Prolog术语。这也是一种反射机制,尽管只需要一个谓词用于各种不同的约束求解器。

例如,如果可用,您可以使用 copy_term/3 获取剩余目标作为Prolog目标的列表

?- X #> 3, copy_term(X, X, Gs).
Gs = [clpfd:(X in 4..sup)],
X in 4..sup.

从这些目标中,再次直接推断出X域名的下限。

请注意,顶级可以使用相同的机制来实际产生剩余目标。