Reputation: 451
I am new to ProLog and I am having some troubles understanding recursion over lists.
I am stuck on this exercise. Basically given the vocabulary I need to convert a list of Italian numbers to English numbers.
This is my 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).
This program should give the translated list (in reverse order). However, it only outputs true when I pass:
?- listran(X, [uno, due, tre]).
I've tried to trace it and seems that at the end removes?? all elements from my translated list. This is the trace output.
[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.
Can someone help me understanding this little problem?
Thank you in advance.
Upvotes: 2
Views: 672
Reputation: 5605
An interesting (and "prologish") way is to use 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).
Upvotes: 3
Reputation: 12972
The problem is in both clauses:
listran(L,[]).
listran(L,[H|T]) :- tran(H,E), listran([E|L],T).
here you state that: translate H and place it to head of L and continue, this holds for every L, you need explicitly state that the current head of L is E not add E:
listran([],[]).
listran([E|T1],[H|T]) :- tran(H,E), listran(T1,T).
Here you say the head of first list is E and continue with rest until base case where both lists are empty.
Upvotes: 4