From Undecidability Require Export ArithPrelim. (* [nia] etc. *)
From Coq Require Export BinPos.
(* Compute 42. (* default number notation is still for [nat] *) *)
Local Open Scope positive_scope.
(* Local Set Printing All. *)
(* Compute 42 % positive. *)
(* Compute 42 : positive. *)
(* Local Unset Printing All. *)
(* Big binary numbers are not a problem for Coq *)
(* Compute (42 ^ 42) % positive. *)
(* Number of bits required to represent this big number *)
(* Compute Pos.size_nat (42 ^ 42). *)
(* ** General definitions and lemmas on binary numbers *)
(* Append a lower-order bit *)
Definition append_bit (p : positive) (b : bool) := if b then p~1 else p~0.
Notation "p ~~ b" := (append_bit p b) (at level 7, left associativity, format "p '~~' b") : positive_scope.
Definition bitToSigPos (b : bool) : sigPos := if b then sigPos_xI else sigPos_xO.
Definition bitToSigPos' (b : bool) : sigPos^+ := inr (bitToSigPos b).
(* [bits_to_pos] Computes the [positive] that is represented by the bitstring [true :: bits], where [true] is the HSB *)
Fixpoint bits_to_pos' (bits : list bool) : positive :=
match bits with
| nil => 1
| b :: bits' => (bits_to_pos' bits') ~~ b
end.
Definition bits_to_pos (bits : list bool) := bits_to_pos' (rev bits).
(* Compute bits_to_pos [false; true; false; true; false]. (* 42 *) *)
(* Compute bits_to_pos [false; true; false; true; true]. (* 43 -> last bit is LSB *) *)

Lemma pos_to_bits_append_bits' : forall bits1 bits2, pos_to_bits (append_bits (bits_to_pos bits1) bits2) = bits1 ++ bits2.