Make list flat Prolog

2019-09-08 13:55发布

I am trying to do:

Flatten a nested list structure. Transform a list, possibly holding lists as elements into a 'flat' list by replacing each list with its elements (recursively).

Example: ?- my_flatten([a, [b, [c, d], e]], X). X = [a, b, c, d, e] And my attempt:

unwinder([], APP, APP).
unwinder([E|Es], T, APP) :- is_list(E), unwinder(E, T,APP), unwinder(Es, T,APP). 
unwinder([E|Es], T, APP) :- \+ is_list(E),  unwinder(Es, K, APP), append( [E], T, APP).

I suppose that the problem is append, especially I still have a problem with unification :)

Please explain in terms of unification.

标签: prolog
1条回答
我命由我不由天
2楼-- · 2019-09-08 14:42

One thing, your parameters K, T and APP have a messy in your predicate. In the second case:

unwinder([E|Es], T, APP) :- \+ is_list(E),  unwinder(Es, K, APP), append( [E], T, APP).

You go recursively to get K (i think) but never use it.

I re-write (a little) your code:

unwinder([], []).
unwinder([E|ES], APP) :-
    is_list(E), !,
    unwinder(E, K1),
    unwinder(ES, K2),
    append(K1, K2, APP). 
unwinder([E|ES], [E|K]) :-
    unwinder(ES, K).

First. Empty case.

Second. If the element is a list, go recursively through it and recursively through the rest of the list (ES). Then append the unified lists (K1 & K2).

Third. Don't check is list (you did it before), cons (|) the element (not a list) with unified list K.

Note: The ! symbol don't let go back the execution (backtracking) before that point. So, if the predicate fails in some point of second case, it can't go back to try the thrid.

查看更多
登录 后发表回答