Пролог функция содержится? - PullRequest
2 голосов
/ 22 марта 2012

Я пытаюсь сделать предикат Пролога iscontained/2: iscontained(List, Search), где он возвращает true., если Search указан в пределах указанных List, false., если нет.И если это переменная, которая вводится, то она просто возвращает, что она равна каждому элементу в списке.

Пример:

?- iscontained([a, b, c], a).

true.

?- iscontained([a, b, c], d).

false.

?- iscontained([a, b, c], A).

A = a;
A = b;
A = c;
false.

Мне нужно пушить в правильном направлении, не прося раздачи, если вы не знаете, как это сделать быстро.Любая помощь приветствуется, спасибо.

Ответы [ 3 ]

3 голосов
/ 22 марта 2012

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

Классическая версия:

member(Item, [Item|_List]).
member(Item, [_Head|List]) :- member(Item, List).

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

?- member(A, [1, 2, 3]).
A = 1;
A = 2;
A = 3<strong>;
false</strong>.

, а

member2(Item, [Head|List]) :-
    member2(List, Item, Head).

member2(_List, Item, Item).
member2([Head|List], Item, _PreviousHead) :-
    member2(List, Item, Head).

обрабатывает пустой список одновременно с последним элементом и позволяет оптимизировать:

?- member2(A, [1, 2, 3]).
A = 1;
A = 2;
A = 3.

Это версия, используемая в SWI-Prolog (и, конечно, Jekejeke Prolog и, возможно, других). Автор - Гертьян ван Ноорд.

Это просто напоминание о том, что, хотя упражнение по созданию member/2 отлично подходит для себя, это не должно приводить к тому, что вы впоследствии не будете использовать встроенные модули, они часто хорошо настроены и более эффективны!

3 голосов
/ 23 марта 2012

Обратите внимание, что часто предлагаемый предикат member/2 допускает решения, которые вообще не являются списками:

?- member(e,[e|nonlist]).
true.

Это не большая проблема во многих ситуациях, но, тем не менее, следует упомянуть.

Естественное, симметричное определение, которое допускает только списки, использует DCG:

... --> [] | [_], ... .

iscontained(Es, E) :-
   phrase((...,[E],...), Es).

... - это нетерминал, который обозначает произвольную последовательность.

Хотя это полностью излишнедля этого крошечного примера он дает вам шаблон для более интересных шаблонов.Как

iscontainedtwice(Es, E) :-
   phrase((...,[E],...,[E],...), Es).
1 голос
/ 22 марта 2012

Вам нужно будет рассмотреть два случая.Я оставлю текст правил на ваше усмотрение.

  • iscontained([A|Xs],A)
  • iscontained([X|Xs],A)

[отредактировано для удаления ссылки напустой список: пустой список не содержит ничего: при возникновении предиката происходит сбой.]

...