2014-11-18 2 views
0

У меня есть функция с именем member, которая должна принимать в качестве аргумента: 1) имя 2) список имен.Prolog - 'Member Of' List

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

Например, моя программа Пролог содержит ...

namesList(mike,joe,bob,jill). 

member(Element, [Element|_]):-!. 
member(Element, [_|Tail]):-member(Element,Tail). 

Так что, когда я в строке Пролога и введите в member(mike,namesList). Прологе должен вывести true, но вместо этого печатает false.

Я правильно вызываю функцию или не могу использовать уже созданный экземпляр списка?

+1

'namesList', несмотря на его имя, не объединяется в список прологов. Вы должны были написать 'namesList ([mike, joe, bob, jill]).' И ваш запрос должен выглядеть как 'namesList (Names), member (mike, Names) .' – gusbro

+0

Списки пролога записываются в скобках (' [. ..] '). Вы можете найти эту информацию в любом базовом учебнике Prolog или в руководстве Prolog. – lurker

ответ

1

Во-первых, у Prolog нет функции: есть предикаты.

Во-вторых, непустой список пролога написан с использованием квадратных скобок — [a,b,c,d] с пустым списком, обозначенным атомом []. Списки фактически представлены структурой ./2, где первым аргументом является первый элемент (глава) списка, а второй аргумент - это остаток списка, либо другой непустой список, либо самый пустой список. Это то, что писатели компилятора любят называть синтаксическим сахаром. Таким образом,

  • [a] в точности эквивалентен .(a,[]).
  • [a,b] в точности эквивалентен .(a,.(b,[])).
  • [a,b,c] в точности эквивалентно .(a,.(b,.(c,[])))
  • т.д.

И

  • [A|B] точно equivelent к .(A,B).

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

Так что ... вы могли бы хранить список имен это:

names_list([mike,joe,bob,jill]). 

в этом случае, вы могли бы сказать:

?- names_list(Names) , member(mike,Names) . 
true. 

Однако ... Вы могли бы найти это проще, если вы сохранили свои имена в более ... пролог-виде:

name(mike) . 
name(joe ) . 
name(bob ) . 
name(jill) . 

Затем...

  • Вы можете проверить существование обычным способом:

    ?- N = sam , name(N) , 
    false. 
    
  • Или, вы можете перемещаться по ним с помощью возвратов:

    ?- name(N). 
    N = mike ; 
    N = joe ; 
    N = tim ; 
    N = jill. 
    
  • И, если вам действительно нужны как список, легко получить их в такой форме:

    ?- findall(N,name(N),Ns). 
    Ns = [mike, joe, tim, jill]. 
    

Наконец, следует отметить, список имен можно извлечь из вашего

names_list(mike , joe , bob , jill). 

, но это не самый элегантный в мире вещь:

extract(Name , Arguments) :- 
    atom(Name) , 
    current_functor(Name,Arity) , 
    length(Arguments,Arity) , 
    Goal =.. [Name|Arguments] , 
    callable(Goal) , 
    call(Goal) 
    . 

Как только вы что, вы можете сказать:

?- extract(names_list,Names) , member(mike,Name). 
true.