Argument.py 5.66 KB
#! /usr/bin/python
# -*- coding: utf-8 -*-

from semantics.models import RelationalSelectionalPreference, PredefinedSelectionalPreference, \
                             SelectionalPreferenceRelation, ArgumentRole
import semantics.models
from meanings.models import Synset

class Relation:

    def __init__(self, type, argument_type, to):
        self._type = type
        self._argument_type = argument_type
        self._to = to

    @classmethod
    def fromTree(cls, tree):
        type = tree._children[0]._children[0]._attrs['value']
        argument_type = tree._children[1]._children[0]._attrs['type']
        to = tree._children[1]._children[0]._attrs['sameAs'][1:]
        if argument_type != 'argument':
            print(argument_type, to)
            raise UnknownError()
        return cls(type, argument_type, to)

    def store(self, frame, argument):
        role = self._to._semantic_role.get()
        to = frame.sorted_arguments().get(role=role)
        relation = SelectionalPreferenceRelation.objects.get(key=self._type)
        pref = RelationalSelectionalPreference(relation=relation, to=to)
        pref.save()
        argument.relations.add(pref)
    
    def __unicode__(self):
        return self._type + '->' + unicode(self._to._semantic_role)

class SelectionalPreference:

    def __init__(self, type, value):
        self._type = type
        self._value = value

    @classmethod
    def forType(cls, type, values):
        result = []
        reference_to_solve = []
        if type == 'predef':
            for value in values:
                result.append(cls(type, value._attrs['value']))
        elif type == 'synset':
            for value in values:
                result.append(cls(type, value._attrs['value']))
        elif type == 'relation':
            for value in values:
                x = Relation.fromTree(value)
                result.append(cls(type, x))
                reference_to_solve.append(x)
        else:
            print(type, values)
            raise UnknownError()
        return result, reference_to_solve
        # return [cls(type, value._attrs['value']) for value in values]
        
    @classmethod
    def fromTree(cls, tree):
        preferences = []
        references = []
        for subtree in tree._children[0]._children:
            new_preferences, new_references = cls.forType(subtree._attrs['name'][:-1], subtree._children[0]._children)
            preferences += new_preferences
            references += new_references
        return preferences, references

    def store(self, frame, argument):
        if self._type == 'predef':
            pref = PredefinedSelectionalPreference.objects.get(key=self._value)
            argument.predefined.add(pref)
        elif self._type == 'synset':
            pref = Synset.objects.get(id=self._value)
            argument.synsets.add(pref)
        elif self._type == 'relation':
            self._value.store(frame, argument)
        else:
            print(type, values)
            raise UnknownError()
        
    def __unicode__(self):
        return unicode(self._value)

        
class SemanticRole:

    def __init__(self, value, attribute=None):
        self._value = value
        self._attribute = attribute

    def get(self):
        return self.store()
        
    def store(self):
        role = semantics.models.SemanticRole.objects.get(role=self._value)
        if self._attribute is not None:
            attribute = semantics.models.RoleAttribute.objects.get(attribute=self._attribute)
        else:
            attribute=None
        argument_role = semantics.models.ArgumentRole.objects.get(role=role, attribute=attribute)
        return argument_role
        
    def __unicode__(self):
        if self._attribute is None:
            return self._value.lower()
        else:
            return '(' + self._value.lower() + '-' + self._attribute.lower() + ')'
        
        
class Argument:

    def __init__(self, semantic_role, selectional_preferences, references, id):
        self._frame = None
        self._semantic_role = semantic_role
        self._selectional_preferences = selectional_preferences
        self._references = references
        self._id = id
        
    @classmethod
    def fromTree(cls, tree):
        id = tree._attrs['xml:id']
        attribute = None
        selectional_preferences = []
        references = []

        for subtree in tree._children:
            if subtree._attrs['name'] == 'role':
                role = subtree._children[0]._attrs['value']
            elif subtree._attrs['name'] == 'role_attribute':
                attribute = subtree._children[0]._attrs['value']
            elif subtree._attrs['name'] == 'sel_prefs':
                selectional_preferences, references = SelectionalPreference.fromTree(subtree)
            else:
                print(subtree._attrs['name'])
                raise UnknownError()

        semantic_role = SemanticRole(role, attribute)
        
        return cls(semantic_role, selectional_preferences, references, id)

    def getId(self):
        return self._id

    def get(self, frame):
        role = self._semantic_role.get()
        argument = semantics.models.Argument.objects.get(frame=frame, role=role)
        return argument        
    
    def store(self, frame):
        role = self._semantic_role.store()
        argument = semantics.models.Argument(role=role, frame=frame)
        argument.save()
        return argument

    def store_preferences(self, frame, argument):
        for preference in self._selectional_preferences:
            preference.store(frame, argument)
    
    def __unicode__(self):
        return unicode(self._semantic_role) + '[' + ','.join([unicode(pref) for pref in self._selectional_preferences]) + ']'