Сплющить в прологе - как то еще

Посмотрите на мою реализацию flatten: в общем, это работает. Единственная проблема для my_flatten([], F) - это дает F=[]; F=[[]] вместо F=[],

my_flatten(L, X) :-
   my_flatten(L, X, []). %, reverse(F, X).

my_flatten([], Acc, Acc).
my_flatten([H|T], F, Acc) :-
   my_flatten(H, F1, Acc),
   my_flatten(T, F, F1), !.                         
my_flatten(X, [X|Acc], Acc).        

За my_flatten(X, [1,2,3]) эта программа зацикливается - это нормально, потому что существует бесконечно много ответов, таких как: [[],[],[],[],1,2,3],
Однако та же проблема, что и выше - для my_flatten(X, []) это должно быть также зацикливание, но дает []; [[]],

Более того, результат обратный - но мне все равно - если я раскомментирую reverse все будет хорошо - но тогда вместо зацикливания, упомянутого выше, возвращается false,

Можете ли вы помочь мне изменить этот код таким образом, чтобы он вернулся [] за my_flatten([], X)?

Я реализовал предложения @lurker:

my_flatten(L, F) :-
   my_flatten(L, X, []),
   reverse(F, X).

my_flatten([], Acc, Acc).
my_flatten([H|T], F, Acc) :- 
   is_list(H), 
   my_flatten(H, F1, Acc),
   my_flatten(T, F, F1).
my_flatten([X|T], F, Acc) :-
   not(is_list(X)),
   my_flatten(T, F, [X|Acc]).

1 ответ

Решение

Прежде чем ответить на ваш актуальный вопрос, у меня есть один комментарий по использованию flatten/2:

Не

Причина: flatten/2 это не настоящее отношение. Например, у нас есть:

? - X = [a], сплющить (X, Ls).
X = [a],Ls = [а].

но:

? - сплющить (X, Ls), X = [a].
X = [a],Ls = [[a]].

Это, очевидно, не имеет смысла с логической точки зрения.

Пожалуйста, используйте append/2 вместо этого, чтобы удалить только один уровень вложенности, и попробуйте реализовать это.

Подсказка: используйте dcg!

я знаю это flatten/2 показывается или запрашивается во многих курсах Пролога. Это не значит, что это полезно, ценно, поучительно или что-то в этом роде.

Теперь к вашему актуальному вопросу:

Всегда также попробуйте самый общий запрос:

? - my_flatten (X, Ls).
X = Ls, Ls = [];
X = [[]],
Ls = [].

Начните с этого: этот ответ слишком общий, слишком конкретный или оба? Думать об этом.

Затем подумайте о том, что должно быть в аргументах, чтобы это имело смысл, т. Е. При каких условиях мы можем даже дать здравые ответы, которые нельзя сделать бессмысленными с дальнейшими примерами?

Это поможет вам прочитать об ошибке-экземпляре в Прологе.

Другие вопросы по тегам