docs: def point_mutate(self,p_i,func_set,term_set):
          """point mutation on individual p_i"""
          # point mutation
          x = self.random_state.randint(len(p_i))
          arity = p_i[x].arity[p_i[x].in_type]
          # find eligible replacements based on arity and type
          reps = [n for n in func_set+term_set
                  if n.arity[n.in_type]==arity and n.out_type==p_i[x].out_type
                  and n.in_type==p_i[x].in_type]
  
          tmp = reps[self.random_state.randint(len(reps))]
          tmp_p = p_i[:]
          p_i[x] = tmp
          if not self.is_valid_program(p_i):
              print("old:",tmp_p)
              print("new:",p_i)
              raise ValueError('Mutation produced an invalid program.')