Overview of penguin source:

First remember that this is a hack; it's not polished and not meant to
be polished. So there are various dangling loose ends and such.

The sources are listed in the makefile in order from low to high level
(as required by ocaml) and grouped by topic.

1. support code
	Util - random list and printing ops and other loose bits
	Types - common functor applications (maps, sets) and some common types
	Log - stuff for writing to a log file
	Pos - file positions, cribbed from bintools
              (mostly in fact not actually used)
	Modes - place to put switches for choosing operating modes
	Dumptools - for dumping abstract syntax, copied from bintools
	Mintops - definitions for machine integer operations
	Ppoint - program points (sealed abstraction)
	Symbolic - a wrapper type for symbolic values

2. logic-level and mips stuff
(these are interrelated and not easily teased apart, so I haven't
tried that hard)
	Mipsstate - stuff relating to processor state
	Mips - mips instruction set, and also logic expressions
	Enabled - switches for turning on and off instructions and registers
	Insns - specific stuff for listing instructions and operands
	Mipstools - further mips-related code
	Syminsns - code for creating symbolic instructions
	Printasm - code for printing the mips instruction set
	Printlogic - code for printing logic expression

3. specifications
	Lextools - lexer support, copied from bintools
	Spectree - parse tree for specifications
	Speccomp - compile specifications to logic expressions from Mips
	Specparse - specification parser
	Speclex - specification lexer

4. more logic-level stuff
	Typecheck - typechecker for the logic expressions from Mips
	Simplify - optimizer for the logic expressions from Mips
		   (does nothing so far)
	Symexec - symbolic execution

5. smt-level stuff
	Smt - SMT abstract syntax
	Printsmt - printing for Smt
	Smtopt - simple legibility optimizations for Smt
	Smtcheck - typechecker for Smt
	Solver - solver interface
	Build - compile logic expressions to smt

6. Toplevel stuff
	Synthcegis - synthesize via CEGIS loop
	Synthdirect - synthesize via direct forall query
	Main - top top level


The basic flow is as follows:
   - The input spec is read in and compiled to Mips.expr logic
     expressions.
   - A sequence of symbolic instructions and program points is
     generated. This generates the control variables and some
     initial logic expressions about them, e.g. value range
     constraints arising from types.
   - Symbolic execution turns the symbolic instructions into more
     logic expressions about the constraints and about machine state
     at program points.
   - The Build module turns all this logic into SMT, which among other
     things creates SMT variables for machine state and turns machine
     state references into references to those variables.
   - The resulting SMT is then fed to the solver.
   - (The previous two steps repeat for CEGIS synthesis.)
   - The resulting assignment to the control variables, if any, is
     turned back into instructions.
