# -*- coding: utf-8 -*- from django.db.models import Max from dictionary.models import Lemma, reflex_phrase_types from semantics.models import LexicalUnitExamples from semantics.utils import get_structural_matching_frame def validate_frames(lemma_id): lemma = Lemma.objects.get(id=lemma_id) visible_frames = lemma.entry_obj.visible_frames() error_msg = u'' for frame in visible_frames.all(): error_msg = frame_valid(lemma, frame, visible_frames) if error_msg: break return error_msg def frame_valid(lemma, frame, frames): error_msg = '' complements = frame.complements.all() if not arguments_exists(complements): error_msg = u'Semantyka: Rama semantyczna %d jest pusta.' % frame.id elif not lexical_units_exists(frame): error_msg = u'Semantyka: Rama semantyczna %d nie ma dodanych znaczeń.' % frame.id elif not frame.opinion_selected(): error_msg = u'Semantyka: Rama semantyczna %d nie ma wybranej opinii.' % frame.id elif not roles_unique(complements): error_msg = u'Semantyka: Rama semantyczna %d nie zawiera unikalnych ról.' % frame.id elif not arguments_pinned(complements): error_msg = u'Semantyka: Rama semantyczna %d zawiera argumenty, które nie są powiązane z żadnym schematem.' % frame.id elif not preferences_selected(complements): error_msg = u'Semantyka: Rama semantyczna %d zawiera argumenty bez zdefiniowanych preferencji selekcyjnych.' % frame.id elif not examples_added(frame): error_msg = u'Semantyka: Rama semantyczna %d nie ma dopiętych przykładów.' % frame.id elif duplicates_exists(frame, frames): error_msg = u'Semantyka: Rama semantyczna %d posiada duplikaty.' % frame.id elif not schemas_reflex_agreed(lemma, frame): error_msg = u'Semantyka: Rama semantyczna %d ma dopięte elementy o niezgodnej zwrotności.' % frame.id elif nonch_pinned(frame): error_msg = u'Semantyka: Rama semantyczna %d jest dopięta do typu frazy nonch.' % frame.id elif multiplied_same_arg_in_schema(frame): error_msg = u'Semantyka: Rama semantyczna %d posiada argument wielokrotnie powiązany z tym samym schematem.' % frame.id # phraseologic elif multiword_only_frame_connected_to_not_phr_schema(frame): error_msg = u'Semantyka: Rama semantyczna %d (o samych wielosłownych znaczeniach) może być podłączona jedynie do schematów frazeologicznych.' % frame.id elif not multiword_frame_connected_to_at_least_one_phr_schema(frame): error_msg = u'Semantyka: Rama semantyczna %d (posiadająca wielosłowne znaczenie) musi zostać podłączona do co najmniej jednego schematu frazeologicznego.' % frame.id elif not frame_is_using_phraseologic_phr_type(frame): error_msg = u'Semantyka: Rama semantyczna %d podłączona do schematu frazeologicznego musi wykorzystywać co najmniej jeden zleksykalizowany typ frazy.' % frame.id elif not multiword_frame_has_lemma(frame): error_msg = u'Semantyka: Rama semantyczna %d musi posiadać rolę Lemma.' % frame.id elif singleword_only_frame_has_lemma(frame): error_msg = u'Semantyka: Rama semantyczna %d nie powinna posiadać roli Lemma.' % frame.id elif not lemma_always_pinned(frame): error_msg = u'Semantyka (rama %d): Rola Lemma, dla ram o samych znaczeniach wielosłownych, musi być zawsze realizowana w podłączonych schematach.' % frame.id return error_msg def arguments_exists(complements): return complements.exists() def lexical_units_exists(frame): return frame.lexical_units.exists() def roles_unique(complements): roles = set() for complement in complements: role_ids = [role.id for role in complement.roles.all()] role_ids.sort() role = tuple(role_ids) if role in roles: return False else: roles.add(role) return True def arguments_pinned(complements): for compl in complements: if not compl.realizations.exists(): return False return True def preferences_selected(complements): for complement in complements: if complement.realizations.exists() and complement.has_only_phraseologic_realizations(): pass elif not preference_valid(complement): return False return True def preference_valid(complement): preference = complement.selective_preference if preference is None: return False generals = preference.generals synsets = preference.synsets relations = preference.relations synset_relations = preference.synset_relations if generals.count() + synsets.count() + relations.count() + synset_relations.count() > 0: return True return False def examples_added(frame): for lexical_unit in frame.lexical_units.all(): if LexicalUnitExamples.objects.filter(lexical_unit=lexical_unit).exists(): return True return False def duplicates_exists(frame, frames): # frazeologicznych ram nie sprawdzamy if frame.complements.filter(roles__role='Lemma').exists(): return False frames_to_check = frames.exclude(id=frame.id) if get_structural_matching_frame(frames_to_check, frame): return True return False def schemas_reflex_agreed(lemma, frame): agreed = True complements = frame.complements.all() lexical_units = frame.lexical_units.all() for schema in lemma.frames.all(): schema_agreed = False for lex_unit in lexical_units: if schema_lex_unit_reflex_agree(lex_unit, schema, complements): schema_agreed = True break if not schema_agreed: agreed = False break return agreed def schema_lex_unit_reflex_agree(lexical_unit, schema, complements): if complements.filter(realizations__frame=schema).exists(): if (not reflex_with_self_mark_agreed(lexical_unit, schema) and not (lexical_unit.is_reflexive() and not lexical_unit.is_new() and reflex_with_phrase_types_agreed(lexical_unit, schema, complements))): return False return True def reflex_with_self_mark_agreed(lexical_unit, schema): schema_self_mark = schema.get_char_value('ZWROTNOŚĆ').value if not lexical_unit.is_reflexive() == bool(schema_self_mark): return False return True def reflex_with_phrase_types_agreed(lexical_unit, schema, complements): max_alternations = complements.all().aggregate(Max('realizations__alternation'))['realizations__alternation__max'] for alternation in range(1, max_alternations+1): if not reflex_with_alternation_phrase_types_agreed(complements, schema, alternation): return False return True def reflex_with_alternation_phrase_types_agreed(complements, schema, alternation): for compl in complements: if compl.realizations.filter(argument__type__in=reflex_phrase_types(), alternation=alternation, frame=schema).exists(): return True return False def nonch_pinned(frame): if frame.complements.filter(realizations__argument__text_rep='nonch').exists(): return True return False def multiplied_same_arg_in_schema(frame): for compl in frame.complements.all(): if compl.roles.filter(role='Lemma').exists(): continue else: for real in compl.realizations.all(): same_frame_realizations = compl.realizations.filter(frame=real.frame, alternation=real.alternation) if same_frame_realizations.exclude(position=real.position).exists(): return True return False # phraseologic def multiword_only_frame_connected_to_not_phr_schema(frame): if (frame.multiword_meanings_only() and frame.complements.filter(realizations__frame__phraseologic=False).exists()): return True return False def multiword_frame_connected_to_at_least_one_phr_schema(frame): valid = False if not frame.has_multiword_meaning(): valid = True elif (frame.has_multiword_meaning() and frame.complements.filter(realizations__frame__phraseologic=True).exists()): valid = True return valid def frame_is_using_phraseologic_phr_type(frame): phr_connected_schemata = frame.connected_schemata().filter(phraseologic=True) for schema in phr_connected_schemata: schema_ok = False for compl in frame.complements.all(): for real in compl.realizations.filter(frame=schema): if real.argument.is_phraseologic(): schema_ok = True break if schema_ok: break if not schema_ok: return False return True def multiword_frame_has_lemma(frame): valid = False if not frame.has_multiword_meaning(): valid = True elif (frame.has_multiword_meaning() and frame.role_exists('Lemma')): valid = True return valid def singleword_only_frame_has_lemma(frame): if(not frame.has_multiword_meaning() and frame.role_exists('Lemma')): return True return False def lemma_always_pinned(frame): if frame.role_exists('Lemma') and frame.multiword_meanings_only(): lemma_arg = frame.complements.get(roles__role='Lemma') connected_schemata = frame.connected_schemata() for schema in connected_schemata: if not lemma_arg.realizations.filter(frame=schema).exists(): return False return True def validate_schemas(lemma_id): error_msg = '' lemma = Lemma.objects.get(id=lemma_id, old=False) if not all_schemas_used(lemma): error_msg = u'Semantyka nie wykorzystuje wszystkich poprawnych schematów walencyjnych.' return error_msg def all_schemas_used(lemma): frames = lemma.entry_obj.visible_frames() schemas = lemma.frames for schema in schemas.all(): if not schema_is_bad(lemma, schema) and not schema_used(schema, frames): return False return True def schema_is_bad(lemma, schema): schema_opinion = lemma.frame_opinions.get(frame=schema) if schema_opinion.value.short == 'bad': return True return False def schema_used(schema, frames): for frame in frames: if frame.complements.filter(realizations__frame=schema).exists(): return True return False def validate_lexical_units(lemma_id): error_msg = '' lemma = Lemma.objects.get(id=lemma_id, old=False) lexical_units = lemma.entry_obj.meanings for lex_unit in lexical_units.all(): if not examples_reflex_agreed(lex_unit): error_msg = u'Semantyka: Znaczenie %s ma podpięte przykłady o niezgodnej zwrotności.' % unicode(lex_unit) elif hanging_meaning(lex_unit): error_msg = u'Semantyka: Znaczenie %s nie jest reprezentowane przez żadną ramę semantyczną.' % unicode(lex_unit) if error_msg: break return error_msg def examples_reflex_agreed(lexical_unit): lex_examples = LexicalUnitExamples.objects.filter(lexical_unit=lexical_unit) for lex_example in lex_examples: schema_reflex = lex_example.example.frame.get_char_value('ZWROTNOŚĆ').value if (not (lexical_unit.is_reflexive() == bool(schema_reflex)) and not (lexical_unit.is_reflexive() and not lexical_unit.is_new() and lex_example.example.arguments.filter(arguments__type__in=reflex_phrase_types()).exists())): return False return True def hanging_meaning(lexical_unit): if lexical_unit.luid < 0 and not lexical_unit.actual_frames().exists(): return True return False