My goal is to have something like dave's grandfather to be parsed as match (:Male {name: 'Dave' })<-[:PARENT]-(parent)<-[:PARENT]-(grandfather:Male) return grandfather
If you want to label the grandfathers of Dave you could simply tag them:
match (:Male {name: 'Dave' })<-[:PARENT]-(parent)<-[:PARENT]-(grandfather:Male)
set grandfather:GrandfatherOfDave
Be careful, however, if you have more than one of this procedural inference rules. If they depend on each other (think of a :SON relationship that implies a reverse :PARENT relationship) you have to take care of their execution order, check of termination, etc.
What you describe might require the RDFS/OWL model and reasoning: