109 lines
4.3 KiB
Python
109 lines
4.3 KiB
Python
import core.utils
|
|
from core.builtin_concepts import BuiltinConcepts, ErrorConcept
|
|
from core.concept import Concept, DEFINITION_TYPE_DEF, ensure_concept, DEFINITION_TYPE_BNF
|
|
from core.sheerka.services.sheerka_service import BaseService
|
|
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
|
|
|
|
BNF_NODE_PARSER_CLASS = "parsers.BnfNodeParser_Old.BnfNodeParser"
|
|
BASE_NODE_PARSER_CLASS = "parsers.BaseNodeParser.BaseNodeParser"
|
|
|
|
|
|
class SheerkaCreateNewConcept(BaseService):
|
|
"""
|
|
Manage the creation of a new concept
|
|
"""
|
|
|
|
NAME = "CreateNewConcept"
|
|
|
|
def __init__(self, sheerka):
|
|
super().__init__(sheerka)
|
|
self.bnp = core.utils.get_class(BASE_NODE_PARSER_CLASS) # BaseNodeParser
|
|
|
|
def initialize(self):
|
|
self.sheerka.bind_service_method(self.create_new_concept, True)
|
|
|
|
def create_new_concept(self, context, concept: Concept):
|
|
"""
|
|
Adds a new concept to the system
|
|
:param context:
|
|
:param concept: DefConceptNode
|
|
:return: digest of the new concept
|
|
"""
|
|
|
|
ensure_concept(concept)
|
|
|
|
sheerka = self.sheerka
|
|
|
|
concept.init_key()
|
|
init_bnf_ret_value = None
|
|
|
|
cache_manager = sheerka.cache_manager
|
|
|
|
if cache_manager.exists(sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash()):
|
|
error = SheerkaDataProviderDuplicateKeyError(sheerka.CONCEPTS_BY_KEY_ENTRY + "." + concept.key,
|
|
concept)
|
|
return sheerka.ret(
|
|
self.NAME,
|
|
False,
|
|
sheerka.new(BuiltinConcepts.ALREADY_DEFINED, body=concept),
|
|
error.args[0])
|
|
|
|
# set id before saving in db
|
|
sheerka.set_id_if_needed(concept, False)
|
|
|
|
# compute new concepts_by_first_keyword
|
|
init_ret_value = self.bnp.get_concepts_by_first_token(context, [concept], True)
|
|
if not init_ret_value.status:
|
|
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
|
|
concepts_by_first_keyword = init_ret_value.body
|
|
|
|
# computes resolved concepts_by_first_keyword
|
|
init_ret_value = self.bnp.resolve_concepts_by_first_keyword(context, concepts_by_first_keyword)
|
|
if not init_ret_value.status:
|
|
return sheerka.ret(self.NAME, False, ErrorConcept(init_ret_value.value))
|
|
resolved_concepts_by_first_keyword = init_ret_value.body
|
|
|
|
# if everything is fine
|
|
concept.freeze_definition_hash()
|
|
cache_manager.add_concept(concept)
|
|
cache_manager.put(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, False, concepts_by_first_keyword)
|
|
cache_manager.put(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, False, resolved_concepts_by_first_keyword)
|
|
|
|
if concept.metadata.definition_type == DEFINITION_TYPE_DEF and concept.metadata.definition != concept.name:
|
|
# allow search by definition when definition relevant
|
|
cache_manager.put(self.sheerka.CONCEPTS_BY_NAME_ENTRY, concept.metadata.definition, concept)
|
|
|
|
# update references
|
|
for ref in self.compute_references(concept):
|
|
cache_manager.put(sheerka.CONCEPTS_REFERENCES_ENTRY, ref, concept.id)
|
|
|
|
# TODO : this line seems to be useless
|
|
# The grammar is never reset
|
|
if concept.bnf and init_bnf_ret_value is not None and init_bnf_ret_value.status:
|
|
sheerka.cache_manager.clear(sheerka.CONCEPTS_GRAMMARS_ENTRY)
|
|
|
|
# process the return if needed
|
|
ret = sheerka.ret(self.NAME, True, sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
|
|
return ret
|
|
|
|
def compute_references(self, concept):
|
|
"""
|
|
We need to keep a track of all concepts used by the current concept
|
|
So that if one of these are modified, we can modify the current concept accordingly
|
|
:param concept:
|
|
:return:
|
|
"""
|
|
refs = set()
|
|
|
|
if concept.metadata.definition_type == DEFINITION_TYPE_BNF:
|
|
from parsers.BnfNodeParser import BnfNodeConceptExpressionVisitor
|
|
other_concepts_visitor = BnfNodeConceptExpressionVisitor()
|
|
other_concepts_visitor.visit(concept.bnf)
|
|
|
|
for concept in other_concepts_visitor.references:
|
|
if isinstance(concept, str):
|
|
concept = self.sheerka.get_by_key(concept)
|
|
refs.add(concept.id)
|
|
|
|
return refs
|