code: def add_types(graph, phenotypes):  # TODO missing expression phenotypes! also basket type somehow :(
      
  
      collect = defaultdict(set)
      def recurse(id_, start, level=0):
          #print(level)
          for t in graph.g.triples((None, None, id_)):
              if level == 0:
                  if t[1] != rdflib.term.URIRef('http://www.w3.org/2002/07/owl#someValuesFrom'):
                      continue
              if type_check(t, (rdflib.term.URIRef, rdflib.term.URIRef, rdflib.term.BNode)):
                  #print(start, t[0])
                  collect[start].add(t[0])
                  return  #  we're done here, otherwise we hit instantiated subclasses
              if level > 1:
                  if t[1] == rdflib.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#first') or \
                     t[1] == rdflib.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#rest'):
                      continue
  
              recurse(t[0], start, level + 1)
  
  
      for phenotype in phenotypes:
          recurse(phenotype, phenotype)
  
      return collect
docs: Add disjoint union classes so that it is possible to see the invariants
          associated with individual phenotypes