首页 文章

SWI Prolog - 带列表的递归

提问于
浏览
3

我是ProLog的新手,我在理解列表递归方面遇到了一些麻烦 .

我坚持这个练习 . 基本上,我需要将意大利语数字列表转换为英语数字 .

这是我的KB .

tran(uno, one).
tran(due, two).
tran(tre, three).
tran(quattro, four).
tran(cinque, five).
tran(sei, six).
tran(sette, seven).
tran(otto, eight).
tran(nove, nine).

listran(L,[]).
listran(L,[H|T]) :- tran(H,E), listran([E|L],T).

该程序应该提供翻译列表(以相反的顺序) . 但是,当我通过时它只输出 true

?- listran(X, [uno, due, tre]).

我试图追踪它,似乎最终删除?我翻译的列表中的所有元素 . 这是跟踪输出 .

[trace]  ?- listran(X,[uno,due,tre]).
   Call: (8) listran(_5566, [uno, due, tre]) ? creep
   Call: (9) tran(uno, _5820) ? creep
   Exit: (9) tran(uno, one) ? creep
   Call: (9) listran([one|_5566], [due, tre]) ? creep
   Call: (10) tran(due, _5826) ? creep
   Exit: (10) tran(due, two) ? creep
   Call: (10) listran([two, one|_5566], [tre]) ? creep
   Call: (11) tran(tre, _5832) ? creep
   Exit: (11) tran(tre, three) ? creep
   Call: (11) listran([three, two, one|_5566], []) ? creep
   Exit: (11) listran([three, two, one|_5566], []) ? creep
   Exit: (10) listran([two, one|_5566], [tre]) ? creep
   Exit: (9) listran([one|_5566], [due, tre]) ? creep
   Exit: (8) listran(_5566, [uno, due, tre]) ? creep
true.

有人能帮我理解这个小问题吗?

先感谢您 .

2 回答

  • 5

    问题出在两个条款中:

    listran(L,[]).
    listran(L,[H|T]) :- tran(H,E), listran([E|L],T).
    

    在这里你陈述:翻译H并将其置于L的头部并继续,这适用于每个L,你需要明确说明L的当前头是E而不是添加E:

    listran([],[]).
    listran([E|T1],[H|T]) :- tran(H,E), listran(T1,T).
    

    在这里你说第一个列表的头部是E并继续休息,直到两个列表为空的基本情况 .

  • 3

    一个有趣的(和“prologish”)方式是使用DCG:

    tran(uno) --> [one].
    tran(due) --> [two].
    tran(tre) --> [three].
    tran(quattro) --> [four].
    tran(cinque) --> [five].
    tran(sei) -->  [six].
    tran(sette) -->  [seven].
    tran(otto) -->  [eight].
    tran(nove) --> [nine].
    
    listran(In,Out) :-
        phrase(trans(In), Out).
    
    trans([]) --> [].
    
    trans([H|T]) --> tran(H), trans(T).
    

相关问题