Learning to Reason via Program Generation, Emulation, and Search