= Solution
Use first cousins: the children of the siblings of a recorded parent. This includes cousins through a parent's half-sibling under the convention above. In <Haskell>:
``
cousins :: Database -> Person -> [Person]
cousins db p = unique [q | parent <- parents db p,
auntOrUncle <- siblings db parent,
q <- children db auntOrUncle, q /= p]
``
Selecting siblings of parents avoids the mistake of returning all people with a common grandparent, which would also return ordinary siblings. The explicit exclusion of `p` is harmless on an ordinary consistent pedigree and prevents a self-result in unusual records. Multiple relationship paths give just one output entry after <duplicate removal>. Thus
$$
\boxed{\operatorname{cousins}(db,p)=
\bigcup_{r\in\operatorname{parents}(db,p)}\ \bigcup_{s\in\operatorname{siblings}(db,r)}
\operatorname{children}(db,s)\setminus\{p\}.}
$$
Back to article page