У меня есть школьный проект по 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 ' я боролся с этим последние пару дней, и я еще не понял этого. Я знаю, что это очень длинный и тяжелый код, но этот новичок мог бы помочь, так как проект должен быть выполнен через два дня: /