Ответ в теме: База данных учеников. Обработка ошибок

      Комментарии к записи Ответ в теме: База данных учеников. Обработка ошибок отключены
#1799

Стандартная функция findall позволяет выбрать из базы данных все значения удовлетворяющие заданному критерию.
findall(Фамилия,ученик(Фамилия,_,_,_),L),member(Фамилия,L)
В списке L будут только фамилии, причем все одинаковые. Если такого ученика в базе нет — список будет пустым. Можно проверить список на пустоту, но к решить задачу Вам это не поможет. Можно формировать список кортежей из фамилий и оценок, но проще решить задачу другим путем:

ученик(иванов, математика, 5, 12).
ученик(иванов, физика, 3, 12).
ученик(петров, математика, 2, 12).
 
listsum([], 0).
listsum([H|T], S):-
  listsum(T, SS), S is SS + H.
 
goal:-
  write('Введите фамилию ученика: '), read(Фамилия),
  ученик(Фамилия, _, _, _), !,
  findall(Point, ученик(Фамилия, _, Point, _), Points),
  listsum(Points, Sum), length(Points, Len), GPA is Sum / Len,
  write(['GPA: ', GPA]), nl;
  write('плохая фамилия, повторите ввод'), nl, gpa.
?- goal.
  Введите фамилию ученика: сидоров.
  плохая фамилия, повторите ввод
  Введите фамилию ученика: иванов.
  [GPA: ,4]
  true.

Проверка корректности введенных данных производится в goal – фамилия запрашивается до тех пор, пока не будет существовать соответствующая запись в базе данных. Если студент найден, то с помощью findall собираются баллы ученика, а затем, вычисляется средний балл.