setof/3 и NAF

Поэтому у меня есть множество фактов:

course(cs61,  "intro to cs")
...
course(cs62b, "data structure")
...
grade(adam,       cs61, spring11, "A")
...
grade(chrisitian, cs61, fall2010, "A-")

Мне нужно определить предикат good_standing(Student) определить, является ли Student получил A в каждом классе он брал. Я должен использовать 2 разных подхода:

  1. использование setof/3
  2. использовать NAF

на 1-м. Я пытался выяснить, получить Result_list: набор студентов, которые получили A из каждого класса, который он взял. а затем позвоните member(Student, Result_list), Но я не знаю, что получить Result_list так как синтаксис немного странный для меня.

1 ответ

Решение

1) Для решения NAF вы должны иметь в виду, что учащийся с хорошей репутацией - это тот, у кого нет оценок ниже A, т. Е. Тот, у которого нет курса, который он / она прошел, и оценка ниже, чем A. Мы также потребуйте, чтобы этот человек прошел хотя бы один курс.

good_standing(Student) :- grade(Student, _,_,_), 
                          \+ (grade(Student, Course, _, Grade), 
                              lower(Grade,"A")).

с более низким /2 определяющим соотношением между оценками:

lower("A-","A").
lower("B","A").
...

Решение выше работает, если студенты получают только один класс за курс.

2) Для решения setof вы можете найти все оценки на одного учащегося и проверить, что они A.

grade(Student, Grade) :- grade(Student, _,_,Grade).
good_standing(Student) :- setof(Grade, grade(Student,Grade), ["A"]).

В качестве альтернативы, как предполагает false, мы можем сделать экзистенциальную квантификацию явной в setof:

good_standing(Student) :- setof(Grade, 
                                Course^Period^grade(Student,Course,Period,Grade),
                                ["A"]).
Другие вопросы по тегам