gpt4 book ai didi

recursion - Prolog:以递归方式使用 =../2 (Univ)

转载 作者:行者123 更新时间:2023-12-02 21:43:35 26 4
gpt4 key购买 nike

我在 Prolog (SWI-Prolog) 中遇到一个非常简单的问题,但我无法弄清楚。

我想要的是创建一个递归谓词,它能够将任何嵌套列表交换为复合术语。

我想在这两种表示之间交换,因为我使用的是适用于列表表示的替代算法,并且我希望复合表示作为输出。

所以我想:

list_2_compound(List,Compound).

例如,其工作原理如下

list_2_compound([seq, [seq, [if, p1, p2], p2], p1, p3], Compound).

Compound = seq(seq(if(p1, p2), p2), p1, p3)

所以我通常想使用 =.. 运算符:

Compound =.. [if, p1, p2] 
Compound = if(p1,p2)

但现在以递归方式横向到嵌套列表。

最佳答案

比我乍一看想象的要棘手一些。

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 评论后,很明显存在一个错误,但事实并非如此

the same solution an infinite number of times

自从我们有了

?- 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 年的评论中解释的解决方案相同......

关于recursion - Prolog:以递归方式使用 =../2 (Univ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19917369/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com