乍一看比我想象的要棘手一些。
list_2_compound(L, T) :-
var(T)
-> L = [F|Fs], maplist(list_2_compound, Fs, Ts), T =.. [F|Ts]
; atomic(T)
-> L = T
; L = [F|Fs], T =.. [F|Ts], maplist(list_2_compound, Fs, Ts).
list_2_compound(T, T).
(我之前的帖子在相反的情况下产生了太多的嵌套列表)。测试:
1 ?- list_2_compound([seq, [seq, [if, p1, p2], p2], p1, p3], Compound).
Compound = seq(seq(if(p1, p2), p2), p1, p3)
.
2 ?- list_2_compound(S, $Compound).
S = [seq, [seq, [if, p1, p2], p2], p1, p3]
.
编辑
在@damianodamiano 发表评论后,很明显有一个错误,但事实并非如此
无限次相同的解决方案
因为我们有
?- aggregate(count,L^list_2_compound(L, seq(seq(if(p1, p2), p2), p1, p3)),N).
N = 45.
最后,只是“catch all”子句与上面已经处理的案例重叠——毫无用处。但是为了避免混淆,并更好地利用这段代码的声明性属性,我将把谓词重命名为list_compound
:
list_compound(L, T) :-
( var(T)
-> L = [F|Fs], maplist(list_compound, Fs, Ts), T =.. [F|Ts]
; atomic(T)
-> L = T
; L = [F|Fs], T =.. [F|Ts], maplist(list_compound, Fs, Ts)
),
!.
list_compound(T, T).
现在我们有了一个确定性的计算:
?- list_compound(L, seq(seq(if(p1, p2), p2), p1, p3)).
L = [seq, [seq, [if, p1, p2], p2], p1, p3].
?- list_compound($L, C).
C = seq(seq(if(p1, p2), p2), p1, p3),
L = [seq, [seq, [if, p1, p2], p2], p1, p3].
所以,这与@patta1986 在 2013 年的评论中解释的解决方案相同......