Skip to content
This repository was archived by the owner on Dec 16, 2022. It is now read-only.

Commit 7ddc7f1

Browse files
authored
Automatically map function names to aliases for NLTK's logic parser (#1870)
* added a name mapper to take care of alias automatically * removed obsolete lines
1 parent 3989000 commit 7ddc7f1

8 files changed

+298
-246
lines changed

allennlp/semparse/type_declarations/nlvr_type_declaration.py

+102-105
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
"""
22
Defines all the types in the QuaRel domain.
33
"""
4-
from typing import Dict
5-
from allennlp.semparse.type_declarations.type_declaration import ComplexType, NamedBasicType, Type
4+
from allennlp.semparse.type_declarations.type_declaration import ComplexType, NamedBasicType, NameMapper
65

76
class QuarelTypeDeclaration:
87
def __init__(self, syntax: str) -> None:
98

10-
self.common_name_mapping: Dict[str, str] = {}
11-
12-
self.common_type_signature: Dict[str, Type] = {}
9+
self.name_mapper = NameMapper()
1310

1411
num_type = NamedBasicType("NUM")
1512
attr_type = NamedBasicType("ATTR")
@@ -30,18 +27,18 @@ def __init__(self, syntax: str) -> None:
3027
infer_function_type = ComplexType(attr_type,
3128
ComplexType(attr_type,
3229
ComplexType(attr_type, num_type)))
33-
self.add_common_name_with_type("infer", "I10", infer_function_type)
30+
self.name_mapper.map_name_with_signature("infer", infer_function_type)
3431
# Attributes
35-
self.add_common_name_with_type("friction", "A10", attr_function_type)
36-
self.add_common_name_with_type("smoothness", "A11", attr_function_type)
37-
self.add_common_name_with_type("speed", "A12", attr_function_type)
38-
self.add_common_name_with_type("heat", "A13", attr_function_type)
39-
self.add_common_name_with_type("distance", "A14", attr_function_type)
32+
self.name_mapper.map_name_with_signature("friction", attr_function_type)
33+
self.name_mapper.map_name_with_signature("smoothness", attr_function_type)
34+
self.name_mapper.map_name_with_signature("speed", attr_function_type)
35+
self.name_mapper.map_name_with_signature("heat", attr_function_type)
36+
self.name_mapper.map_name_with_signature("distance", attr_function_type)
4037

4138
# For simplicity we treat "high" and "low" as directions as well
42-
self.add_common_name_with_type("high", "R12", rdir_type)
43-
self.add_common_name_with_type("low", "R13", rdir_type)
44-
self.add_common_name_with_type("and", "C10", and_function_type)
39+
self.name_mapper.map_name_with_signature("high", rdir_type)
40+
self.name_mapper.map_name_with_signature("low", rdir_type)
41+
self.name_mapper.map_name_with_signature("and", and_function_type)
4542

4643
self.curried_functions = {
4744
attr_function_type: 2,
@@ -59,14 +56,14 @@ def __init__(self, syntax: str) -> None:
5956
infer_function_type = ComplexType(attr_type,
6057
ComplexType(attr_type,
6158
ComplexType(attr_type, num_type)))
62-
self.add_common_name_with_type("infer", "I10", infer_function_type)
59+
self.name_mapper.map_name_with_signature("infer", infer_function_type)
6360
# TODO: Remove this?
64-
self.add_common_name_with_type("placeholder", "A99", attr_function_type)
61+
self.name_mapper.map_name_with_signature("placeholder", attr_function_type)
6562

6663
# For simplicity we treat "high" and "low" as directions as well
67-
self.add_common_name_with_type("high", "R12", rdir_type)
68-
self.add_common_name_with_type("low", "R13", rdir_type)
69-
self.add_common_name_with_type("and", "C10", and_function_type)
64+
self.name_mapper.map_name_with_signature("high", rdir_type)
65+
self.name_mapper.map_name_with_signature("low", rdir_type)
66+
self.name_mapper.map_name_with_signature("and", and_function_type)
7067

7168
self.curried_functions = {
7269
attr_function_type: 2,
@@ -85,32 +82,32 @@ def __init__(self, syntax: str) -> None:
8582
infer_function_type = ComplexType(attr_type,
8683
ComplexType(attr_type,
8784
ComplexType(attr_type, num_type)))
88-
self.add_common_name_with_type("infer", "I10", infer_function_type)
85+
self.name_mapper.map_name_with_signature("infer", infer_function_type)
8986
# Attributes
90-
self.add_common_name_with_type("friction", "A10", attr_function_type)
91-
self.add_common_name_with_type("smoothness", "A11", attr_function_type)
92-
self.add_common_name_with_type("speed", "A12", attr_function_type)
93-
self.add_common_name_with_type("heat", "A13", attr_function_type)
94-
self.add_common_name_with_type("distance", "A14", attr_function_type)
95-
self.add_common_name_with_type("acceleration", "A15", attr_function_type)
96-
self.add_common_name_with_type("amountSweat", "A16", attr_function_type)
97-
self.add_common_name_with_type("apparentSize", "A17", attr_function_type)
98-
self.add_common_name_with_type("breakability", "A18", attr_function_type)
99-
self.add_common_name_with_type("brightness", "A19", attr_function_type)
100-
self.add_common_name_with_type("exerciseIntensity", "A20", attr_function_type)
101-
self.add_common_name_with_type("flexibility", "A21", attr_function_type)
102-
self.add_common_name_with_type("gravity", "A22", attr_function_type)
103-
self.add_common_name_with_type("loudness", "A23", attr_function_type)
104-
self.add_common_name_with_type("mass", "A24", attr_function_type)
105-
self.add_common_name_with_type("strength", "A25", attr_function_type)
106-
self.add_common_name_with_type("thickness", "A26", attr_function_type)
107-
self.add_common_name_with_type("time", "A27", attr_function_type)
108-
self.add_common_name_with_type("weight", "A28", attr_function_type)
87+
self.name_mapper.map_name_with_signature("friction", attr_function_type)
88+
self.name_mapper.map_name_with_signature("smoothness", attr_function_type)
89+
self.name_mapper.map_name_with_signature("speed", attr_function_type)
90+
self.name_mapper.map_name_with_signature("heat", attr_function_type)
91+
self.name_mapper.map_name_with_signature("distance", attr_function_type)
92+
self.name_mapper.map_name_with_signature("acceleration", attr_function_type)
93+
self.name_mapper.map_name_with_signature("amountSweat", attr_function_type)
94+
self.name_mapper.map_name_with_signature("apparentSize", attr_function_type)
95+
self.name_mapper.map_name_with_signature("breakability", attr_function_type)
96+
self.name_mapper.map_name_with_signature("brightness", attr_function_type)
97+
self.name_mapper.map_name_with_signature("exerciseIntensity", attr_function_type)
98+
self.name_mapper.map_name_with_signature("flexibility", attr_function_type)
99+
self.name_mapper.map_name_with_signature("gravity", attr_function_type)
100+
self.name_mapper.map_name_with_signature("loudness", attr_function_type)
101+
self.name_mapper.map_name_with_signature("mass", attr_function_type)
102+
self.name_mapper.map_name_with_signature("strength", attr_function_type)
103+
self.name_mapper.map_name_with_signature("thickness", attr_function_type)
104+
self.name_mapper.map_name_with_signature("time", attr_function_type)
105+
self.name_mapper.map_name_with_signature("weight", attr_function_type)
109106

110107
# For simplicity we treat "high" and "low" as directions as well
111-
self.add_common_name_with_type("high", "R12", rdir_type)
112-
self.add_common_name_with_type("low", "R13", rdir_type)
113-
self.add_common_name_with_type("and", "C10", and_function_type)
108+
self.name_mapper.map_name_with_signature("high", rdir_type)
109+
self.name_mapper.map_name_with_signature("low", rdir_type)
110+
self.name_mapper.map_name_with_signature("and", and_function_type)
114111

115112
self.curried_functions = {
116113
attr_function_type: 2,
@@ -121,19 +118,15 @@ def __init__(self, syntax: str) -> None:
121118
else:
122119
raise Exception(f"Unknown LF syntax specification: {syntax}")
123120

124-
self.add_common_name_with_type("higher", "R10", rdir_type)
125-
self.add_common_name_with_type("lower", "R11", rdir_type)
121+
self.name_mapper.map_name_with_signature("higher", rdir_type)
122+
self.name_mapper.map_name_with_signature("lower", rdir_type)
126123

127-
self.add_common_name_with_type("world1", "W11", world_type)
128-
self.add_common_name_with_type("world2", "W12", world_type)
124+
self.name_mapper.map_name_with_signature("world1", world_type)
125+
self.name_mapper.map_name_with_signature("world2", world_type)
129126

130127
# Hack to expose types
131128
self.world_type = world_type
132129
self.attr_function_type = attr_function_type
133130
self.var_type = var_type
134131

135132
self.starting_types = {num_type}
136-
137-
def add_common_name_with_type(self, name: str, mapping: str, type_signature: Type) -> None:
138-
self.common_name_mapping[name] = mapping
139-
self.common_type_signature[mapping] = type_signature

allennlp/semparse/type_declarations/type_declaration.py

+49
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,55 @@ def __eq__(self, other):
478478
return NotImplemented
479479

480480

481+
class NameMapper:
482+
"""
483+
The ``LogicParser`` we use has some naming conventions for functions (i.e. they should start
484+
with an upper case letter, and the remaining characters can only be digits). This means that we
485+
have to internally represent functions with unintuitive names. This class will automatically
486+
give unique names following the convention, and populate central mappings with these names. If
487+
for some reason you need to manually define the alias, you can do so by passing an alias to
488+
`map_name_with_signature`.
489+
490+
Parameters
491+
----------
492+
language_has_lambda : ``bool`` (optional, default=False)
493+
If your language has lambda functions, the word "lambda" needs to be in the common name
494+
mapping, mapped to the alias "\". NLTK understands this symbol, and it doesn't need a type
495+
signature for it. Setting this flag to True adds the mapping to `common_name_mapping`.
496+
"""
497+
def __init__(self, language_has_lambda: bool = False) -> None:
498+
self.common_name_mapping: Dict[str, str] = {}
499+
if language_has_lambda:
500+
self.common_name_mapping["lambda"] = "\\"
501+
self.common_type_signature: Dict[str, Type] = {}
502+
self._name_counter = 0
503+
504+
def map_name_with_signature(self,
505+
name: str,
506+
signature: Type,
507+
alias: str = None) -> None:
508+
if name in self.common_name_mapping:
509+
alias = self.common_name_mapping[name]
510+
old_signature = self.common_type_signature[alias]
511+
if old_signature != signature:
512+
raise RuntimeError(f"{name} already added with signature {old_signature}. "
513+
f"Cannot add it again with {signature}!")
514+
else:
515+
alias = alias or f"F{self._name_counter}"
516+
self._name_counter += 1
517+
self.common_name_mapping[name] = alias
518+
self.common_type_signature[alias] = signature
519+
520+
def get_alias(self, name: str) -> str:
521+
if name not in self.common_name_mapping:
522+
raise RuntimeError(f"Unmapped name: {name}")
523+
return self.common_name_mapping[name]
524+
525+
def get_signature(self, name: str) -> Type:
526+
alias = self.get_alias(name)
527+
return self.common_type_signature[alias]
528+
529+
481530
def substitute_any_type(type_: Type, basic_types: Set[BasicType]) -> List[Type]:
482531
"""
483532
Takes a type and a set of basic types, and substitutes all instances of ANY_TYPE with all

allennlp/semparse/type_declarations/wikitables_lambda_dcs.py

+40-40
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77
from nltk.sem.logic import Type, BasicType, ANY_TYPE, ComplexType as NltkComplexType
88

9-
from allennlp.semparse.type_declarations.type_declaration import ComplexType, HigherOrderType
10-
from allennlp.semparse.type_declarations.type_declaration import PlaceholderType, NamedBasicType
11-
from allennlp.semparse.type_declarations.type_declaration import UnaryOpType, BinaryOpType
9+
from allennlp.semparse.type_declarations.type_declaration import (ComplexType, HigherOrderType,
10+
PlaceholderType, NamedBasicType,
11+
UnaryOpType, BinaryOpType,
12+
NameMapper)
1213

1314

1415
class ReverseType(PlaceholderType, HigherOrderType):
@@ -209,40 +210,39 @@ def substitute_any_type(self, basic_types: Set[BasicType]) -> List[Type]:
209210
# argmax, argmin
210211
ARG_EXTREME_TYPE = ArgExtremeType()
211212

212-
213-
COMMON_NAME_MAPPING = {"lambda": "\\", "var": "V", "x": "X"}
214-
215-
216-
COMMON_TYPE_SIGNATURE = {"V": IDENTITY_TYPE, "X": ANY_TYPE}
217-
218-
219-
def add_common_name_with_type(name, mapping, type_signature):
220-
COMMON_NAME_MAPPING[name] = mapping
221-
COMMON_TYPE_SIGNATURE[mapping] = type_signature
222-
223-
add_common_name_with_type("reverse", "R", REVERSE_TYPE)
224-
add_common_name_with_type("argmax", "A0", ARG_EXTREME_TYPE)
225-
add_common_name_with_type("argmin", "A1", ARG_EXTREME_TYPE)
226-
add_common_name_with_type("max", "M0", UNARY_DATE_NUM_OP_TYPE)
227-
add_common_name_with_type("min", "M1", UNARY_DATE_NUM_OP_TYPE)
228-
add_common_name_with_type("and", "A", CONJUNCTION_TYPE)
229-
add_common_name_with_type("or", "O", CONJUNCTION_TYPE)
230-
add_common_name_with_type("fb:row.row.next", "N", ROW_TO_ROW_TYPE)
231-
add_common_name_with_type("number", "I", NUMBER_FUNCTION_TYPE)
232-
add_common_name_with_type("date", "D0", DATE_FUNCTION_TYPE)
233-
add_common_name_with_type("fb:cell.cell.part", "P", PART_TO_CELL_TYPE)
234-
add_common_name_with_type("fb:cell.cell.date", "D1", DATE_TO_CELL_TYPE)
235-
add_common_name_with_type("fb:cell.cell.number", "I1", NUM_TO_CELL_TYPE)
236-
add_common_name_with_type("fb:cell.cell.num2", "I2", NUM_TO_CELL_TYPE)
237-
add_common_name_with_type("fb:row.row.index", "W", ROW_INDEX_TYPE)
238-
add_common_name_with_type("fb:type.row", "T0", ROW_TYPE)
239-
add_common_name_with_type("fb:type.object.type", "T", ROW_TO_ROW_TYPE)
240-
add_common_name_with_type("count", "C", COUNT_TYPE)
241-
add_common_name_with_type("!=", "Q", IDENTITY_TYPE)
242-
add_common_name_with_type(">", "G0", UNARY_DATE_NUM_OP_TYPE)
243-
add_common_name_with_type(">=", "G1", UNARY_DATE_NUM_OP_TYPE)
244-
add_common_name_with_type("<", "L0", UNARY_DATE_NUM_OP_TYPE)
245-
add_common_name_with_type("<=", "L1", UNARY_DATE_NUM_OP_TYPE)
246-
add_common_name_with_type("sum", "S0", UNARY_NUM_OP_TYPE)
247-
add_common_name_with_type("avg", "S1", UNARY_NUM_OP_TYPE)
248-
add_common_name_with_type("-", "F", BINARY_NUM_OP_TYPE) # subtraction
213+
name_mapper = NameMapper(language_has_lambda=True) # pylint: disable=invalid-name
214+
215+
# We hardcode some the names "V" and "X" to mean "var" and "x" in the DynamicTypeLogicParser to deal
216+
# with these special types appropriately. So forcing their aliases here.
217+
name_mapper.map_name_with_signature(name="var", signature=IDENTITY_TYPE, alias="V")
218+
name_mapper.map_name_with_signature(name="x", signature=ANY_TYPE, alias="X")
219+
220+
name_mapper.map_name_with_signature("reverse", REVERSE_TYPE)
221+
name_mapper.map_name_with_signature("argmax", ARG_EXTREME_TYPE)
222+
name_mapper.map_name_with_signature("argmin", ARG_EXTREME_TYPE)
223+
name_mapper.map_name_with_signature("max", UNARY_DATE_NUM_OP_TYPE)
224+
name_mapper.map_name_with_signature("min", UNARY_DATE_NUM_OP_TYPE)
225+
name_mapper.map_name_with_signature("and", CONJUNCTION_TYPE)
226+
name_mapper.map_name_with_signature("or", CONJUNCTION_TYPE)
227+
name_mapper.map_name_with_signature("fb:row.row.next", ROW_TO_ROW_TYPE)
228+
name_mapper.map_name_with_signature("number", NUMBER_FUNCTION_TYPE)
229+
name_mapper.map_name_with_signature("date", DATE_FUNCTION_TYPE)
230+
name_mapper.map_name_with_signature("fb:cell.cell.part", PART_TO_CELL_TYPE)
231+
name_mapper.map_name_with_signature("fb:cell.cell.date", DATE_TO_CELL_TYPE)
232+
name_mapper.map_name_with_signature("fb:cell.cell.number", NUM_TO_CELL_TYPE)
233+
name_mapper.map_name_with_signature("fb:cell.cell.num2", NUM_TO_CELL_TYPE)
234+
name_mapper.map_name_with_signature("fb:row.row.index", ROW_INDEX_TYPE)
235+
name_mapper.map_name_with_signature("fb:type.row", ROW_TYPE)
236+
name_mapper.map_name_with_signature("fb:type.object.type", ROW_TO_ROW_TYPE)
237+
name_mapper.map_name_with_signature("count", COUNT_TYPE)
238+
name_mapper.map_name_with_signature("!=", IDENTITY_TYPE)
239+
name_mapper.map_name_with_signature(">", UNARY_DATE_NUM_OP_TYPE)
240+
name_mapper.map_name_with_signature(">=", UNARY_DATE_NUM_OP_TYPE)
241+
name_mapper.map_name_with_signature("<", UNARY_DATE_NUM_OP_TYPE)
242+
name_mapper.map_name_with_signature("<=", UNARY_DATE_NUM_OP_TYPE)
243+
name_mapper.map_name_with_signature("sum", UNARY_NUM_OP_TYPE)
244+
name_mapper.map_name_with_signature("avg", UNARY_NUM_OP_TYPE)
245+
name_mapper.map_name_with_signature("-", BINARY_NUM_OP_TYPE) # subtraction
246+
247+
COMMON_NAME_MAPPING = name_mapper.common_name_mapping
248+
COMMON_TYPE_SIGNATURE = name_mapper.common_type_signature

0 commit comments

Comments
 (0)