我想创建一个简单的程序,通过另一个列表重复扩展列表,但是每一步都会给出一个结果。
我有类似的东西,它只运行一次:
repeat(S, R, X) :- append(S,R,X).
:- repeat([y], [x], X).
X = [y,x].
然后我尝试了这个,它永远运行:
repeat(S, R, X) :- append(S,R,X), repeat(S,R,X).
我可以通过哪些方式输出这样的程序:
:- repeat([y], [x], X).
X = [y,x];
X = [y,x,x];
X = [y,x,x,x];
x = [y,x,x,x,x];
....
我认为我需要某种基本情况?
答案 0 :(得分:1)
但是每一步都会给出一个结果。
如您所知,Prolog可以向后前进或。
然后可以更好地将功能请求与另一个列表分开,复制部分已经由append / 3覆盖。最后一个使用差异列表更好地编码,很容易通过短语/ 3接口:
% service 'grammar'
enlist(L), L --> [] ; enlist(L).
产生
?- phrase(enlist([1,2]), [], L).
L = [1, 2] ;
L = [1, 2, 1, 2] ;
...
然后我们可以写
repeat(S, R, X) :-
append(S, P, X),
phrase(enlist(R), [], P).
我们显然得到了
?- repeat([a,b],[1,2],L).
L = [a, b, 1, 2] ;
L = [a, b, 1, 2, 1, 2] ;
...
答案 1 :(得分:1)
你可以尝试
repeat(S, R, X) :-
S = X; append(S,R,X1), repeat(X1,R,X).
答案 2 :(得分:1)
与CapelliC的解决方案类似,使用DCG,此处仅作为轻微变体提供,不使用append
并避免R = []
的冗余解决方案。
rep(S, _) --> S.
rep(S, R) --> {R \= []}, rep(S, R), R.
repeat(S, R, X) :- phrase(rep(S, R), X).
这会产生:
| ?- repeat([y], [x], L).
L = [y] ? ;
L = [y,x] ? ;
L = [y,x,x] ? ;
...
和
| ?- repeat([a,b],[1,2],L).
L = [a,b] ? ;
L = [a,b,1,2] ? ;
L = [a,b,1,2,1,2] ?
答案 3 :(得分:1)
难道你不能这么简单吗?
repeat(Xs,Ys,Zs) :- append(Xs,Ys,Zs) .
repeat(Xs,Ys,Zs) :- append(Xs,Ys,Ts) , repeat(Ts,Ys,Zs) .
或者
repeat(Xs,Ys,Zs) :-
append(Xs,Ys,Ts) ,
(
Ts=Zs
;
repeat(Ts,Ys,Zs)
) .
答案 4 :(得分:0)
是的,你确实需要一个基本案例。如果你想回溯(按; 获得另一个答案),你至少要有一个选择。你需要能够做出最后的选择并以不同的方式选择。
基本情况是
% We append the tail to the head.
repeat(H, T, L) :- append(H, T, L).
另一种选择是
% We repeat H and T (the base case) and then append T to that.
repeat(H, T, L) :-
repeat(H, T, L1),
append(L1, T, L).