def constituents(self, constraint=None):
<EOL>W = self.words<EOL>n = len(self.pattern.sequence)<EOL>if isinstance(constraint, (int, Constraint)):<EOL><INDENT>if isinstance(constraint, int):<EOL><INDENT>i = constraint <EOL>i = i<<NUM_LIT:0> and i%n or i<EOL><DEDENT>else:<EOL><INDENT>i = self.pattern.sequence.index(constraint)<EOL><DEDENT>W = self._map2.get(i,[])<EOL>W = [self.words[i-self.words[<NUM_LIT:0>].index] for i in W]            <EOL><DEDENT>if isinstance(constraint, (list, tuple)):<EOL><INDENT>W = []; [W.extend(self._map2.get(j<<NUM_LIT:0> and j%n or j,[])) for j in constraint]<EOL>W = [self.words[i-self.words[<NUM_LIT:0>].index] for i in W]<EOL>W = unique(W)<EOL><DEDENT>a = []<EOL>i = <NUM_LIT:0><EOL>while i < len(W):<EOL><INDENT>w = W[i]<EOL>if w.chunk and W[i:i+len(w.chunk)] == w.chunk.words:<EOL><INDENT>i += len(w.chunk) - <NUM_LIT:1><EOL>a.append(w.chunk)<EOL><DEDENT>else:<EOL><INDENT>a.append(w)<EOL><DEDENT>i += <NUM_LIT:1><EOL><DEDENT>return a<EOL>
Returns a list of Word and Chunk objects, 
            where words have been grouped into their chunks whenever possible.
            Optionally, returns only chunks/words that match given constraint(s), or constraint index.