накапливающие элементы в списке - PullRequest
0 голосов
/ 18 апреля 2020

Так что моя проблема в том, что у меня есть предикат espaco_fila (F, E), в котором F - это список, содержащий элементы, а #, L - результирующий список без #.

Пример:

Мой вывод:

?- espaco_fila([1,2,3,#,1,2,3,4], E).
E = [1,2,3];
false.

?- espaco_fila([1,2,3,#,1,2,#,3,4,5], E).
E = [1,2,3];
false.

?- espaco_fila([1,2,3], E).
E = [];
false.

Правильный вывод:

?- espaco_fila([1,2,3,#,1,2,3,4], E).
E = [1,2,3];
E = [1,2,3,4];
false.

?- espaco_fila([1,2,3,#,1,2,#,3,4,5], E).
E = [1,2,3];
E = [3,4,5];
false.

?- espaco_fila([1,2,3], E).
E = [1,2,3];
false.

Но вместо этого я получаю 1-й список в результате, вместо ретроспективы и получения обоих списков и пустой список, если я набираю только цифры и не могу понять, почему.

Программа:

espaco_fila(F, E) :- espaco_fila(F,E,[],[]).

espaco_fila([],ACP,ACP,_).
espaco_fila([P|R],E,ACP,ACE) :-
   P \== #,
   append(ACE,[P],NACE),
   espaco_fila(R,E,ACP,NACE).
espaco_fila([P|R],E,ACP,ACE) :-
   P == #,
   length(ACE,COMP),
   COMP >= 3,!,
   append(ACP,ACE,NACP),
   espaco_fila([],E,NACP,[]).
espaco_fila([P|R],E,ACP,ACE) :-
   P == #,
   length(ACE,COMP),
   COMP < 3,!,
   espaco_fila(R,E,ACP,[]).

Действительно, любая помощь будет признательна.

1 Ответ

1 голос
/ 19 апреля 2020

Это

espaco_fila([P|R],E,ACP,ACE) :- P == #,
                                length(ACE,COMP),
                                COMP >= 3,!,
                                append(ACP,ACE,NACP),
                                espaco_fila([],E,NACP,[]).

... является ветвью успеха.

Я не могу полностью судить, правильно ли он закодирован, но он не останавливается .

Он продолжается с рекурсивным вызовом.

Вместо этого вы хотите, чтобы он остановился с успехом, и позволить пользователю запрашивать дополнительные решения с использованием обратного отслеживания.

Таким образом, у вас должно быть две ветви, одна из которых останавливается, и альтернативная с той же защитой, которая является попытался вернуться назад:

espaco_fila(F,Result) :- espaco_fila(F,[],Result).

% at list end, the result is what's in the accumulator

espaco_fila([],Acc,Acc). 

% not on an #, accumulate, recurse

espaco_fila([R|Rs],Acc,Result) :- 
   R \= #,
   !,      
   append(Acc,[R],NextAcc),
   espaco_fila(Rs,NextAcc,Result).

% hit a # and accumulator has > 3 atoms, then the result is what's in
% the accumulator

espaco_fila([#|R],Acc,Acc) :-
   length(Acc,L),
   L >= 3.

% ALTERNATIVELY (on retry or length too small), the (next) result is
% what's being generated by a recursive call. This behaves as if the
% clause above had never even happened (really as in Greg Egan's "Quarantine")

espaco_fila([#|R],_,Result) :-
   espaco_fila(R,[],Result).

Я не уверен на 100%, что это работает, вы хотите написать для этого модульные тесты. Модульные тесты и разработка через тестирование хороши!

Примечание: используйте унификацию = и невозможную унификацию \= вместо структурной эквивалентности == и структурной неэквивалентности \==.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...