This program came to be known as the Legato's challenge in the community, where
the challenge was to prove that it indeed does perform multiplication. This file
formalizes the Mostek architecture in Haskell and proves that Legato's algorithm
is indeed correct.

Abstraction of the machine: The CPU consists of memory, registers, and flags.
Unlike traditional hardware, we assume the program is stored in some other memory area that
we need not model. (No self modifying programs!)

Checking overflow. In Legato's multipler the ADC instruction
needs to see if the expression x + y + c overflowed, as checked
by this function. Note that we verify the correctness of this check
separately below in checkOverflowCorrect.

ROR, memory version: Rotate the value at memory location a
to the right by 1 bit, using the carry flag as a transfer position.
That is, the final bit of the memory location becomes the new carry
and the carry moves over to the first bit. This very instruction
is one of the reasons why Legato's multiplier is quite hard to understand
and is typically presented as a verification challenge.

Legato's algorithm in Haskell/SBV

Parameterized by the addresses of locations of the factors (F1 and F2),
the following program multiplies them, storing the low-byte of the result
in the memory location lowAddr, and the high-byte in register A. The
implementation is a direct transliteration of Legato's algorithm given
at the top, using our notation.

Verification interface

Given address/value pairs for F1 and F2, and the location of where the low-byte
of the result should go, runLegato takes an arbitrary machine state m and
returns the high and low bytes of the multiplication.

The correctness theorem. For all possible memory configurations, the factors (x and y below), the location
of the low-byte result and the initial-values of registers and the flags, this function will return True only if
running Legato's algorithm does indeed compute the product of x and y correctly.