Specifically, it uses the not/1 predicate, which is not given in the text, and negation in general is not discussed until chapter 10. Unfortunately, I don't think there's a way to cleanly answer this without negation. You can write it in a way that the first result of set/2 will be the one you are looking for, but subsequent results from set([...],X). will have duplicate entries, and queries to set([...],[...]). with duplicate entries in the second argument will succeed.