Создание списков всех длин между пределами

Я пытаюсь создать список случайной длины, используя библиотеки lists и clpfd. Я пробовал следующее:

?- use_module(library(clpfd)).
?- use_module(library(lists)).

gen_mem_burst(X) :-
    Len in 1..2,
    length(X, Len).

Я вижу, что Prolog сначала находит решение только с одним элементом списка, а затем решение с двумя элементами, как я и ожидал. После этого он выдает сообщение «вне глобального стека». Я проследил его и заметил, что он постоянно пытается установить Len в 3, 4, 5, ... и так далее. Как я могу остановить его?

Я новичок в Prolog, и я даже не уверен, что это действительная модель использования. В других языках, основанных на ограничениях, которые я использовал (например, SystemVerilog), это легко возможно.


person Tudor Timi    schedule 29.09.2015    source источник


Ответы (1)


По крайней мере, с SWI-Prolog length/2 не работает точно так, как ожидалось, когда задействованы переменные с ограничениями: я застрял на такая же проблема. Есть несколько хороших ответов, которые могут дать вам подсказки.

В любом случае, отвечая на название вашего вопроса: создание списка случайной длины:

?- set_random(seed(1)), /* if you want to seed */
   Len is random(9),
   length(L, Len).
Len = 2,
L = [_G2748, _G2751].

Если вам просто нужно создать списки всех длин между двумя пределами,

?- between(1, 3, Len), length(L, Len).

это, вероятно, самый простой способ пойти.

person Community    schedule 29.09.2015
comment
Думаю, я неудачно выбрал название. Мое намерение состоит в том, чтобы иметь возможность генерировать все возможности (т. е. списки длины 1 и списки длины 2). Я использовал метод fd_length(..) по вашей ссылке. - person Tudor Timi; 29.09.2015
comment
@Tudor Хм, все еще не уверен. Вы абсолютно хотите использовать для этого ограниченную переменную? Смотрите обновление к моему ответу, чтобы узнать, как это сделать без него. fd_length/2, как бы хорошо это ни было, является излишним, если вам действительно не нужно накладывать правильное ограничение CLP (FD) на длину списка. - person ; 29.09.2015
comment
Использование between даже круче для моих требований (поскольку мне просто нужно подметать), но хорошо иметь в виду подход fd_length/2, если мне когда-нибудь понадобится добавить более сложные ограничения к длине списка. - person Tudor Timi; 29.09.2015