所以我的问题是,我有一个谓词n_aleatorios(El,INF,SUP,L),其中El是列表的长度,INF是列表的下限值,SUP是列表的下限值该列表,而L是一个列表。
此谓词的目的是创建随机整数列表。
问题是,这样做的结果是正确的,而不是统一并给出列表的结果。
辅助谓词:
/*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]
非常感谢您的帮助。
nao_membro(X, [P | R]) :-
X =\= P,
nao_membro(X, R).
如果可以确保=\=
和\==
都不新鲜,请使用[算术不等式] X
代替“结构不等式” P
。实际上,这里它们始终是整数。
固定代码:
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)..