generateDefs :: ConsPDTree -> ([Def], G X)
generateDefs tree =
  let toplevel = fromJust $ nodeContent tree in
  let leaves = collectLeaves tree in
  let gens = collectGens tree in
  let distinct = nub $ map snd leaves in
  let simplified = restrictSubsts $ simplify $ renameAmbigousVars tree in
  let nodes = (toplevel, simplified) : map (\(_,x) -> findNode x tree) gens ++ map (`findNode` tree) distinct in
  let definitions = foldl (\defs gs -> fst3 (CpdR.renameGoals gs defs) ) [] $ map fst nodes in
  let defWithTree = zip (reverse definitions) (map snd nodes) in
  let invocations = map (generateInvocation definitions) leaves in
  trace (printf "\nDefinitions\n%s\n\n" (intercalate "\n" (map show definitions))) $ 
  let defs = map (generateDef definitions invocations) defWithTree in
  -- let defs = map (generateDef invocations) defWithTree in
  let (_, newGoal) = generateInvocation definitions (toplevel, toplevel) in
  (defs, Res.vident <$> newGoal)
generateDefs :: ConsPDTree -> ([Def], G X)
generateDefs tree =
  let toplevel = fromJust $ nodeContent tree in
  let leaves = collectLeaves tree in
  let gens = collectGens tree in
  let distinct = nub $ map snd leaves in
  let simplified = restrictSubsts $ simplify $ renameAmbigousVars tree in
  let nodes = (toplevel, simplified) : map (\(_,x) -> findNode x tree) gens ++ map (`findNode` tree) distinct in
  let definitions = foldl (\defs gs -> fst3 (CpdR.renameGoals gs defs) ) [] $ map fst nodes in
  let defWithTree = zip (reverse definitions) (map snd nodes) in
  let invocations = map (generateInvocation definitions) leaves in
  trace (printf "\nDefinitions\n%s\n\n" (intercalate "\n" (map show definitions))) $ 
  let defs = map (generateDef definitions invocations) defWithTree in
  -- let defs = map (generateDef invocations) defWithTree in
  let (_, newGoal) = generateInvocation definitions (toplevel, toplevel) in
  (defs, Res.vident <$> newGoal)
generateDefs tree =
  let toplevel = fromJust $ nodeContent tree in
  let leaves = collectLeaves tree in
  let gens = collectGens tree in
  let distinct = nub $ map snd leaves in
  let simplified = restrictSubsts $ simplify $ renameAmbigousVars tree in
  let nodes = (toplevel, simplified) : map (\(_,x) -> findNode x tree) gens ++ map (`findNode` tree) distinct in
  let definitions = foldl (\defs gs -> fst3 (CpdR.renameGoals gs defs) ) [] $ map fst nodes in
  let defWithTree = zip (reverse definitions) (map snd nodes) in
  let invocations = map (generateInvocation definitions) leaves in
  trace (printf "\nDefinitions\n%s\n\n" (intercalate "\n" (map show definitions))) $ 
  let defs = map (generateDef definitions invocations) defWithTree in
  -- let defs = map (generateDef invocations) defWithTree in
  let (_, newGoal) = generateInvocation definitions (toplevel, toplevel) in
  (defs, Res.vident <$> newGoal)