Tutorial 1.2: Executing Programs in a Domain-Specific Language#

[1]:
# From tutorial/1-dsl/1-types-and-functions
from concepts.dsl.dsl_types import ValueType, ConstantType, BOOL, FLOAT32, VectorValueType
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)))
[1]:
Function<same_size(#0: size, #1: size) -> bool>
[2]:
from dataclasses import dataclass, field
from typing import Tuple, List

@dataclass
class Item(object):
    color: str
    shape: str
    size: Tuple[float, float, float]


@dataclass
class Scene(object):
    items: List[Item]
[3]:
from concepts.dsl.executors.function_domain_executor import FunctionDomainExecutor
[4]:
class Executor(FunctionDomainExecutor):
    def scene(self):
        return self.grounding.items
    def filter_color(self, inputs, color_name):
        return [o for o in inputs if o.color == color_name]
    def filter_shape(self, inputs, shape_name):
        return [o for o in inputs if o.shape == shape_name]
    def unique(self, inputs):
        assert len(inputs) == 1
        return inputs[0]
    def color_of(self, obj):
        return obj.color
    def shape_of(self, obj):
        return obj.shape
    def size_of(self, obj):
        return obj.size
    def same_color(self, c1, c2):
        return c1 == c2
    def same_shape(self, s1, s2):
        return s1 == s2
    def same_size(self, z1, z2):
        return all(abs(sz1 - sz2) < 0.1 for sz1, sz2 in zip(z1, z2))
[5]:
scene = Scene([
    Item('red', 'box', (1, 1, 1)),
    Item('blue', 'box', (1, 1, 1)),
    Item('green', 'box', (2, 2, 2))
])
[6]:
executor = Executor(domain)
10 11:37:26 Function scene automatically registered.
10 11:37:26 Function filter_color automatically registered.
10 11:37:26 Function filter_shape automatically registered.
10 11:37:26 Function unique automatically registered.
10 11:37:26 Function color_of automatically registered.
10 11:37:26 Function shape_of automatically registered.
10 11:37:26 Function size_of automatically registered.
10 11:37:26 Function same_color automatically registered.
10 11:37:26 Function same_shape automatically registered.
10 11:37:26 Function same_size automatically registered.
[7]:
result = executor.execute('scene()', scene)
print(result)
print(type(result))
print(result.dtype)
print(result.value)
V([Item(color='red', shape='box', size=(1, 1, 1)), Item(color='blue', shape='box', size=(1, 1, 1)), Item(color='green', shape='box', size=(2, 2, 2))], dtype=item_set)
<class 'concepts.dsl.value.Value'>
item_set
[Item(color='red', shape='box', size=(1, 1, 1)), Item(color='blue', shape='box', size=(1, 1, 1)), Item(color='green', shape='box', size=(2, 2, 2))]
[8]:
executor.execute('filter_color(scene(), "red")', scene)
[8]:
V([Item(color='red', shape='box', size=(1, 1, 1))], dtype=item_set)
[9]:
executor.execute('''same_shape(
    shape_of(unique(filter_color(scene(), "blue"))),
    shape_of(unique(filter_color(scene(), "red")))
)''', scene)
[9]:
V(True, dtype=bool)
[10]:
executor.execute(domain.f_same_size(
    domain.f_size_of(domain.f_unique(domain.f_filter_color(domain.f_scene(), "blue"))),
    domain.f_size_of(domain.f_unique(domain.f_filter_color(domain.f_scene(), "green")))
), scene)
[10]:
V(False, dtype=bool)
[11]:
same_color_obj = domain.lam(lambda x, y: domain.f_same_color(
    domain.f_color_of(domain.f_unique(x)),
    domain.f_color_of(domain.f_unique(y))
))
[12]:
print(same_color_obj)
def __lambda__(x: item_set, y: item_set): return same_color(color_of(unique(V::x)), color_of(unique(V::y)))
[13]:
print(same_color_obj.derived_expression)
same_color(color_of(unique(V::x)), color_of(unique(V::y)))
[14]:
executor.execute(same_color_obj(
    domain.f_filter_color(domain.f_scene(), "green"),
    domain.f_filter_color(domain.f_scene(), "blue")
), scene)
[14]:
V(False, dtype=bool)
[15]:
expr = executor.parse_expression('filter_color(scene(), "red")')
print(repr(expr))
FunctionApplicationExpression<filter_color(scene(), V(red, dtype=concept_name))>
[16]:
print(repr(expr.function))
print(repr(expr.arguments[0]))
print(repr(expr.arguments[1]))
Function<filter_color(#0: item_set, #1: concept_name) -> item_set>
FunctionApplicationExpression<scene()>
ConstantExpression<V(red, dtype=concept_name)>