Dream Coder - Algorithm 2

Support/Figures/Pasted image 20241211010156.png

Type Unification and the sample' Function

The core of the sample' function involves generating a program whose type unifies with a desired type τ. The unification process ensures that the program generated has the correct type or can be transformed into one that matches τ.

Understanding Type Unification:

Type unification is the process of making two types compatible by finding a substitution (if needed) such that both types become equal. Specifically:

Case 1: τ is a function type αβ

Case 2: τ is not a function type (i.e., a concrete type)

Generating a Program Based on τ

The algorithm proceeds by generating a program from the library D and the environment E, ensuring that the generated program's type matches τ.

  1. Picking a Set of Primitives:

    • We first pick a set of primitives (programs ρ) from the library D and the environment E.
    • These primitives must have a type τ such that:
      • If τ is a lambda function αβ, then β must unify with τ.
      • Otherwise, τ must unify (be equal to) τ.
  2. Handling Variables:

    • Next, we need to consider variables. These are programs that exist in the environment E.
    • We draw a program e with probability proportional to the weight assigned to e by θ if eD.
    • If eD, we instead use θvar, which is the |D|+1-th component of θ, and we draw e with probability proportional to θvar|variables|.
  3. Type Checking:

    • Notice that the drawn program e has type τ.
    • We check if τ unifies with τ.
  4. Handling Lambda Functions:

    • If τ is a lambda function, we retrieve its argument types using args (this is done in line 24).
    • We then sample all the arguments required to apply e (steps 18 to 20).
    • Finally, we return e with all its arguments bundled into one tuple.