depth-first validation