A very simple way to detect this, is by checking that constraint itself:
What cannot happend is that a horse appear as a father or grandfather or greatgrandfather of ITSELF.
Whenever you insert a node in your tree, traverse the tree to the root to make sure that the horse does not exist as a any kind of parent.
To speed this up, you can associate a hashtable to each node, where you cache the answer of such a lookup. Then you don't have to search the entire path next time you insert a horse under that node.
Consider a path of A -> B -> C (that is A is the root and B is a child of A and C is a child of C. Then you want to insert a horse B under C. then you traverse towards A and find that the same horse is a parent of C, so you add B to a hashtable in the node C. Then the next time you want to add B anywhere under C, you dont have to look further than C.
I'm not sure that whis optimization will really be an optimization, as it depends a lot on the data.