def fallback_schema(cat):
    rules = ["{(TEMP 0)}"]
    while "/" in cat or "\\" in cat:
        parts = category.divide(cat)
        if parts[1] == "/":
            rules.append("(NP 0 1)")
        else:
            rules.append("(NP 1 0)")
        cat = parts[0]
        plain_cat = cat
        if plain_cat not in markup_info:
            plain_cat = category.strip_square_brackets(cat)
        if plain_cat in markup_info:
            markup_lines = markup_info[plain_cat][1:]
            if "/" not in markup_lines[0] and "\\" not in markup_lines[0]:
                rules += markup_lines
                return rules
    return rules
Beispiel #2
0
def determine_combinator(source, result):
    ###	print len(source)
    ###	print ' '.join(source), result
    if len(source) == 0:
        return 'lex'
    if len(source) == 1:
        if get_unary(source[0].category, result) is not None:
            return 'unary'
        return 'type'
    if len(source) == 2:
        left = source[0].category
        right = source[1].category
        result_parts = category.divide(result)
        left_parts = category.divide(left)
        right_parts = category.divide(right)

        if get_binary(left, right, result) is not None:
            return 'binary'

        # Coordination
        # X = X CONJ X
        if left == 'conj' or (result.endswith('[conj]')
                              and not '[conj]' in right):
            if right == 'conj\\conj':
                return 'fa.b'
            return 'conj1'
        elif 'conj' in source[1].rule or '[conj]' in right:
            if category.compare(left, right):
                return 'conj2'
            if category.compare(category.divide(left)[2],
                                right) and category.divide(left)[1] == '/':
                return 'fa.f'
            if category.compare(
                    category.divide(right)[0],
                    left) and category.divide(right)[1] is not None:
                if 'conj2' in source[
                        1].rule or '[conj]' in right and category.compare(
                            category.divide(right)[2], left):
                    return 'fa.b'
                else:
                    return 'conj1'
            if category.compare(category.divide(right)[2], left):
                return 'fa.b'
            if (category.compare(left_parts[2], result_parts[2])
                    and category.compare(left_parts[0], right_parts[2])
                    and category.compare(right_parts[0], result_parts[0])
                    and left_parts[1] == result_parts[1] == '/'
                    and right_parts[1] == '\\'):
                return 'cc.b'
            if (category.compare(left_parts[2], right_parts[0])
                    and category.compare(left_parts[0], result_parts[0])
                    and category.compare(right_parts[2], result_parts[2]) and
                    left_parts[1] == right_parts[1] == result_parts[1] == '/'):
                return 'fc.f'
            if (category.compare(left_parts[2], result_parts[2])
                    and category.compare(left_parts[0], right_parts[2])
                    and category.compare(right_parts[0], result_parts[0])
                    and left_parts[1] == right_parts[1] == result_parts[1] ==
                    '\\'):
                return 'fc.b'
            if category.compare(result, left):
                if '[conj]' in result:
                    return 'conj2'
                raw_right = right
                if '[conj]' in right:
                    raw_right = right[:-6]
                if category.compare(result, raw_right):
                    return 'conj2'
            else:
                return 'conj2'
        elif 'conj1' in source[0].rule or '[conj]' in left:
            return 'conj2'
        # consider conj3, to handle , separated lists

        # Function application
        # X = X/Y + Y
        if (left_parts[1] == '/' and category.compare(left_parts[2], right)
                and category.compare(left_parts[0], result)):
            return 'fa.f'
        # X = Y + X\Y
        if (right_parts[1] == '\\' and category.compare(right_parts[2], left)
                and category.compare(right_parts[0], result)):
            return 'fa.b'

        # Function composition
        # X/Z = X/Y + Y/Z
        if (category.compare(left_parts[2], right_parts[0])
                and category.compare(left_parts[0], result_parts[0])
                and category.compare(right_parts[2], result_parts[2])
                and left_parts[1] == right_parts[1] == result_parts[1] == '/'):
            return 'fc.f'
        # X\Z = Y\Z + X\Y
        if (category.compare(left_parts[2], result_parts[2])
                and category.compare(left_parts[0], right_parts[2])
                and category.compare(right_parts[0], result_parts[0]) and
                left_parts[1] == right_parts[1] == result_parts[1] == '\\'):
            return 'fc.b'

        # Crossed composition
        # X/Z = Y/Z + X\Y
        # For example:
        # (S\NP)/(S\NP) = (S\NP)/(S\NP) + (S\NP)\(S\NP)
        if (category.compare(left_parts[2], result_parts[2])
                and category.compare(left_parts[0], right_parts[2])
                and category.compare(right_parts[0], result_parts[0])
                and left_parts[1] == result_parts[1] == '/'
                and right_parts[1] == '\\'):
            return 'cc.b'
        # Z\X = Z/Y + Y\X
        # ((S\NP)/S)/(S\NP) = ((S\NP)/S)/(S\NP) + (S\NP)\(S\NP)

        # Backward crossed substitution
        # X/Z = B/Z + (X\B)/Z
        if (left_parts[1] == right_parts[1] == result_parts[1] == '/'
                and category.compare(left_parts[2], result_parts[2])
                and category.compare(right_parts[2], result_parts[2])):
            sub_parts = category.divide(right_parts[0])
            if (category.compare(sub_parts[0], result_parts[0])
                    and category.compare(sub_parts[2], left_parts[0])
                    and sub_parts[1] != left_parts[1]):
                return 'bs.f'
        # X\Z = (X/B)\Z + B\Z
        if (left_parts[1] == right_parts[1] == result_parts[1] == '\\'
                and category.compare(left_parts[2], result_parts[2])
                and category.compare(right_parts[2], result_parts[2])):
            sub_parts = category.divide(left_parts[0])
            if (sub_parts[0] == result_parts[0]
                    and sub_parts[2] == right_parts[0]
                    and sub_parts[1] != right_parts[1]):
                return 'bs.b'
        # There are restrictions on what B can be, but since this is a parse, and
        # all other options have been exhausted, this must be what is going on

        # Uncomment to see what is misc:


###	if left == result and '/' not in right and '\\' not in right:
###		pass
###	elif right == result and '/' not in left and '\\' not in left:
###		pass
###	elif '[conj]' in left or '[conj]' in right or '[conj]' in result:
###		pass
###	else:
###		print 'misc rule:', left, right, result
###		print ' ', left_parts
###		print ' ', right_parts
###		print ' ', result_parts
        if category.divide(result)[0] == right and category.divide(
                result)[1] is not None:
            return 'conj1'
    return 'misc'
Beispiel #3
0
def determine_combinator(source, result):
###	print len(source)
###	print ' '.join(source), result
	if len(source) == 0:
		return 'lex'
	if len(source) == 1:
		if get_unary(source[0].category, result) is not None:
			return 'unary'
		return 'type'
	if len(source) == 2:
		left = source[0].category
		right = source[1].category
		result_parts = category.divide(result)
		left_parts = category.divide(left)
		right_parts = category.divide(right)

		if get_binary(left, right, result) is not None:
			return 'binary'

		# Coordination
		# X = X CONJ X
		if left == 'conj' or (result.endswith('[conj]') and not '[conj]' in right):
			if right == 'conj\\conj':
				return 'fa.b'
			return 'conj1'
		elif 'conj' in source[1].rule or '[conj]' in right:
			if category.compare(left, right):
				return 'conj2'
			if category.compare(category.divide(left)[2], right) and category.divide(left)[1] == '/':
				return 'fa.f'
			if category.compare(category.divide(right)[0], left) and category.divide(right)[1] is not None:
				if 'conj2' in source[1].rule or '[conj]' in right and category.compare(category.divide(right)[2], left):
					return 'fa.b'
				else:
					return 'conj1'
			if category.compare(category.divide(right)[2], left):
				return 'fa.b'
			if (category.compare(left_parts[2], result_parts[2]) and
					category.compare(left_parts[0], right_parts[2]) and
					category.compare(right_parts[0], result_parts[0]) and
					left_parts[1] == result_parts[1] == '/' and
					right_parts[1] == '\\'):
				return 'cc.b'
			if (category.compare(left_parts[2], right_parts[0]) and
					category.compare(left_parts[0], result_parts[0]) and
					category.compare(right_parts[2], result_parts[2]) and
					left_parts[1] == right_parts[1] == result_parts[1] == '/'):
				return 'fc.f'
			if (category.compare(left_parts[2], result_parts[2]) and
					category.compare(left_parts[0], right_parts[2]) and
					category.compare(right_parts[0], result_parts[0]) and
					left_parts[1] == right_parts[1] == result_parts[1] == '\\'):
				return 'fc.b'
			if category.compare(result, left):
				if '[conj]' in result:
					return 'conj2'
				raw_right = right
				if '[conj]' in right:
					raw_right = right[:-6]
				if category.compare(result, raw_right):
					return 'conj2'
			else:
				return 'conj2'
		elif 'conj1' in source[0].rule or '[conj]' in left:
			return 'conj2'
		# consider conj3, to handle , separated lists

		# Function application
		# X = X/Y + Y
		if (left_parts[1] == '/' and
		    category.compare(left_parts[2], right) and
		    category.compare(left_parts[0], result)):
			return 'fa.f'
		# X = Y + X\Y
		if (right_parts[1] == '\\' and
		    category.compare(right_parts[2], left) and
		    category.compare(right_parts[0], result)):
			return 'fa.b'

		# Function composition
		# X/Z = X/Y + Y/Z
		if (category.compare(left_parts[2], right_parts[0]) and
		    category.compare(left_parts[0], result_parts[0]) and
		    category.compare(right_parts[2], result_parts[2]) and
		    left_parts[1] == right_parts[1] == result_parts[1] == '/'):
			return 'fc.f'
		# X\Z = Y\Z + X\Y
		if (category.compare(left_parts[2], result_parts[2]) and
		    category.compare(left_parts[0], right_parts[2]) and
		    category.compare(right_parts[0], result_parts[0]) and
		    left_parts[1] == right_parts[1] == result_parts[1] == '\\'):
			return 'fc.b'

		# Crossed composition
		# X/Z = Y/Z + X\Y
		# For example:
		# (S\NP)/(S\NP) = (S\NP)/(S\NP) + (S\NP)\(S\NP)
		if (category.compare(left_parts[2], result_parts[2]) and
		    category.compare(left_parts[0], right_parts[2]) and
		    category.compare(right_parts[0], result_parts[0]) and
		    left_parts[1] == result_parts[1] == '/' and
		    right_parts[1] == '\\'):
			return 'cc.b'
		# Z\X = Z/Y + Y\X
		# ((S\NP)/S)/(S\NP) = ((S\NP)/S)/(S\NP) + (S\NP)\(S\NP)

		# Backward crossed substitution
		# X/Z = B/Z + (X\B)/Z
		if (left_parts[1] == right_parts[1] == result_parts[1] == '/' and
		    category.compare(left_parts[2], result_parts[2]) and
		    category.compare(right_parts[2], result_parts[2])):
			sub_parts = category.divide(right_parts[0])
			if (category.compare(sub_parts[0], result_parts[0]) and
			    category.compare(sub_parts[2], left_parts[0]) and
			    sub_parts[1] != left_parts[1]):
				return 'bs.f'
		# X\Z = (X/B)\Z + B\Z
		if (left_parts[1] == right_parts[1] == result_parts[1] == '\\' and
		    category.compare(left_parts[2], result_parts[2]) and
		    category.compare(right_parts[2], result_parts[2])):
			sub_parts = category.divide(left_parts[0])
			if (sub_parts[0] == result_parts[0] and
			    sub_parts[2] == right_parts[0] and
			    sub_parts[1] != right_parts[1]):
				return 'bs.b'
		# There are restrictions on what B can be, but since this is a parse, and
		# all other options have been exhausted, this must be what is going on

		# Uncomment to see what is misc:
###	if left == result and '/' not in right and '\\' not in right:
###		pass
###	elif right == result and '/' not in left and '\\' not in left:
###		pass
###	elif '[conj]' in left or '[conj]' in right or '[conj]' in result:
###		pass
###	else:
###		print 'misc rule:', left, right, result
###		print ' ', left_parts
###		print ' ', right_parts
###		print ' ', result_parts
		if category.divide(result)[0] == right and category.divide(result)[1] is not None:
			return 'conj1'
	return 'misc'