【发布时间】:2020-01-04 12:12:28
【问题描述】:
给定字母 [a, b, c] 生成包含由这些字母组成的所有长度为 N 的单词的列表。 例如:
?- generate(2, L).
应该输出:
L = [aa, ab, ac, ba, bb, bc, ca, cb, cc]。
起初,这似乎是一个非常简单的问题,但我发现我的实现都不起作用。
这是第二个实现,一种有效的实现。
letter(X) :- member(X, [a, b, c]).
generateWord(0, []) :- !.
generateWord(N, [H|T]) :-
letter(H),
NextN is N - 1,
generateWord(NextN, T).
generateAtomicWord(N, Word) :-
generateWord(N, WList),
atomic_list_concat(WList, Word).
maxSolutions(N, R) :- R is N ** 3.
generate(N, CurrentList, ResultList) :-
maxSolutions(N, R),
length(CurrentList, L),
L =:= R,
append(CurrentList, [], ResultList), !.
generate(N, CurrentList, ResultList) :-
generateAtomicWord(N, NewWord),
\+ member(NewWord, CurrentList),
append(CurrentList, [NewWord], NewList),
generate(N, NewList, ResultList).
generate(N, ResultList) :-
generate(N, [], ResultList).
它有点工作,因为当给定 N = 3 时,程序输出:
L = [aaa, aab, aac, aba, abb, abc, aca, acb, acc|...]
我的第一个实现是不同的,但我无法让它在任何情况下都起作用。
letter(X) :- member(X, [a, b, c]).
generateWord(0, []) :- !.
generateWord(N, [H|T]) :-
letter(H),
NextN is N - 1,
generateWord(NextN, T), !.
generateAtomicWord(N, Word) :-
generateWord(N, WList),
atomic_list_concat(WList, Word).
maxSolutions(N, R) :- R is N ** 3.
generate(N, [H]) :- generateAtomicWord(N, H).
generate(N, [H|T]) :-
generate(N, T),
length(T, TailLen),
maxSolutions(N, M),
(TailLen =:= M -> !;
generateAtomicWord(N, H),
\+ member(H, T)).
这只是输出:
L = [aa]
当请求其余解决方案时,它会循环。
必须在不使用谓词的情况下解决问题,例如:
findall、findsol、bagof、setof 等...
找到所有解决方案。
我添加了标签 backtracking 因为它确实类似于回溯问题,但我不知道 Prolog 中的标准实现可能是什么样的。
【问题讨论】:
-
请提供更多关于本练习的具体背景的信息。
标签: prolog backtracking