一見思ったよりも少しトリッキーです。
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年にコメントで説明したのと同じソリューションです...