(** * Things common to shift-overflow machines *)
(** This is mostly the [b] function, which expresses the distance to the next power of two. *)
Set Default Goal Selector "!".
(** We use a definition of [b] shifted by 1 compared to the informal proof, i.e. we can do [n + b n] is the farthest we can go without reaching a new power of two. *)
Fixpoint b (n : positive) : N :=
match n with
| xH => N0
| xO n' => N.succ_double (b n')
| xI n' => N.double (b n')
end.
Inductive has0 : positive -> Prop :=
| has0_0 n: has0 (n~0)
| has0_1 n: has0 n -> has0 (n~1).
#[export] Hint Constructors has0 : core.
Inductive all1 : positive -> Prop :=
| all1_H:   all1 1
| all1_1 n: all1 n -> all1 (n~1).
#[export] Hint Resolve b0_all1 : core.
#[export] Hint Extern 1 (has0 _) => apply bgt0_has0; lia : core.
#[export] Hint Immediate b_add_self : core.
Fixpoint pow4 (k : nat) (n : positive) : positive :=
match k with
| O => n
| S k => pow4 k (n~0~0)
end.

Lemma b_pow4 : forall k n,
(b (pow4 k n) = pow2 (2 * k) * (b n + 1) - 1)%N.