the intermediate state may be either an integer or a string, so we have properties dealing with both inputs and strings. In an abstract sense, a property acts on an input and an output, but some properties will simply ignore the input, and so we implement those as functions with only one argument. Thus, we have four types of properties:

-   properties acting on a single string (Listing \[listing:singlestringproperties\]).

-   properties acting on a single integer (Listing \[listing:singleintegerproperties\]).

-   properties acting on a string and the output string (Listing \[listing:stringstringproperties\]).

-   properties acting on an integer and the output string (Listing \[listing:integerstringproperties\]).

For a program with multiple inputs, we simply loop over all the inputs and the output, computing all of the relevant types of properties for each. For example, a program taking two string inputs and yielding one string output will have single-argument string properties for the output and two sets of double-argument string properties, one for each input. We fix a maximum number of inputs and pad the signatures so that they are all the same size.

    str.isEmpty()               // is empty?
    str.length() == 1           // is single char?
    str.length() <= 5           // is short string?
    str.equals(lower)           // is 