[docs]classEntityManager:"""文書全体のエンティティを管理."""entities:ClassVar[dict[int,Entity]]={}#: ID をキーとするエンティティの辞書.
[docs]@classmethoddefget_or_create_entity(cls,exophora_referent:Optional[ExophoraReferent]=None,eid:Optional[int]=None)->Entity:"""自身が参照するエンティティを作成. exophora_referent が singleton entity だった場合を除き,新しく Entity のインスタンスを作成して返す. singleton entity とは,「著者」や「不特定:人1」などの文書中に必ず一つしか存在しないような entity. 一方で,「不特定:人」や「不特定:物」は複数存在しうるので singleton entity ではない. Args: exophora_referent: 外界照応における照応先.対応するものがなければ None. eid: エンティティ ID.None の場合自動で割り振る. Returns: Entity: 作成されたエンティティ. """ifexophora_referentisnotNoneandexophora_referent.is_singleton():entities=[eforeincls.entities.values()ifexophora_referent==e.exophora_referent]# If a singleton entity already exists, do not create a new entity, but return that entity.ifentities:assertlen(entities)==1# ensure that there is only one singleton entityreturnentities[0]ifeidincls.entities:returncls.entities[eid]elifeidisNone:eid=max(cls.entities.keys())+1ifcls.entitieselse0entity=Entity(eid,exophora_referent=exophora_referent)cls.entities[eid]=entityreturnentity
[docs]@classmethoddefmerge_entities(cls,source_mention:"BasePhrase",target_mention:Optional["BasePhrase"],source_entity:Entity,target_entity:Entity,is_nonidentical:bool,)->None:"""2つのエンティティをマージ. source_mention と source_entity, target_mention と target_entity の間には参照関係があるが, source と target 間には関係が作られていないので,add_mention する. source_entity と target_entity が同一のエンティティであり,exophor も同じか片方が None ならば target_entity の方を削除する. Args: source_mention: ソース側メンション. target_mention: ターゲット側メンション.メンションが存在しない場合は None. source_entity: ソース側エンティティ. target_entity: ターゲット側エンティティ. is_nonidentical: ソース側メンションとターゲット側メンションの関係が nonidentical なら True. """asserttarget_entityintarget_mention.entities_alliftarget_mentionelseTrueassertsource_entityinsource_mention.entities_allis_tgt_nonidentical=target_mentionisnotNoneandtarget_entityintarget_mention.entities_nonidenticalis_src_nonidentical=source_entityinsource_mention.entities_nonidenticalifsource_entityistarget_entity:ifnotis_nonidentical:# When two sides of a triangle formed by source_entity (=target_entity), source_mention, and# target_mention are identical, the other side is also identical.ifnotis_src_nonidenticalandis_tgt_nonidentical:asserttarget_mentionisnotNonesource_entity.add_mention(target_mention,is_nonidentical=False)ifis_src_nonidenticalandnotis_tgt_nonidentical:source_entity.add_mention(source_mention,is_nonidentical=False)returniftarget_mentionisnotNone:source_entity.add_mention(target_mention,is_nonidentical=(is_nonidenticaloris_src_nonidentical))target_entity.add_mention(source_mention,is_nonidentical=(is_nonidenticaloris_tgt_nonidentical))# When source_entity and target_entity may not be identical, do not delete target_entity.ifis_nonidenticaloris_tgt_nonidenticaloris_src_nonidentical:return# When exophora_referent of source_entity and target_entity is different, target_entity is not deleted.if(source_entity.exophora_referentisnotNoneandtarget_entity.exophora_referentisnotNoneandsource_entity.exophora_referent!=target_entity.exophora_referent):return# prepare to delete target_entity as followsifsource_entity.exophora_referentisNone:source_entity.exophora_referent=target_entity.exophora_referentfortmintarget_entity.mentions_all:source_entity.add_mention(tm,is_nonidentical=target_entityintm.entities_nonidentical)# Arguments also have entity ids and will be updated.source_sentence=source_mention.sentencepas_list=source_mention.document.pas_listifsource_sentence.has_document()elsesource_sentence.pas_listforargin[argforpasinpas_listforargsinpas.get_all_arguments(relax=False).values()forarginargs]:ifisinstance(arg,ExophoraArgument)andarg.eid==target_entity.eid:arg.eid=source_entity.eidcls.delete_entity(target_entity)