Списки фильтрации в SWI-Prolog - PullRequest
0 голосов
/ 05 мая 2020

У меня есть школьный проект по Prolog, и мы должны написать программу для решения кроссвордов. Один из предикатов, который нам сказали разработать, выглядит следующим образом:

mypredicate(PossibleWords, NewPossibleWords)

Я думаю, что самый простой способ объяснить, что он должен делать, - это привести пример того, что требуется:

?- PossibleWords =
  [[[d, i, a], [[d, i, a]]],
   [[s, P16, P17, P18], [[s, e, d, e], [s, o, a, r]]],
   [[m, P24, e], [[m, a, e]]],
   [[d, a, o], [[d, a, o]]],
   [[m, a, n, d, e], [[m, a, n, d, e]]],
   [[d, P21, P31, m, P51], [[d, r, a, m, a]]],
   [[a, m, e, n, o], [[a, m, e, n, o]]],
   [[s, e, d, e], [[s, e, d, e]]],
   [[P17, P27, o], [[a, t, o], [d, a, o]]]],
   mypredicate(PossibleWords, NewPossibleWords).

Ожидаемый результат:

NewPossibleWords =
 [[[d, i, a], [[d, i, a]]],
  [[s, P16, P17, P18], [[s, o, a, r]]],
  [[m, P24, e], [[m, a, e]]],
  [[d, a, o], [[d, a, o]]],
  [[m, a, n, d, e], [[m, a, n, d, e]]],
  [[d, P21, P31, m, P51], [[d, r, a, m, a]]],
  [[a, m, e, n, o], [[a, m, e, n, o]]],
  [[s, e, d, e], [[s, e, d, e]]],
  [[P17, P27, o], [[a, t, o]]]].

Итак, в основном, поскольку слово [s,e,d,e] появляется отдельно в одной из строк, я должен удалить все остальные его экземпляры в списке. То же самое относится, например, к [d,a,o].

Ниже приведено явно неправильное решение, которое я придумал:

%   mypredicate_line(Line, Unicas, UpdatedLine) means that UpdatedLine is the result of removing
%   words that appear alone in other line (these words are all included in the list Unicas) from
%   Line.


%   Handles the "do not delete if word is alone" case
mypredicate_line([Space, SpaceWords], _ , UpdatedLine) :-
    length(SpaceWords,1), UpdatedLine = [Space, SpaceWords], !.

%   Handles all cases that involve subtraction
mypredicate_line([Space, SpaceWords], Unicas, UpdatedLine) :-
    subtract(SpaceWords, Unicas, FilteredWords),
    UpdatedLine = [Space, FilteredWords].



%   mypredicate(PossibleWords,NewPossibleWords) is the result of removing "duplicates" of words that 
%   appear alone somewhere else.

mypredicate(PossibleWords, NewPossibleWords) :-
    obtem_unicas(PossibleWords, Unicas),
    bagof(UpdatedLine,
    (member(Line, PossibleWords),
    mypredicate_line(Line, Unicas, UpdatedLine)),    
    NewPossibleWords).

Предикат obtem_unicas/2 находит каждое слово, которое появляется отдельно в строке и добавляет его в список, который я назвал Unicas. В этом примере Unicas = [[d,i,a],[m,a,e],[d,a,o],[m,a,n,d,e],[d,r,a,m,a],[a,m,e,n,o],[s,e,d,e]].

Результат моего кода с точно таким же тестовым вводом:

PossibleWords = [[[d, i, a], [[d, i, a]]], [[s, P16, P17, P18], [[s, e, d, e], [s, o, a|...]]], [[m, P24, e], [[m, a, e]]], [[m, a, n, d|...], [[m, a|...]]], [[d, P21, P31|...], [[d|...]]], [[a, m|...], [[...|...]]], [[s|...], [...]], [[...|...]|...]],
NewPossibleWords = [[[P17, P27, o], [[a, t, o], [d, a, o]]]] ;

PossibleWords = [...] (same for all)
NewPossibleWords = [[[a, m, e, n, o], [[a, m, e, n, o]]]] ;

PossibleWords = [...]
NewPossibleWords = [[[d, P21, P31, m, P51], [[d, r, a, m, a]]]] ;

PossibleWords = [...]
NewPossibleWords = [[[d, i, a], [[d, i, a]]]] ;

PossibleWords = [...]
NewPossibleWords = [[[m, P24, e], [[m, a, e]]]] ;

PossibleWords = [...]
NewPossibleWords = [[[m, a, n, d, e], [[m, a, n, d, e]]]] ;

PossibleWords = [...]
NewPossibleWords = [[[s, P16, P17, P18], [[s, o, a, r]]]] ;

PossibleWords = [...]
NewPossibleWords = [[[s, e, d, e], [[s, e, d, e]]]].

Как видите, две основные проблемы:

  • bagof/3 не добавлял все эти строки в один список (для этого я попытался использовать другой bagof поверх этой функции, но я предполагаю, что это не должно быть необходимо с правильной коррекцией);

  • Они не сохранили тот порядок, который им нужен, появляясь в кажущемся случайном порядке.

I ' я боролся с этим последние пару дней, и я еще не понял этого. Я знаю, что это очень длинный и тяжелый код, но этот новичок мог бы помочь, так как проект должен быть выполнен через два дня: /

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