Two issues in the solutions pointed by Shevliaskovic and mbratch. In the first case, aggregate_all /3
is not a standard predicate, making that solution less portable. But using setof/3
in the way shown will not give the expected results due to the anonymous variable:
?- setof(M, studies(M, _), ListOfModules), length(ListOfModules, Num).
ListOfModules = [com],
Num = 1 ;
ListOfModules = [cse],
Num = 1 ;
ListOfModules = [com, cse],
Num = 2 ;
ListOfModules = [cmt, com, cse],
Num = 3 ;
ListOfModules = [cmt],
Num = 1.
To make the problem more clear, we can replace the anonymous variable by a named variable:
?- setof(M, studies(M, A), ListOfModules), length(ListOfModules, Num).
A = ads,
ListOfModules = [com],
Num = 1 ;
A = algorithms,
ListOfModules = [cse],
Num = 1 ;
A = aplc,
ListOfModules = [com, cse],
Num = 2 ;
A = pm,
ListOfModules = [cmt, com, cse],
Num = 3 ;
A = uc,
ListOfModules = [cmt],
Num = 1.
Correcting this issue is easy. The solution is to explicitly qualify the second argument of studies/2
so that we don't get a solution for each value of the second argument:
?- setof(M, A^studies(M, A), ListOfModules), length(ListOfModules, Num).
ListOfModules = [cmt, com, cse],
Num = 3.