code: def add_annotation(
              self,
              subj: URIRef,
              pred: URIRef,
              obj: Union[Literal, URIRef],
              a_p: URIRef ,
              a_o: Union[Literal, URIRef],
          ) -> BNode:
          
          bnode: BNode = self.triple2annotation_bnode.get( (subj, pred, obj) )
          if not bnode:
              a_s: BNode = BNode()
              self.triple2annotation_bnode[(subj, pred, obj)]: BNode = a_s
              self.g.add((a_s, RDF.type, OWL.Axiom))
              self.g.add((a_s, OWL.annotatedSource, self.process_subj_or_pred(subj)))
              self.g.add((a_s, OWL.annotatedProperty,self.process_subj_or_pred(pred)))
              self.g.add((a_s, OWL.annotatedTarget, self.process_obj(obj)))
          else:
              a_s: BNode = bnode
          self.g.add((a_s, self.process_subj_or_pred(a_p), self.process_obj(a_o)))
          return bnode
docs: Adds annotation to rdflib graph.
  
          The annotation axiom will filled in if this is a new annotation for the triple.
  
          Args:
              subj: Entity subject to be annotated
              pref: Entities Predicate Anchor to be annotated
              obj: Entities Object Anchor to be annotated
              a_p: Annotation predicate
              a_o: Annotation object
  
          Returns:
              A BNode which is an address to the location in the RDF graph that is storing the
              annotation information.