Пролог проверяет, содержит ли список четный номер элемента - PullRequest
0 голосов
/ 07 июня 2018

Я должен проверить, содержит ли список четное число элементов без встроенных модулей.

Пример:

containsEvenNumber([a,b,c,a,a], a).

возвращает false

containsEvenNumber([a,b,c,a], a).

возвращает true

Текущее состояние:

not(A) :-
    A, !,
    fail.
not(_).
equal([E|_], E).
containsEvenNumber([], _).
containsEvenNumber([E|Tail], E) :-
    unevenCount(Tail, E).

containsEvenNumber([Head|Tail], E) :-
    not(equal([Head|Tail], E)),
    evenCount(Tail, E).

evenCount([], _).
evenCount([E|Tail], E) :-
    unevenCount(Tail, E).

evenCount([Head, Tail], E) :-
    not(equal([Head|Tail], E)),
    unevenCount(Tail, E).

unevenCount([], _) :-
    fail.
unevenCount([E, Tail], E) :-
    evenCount(Tail, E).

unevenCount([Head, Tail], E) :-
    not(equal([Head|Tail], E)),
    unevenCount(Tail, E).

Я пытаюсь переключаться между состояниями при появлении элемента.Это не работает, потому что я никогда не вхожу в состояние, когда голова не является элементом, или, скорее, сказано, я также вхожу в состояние и возвращаю false, когда голова является элементом.

Как я могу сделатьэто работает / исправить это?

1 Ответ

0 голосов
/ 08 июня 2018

«Переключение между состояниями» на самом деле является хорошим способом решения этой проблемы.Логика должна следовать этим простым правилам:

  1. В [X|Xs] есть четное количество X элементов, если в * нечетное количество X элементов Xs.

  2. В [Y|Xs] содержится четное количество элементов X, если X и Y различны, а в X - четное числоэлементы в Xs.

  3. В [X|Xs] есть нечетное число X элементов, если в Xs. * 1028 есть четное число X элементов.*

  4. В [Y|Xs] есть нечетное количество элементов X, если X и Y различны, а в Xs есть нечетное количество X элементов..

Тогда у вас есть базовые случаи:

В [].

* 1048 есть четное число любого элемента.* В
[X] есть нечетное число X.

Вам просто нужно написать эти правила как Пролог.Однако у вашей реализации есть несколько проблем.

В некоторых случаях вы пишете список как [Head, Tail] вместо [Head|Tail].[Head, Tail] - список из ровно двух элементов.Кроме того, ваш базовый случай для unevenCount/2 (который я предполагаю, что вы имеете в виду нечетное число) неверен.Если у вас есть базовый случай, который всегда терпит неудачу, то ваш предикат всегда будет терпеть неудачу.За некоторыми исключениями, вы должны написать свои предикатные предложения, чтобы успешно, а не неудачно.Сбой произойдет автоматически, когда успех не может быть достигнут.

Давайте попробуем выписать правила выше.Прологи ISO уже имеют \+, поэтому вам не нужно определять not/1.Кроме того, запись equal([E|_], E). не требуется.Вы можете сделать это прямо в своем коде с простотой.

evenCount(_, []).          % base case for even
evenCount(X, [X|Xs]) :-    % rule #1
    oddCount(X, Xs).
evenCount(X, [Y|Xs]) :-    % rule #2
    dif(X, Y),
    evenCount(X, Xs).

oddCount(X, [X]).          % base case for odd
oddCount(X, [X|Xs]) :-     % rule #3
    evenCount(X, Xs).
oddCount(X, [Y|Xs]) :-     % rule #4
    dif(X, Y),
    oddCount(X, Xs).

SWI Prolog определяет dif/2.Вы также можете использовать \==, но он не является чисто определенным (и поэтому не ведет себя как обычно) как dif/2.

...