--
```import "Bits.html"  -- see Bits.html source here.

-----------------------------------------------------

add3Bits:: Bit i -> Bit j -> Bit k -> Seq Bit 2t {plus i {plus j k}}
add3Bits Zero Zero Zero = [Zero,Zero]b
add3Bits Zero Zero One  = [One,Zero]b
add3Bits Zero One  Zero = [One,Zero]b
add3Bits Zero One  One  = [Zero,One]b
add3Bits One  Zero Zero = [One,Zero]b
add3Bits One  Zero One  = [Zero,One]b
add3Bits One  One  Zero = [Zero,One]b
add3Bits One  One  One  = [One,One]b

adder':: Bit i -> Seq Bit n j -> Seq Bit n k -> Seq Bit (S n) {plus i {plus j k}}
adder' carry Nil Nil = Cons carry Nil
where theorem plusZ
adder' carry (Cons b xs) (Cons c ys) = Cons ans tail
where [ans,carry2]b = add3Bits carry b c
tail = adder' carry2 xs ys
theorem plusAssoc, plusNorm

-- When you're just getting started don't need to specifiy a carry bit

adder:: Seq Bit n i -> Seq Bit n j -> Seq Bit (S n) {plus i j}

---------------------------------------------------
-- Now lets make an adder using symbolic bits.
-- We'll need a very specific lemma, but it is
-- easy to prove by exhaustive analysis.

lemma:: Bit a -> Bit b -> Bit c ->
Equal {plus {plus {or {and a b}
{or {and a c} {and b c}}}
{or {and a b} {or {and a c} {and b c}}}}
{xor a {xor b c}}}
{plus a {plus b c}}
lemma Zero Zero Zero = Eq
lemma Zero Zero One = Eq
lemma Zero One  Zero = Eq
lemma Zero One  One = Eq
lemma One  Zero Zero = Eq
lemma One  Zero One = Eq
lemma One  One  Zero = Eq
lemma One  One  One = Eq

add3SymBits:: SymBit i -> SymBit j -> SymBit k -> Seq SymBit 2t {plus i {plus j k}}
add3SymBits i j k = check
[Xor i (Xor j k),
Or (And i j) (Or (And i k) (And j k))]b
where theorem hyp = lemma (eval i) (eval j) (eval k)

adderS:: SymBit i -> Seq SymBit n j -> Seq SymBit n k -> Seq SymBit (S n) {plus i {plus j k}}
adderS carry Nil Nil = Cons carry Nil
where theorem plusZ
adderS carry (Cons b xs) (Cons c ys) = Cons ans tail
where [ans,carry2]b = add3SymBits carry b c
tail = adderS carry2 xs ys
theorem plusAssoc, plusNorm

two = [Var "x",Var "y"]b
one = [Var "m", Var "n"]b
three = [I,I,O]b

ans = (adderS O two one)