Обучающий пролог

#prolog

#пролог

Вопрос:

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

Например, у меня есть это

 a(b(1)).
a(b(2)).
a(b(3)).
a(b(4)).
a(b(6)).
  

В упражнении требуется вывести (используя writeln(X)) все b (Y), если Y — четное число.

Я могу определить, четное ли это число, используя это, если я не ошибаюсь

 a(b(X)) mod 2 =:= 0
  

но я не могу понять, как это проверить и напечатать все цифры.

Ответ №1:

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

одна из причин, по которой мне действительно нравится prolog, заключается в том, что я просто пишу то, что хочу:

Я хочу напечатать все X, которые имеют определенный атрибут.
Давайте сначала опишем атрибут.

X имеет атрибут, если он принадлежит базе данных, является четным

 has_attribute(X):-
    belongs_db(X),
    is_even(X).
  

X принадлежит базе данных, если есть предложение a(b(X))

 belongs_in_db(X):-
    a(b(X)).
  

X равно четности, если остаток от деления на 2 равен 0:

 is_even(X):-
    0 =:= X mod 2.
  

теперь мы можем задать has_attribute(X), и prolog ответит, перечислив каждый X.
но мы хотим, чтобы все X. для этого мы будем использовать предикат findall/3
Найдите все X, у которых есть нужный мне атрибут, и поместите их в список

 findall(X,has_attribute(X),List).
  

теперь у нас есть все X в списке, и мы хотим их распечатать
простой способ — просто использовать writeln / 1:

 writeln(List)
  

итак, в конце:

 run:-
    findall(X,has_attribute(X),List),
    writeln(List).

has_attribute(X):-
     a(b(X),
     0 =:= X mod 2.
  

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

если список пуст, я закончил

 my_print_list([]).
  

если в списке есть хэд и хвост, я напечатаю первый элемент, а затем хвост:

 my_print_list([Head|Tail]):-
    writeln(Head),
    my_print_list(Tail).
  

Ответ №2:

равно_even(N) :-
 0 =:= N мод 2.

число всех событий:- 
a(b(X)), 
равно_even(X), 
writeln(X), 
 сбой.
all_even_number.