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

      Комментарии к записи Ответ в теме: База данных учеников. Обработка ошибок отключены
#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 собираются баллы ученика, а затем, вычисляется средний балл.