the desired weight. For example, if we are trying to construct all values of weight 10 of the form [`Concat`]{}$(x, y)$, we iterate over all values where $x$ has weight $1$ and $y$ has weight $8$, and then where $x$ has weight $2$ and $y$ has weight $7$, and so forth. (The [`Concat`]{} function itself contributes weight $1$.) Every time a new expression is constructed, we evaluate it on the given inputs, terminating the search when the expression produces the desired outputs.

Property Signatures {#section:property_signatures}
-------------------

In order to perform machine learning on values encountered during the enumeration, we make use of recent work on Property Signatures [@SIGNATURES]. Consider a function with input type $\tau_{in}$ and output type $\tau_{out}$. In this context, a property is a function of type: $(\tau_{in}, \tau_{out}) \rightarrow \texttt{Bool}$ that describes some aspect of the function under consideration. If we have a list of such properties and some inputs and outputs of the correct type, we can evaluate all the properties on the input-output pairs to get a list of outputs that we will call the property signature. More precisely, given a list of $n$ input-output pairs and a list of $k$ properties, the property signature 