“Nonatomic expression” error when identifying certain positions in a list [duplicate]

This question already has an answer here:

Using Position (which requires a pattern) in the same manner as Select (which requires a criterion)

4 answers

Please can anyone help ?
I have a list of sets, and I am trying to find the positions in that list of those sets which are subsets of a given set. (Here I am ignoring the distinction between lists and sets, possibly at my peril.)

The following code

subsetQ[A_, B_] := Intersection[A, B] == A;
Position[{{a, b}, {b}, {e, f}, {c, e}, {c}}, _?(subsetQ[#, {b, c, e}] &), 1]

gives the output

{{2}, {4}, {5}}

which is exactly what I want.

Many thanks to these contributors

How to find the position of elements in a list satisfying criteria

for showing me the way.
However, my code also generates the error message

Intersection::normal: “Nonatomic expression expected at position 1 in List[Intersection]{b,c,e}.”

Is there a way to avoid this message, other than suppressing it using

Off[General::normal].

?

I have studied the documentation here:

http://reference.wolfram.com/language/tutorial/PuttingConstraintsOnPatterns.html

to try to understand whether I should use x_/; or _?() but I confess I don’t understand it well.

Thank you very much.

=================

=================

2 Answers
2

=================

Specifying that your pattern should only match expressions with a List head prevents the error that you observed.

In addition, there already is a built-in SubsetQ function (here are its docs). I would typically try to use a built-in over a user function whenever possible, since the former might benefit from better algorithms and internal optimizations under the hood.

The syntax of the built in is slightly different from that of your function, but the idea is essentially the same. Here are two versions that achieve the same goal using either PatternTest (?) or Condition (/;):

Position[{{a, b}, {b}, {e, f}, {c, e}, {c}}, p_List /; SubsetQ[{b, c, e}, p], 1]
Position[{{a, b}, {b}, {e, f}, {c, e}, {c}}, _List?(SubsetQ[{b, c, e}, #] &), 1]

(* Out:
{{2}, {4}, {5}}
{{2}, {4}, {5}}
*)

Leonid Shifrin recently wrote up a deeper discussion of PatternTest vs. Condition that you might be interested as an answer to this question: Why does pattern test work only with pure functions?

Add the option Heads -> False:

Position[{{a, b}, {b}, {e, f}, {c, e}, {c}}, _?(subsetQ[#, {b, c, e}]&), 1, Heads->False]

(* Out: {{2}, {4}, {5}} *)