Tutorial 2.1: Basic Definition of a Combinatory Categorial Grammar#

[1]:
import jacinle
from tabulate import tabulate
[2]:
# From tutorial/1-dsl/1-types-and-functions
from concepts.dsl.dsl_types import ValueType, ConstantType, BOOL, FLOAT32, VectorValueType, FormatContext
from concepts.dsl.dsl_functions import Function, FunctionTyping
from concepts.dsl.function_domain import FunctionDomain

t_item = ValueType('item')
t_item_set = ValueType('item_set')
t_concept_name = ConstantType('concept_name')
t_shape = ValueType('shape')
t_color = ValueType('color')
t_size = VectorValueType(FLOAT32, 3, alias='size')

domain = FunctionDomain()
domain.define_type(t_item)
domain.define_type(t_item_set)
domain.define_type(t_concept_name)
domain.define_type(t_color)
domain.define_type(t_shape)
domain.define_type(t_size)
domain.define_function(Function('scene', FunctionTyping[t_item_set]()))
domain.define_function(Function('filter_color', FunctionTyping[t_item_set](t_item_set, t_concept_name)))
domain.define_function(Function('filter_shape', FunctionTyping[t_item_set](t_item_set, t_concept_name)))
domain.define_function(Function('unique', FunctionTyping[t_item](t_item_set)))
domain.define_function(Function('color_of', FunctionTyping[t_color](t_item)))
domain.define_function(Function('shape_of', FunctionTyping[t_shape](t_item)))
domain.define_function(Function('size_of', FunctionTyping[t_size](t_item)))
domain.define_function(Function('same_color', FunctionTyping[BOOL](t_color, t_color)))
domain.define_function(Function('same_shape', FunctionTyping[BOOL](t_shape, t_shape)))
domain.define_function(Function('same_size', FunctionTyping[BOOL](t_size, t_size)))
[2]:
Function<same_size(#0: size, #1: size) -> bool>
[3]:
from concepts.language.ccg.syntax import CCGPrimitiveSyntaxType, CCGConjSyntaxType
[4]:
N = CCGPrimitiveSyntaxType('N')
N
[4]:
CCGPrimitiveSyntaxType<N>
[5]:
S = CCGPrimitiveSyntaxType('S')
S
[5]:
CCGPrimitiveSyntaxType<S>
[6]:
S_slash_N = S/N
S_slash_N
[6]:
CCGComposedSyntaxType<S/N>
[7]:
print(repr(S_slash_N.main))
CCGPrimitiveSyntaxType<S>
[8]:
print(repr(S_slash_N.sub))
CCGPrimitiveSyntaxType<N>
[9]:
S_slash_N.fapp(N)
[9]:
CCGPrimitiveSyntaxType<S>
[10]:
try:
    S_slash_N.bapp(N)
except Exception as e:
    print(e)
(Syntax) Cannot make backward application of N and S/N.
[11]:
S_slash_N_slash_N = S/N/N
S_slash_N_slash_N
[11]:
CCGComposedSyntaxType<S/N/N>
[12]:
print(repr(S_slash_N_slash_N.main))
CCGComposedSyntaxType<S/N>
[13]:
print(repr(S_slash_N_slash_N.sub))
CCGPrimitiveSyntaxType<N>
[14]:
CONJ = CCGConjSyntaxType('CONJ')
[15]:
CONJ.coord3(S_slash_N, S_slash_N)
[15]:
CCGComposedSyntaxType<S/N>
[16]:
from concepts.language.ccg.syntax import CCGSyntaxSystem
[17]:
ss = CCGSyntaxSystem()
ss.define_primitive_type('S')
ss.define_primitive_type('N')
print(repr(ss['S/N']))
print(repr(ss['S/N/N']))
print(ss)
CCGComposedSyntaxType<S/N>
CCGComposedSyntaxType<S/N/N>
CCGSyntaxSystem(S, N)
[18]:
from concepts.language.ccg.semantics import CCGSemantics
[19]:
sem_object = CCGSemantics(domain.lam(lambda: domain.f_scene()))
print(sem_object)
print(sem_object.value)
jacinle.stprint(sem_object.flags)
CCGSemantics[scene()]
scene()
dict{
  is_conj: False
  is_constant: False
  is_function: False
  is_function_application: True
  is_lazy: False
  is_none: False
  is_py_function: False
  is_value: True
}
[20]:
sem_red = CCGSemantics(domain.lam(lambda x: domain.f_filter_color(x, 'red')))
print(sem_red)
print(sem_red.value)
jacinle.stprint(sem_red.flags)
CCGSemantics[def __lambda__(x: item_set): return filter_color(V::x, red)]
def __lambda__(x: item_set): return filter_color(V::x, red)
dict{
  is_conj: False
  is_constant: False
  is_function: True
  is_function_application: False
  is_lazy: False
  is_none: False
  is_py_function: False
  is_value: False
}
[21]:
sem_red_object = sem_red.fapp(sem_object)
print(sem_red_object)
print(sem_red_object.value)
jacinle.stprint(sem_red_object.flags)
CCGSemantics[CCGSemanticsLazyValue(composition_type=<CCGCompositionType.FORWARD_APPLICATION: 'forward_application'>, lhs=Function<def __lambda__(x: item_set): return filter_color(V::x, red)>, rhs=FunctionApplicationExpression<scene()>, conj=None)]
CCGSemanticsLazyValue(composition_type=<CCGCompositionType.FORWARD_APPLICATION: 'forward_application'>, lhs=Function<def __lambda__(x: item_set): return filter_color(V::x, red)>, rhs=FunctionApplicationExpression<scene()>, conj=None)
dict{
  is_conj: False
  is_constant: None
  is_function: None
  is_function_application: None
  is_lazy: True
  is_none: False
  is_py_function: False
  is_value: None
}
[22]:
from concepts.language.ccg.grammar import CCG
[23]:
ccg = CCG(domain, ss)
ccg.add_entry_simple('red', ss['N/N'], CCGSemantics(domain.lam(lambda x: domain.f_filter_color(x, 'red'))))
ccg.add_entry_simple('object', ss['N'], CCGSemantics(domain.lam(lambda: domain.f_scene())))
[24]:
ccg.print_summary()
Combinatory Categorial Grammar
  FunctionDomain(FunctionDomain)
  CCGSyntaxSystem(S, N)
  CCGCompositionSystem(function_application)
  Lexicon Entries:
    red: Lexicon[syntax=N/N, semantics=def __lambda__(x: item_set): return filter_color(V::x, red), weight=0]
    object: Lexicon[syntax=N, semantics=scene(), weight=0]

[25]:
lexicon_table = list()
with FormatContext(function_format_lambda=True).as_default():
    for word, entries in ccg.lexicon_entries.items():
        for entry in entries:
            lexicon_table.append((word, str(entry.syntax), str(entry.semantics.value), str(entry.weight)))
print(tabulate(lexicon_table, headers=['word', 'syntax type', 'semantic form', 'weight']))
word    syntax type    semantic form                    weight
------  -------------  -----------------------------  --------
red     N/N            lam x.filter_color(V::x, red)         0
object  N              scene()                               0
[26]:
node_red = ccg.make_node('red')
print("make_node('red')", node_red, sep='\n')
node_object = ccg.make_node('object')
print("make_node('object')", node_object, sep='\n')
print("compose(node_red, node_object)", node_red.compose(node_object), sep='\n')
make_node('red')
CCGNode[
  syntax   : N/N
  semantics: CCGSemantics[lam x.filter_color(V::x, red)]
  weight   : 0
]
make_node('object')
CCGNode[
  syntax   : N
  semantics: CCGSemantics[scene()]
  weight   : 0
]
compose(node_red, node_object)
CCGCompositionResult(composition_type=<CCGCompositionType.FORWARD_APPLICATION: 'forward_application'>, result=CCGNode[
  syntax   : N
  semantics: CCGSemantics[CCGSemanticsLazyValue(composition_type=<CCGCompositionType.FORWARD_APPLICATION: 'forward_application'>, lhs=Function<lam x.filter_color(V::x, red)>, rhs=FunctionApplicationExpression<scene()>, conj=None)]
  weight   : 0
])
[27]:
candidate_parsings = ccg.parse('red object')
for node in candidate_parsings:
    print(node)
CCGNode[
  syntax   : N
  semantics: CCGSemantics[CCGSemanticsLazyValue(composition_type=<CCGCompositionType.FORWARD_APPLICATION: 'forward_application'>, lhs=Function<lam x.filter_color(V::x, red)>, rhs=FunctionApplicationExpression<scene()>, conj=None)]
  weight   : 0
]