Section EqShiftL.
(** After killing [n] bits at the left, are the numbers equal ?*)
Definition EqShiftL n x y :=
nshiftl x n = nshiftl y n.
(** * From int31 to list of digits. *)
(** Lower (=rightmost) bits comes first. *)
Definition i2l := recrbis _ nil (fun d _ rec => d::rec).
Fixpoint lshiftl l x :=
match l with
| nil => x
| d::l => sneakl d (lshiftl l x)
end.
Definition l2i l := lshiftl l On.
Fixpoint cstlist (A:Type)(a:A) n :=
match n with
| O => nil
| S n => a::cstlist _ a n
end.
(** [i2l] can be used to define a relation equivalent to [EqShiftL] *)
(** This equivalence allows proving easily the following delicate result *)
End EqShiftL.
(** * More equations about [incr] *)
(** * Conversion from [Z] : the [phi_inv] function *)
(** First, recursive equations *)
(** [phi_inv o inv], the always-exact and easy-to-prove trip : from int31 to Z and then back to int31. *)
(** The other composition [phi o phi_inv] is harder to prove correct. In particular, an overflow can happen, so a modulo is needed. For the moment, we proceed via several steps, the first one being a detour to [positive_to_in31]. *)
(** * [positive_to_int31] *)
(** A variant of [p2i] with [twice] and [twice_plus_one] instead of [2*i] and [2*i+1] *)
Fixpoint p2ibis n p : (N*int31)%type :=
match n with
| O => (Npos p, On)
| S n => match p with
| xO p => let (r,i) := p2ibis n p in (r, twice i)
| xI p => let (r,i) := p2ibis n p in (r, twice_plus_one i)
| xH => (N0, In)
end
end.
Local Open Scope Z_scope.
(** We now prove that this [p2ibis] is related to [phi_inv_positive] *)
(** This gives the expected result about [phi o phi_inv], at least for the positive case. *)
(** Moreover, [p2ibis] is also related with [p2i] and hence with [positive_to_int31]. *)
(** Thanks to the result about [phi o phi_inv_positive], we can now establish easily the most general results about [phi o twice] and so one. *)
(** With the previous results, we can deal with [phi o phi_inv] even in the negative case *)

Lemma phi_phi_inv :
forall z, phi (phi_inv z) = z mod 2 ^ (Z.of_nat size).