问题描述
问题来了:
$ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.6-5-g5aeabd5)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
?- use_module(library(clpfd)).
true.
?- N in 1..3, length(L, N).
N = 1,
L = [_G1580] ;
N = 2,
L = [_G1580, _G1583] ;
N = 3,
L = [_G1580, _G1583, _G1586] ;
ERROR: Out of global stack % after a while
(我可以切换子查询的顺序,结果是一样的).
(I can switch the order of the subqueries, the result is the same).
我想我需要标记 N
才能使用它,但我想知道问题是什么?我之前没能把 length/2
噎住.
I guess I need to label N
before I can use it, but I wonder what the problem is? I have not managed to choke up length/2
before.
推荐答案
可能比稍微不确定的 length/2
更有用的是适当的列表长度约束.您可以在 这里ECLiPSe 实现>,称为 len/2
.有了这个,你会得到以下行为:
What's probably more useful than a slightly less nondeterministic length/2
is a proper list-length constraint. You can find an ECLiPSe implementation of it here, called len/2
. With this you get the following behaviour:
?- N :: 1..3, len(Xs, N).
N = N{1 .. 3}
Xs = [_431|_482] % note it must contain at least one element!
There is 1 delayed goal.
Yes (0.00s cpu)
然后您可以通过枚举 N
来枚举有效列表:
You can then enumerate the valid lists either by enumerating N
:
?- N :: 1..3, len(Xs, N), indomain(N).
N = 1
Xs = [_478]
Yes (0.00s cpu, solution 1, maybe more)
N = 2
Xs = [_478, _557]
Yes (0.02s cpu, solution 2, maybe more)
N = 3
Xs = [_478, _557, _561]
Yes (0.02s cpu, solution 3)
或通过使用旧标准 length/2
生成列表:
or by generating lists with good old standard length/2
:
?- N :: 1..3, len(Xs, N), length(Xs, _).
N = 1
Xs = [_488]
Yes (0.00s cpu, solution 1, maybe more)
N = 2
Xs = [_488, _555]
Yes (0.02s cpu, solution 2, maybe more)
N = 3
Xs = [_488, _555, _636]
Yes (0.02s cpu, solution 3)
这篇关于使用带有 `length/2` 的约束变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!