forall/2 and foreach/2 are interchangeable only if Y
is a ground value when executing forall/2 and foreach/2, see On a logical reading of `foreach/2` predicate - #15 by chansey97
For your example,
?- retractall(course(_)),
foreach(course(CName), student_course(SName, CName)).
true.
?- retractall(course(_)),
student(SName), forall(course(CName), student_course(SName, CName)).
SName = alice ;
SName = bob ;
SName = clark ;
SName = david ;
SName = emily ;
SName = gavin ;
SName = ferry.