diff --git a/frontend/src/components/unification/Unification/LexicalUnitEdit.vue b/frontend/src/components/unification/Unification/LexicalUnitEdit.vue index 60ed43d30be4ddbd9a98af9cf14bf3e60548fb07..fc30aba7ba5e1a38161e7a02acdad9c1c71f382c 100644 --- a/frontend/src/components/unification/Unification/LexicalUnitEdit.vue +++ b/frontend/src/components/unification/Unification/LexicalUnitEdit.vue @@ -279,6 +279,15 @@ Object.assign(LexicalUnitEdit, { } $.prompt(change_title_popup); }, + roleStrMapping(roleName) { + if(roleName === 'role') { + return 'required'; + } else if(roleName === 'modifier') { + return 'typical'; + } else { + return roleName; + } + }, changeRole() { if (!this.active_unified_frame_argument) { alert(gettext("Zaznacz argument, dla którego chcesz wybrać rolę.")); @@ -305,7 +314,7 @@ Object.assign(LexicalUnitEdit, { }).join(""); // const roleTypeHTML = ['required', 'typical'].map(type => { const roleTypeHTML = ['role', 'modifier'].map(type => { - return `<label><input type="radio" name="role_type" value="${type}" /> ${type}</label><br />`; + return `<label><input type="radio" name="role_type" value="${type}" /> ${this.roleStrMapping(type)}</label><br />`; }).join(""); return '<div class="row">' + '<div class="column"><div class="role_select_header">Type</div>' + roleTypeHTML + '</div>' + @@ -1125,7 +1134,7 @@ export default LexicalUnitEdit; @mouseover="unifiedFrameArgumentHovered(argument)" @mouseleave="unifiedFrameArgumentHovered(null)" > - <span style="font-size: 0.8rem;">{{ argument.role_type }}</span> + <span style="font-size: 0.8rem;">{{ roleStrMapping(argument.role_type) }}</span> <div v-if="argument.role" > diff --git a/frontend/src/components/unification/Unification/SelectionalPreference.js b/frontend/src/components/unification/Unification/SelectionalPreference.js index abde3b55257280043660552ada80ec7db4d8ec7a..46d14855b6c44096427ebe43ae09c8df5f33be7c 100644 --- a/frontend/src/components/unification/Unification/SelectionalPreference.js +++ b/frontend/src/components/unification/Unification/SelectionalPreference.js @@ -318,7 +318,26 @@ export default class SelectionalPreference { data: data, timeout: 60000, success: function (response) { - show_info('Preferencja zosała zapisana'); + const succ = response.succ; + if(succ) { + show_info('Preferencja zosała zapisana'); + } else { + const conflict_hyponym = response.conflict_hyponym; + const conflict_hyperonym = response.conflict_hyperonym; + let typeStr = 'hiponimii'; + if(conflict_hyperonym != null){ + typeStr = 'hieronimii'; + } + let errorStr = conflict_hyponym; + if(conflict_hyperonym != null){ + errorStr = conflict_hyperonym; + } + alert('Wybrana preferencja selekcyjna nie mogła zostać zapisana ponieważ wystąpił konflikt w relacji ' + + typeStr + + ' z istniejącą preferencją selekcyjną: ' + + errorStr) + show_info('Preferencja nie zosała zapisana. Wystąpił konflikt w hierarchii ontologicznej.'); + } }, error: function (request, errorType, errorMessage) { show_error(errorType + ' (' + errorMessage + ')'); diff --git a/unifier/apps.py b/unifier/apps.py index dd387d2556c6044b05eef95d3a1227c6c98155ac..e18d14146a3ed70db775c1590b0879947d9dfc88 100644 --- a/unifier/apps.py +++ b/unifier/apps.py @@ -1,5 +1,53 @@ from django.apps import AppConfig +class SynsetHierarchy: + id = -1 + hyponyms = [] + hyperonyms = [] + + def __init__(self, id): + self.id = id + self.hyponyms = [] + self.hyperonyms = [] + + +synset_hierarchy_dict = {} + + class UnifierConfig(AppConfig): name = 'unifier' + + def ready(self): + print("XXXXXXXXXXXXX") + from meanings.models import Synset + from django.db.models import Prefetch + i = 0 + objs = Synset.objects + objs = objs.prefetch_related( + Prefetch( + "hypernyms", + + ) + ) + for synset in objs.all(): + print("i: "+str(i)) + i = i + 1 + curr = None + if synset.id not in synset_hierarchy_dict: + curr = SynsetHierarchy(id=synset.id) + synset_hierarchy_dict[synset.id] = curr + else: + curr = synset_hierarchy_dict[synset.id] + + for hypernym in synset.hypernyms.all(): + curr_hypernym = None + if hypernym.id not in synset_hierarchy_dict: + curr_hypernym = SynsetHierarchy(id=hypernym.id) + synset_hierarchy_dict[hypernym.id] = curr_hypernym + else: + curr_hypernym = synset_hierarchy_dict[hypernym.id] + + curr.hyperonyms.append(curr_hypernym) + curr_hypernym.hyponyms.append(curr) + diff --git a/unifier/views.py b/unifier/views.py index e7c63b87beef16a2711e18f69bc6879651c02fde..99c2add142b814d1468a9d5904c5f05dab7e4d2e 100644 --- a/unifier/views.py +++ b/unifier/views.py @@ -33,9 +33,20 @@ from django.views.decorators.csrf import csrf_exempt import urllib3 +from .apps import synset_hierarchy_dict, SynsetHierarchy from .choices import UnifiedFrameStatus +def get_predefined_preference_synsets(predefined, list_to_fill): + for pp in predefined: + if pp.members: + synsets_all = pp.members.synsets.all() + list_to_fill.extend(list(map(lambda s: s.id, synsets_all))) + generals_all = pp.members.generals.all() + if generals_all: + get_predefined_preference_synsets(generals_all, list_to_fill) + + @ajax_required @transaction.atomic def save_synset_preference(request): @@ -45,10 +56,30 @@ def save_synset_preference(request): synset_preference_id = request.POST['synset_preference_id'] unified_frame_argument = UnifiedFrameArgument.objects.get(unified_frame_id=int(frame_id), id=int(complement_id)) - unified_frame_argument.synsets.add(int(synset_preference_id)) - unified_frame_argument.save() - update_argument_preferences_count(unified_frame_argument) + synset_ids_map = map(lambda s: s.id, unified_frame_argument.synsets.all()) + + predefined_synset_ids = [] + get_predefined_preference_synsets(unified_frame_argument.predefined.all(), predefined_synset_ids) + + synset_ids_list = list(synset_ids_map) + synset_ids_list.extend(predefined_synset_ids) + + conflict_hyponym, conflict_hyperonym = synset_hierarchy_constraint_check(int(synset_preference_id), set(synset_ids_list)) + + if conflict_hyponym is None and conflict_hyperonym is None: + unified_frame_argument.synsets.add(int(synset_preference_id)) + unified_frame_argument.save() + update_argument_preferences_count(unified_frame_argument) + return JsonResponse({"succ": True}) + else: + conflict_hyponym_lu = LexicalUnit.objects.filter(synset_id=conflict_hyponym) if conflict_hyponym is not None else None + conflict_hyperonym_lu = LexicalUnit.objects.filter(synset_id=conflict_hyperonym) if conflict_hyperonym is not None else None + + conflict_hyponym_lu_str = ','.join(map(lambda s: str(s), conflict_hyponym_lu.all())) if conflict_hyponym is not None else None + conflict_hyperonym_lu_str = ','.join(map(lambda s: str(s), conflict_hyperonym_lu.all())) if conflict_hyperonym is not None else None + + return JsonResponse({"succ": False, "conflict_hyponym": conflict_hyponym_lu_str, "conflict_hyperonym": conflict_hyperonym_lu_str}) return JsonResponse({}) @@ -889,3 +920,42 @@ def attach_lu_to_unified_frame(request): return JsonResponse({}) return JsonResponse({}) + + +def synset_hierarchy_constraint_check(lu_id, pref_lu_ids): + + conflict_hyponym = None + if lu_id in synset_hierarchy_dict: + synset_hierarchy = synset_hierarchy_dict[lu_id] + conflict_hyponym = hierarchy_constraint_check_hypo(synset_hierarchy, lu_id, pref_lu_ids) + + conflict_hyperonym = None + if lu_id in synset_hierarchy_dict: + synset_hierarchy = synset_hierarchy_dict[lu_id] + conflict_hyperonym = hierarchy_constraint_check_hyperonyms(synset_hierarchy, lu_id, pref_lu_ids) + + return conflict_hyponym, conflict_hyperonym + + +def hierarchy_constraint_check_hyperonyms(synset_hierarchy: SynsetHierarchy, lu_id: int, pref_lu_ids: []): + for synset in synset_hierarchy.hyperonyms: + if synset.id in pref_lu_ids: + return synset.id + for synset in synset_hierarchy.hyperonyms: + ret = hierarchy_constraint_check_hyperonyms(synset_hierarchy_dict[synset.id], lu_id, pref_lu_ids) + if ret is not None: + return ret + + return None + + +def hierarchy_constraint_check_hypo(synset_hierarchy: SynsetHierarchy, lu_id: int, pref_lu_ids: []): + for synset in synset_hierarchy.hyponyms: + if synset.id in pref_lu_ids: + return synset.id + for synset in synset_hierarchy.hyponyms: + ret = hierarchy_constraint_check_hypo(synset_hierarchy_dict[synset.id], lu_id, pref_lu_ids) + if ret is not None: + return ret + + return None