составление списка случайных чисел на прологе - PullRequest
0 голосов
/ 15 апреля 2020

Так что моя проблема в том, что у меня есть этот предикат, который имеет значение n_aleator ios (El, INF, SUP, L), в котором El - длина списка, INF - нижнее предельное значение списка, SUP - значение. верхний предел значения списка, а L - список.

Цель этого предиката - создать список случайных целых чисел.

Проблема в том, что в результате получается значение true вместо объединения и выдачи списка в качестве результата.

вспомогательные предикаты:

/*Checks if a number isnt a member of a list*/

nao_membro(_, []).

nao_membro(X, [P | R]) :- X \== P,
                          nao_membro(X, R).

/*Joins an integer in a sorted list, in a sorted order*/

insere_ordenado(El,[],[El]).

insere_ordenado(El,[P|R],[P|L2]) :- El >= P,
                                    insere_ordenado(El,R,L2).

insere_ordenado(El,[P|R],[El,P|R]) :- El < P.

/*Joins a random integer in a sorted list, in a sorted order*/

junta_novo_aleatorio(L1,INF,SUP,L2) :- random_between(INF, SUP, N),
                                       nao_membro(N,L1),
                                       insere_ordenado(N,L1,L2).

Программа:


n_aleatorios(El,INF,SUP,L) :- n_aleatorios(El,INF,SUP,[],0).

n_aleatorios(El,_,_,L,El).

n_aleatorios(El,INF,SUP,L,AC) :- AC =< El,
                                 junta_novo_aleatorio(L,INF,SUP,L2),
                                 AC_num is AC +1,
                                 n_aleatorios(El,INF,SUP,L2,AC_num).

Мой вывод:

?- n_aleatorios(3, 1, 5, Lst).
true ;
false.

Ожидаемый вывод (например):

?- n_aleatorios(3, 1, 5, Lst).
Lst = [2,3,5]

Действительно, любая помощь будет оценена.

1 Ответ

0 голосов
/ 16 апреля 2020

Исправленный код:

Одно небольшое улучшение здесь:

nao_membro(X, [P | R]) :- 
   X =\= P, 
   nao_membro(X, R).

Используйте «арифметику c неэквивалентность» =\= вместо «структурной неэквивалентности» \== если мы можем быть уверены, что ни X, ни P не бесплатны sh. Действительно, здесь они всегда являются целыми числами.

Фиксированный код:

junta_novo_aleatorio(L1,INF,SUP,L2) :- 
   random_between(INF, SUP, N),
   nao_membro(N,L1),
   insere_ordenado(N,L1,L2).

n_aleatorios(Count,INF,SUP,L) :- 
   n_aleatorios(Count,INF,SUP,[],L).

n_aleatorios(Count,_,_,L,L) :- 
   length(L,Count),!.

n_aleatorios(Count,INF,SUP,Lin,Lout) :- 
   length(Lin,Len), Len<Count,!,
   junta_novo_aleatorio(Lin,INF,SUP,Lmid),
   n_aleatorios(Count,INF,SUP,Lmid,Lout).

Проблемы связаны с тем, что составляемый список не «должным образом» связан с вызовами предикатов. Здесь Lin - это «список ввода». Именно здесь информация «втекает» в предикат. Lin используется для создания нового списка Lout, который снова появляется в аргументе предиката, но теперь информация «вытекает» из предиката обратно к вызывающей стороне.

Я также удалил счетчик, который уже подразумевается в длине Lin.

Обратите внимание, что выбор между двумя пунктами n_aleatorios/5 происходит через защитное устройство, за которым следует «вырезание», которое фиксирует путь выполнения. Второй «вырез» на самом деле не нужен, потому что ниже нет пункта, но все проясняется:

n_aleatorios(Count,_,_,L,L) :- 
   length(L,Count),!,...(we will never try any clause below)..

n_aleatorios(Count,INF,SUP,Lin,Lout) :- 
   length(Lin,Len), Len<Count,!,....(we will never try any clause below)..
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...