Вот один способ, используя встроенные модули SWI-PROLOG для atomic_list_concat/2
, atom_number/2
и select/3
. Во-первых, точка входа относится к реализации, использующей изначально пустой аккумулятор:
numberFromList(L, N) :-
numberFromList(L, [], N).
Предикат numberFromList/3
либо накапливает цифры (не отмеченные) из списка, либо нет, оставляя точки выбора:
numberFromList([_|Cs], Acc, N) :-
numberFromList(Cs, Acc, N).
numberFromList([C|Cs], Acc, N) :-
numberFromList(Cs, [C|Acc], N).
Последнее предложение numberFromList/3
переставляет накопленный список цифр и объединяет их в атом, который затем преобразуется в число при необходимости:
numberFromList([], [C|Cs], N) :-
permute([C|Cs], PermutedAcc),
atomic_list_concat(PermutedAcc, AN),
atom_number(AN, N).
Иногда permute/2
(как определено ниже вручную) может быть доступно как встроенное, например permutation/2
. Вот определение вручную, используя select/3
:
permute([], []).
permute([E|Es], [E0|PL]) :-
select(E0, [E|Es], Rem),
permute(Rem, PL).
Если вы хотите получить список всех результатов и не хотите, чтобы numberFromList/2
возвращал сам себя, вы можете заключить вызов в numberFromList/3
(с пустым аккумулятором в первом предложении numberFromList/2
) в findall/3
вызов.