diff --git a/experiments/convert_to_pdf.sh b/experiments/convert_to_pdf.sh new file mode 100755 index 0000000..5c05bcc --- /dev/null +++ b/experiments/convert_to_pdf.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Define the input and output files +input_file="parametric_expressivity.md" +output_file="parametric_expressivity.pdf" + +# Check if the input file exists +if [ -f "$input_file" ]; then + echo "Converting $input_file to PDF..." + pandoc "$input_file" -o "$output_file" --pdf-engine=pdflatex + echo "Conversion complete: $output_file created." +else + echo "Error: $input_file not found." + exit 1 +fi diff --git a/experiments/grid_xform_spec_10.py b/experiments/grid_xform_spec_10.py new file mode 100644 index 0000000..de21a29 --- /dev/null +++ b/experiments/grid_xform_spec_10.py @@ -0,0 +1,23 @@ +# type: ignore + +""" +Describe this transformation from grids to grids (ARC challenge). +""" + + +class GridTransformSpec: + colors = ["blue", "red", "green" "yellow"] + + def Pre(self): + Objs = self.find_objects() + assert all(obj.getColor() == "grey" for obj in Objs1) + Objs1 = sorted(Objs, key=lambda obj: obj.height) + return Objs + + def Post(self): + Objs = self.Pre() + + def obj_func(obj, index): + color = colors[index] + return obj.copy().setColor(color) + return Grid.from_objects(Objs, obj_func=obj_func) diff --git a/experiments/grid_xform_spec_5.py b/experiments/grid_xform_spec_5.py new file mode 100644 index 0000000..6db2166 --- /dev/null +++ b/experiments/grid_xform_spec_5.py @@ -0,0 +1,39 @@ +# type: ignore + +""" +Describe this transformation from grids to grids (ARC challenge). +Notice that transformations are described as predicates `Pre --> Post` where `Pre` describes the grid before the transformation, and `Post` the grid after the transformation. +To connect different predicates, `&&` is used for conjunction. +For example ` Obj1.getColor() == Obj2.getColor && Obj1.getSize() = (3,3)`. + +Note that NestedGrid(origin, size) return a new nested grid, where there is a sub-grid of size `size` at each coordinate `(x,y)`. At coordinate `(0,0)`, the nested grid contains the grid of size `size` at position `origin` in the initial grid. +All operations are immutable. In particular setXXX returns a copy of the receives with some property set as in the argument. +""" + + +class GridTransformSpec: + def Pre(self): + Objs = self.find_objects() + Obj = Objs.max() + Origin = Obj.getOrigin() + Size = Obj.getSize() + NestedGrid = self.grid_to_subgrids(subgrid_size=Size, origin=Origin) + return [NestedGrid, Obj] + + def Post(): + NG0, Obj0 = self.Pre() + + def clamp(p): + return [max(min(p[0], 1), -1), max(min(p[1], 1), -1)] + + def is_cardinal_or_diagonal(p): + return p[0] == 0 or p[1] == 0 or abs(p[0]) == abs(p[1]) + + def new_color(p): + Obj = NG0[clamp(p)] + return Obj.getColor() if is_cardinal_or_diagonal(p): else 0 + NG1 = create_grid_of_objects(subgrid_size=Size, + subgrid_func=lambda p: Obj.copy().setColor(get_color(p))) + Grid1 = NG1.flatten() + Grid1 = Grid1.shift(Origin) + return Grid1 diff --git a/experiments/parametric_expressivity.md b/experiments/parametric_expressivity.md new file mode 100644 index 0000000..b89a619 --- /dev/null +++ b/experiments/parametric_expressivity.md @@ -0,0 +1,78 @@ + + +### Introduction + +In the ARC challenge DSL, transformations (xforms) map one grid to another. To formalize these transformations, we use **shape types** to describe the sets of grids that a transformation can operate on. This allows us to distinguish between non-parametric and parametric transformations, depending on whether the transformations are specific to particular grid types or generalized using type variables. + +### Shape Types + +A **shape type** $S$ denotes a set of grids. This can capture structure such as dimensions, content patterns, or other properties. For example: + +- $S$ could represent all grids of a certain size, like all $3 \times 3$ grids. +- $S$ could also represent grids with a specific pattern, such as grids where all cells along the diagonal are the same. + +Shape types include singleton types, denoting specific grids, and type variables `X` of kind `Grid` (for now). + +### Transformations + +A **transformation** $\text{xf}$ is a total function $Grid \rightarrow Grid$. + +### Specs +A **spec** $[S,T]$ denotes the set of transformations $\text{xf}$ such that $\forall G \in Grid. G \in S \Rightarrow \text{xf}(G) \in T$ + +In addition, $[S1,T1] \wedge [S2,T2] \wedge [S3,T3]$ is also a spec, denoting the intersection. + +### Matching +A **spec** $[S,T]$ matches an example $(I,O)$ if + +1. $I \in S$ +2. $\forall \text{xf}. \text{xf} \in [S,T] \Rightarrow \text{xf}(I) = O$ + +Intuitively, matching means that the spec admits the input $I$, and exactly specifies the behaviour on it. + +### Non-Parametric Matching + +Given examples $I_i \rightarrow O_i$ for $i = 1..3$, the following spec matches all of them: + +$$[I1,O1] \wedge [I2,O2] \wedge [I3,O3]$$ + +where we write `I` as the singleton shape type denoting exactly `I`. + +Here's an example + +```python +def flip_2x2(grid): + # Assumes grid is 2x2 + return [[grid[0][1], grid[0][0]], + [grid[1][1], grid[1][0]]] +``` + +This transformation, `flip_2x2`, is specifically designed to work only for $2 \times 2$ grids. It does not generalize to other grid sizes. + + +### Parametric Spec + +Consider this example + +```python +def flip_grid(grid): + # Flip any grid horizontally + return [row[::-1] for row in grid] +``` + +This transformation, `flip_grid`, works for grids of any size by flipping each row horizontally. + +In addition to the non-parametric spec above, this transformation satisfies spec $[X, Flip(X)]$ where: + +- $X$ represents any grid. +- $\text{Flip}(X)$ denotes the grid $X$ flipped horizontally. + +### Genericity of Specs + +A spec $\text{spec1}$ is more specific than $\text{spec2}$ if it is a strict subset. +In the examples above, the non-parametric spec is more specific than the parametric one. + +### Genericity of Transformation + +A transformation $\text{xf1}$ is more generic than $\text{xf2}$ if it satisfies more generic specs. +In the examples above, `flip_grid` is more generic than `flip_2x2`. diff --git a/experiments/parametric_expressivity.pdf b/experiments/parametric_expressivity.pdf new file mode 100644 index 0000000..72af4f1 Binary files /dev/null and b/experiments/parametric_expressivity.pdf differ