Search code examples
prologprolog-findall

findall(X,condition,List) list is filled with pointers and not real objects


I am trying to get a list full of objects from the database that fit my condition.

Here is my database:

student(1234,[statistics/a,algorithms/b,prolog/a,infi/b]).
student(4321,[java/a,algorithms/a,prolog/b,probability/b,infi/a]).
student(1111,[algorithms/a,prolog/a,c/a,infi/a]).
student(2222,[c/b,algorithms/b,prolog/b,infi/a]).
student(3333,[java/b,algorithms/b,prolog/a,infi/a]).
student(4444,[java/a,c/a,prolog/a]).
student(5555,[java/a,c/a,prolog/b,infi/b]).
student(6666,[java/a,c/a,prolog/b,infi/b,probability/b,algorithms/b]).

I wrote a predicat that queries which student has a string in the list attached to him that has: "infi/a"

findall(Ns,(student(Id,List),subset([infi/a],List)),L1)

The problem is that L1 does not return me a list as the following:

L1 = [student(2222,[c/b,algorithms/b,prolog/b,infi/a]),
      student(1111,[algorithms/a,prolog/a,c/a,infi/a]) etc...]

It returns:

L1 = [_G2044, _G2041, _G2038, _G2035].

Why does this happen and how can I fix this?


Solution

  • You probably need to look up the specifications of the findall/3 predicate the first parameters is the Template (or yield): it specifies what you want to put into the list.

    So you should not simply write X, but a term in which you are interested. For instance:

    findall(Id,(student(Id,List),subset([infi/a],List)),L1).

    will generate all the Ids of the students with infi/a in their list of courses; or if you are interested in the student/2 objects, you can write:

    findall(student(Id,List),(student(Id,List),subset([infi/a],List)),L1).

    So typically you work with the variable(s) you specify in the Goal (the second parameter), in case there is a free variable in your yield, it will make new free variables.