A couple more hints.
It’s often easier to write a predicate that verifies a result than one that computes a result. A small modification can often change a predicate that verifies into one that computes (sometimes, no change is needed; sometimes it’s much more difficult to write a predicate that computes than one that checks).
There are many ways the data can be represented. OP’s representation [b,d,b,a,d,c,c,d,a,c]
makes both the student and the question number implicit. It’s also possible to be explicit, e.g., by a predicate that lists facts:
master(1, b). % the answer for question #1 is b
master(2, d).
% ... etc.
student1(1, b). % student1' answer to question #1 is b
Or:
answer(master, 1, b). % the master answer for question #1 is b.
answer(student4, 10, a). % student4's answer for question #10 is a.
There are also many ways to enumerate facts.
possible_answer(a).
possible_answer(b).
possible_answer(c).
possible_answer(d).
or:
possible_answer(Answer) :- member(Answer, [a,b,c,d]).
And the grade for a single question can be computed in many ways. In general, you want “If the student’s answer for a question equals the master answer for the same question, then the grade is 1, else 0.” So, if you’re using the answer/3
predicate above, you can compute this by:
grade(Student, QuestionNumber, Grade) :-
answer(Student, QuestionNumber, StudentAnswer),
answer(master, QuestionNumber, MasterAnswer),
answer_check(StudentAnswer, MasterAnswer, Grade).
% answer_check/3 has Grade=1 if both the StudentAnswer and MasterAnswer are the same, and 0 if they're different.
```[spoiler]This text will be blurred[/spoiler]