from dataclasses import dataclass from cache.Cache import Cache from core.builtin_concepts import BuiltinConcepts from core.builtin_helpers import ensure_concept from core.global_symbols import NotFound from core.sheerka.services.sheerka_service import BaseService, ServiceObj @dataclass class KnownPluralObj(ServiceObj): """ Order to store """ concept: str # id of the concept plural: str # id of its plural class SheerkaPluralManager(BaseService): NAME = "PluralManager" KNOWN_PLURAL_ENTRY = "SheerkaPluralManager:KnownPlural" def __init__(self, sheerka): super().__init__(sheerka, order=22) def initialize(self): cache = Cache().auto_configure(self.KNOWN_PLURAL_ENTRY) self.sheerka.om.register_cache(self.KNOWN_PLURAL_ENTRY, cache) self.sheerka.bind_service_method(self.NAME, self.set_plural, True) self.sheerka.bind_service_method(self.NAME, self.is_plural, False) self.sheerka.bind_service_method(self.NAME, self.known_plural, False) def set_plural(self, context, concept_a, concept_b): """ Set that a concept_a is the plural of concept_b :param context: :param concept_a: :param concept_b: :return: """ context.log(f"Setting concept {concept_a} as plural of {concept_b}", who=self.NAME) ensure_concept(concept_a, concept_b) if context.in_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED): concept_to_use = self.sheerka.get_by_id(concept_a.id) else: concept_to_use = concept_a if concept_to_use.get_prop(BuiltinConcepts.PLURAL) == concept_b: return self.sheerka.ret( self.NAME, False, self.sheerka.new(BuiltinConcepts.PROPERTY_ALREADY_DEFINED, property_value=concept_b, property_name=BuiltinConcepts.PLURAL, concept=concept_a)) if context.in_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED): # update the list of known plurals known_plural = KnownPluralObj(context.event.get_digest(), concept_b.id, concept_a.id) self.sheerka.om.put(self.KNOWN_PLURAL_ENTRY, concept_b.id, known_plural) # update the concept to_add = {"props": {BuiltinConcepts.PLURAL: concept_b}} res = self.sheerka.modify_concept(context, concept_to_use, to_add) concept_a.set_prop(BuiltinConcepts.PLURAL, concept_b) # do it AFTER calling modify_concept() return res else: concept_a.set_prop(BuiltinConcepts.PLURAL, concept_b) return self.sheerka.ret(self.NAME, True, concept_a) def is_plural(self, concept_a, concept_b=None): """ True if concept_a is a plural if concept_b is omitted True if concept_a is the plural of concept_b if concept_b is given :param concept_a: :param concept_b: :return: """ ensure_concept(concept_a) if concept_b is None: return BuiltinConcepts.PLURAL in concept_a.get_metadata().props ensure_concept(concept_b) return concept_a.get_prop(BuiltinConcepts.PLURAL) == concept_b def known_plural(self, concept): """ Return the id of the concept's known plural if any. NotFound otherwise :param concept: :return: """ ensure_concept(concept) res = self.sheerka.om.get(self.KNOWN_PLURAL_ENTRY, concept.id) if res is NotFound: return NotFound return res.plural