<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_annotation( self, subj: URIRef, pred: URIRef, obj: Union[Literal, URIRef], a_p: URIRef , a_o: Union[Literal, URIRef], ) -> BNode: """ 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. """

        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