coqbooks/src/thue_morse.v
Thomas Baruchel 33e87e55b5 Update
2023-01-07 11:27:20 +01:00

1347 lines
52 KiB
Coq

(** * The Thue-Morse sequence
Some proofs related to the Thue-Morse sequence.
See:
- https://oeis.org/A010060
- https://en.wikipedia.org/wiki/Thue%E2%80%93Morse_sequence
*)
Require Import Coq.Lists.List.
Require Import PeanoNat.
Require Import Nat.
Require Import Bool.
Import ListNotations.
(**
This whole notebook contains proofs related to the following two functions.
Nothing else is defined afterwards in the current notebook.
*)
Fixpoint tm_morphism (l:list bool) : list bool :=
match l with
| nil => []
| h :: t => h :: (negb h) :: (tm_morphism t)
end.
Fixpoint tm_step (n: nat) : list bool :=
match n with
| 0 => false :: nil
| S n' => tm_morphism (tm_step n')
end.
(**
More or less "general" lemmas, which are not directly related to
the previous functions are proved below.
*)
Lemma lt_split_bits : forall n m k j,
0 < k -> j < 2^m -> k*2^m < 2^n -> k*2^m+j < 2^n.
Proof.
intros n m k j. intros H I J.
assert (K: 2^m <= k*2^m). rewrite <- Nat.mul_1_l at 1.
apply Nat.mul_le_mono_r. rewrite Nat.le_succ_l. assumption.
assert (L:2^m < 2^n). generalize J. generalize K. apply Nat.le_lt_trans.
assert (k < 2^(n-m)). rewrite Nat.mul_lt_mono_pos_r with (p := 2^m).
rewrite <- Nat.pow_add_r. rewrite Nat.sub_add. assumption.
apply Nat.pow_lt_mono_r_iff in L. apply Nat.lt_le_incl. assumption.
apply Nat.lt_1_2. rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
replace (2^(n-m)) with (S (2^(n-m)-1)) in H0. rewrite Nat.lt_succ_r in H0.
apply Nat.mul_le_mono_r with (p := 2^m) in H0.
rewrite Nat.mul_sub_distr_r in H0. rewrite Nat.mul_1_l in H0.
rewrite <- Nat.pow_add_r in H0. rewrite Nat.sub_add in H0.
rewrite Nat.add_le_mono_r with (p := j) in H0.
assert (2^n - 2^m + j < 2^n).
rewrite Nat.add_lt_mono_l with (p := 2^n) in I.
rewrite Nat.add_lt_mono_r with (p := 2^m).
rewrite <- Nat.add_assoc. rewrite <- Nat.add_sub_swap.
rewrite Nat.add_assoc. rewrite Nat.add_sub. assumption.
apply Nat.lt_le_incl. assumption.
generalize H1. generalize H0. apply Nat.le_lt_trans.
apply Nat.lt_le_incl. rewrite <- Nat.pow_lt_mono_r_iff in L. assumption.
apply Nat.lt_1_2. rewrite <- Nat.add_1_r. apply Nat.sub_add.
rewrite Nat.le_succ_l. rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
Qed.
Lemma count_occ_bool_list : forall (a: list bool),
length a = (count_occ bool_dec a true) + (count_occ bool_dec a false).
Proof.
intro a.
induction a.
- reflexivity.
- destruct a.
+ rewrite count_occ_cons_eq. rewrite count_occ_cons_neq.
simpl. rewrite IHa. reflexivity. easy. reflexivity.
+ rewrite count_occ_cons_neq. rewrite count_occ_cons_eq.
simpl. rewrite Nat.add_succ_r. rewrite IHa. reflexivity. reflexivity. easy.
Qed.
Lemma count_occ_bool_list2 : forall (a: list bool),
count_occ bool_dec a false = count_occ bool_dec a true -> even (length a) = true.
Proof.
intro a. intro H.
rewrite count_occ_bool_list. rewrite H.
replace (count_occ bool_dec a true) with (1 * (count_occ bool_dec a true)).
rewrite <- Nat.mul_add_distr_r. rewrite Nat.add_1_r.
replace (2 * count_occ bool_dec a true) with (0 + 2 * count_occ bool_dec a true).
apply Nat.even_add_mul_2. apply Nat.add_0_l. apply Nat.mul_1_l.
Qed.
(**
Some lemmas related to the first function (tm_morphism) are proved here.
They have a wider scope than the following ones since they don't focus on
the Thue-Morse sequence by itself.
*)
Lemma tm_morphism_concat : forall (l1 l2 : list bool),
tm_morphism (l1 ++ l2) = tm_morphism l1 ++ tm_morphism l2.
Proof.
intros l1 l2.
induction l1.
- reflexivity.
- simpl. rewrite IHl1. reflexivity.
Qed.
Lemma tm_morphism_rev : forall (l : list bool),
rev (tm_morphism l) = tm_morphism (map negb (rev l)).
Proof.
intro l. induction l.
- reflexivity.
- simpl. rewrite map_app.
rewrite IHl. rewrite tm_morphism_concat.
rewrite <- app_assoc. simpl.
rewrite negb_involutive. reflexivity.
Qed.
Lemma tm_build_negb : forall (l : list bool),
tm_morphism (map negb l) = map negb (tm_morphism l).
Proof.
intro l.
induction l.
- reflexivity.
- simpl. rewrite IHl. reflexivity.
Qed.
Lemma tm_morphism_double_index : forall (l : list bool) (k : nat),
nth_error l k = nth_error (tm_morphism l) (2*k).
Proof.
intro l.
induction l.
- intro k.
simpl. replace (nth_error [] k) with (None : option bool).
rewrite Nat.add_0_r. replace (nth_error [] (k+k)) with (None : option bool).
reflexivity. symmetry. apply nth_error_None. simpl. apply Nat.le_0_l.
symmetry. apply nth_error_None. simpl. apply Nat.le_0_l.
- intro k. induction k.
+ rewrite Nat.mul_0_r. reflexivity.
+ simpl. rewrite Nat.add_0_r. rewrite Nat.add_succ_r. simpl.
replace (k+k) with (2*k). apply IHl. simpl. rewrite Nat.add_0_r.
reflexivity.
Qed.
Lemma tm_morphism_count_occ : forall (l : list bool),
count_occ Bool.bool_dec (tm_morphism l) true
= count_occ Bool.bool_dec (tm_morphism l) false.
Proof.
intro l. induction l.
- reflexivity.
- destruct a.
+ simpl. apply eq_S. assumption.
+ simpl. apply eq_S. assumption.
Qed.
Lemma tm_morphism_eq : forall (l1 l2 : list bool),
l1 = l2 <-> tm_morphism l1 = tm_morphism l2.
Proof.
intros l1 l2. split.
- intro H. rewrite H. reflexivity.
- generalize l2. induction l1.
+ intro l. intro H. simpl in H.
induction l. reflexivity. simpl in H. inversion H.
+ simpl. intro l0. intro H.
induction l0. simpl in H. inversion H.
simpl in H. inversion H. apply IHl1 in H3. rewrite H3.
reflexivity.
Qed.
Lemma tm_morphism_length : forall (l : list bool),
length (tm_morphism l) = 2 * (length l).
Proof.
induction l.
- reflexivity.
- simpl. rewrite Nat.add_0_r. rewrite IHl.
rewrite Nat.add_succ_r.
simpl. rewrite Nat.add_0_r. reflexivity.
Qed.
Lemma tm_morphism_app : forall (l1 l2 : list bool),
tm_morphism (l1 ++ l2) = tm_morphism l1 ++ tm_morphism l2.
Proof.
intros l1 l2.
induction l1.
- reflexivity.
- simpl. rewrite IHl1. reflexivity.
Qed.
Lemma tm_morphism_app2 : forall (l hd tl : list bool),
tm_morphism l = hd ++ tl
-> even (length hd) = true
-> hd = tm_morphism (firstn (Nat.div2 (length hd)) l).
Proof.
intros l hd tl. intros H I.
assert (J : l = (firstn (Nat.div2 (length hd)) l) ++ (skipn (Nat.div2 (length hd)) l)).
symmetry. apply firstn_skipn.
rewrite tm_morphism_eq in J.
rewrite tm_morphism_app in J. rewrite H in J.
apply app_eq_app in J.
assert (H2: length (tm_morphism l) = length hd + length tl).
rewrite H. apply app_length.
assert (H3: length hd <= length (tm_morphism l)).
rewrite H2. apply Nat.le_add_r.
rewrite tm_morphism_length in H3.
assert (H4: Nat.div2 (length hd) <= length l).
rewrite Nat.mul_le_mono_pos_l with (p := 2).
rewrite <- Nat.add_0_r at 1.
replace (0) with (Nat.b2n (Nat.odd (length hd))) at 2.
rewrite <- Nat.div2_odd. assumption.
rewrite <- Nat.negb_even. rewrite I. reflexivity. apply Nat.lt_0_2.
destruct J. destruct H0; destruct H0.
assert (L: length hd = length hd). reflexivity.
rewrite H0 in L at 2. rewrite app_length in L.
rewrite tm_morphism_length in L.
apply firstn_length_le in H4. rewrite H4 in L.
replace (2 * Nat.div2 (length hd))
with (2 * Nat.div2 (length hd) + Nat.b2n (Nat.odd (length hd))) in L.
rewrite <- Nat.div2_odd in L.
rewrite <- Nat.add_0_r in L at 1.
apply Nat.add_cancel_l in L. symmetry in L.
apply length_zero_iff_nil in L.
rewrite L in H0. rewrite <- app_nil_end in H0. assumption.
rewrite <- Nat.negb_even. rewrite I. simpl.
rewrite Nat.add_0_r. reflexivity.
assert (L: length (tm_morphism (firstn (Nat.div2 (length hd)) l))
= length (tm_morphism (firstn (Nat.div2 (length hd)) l))).
reflexivity. rewrite H0 in L at 2. rewrite app_length in L.
rewrite tm_morphism_length in L.
apply firstn_length_le in H4. rewrite H4 in L.
replace (2 * Nat.div2 (length hd))
with (2 * Nat.div2 (length hd) + Nat.b2n (Nat.odd (length hd))) in L.
rewrite <- Nat.div2_odd in L.
rewrite <- Nat.add_0_r in L at 1.
apply Nat.add_cancel_l in L. symmetry in L.
apply length_zero_iff_nil in L.
rewrite L in H0. rewrite <- app_nil_end in H0. symmetry. assumption.
rewrite <- Nat.negb_even. rewrite I. simpl.
rewrite Nat.add_0_r. reflexivity.
Qed.
Lemma tm_morphism_app3 : forall (l hd tl : list bool),
tm_morphism l = hd ++ tl
-> even (length hd) = true
-> tl = tm_morphism (skipn (Nat.div2 (length hd)) l).
Proof.
intros l hd tl. intros H I.
assert (J: hd = tm_morphism (firstn (Nat.div2 (length hd)) l)).
generalize I. generalize H. apply tm_morphism_app2.
assert (K: (firstn (Nat.div2 (length hd)) l) ++ (skipn (Nat.div2 (length hd)) l) = l).
apply firstn_skipn.
assert (L: tm_morphism l = (tm_morphism (firstn (Nat.div2 (length hd)) l))
++ (tm_morphism (skipn (Nat.div2 (length hd)) l))).
rewrite <- K at 1. apply tm_morphism_app.
rewrite H in L. rewrite <- J in L.
rewrite app_inv_head_iff in L. assumption.
Qed.
(**
Lemmas and theorems below are related to the second function defined initially.
They focus on the Thue-Morse sequence.
*)
Lemma tm_step_lemma : forall n : nat,
tm_morphism (tm_step n) = tm_step (S n).
Proof.
intro n. reflexivity.
Qed.
Theorem tm_step_negb : forall (n : nat),
map negb (tm_step (S n)) = rev (tm_morphism (rev (tm_step n))).
Proof.
intro n.
rewrite <- tm_step_lemma. symmetry.
rewrite tm_morphism_rev. rewrite tm_build_negb. rewrite rev_involutive.
reflexivity.
Qed.
Theorem tm_build : forall (n : nat),
tm_step (S n) = tm_step n ++ map negb (tm_step n).
Proof.
intro n.
induction n.
- reflexivity.
- rewrite <- tm_step_lemma. rewrite IHn. rewrite tm_morphism_concat.
rewrite tm_step_lemma. rewrite IHn. rewrite tm_build_negb.
rewrite <- IHn. rewrite tm_step_lemma. reflexivity.
Qed.
Theorem tm_size_power2 : forall n : nat, length (tm_step n) = 2^n.
Proof.
intro n.
induction n.
- reflexivity.
- rewrite <- tm_step_lemma. rewrite tm_morphism_length.
rewrite Nat.pow_succ_r. rewrite Nat.mul_cancel_l.
assumption. easy. apply Nat.le_0_l.
Qed.
Lemma tm_step_head_1 : forall (n : nat),
tm_step n = false :: tl (tm_step n).
Proof.
intro n.
induction n.
- reflexivity.
- rewrite <- tm_step_lemma. rewrite IHn. reflexivity.
Qed.
Lemma tm_step_end_1 : forall (n : nat),
rev (tm_step n) = odd n :: tl (rev (tm_step n)).
Proof.
intro n.
induction n.
- reflexivity.
- rewrite <- tm_step_lemma. rewrite tm_morphism_rev.
rewrite IHn. simpl. rewrite <- Nat.negb_even at 1. rewrite Nat.odd_succ.
rewrite negb_involutive. reflexivity.
Qed.
Theorem tm_step_double_index : forall (n k : nat),
nth_error (tm_step n) k = nth_error (tm_step (S n)) (2*k).
Proof.
intros n k.
destruct k.
- rewrite Nat.mul_0_r. rewrite tm_step_head_1. simpl.
rewrite tm_step_head_1. reflexivity.
- rewrite <- tm_step_lemma. apply tm_morphism_double_index.
Qed.
Lemma tm_step_single_bit_index : forall (n : nat),
nth_error (tm_step (S n)) (2^n) = Some true.
Proof.
intro n.
rewrite tm_build. rewrite nth_error_app2; rewrite tm_size_power2.
- rewrite Nat.sub_diag.
replace (true) with (negb false). apply map_nth_error.
rewrite tm_step_head_1. reflexivity. reflexivity.
- apply Nat.le_refl.
Qed.
Lemma tm_step_repunit_index : forall (n : nat),
nth_error (tm_step n) (pred (2^n)) = Some (odd n).
Proof.
intro n.
rewrite <- Nat.sub_1_r. rewrite <- tm_size_power2.
rewrite nth_error_nth' with (d := false).
- rewrite <- rev_nth. rewrite tm_step_end_1. simpl. reflexivity.
rewrite tm_size_power2.
rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
- rewrite Nat.sub_1_r. apply Nat.lt_pred_l.
rewrite tm_size_power2. apply Nat.pow_nonzero. easy.
Qed.
Theorem tm_step_count_occ : forall (hd tl : list bool) (n : nat),
tm_step n = hd ++ tl -> even (length hd) = true
-> count_occ Bool.bool_dec hd true = count_occ Bool.bool_dec hd false.
Proof.
intros hd tl n. intros H I.
destruct n.
- assert (J: hd = nil). destruct hd. reflexivity.
simpl in H. inversion H.
symmetry in H2. apply app_eq_nil in H2.
destruct H2. rewrite H0 in I. simpl in I. inversion I.
rewrite J. reflexivity.
- rewrite <- tm_step_lemma in H.
assert (J: hd = tm_morphism (firstn (Nat.div2 (length hd)) (tm_step n))).
generalize I. generalize H. apply tm_morphism_app2.
rewrite J. apply tm_morphism_count_occ.
Qed.
(**
The following lemmas and theorems focus on the stability of the sequence:
while lists in the sequence get longer and longer, the beginning of a
longer list contain the same elements as the previous shorter lists.
*)
Lemma tm_step_next_range :
forall (n k : nat) (b : bool),
nth_error (tm_step n) k = Some b -> nth_error (tm_step (S n)) k = Some b.
Proof.
intros n k b. intro H. assert (I := H).
apply nth_error_split in H. destruct H. destruct H. inversion H.
rewrite tm_build. rewrite nth_error_app1. apply I.
rewrite H0. rewrite app_length. rewrite <- H1. simpl.
apply Nat.lt_add_pos_r. apply Nat.lt_0_succ.
Qed.
Lemma tm_step_add_range : forall (n m k : nat),
k < 2^n -> nth_error (tm_step n) k = nth_error (tm_step (n+m)) k.
Proof.
intros n m k. intro H.
induction m.
- rewrite Nat.add_0_r. reflexivity.
- rewrite Nat.add_succ_r. rewrite <- tm_size_power2 in H.
assert (nth_error (tm_step n) k = Some (nth k (tm_step n) false)).
generalize H. apply nth_error_nth'.
rewrite H0 in IHm. symmetry in IHm.
rewrite H0. symmetry. generalize IHm.
apply tm_step_next_range.
Qed.
Theorem tm_step_stable : forall (n m k : nat),
k < 2^n -> k < 2^m -> nth_error (tm_step n) k = nth_error (tm_step m) k.
Proof.
intros n m k. intros.
assert (I: n < m /\ max n m = m \/ m <= n /\ max n m = n).
apply Nat.max_spec. destruct I.
- destruct H1. replace (m) with (n + (m-n)). apply tm_step_add_range. apply H.
apply Nat.lt_le_incl in H1. replace (m) with (n + m - n) at 2. generalize H1.
apply Nat.add_sub_assoc. rewrite Nat.add_comm.
assert (n <= n). apply le_n. symmetry.
replace (m) with (m + (n-n)) at 1. generalize H3.
apply Nat.add_sub_assoc. rewrite Nat.sub_diag. apply Nat.add_0_r.
- destruct H1. symmetry. replace (n) with (m + (n - m)). apply tm_step_add_range.
apply H0. replace (n) with (m + n - m) at 2. generalize H1.
apply Nat.add_sub_assoc. rewrite Nat.add_comm.
assert (m <= m). apply le_n. symmetry.
replace (n) with (n + (m-m)) at 1. generalize H3.
apply Nat.add_sub_assoc. rewrite Nat.sub_diag. apply Nat.add_0_r.
Qed.
(**
The following lemma states that a block of terms in the Thue-Morse
sequence having a size being a power of 2 is repeated, either
as an identical version or with all values together flipped.
*)
Lemma tm_step_repeating_patterns :
forall (n m i j : nat),
i < 2^m -> j < 2^m
-> forall k, k < 2^n -> nth_error (tm_step m) i
= nth_error (tm_step m) j
<-> nth_error (tm_step (m+n)) (k * 2^m + i)
= nth_error (tm_step (m+n)) (k * 2^m + j).
Proof.
intros n m i j. intros H I.
induction n.
- rewrite Nat.add_0_r. intro k. simpl. rewrite Nat.lt_1_r. intro.
rewrite H0. simpl. easy.
- rewrite Nat.add_succ_r. intro k. intro.
rewrite tm_build.
assert (S: k < 2^n \/ 2^n <= k). apply Nat.lt_ge_cases.
destruct S.
assert (k*2^m < 2^(m+n)).
destruct k.
+ simpl. rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
+ rewrite Nat.mul_lt_mono_pos_r with (p := 2^m) in H1.
rewrite <- Nat.pow_add_r in H1. rewrite Nat.add_comm.
assumption. rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
+ assert (L: forall l, l < 2^m -> k*2^m + l < length (tm_step (m+n))).
intro l. intro M. rewrite tm_size_power2.
destruct k. simpl. assert (2^m <= 2^(m+n)).
apply Nat.pow_le_mono_r. easy. apply Nat.le_add_r.
generalize H3. generalize M. apply Nat.lt_le_trans.
apply lt_split_bits. apply Nat.lt_0_succ. assumption.
assumption.
rewrite nth_error_app1. rewrite nth_error_app1.
generalize H1. apply IHn.
apply L. assumption. apply L. assumption.
+ assert (J: 2 ^ (m + n) <= k * 2 ^ m).
rewrite Nat.pow_add_r. rewrite Nat.mul_comm.
apply Nat.mul_le_mono_r. assumption.
rewrite nth_error_app2. rewrite nth_error_app2. rewrite tm_size_power2.
assert (forall a b, option_map negb a = option_map negb b <-> a = b).
intros a b. destruct a. destruct b. destruct b0; destruct b; simpl.
split; intro; reflexivity. split; intro; inversion H2.
split; intro; inversion H2. split; intro; reflexivity.
split; intro; inversion H2.
destruct b. split; intro; inversion H2. split; intro; reflexivity.
replace (k * 2 ^ m + i - 2^(m + n)) with ((k-2^n)*2^m + i).
replace (k * 2 ^ m + j - 2^(m + n)) with ((k-2^n)*2^m + j).
rewrite nth_error_map. rewrite nth_error_map.
rewrite H2. apply IHn.
rewrite Nat.add_lt_mono_r with (p := 2^n). rewrite Nat.sub_add.
rewrite Nat.pow_succ_r in H0. rewrite <- Nat.add_1_r in H0 at 1.
rewrite Nat.mul_add_distr_r in H0. simpl in H0.
rewrite Nat.add_0_r in H0. assumption.
apply Nat.le_0_l. assumption.
rewrite Nat.mul_sub_distr_r. rewrite <- Nat.pow_add_r.
rewrite Nat.add_sub_swap. replace (n+m) with (m+n). reflexivity.
apply Nat.add_comm. assumption.
rewrite Nat.mul_sub_distr_r. rewrite <- Nat.pow_add_r.
rewrite Nat.add_sub_swap. replace (n+m) with (m+n). reflexivity.
apply Nat.add_comm. assumption.
rewrite tm_size_power2.
assert (k*2^m <= k*2^m + j). apply Nat.le_add_r.
generalize H2. generalize J. apply Nat.le_trans.
rewrite tm_size_power2.
assert (k*2^m <= k*2^m + i). apply Nat.le_add_r.
generalize H2. generalize J. apply Nat.le_trans.
Qed.
(**
The following lemmas and theorems are related to flipping the
most significant bit in the numerical value of indices (of terms
in the lists).
*)
Lemma tm_step_next_range2 :
forall (n k : nat),
k < 2^n -> nth_error (tm_step n) k <> nth_error (tm_step (S n)) (k + 2^n).
Proof.
intros n k. intro H.
rewrite tm_build.
rewrite nth_error_app2. rewrite tm_size_power2. rewrite Nat.add_sub.
assert (nth_error (tm_step n) k = Some (nth k (tm_step n) false)).
generalize H. rewrite <- tm_size_power2. apply nth_error_nth'.
rewrite H0.
assert (nth_error (map negb (tm_step n)) k
= Some (negb (nth k (tm_step n) false))).
generalize H0. apply map_nth_error. rewrite H1.
destruct (nth k (tm_step n) false). easy. easy.
rewrite tm_size_power2. apply Nat.le_add_l.
Qed.
Lemma tm_step_next_range2_flip_two : forall (n k m : nat),
k < 2^n -> m < 2^n ->
nth_error (tm_step n) k = nth_error (tm_step n) m
<->
nth_error (tm_step (S n)) (k + 2^n)
= nth_error (tm_step (S n)) (m + 2^n).
Proof.
intros n k m. intro H. intro I.
(* Part 1: preamble *)
assert (nth_error (tm_step n) k <> nth_error (tm_step (S n)) (k + 2^n)).
generalize H. apply tm_step_next_range2.
assert (nth_error (tm_step n) m <> nth_error (tm_step (S n)) (m + 2^n)).
generalize I. apply tm_step_next_range2.
assert (K: k + 2^n < 2^(S n)). simpl. rewrite Nat.add_0_r.
generalize H. apply Nat.add_lt_mono_r.
assert (J: m + 2^n < 2^(S n)). simpl. rewrite Nat.add_0_r.
generalize I. apply Nat.add_lt_mono_r.
(* Part 2: main proof *)
assert (nth_error (tm_step n) k = Some (nth k (tm_step n) false)).
generalize H. rewrite <- tm_size_power2. apply nth_error_nth'.
assert (nth_error (tm_step n) m = Some (nth m (tm_step n) false)).
generalize I. rewrite <- tm_size_power2. apply nth_error_nth'.
assert (nth_error (tm_step (S n)) (k + 2 ^ n) =
Some (nth (k + 2^n) (tm_step (S n)) false)).
generalize K. rewrite <- tm_size_power2. rewrite <- tm_size_power2.
apply nth_error_nth'.
assert (nth_error (tm_step (S n)) (m + 2 ^ n) =
Some (nth (m + 2^n) (tm_step (S n)) false)).
generalize J. rewrite <- tm_size_power2. rewrite <- tm_size_power2.
apply nth_error_nth'.
rewrite H2. rewrite H3. rewrite H4. rewrite H5.
(* Part 3: handling 16 different cases *)
destruct (nth k (tm_step n) false).
destruct (nth m (tm_step n) false).
destruct (nth (k + 2 ^ n) (tm_step (S n)) false).
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
easy.
rewrite H2 in H0. rewrite H4 in H0. contradiction H0. reflexivity.
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
rewrite H3 in H1. rewrite H5 in H1. contradiction H1. reflexivity.
easy.
destruct (nth (k + 2 ^ n) (tm_step (S n)) false).
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
rewrite H2 in H0. rewrite H4 in H0. contradiction H0. reflexivity.
easy.
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
easy.
rewrite H3 in H1. rewrite H5 in H1. contradiction H1. reflexivity.
destruct (nth m (tm_step n) false).
destruct (nth (k + 2 ^ n) (tm_step (S n)) false).
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
rewrite H3 in H1. rewrite H5 in H1. contradiction H1. reflexivity.
easy.
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
easy.
rewrite H2 in H0. rewrite H4 in H0. contradiction H0. reflexivity.
destruct (nth (k + 2 ^ n) (tm_step (S n)) false).
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
easy.
rewrite H3 in H1. rewrite H5 in H1. contradiction H1. reflexivity.
destruct (nth (m + 2 ^ n) (tm_step (S n)) false).
rewrite H2 in H0. rewrite H4 in H0. contradiction H0. reflexivity.
easy.
Qed.
Lemma tm_step_add_range2_flip_two : forall (n m j k : nat),
k < 2^n -> m < 2^n ->
nth_error (tm_step n) k = nth_error (tm_step n) m
<->
nth_error (tm_step (S n+j)) (k + 2^(n+j))
= nth_error (tm_step (S n+j)) (m + 2^(n+j)).
Proof.
intros n m j k. intros H I.
assert (K: k + 2^n < 2^(S n)). simpl. rewrite Nat.add_0_r.
generalize H. apply Nat.add_lt_mono_r.
assert (J: m + 2^n < 2^(S n)). simpl. rewrite Nat.add_0_r.
generalize I. apply Nat.add_lt_mono_r.
split.
- induction j.
+ intros L. rewrite Nat.add_0_r. rewrite Nat.add_0_r.
rewrite <- tm_step_next_range2_flip_two. apply L. apply H. apply I.
+ intros L.
rewrite Nat.add_succ_r. rewrite Nat.add_succ_r.
assert (2^n < 2^(S n + j)).
assert (n < S n + j). assert (n < S n). apply Nat.lt_succ_diag_r.
generalize H0. apply Nat.lt_lt_add_r.
generalize H0. apply Nat.pow_lt_mono_r. apply Nat.lt_1_2.
assert (k < 2^(S n + j)).
generalize H0. generalize H. apply Nat.lt_trans.
assert (m < 2^(S n + j)).
generalize H0. generalize I. apply Nat.lt_trans.
rewrite <- tm_step_next_range2_flip_two.
assert (nth_error (tm_step n) k = nth_error (tm_step (S n + j)) k).
generalize H1. generalize H. apply tm_step_stable.
assert (nth_error (tm_step n) m = nth_error (tm_step (S n + j)) m).
generalize H2. generalize I. apply tm_step_stable.
rewrite <- H3. rewrite <- H4. apply L.
apply H1. apply H2.
- induction j.
+ intro L. rewrite Nat.add_0_r in L. rewrite Nat.add_0_r in L.
apply tm_step_next_range2_flip_two. apply H. apply I. apply L.
+ intro L.
rewrite Nat.add_succ_r in L. rewrite Nat.add_succ_r in L.
assert (2^n < 2^(S n + j)).
assert (n < S n + j). assert (n < S n). apply Nat.lt_succ_diag_r.
generalize H0. apply Nat.lt_lt_add_r.
generalize H0. apply Nat.pow_lt_mono_r. apply Nat.lt_1_2.
assert (k < 2^(S n + j)).
generalize H0. generalize H. apply Nat.lt_trans.
assert (m < 2^(S n + j)).
generalize H0. generalize I. apply Nat.lt_trans.
rewrite <- tm_step_next_range2_flip_two in L.
assert (nth_error (tm_step n) k = nth_error (tm_step (S n + j)) k).
generalize H1. generalize H. apply tm_step_stable.
assert (nth_error (tm_step n) m = nth_error (tm_step (S n + j)) m).
generalize H2. generalize I. apply tm_step_stable.
rewrite <- H3 in L. rewrite <- H4 in L. apply L.
apply H1. apply H2.
Qed.
(**
The following lemmas and theorems are related to flipping the
least significant bit in the numerical value of indices (of terms
in the lists).
*)
(* Note: a first version included the 0 < k hypothesis but in the very
unorthodox case where k=0 it happens to be true anyway, and the hypothesis
was removed in order to make the theorem more general *)
Theorem tm_step_flip_low_bit :
forall (n m k j : nat),
j < m -> k * 2^m < 2^n
-> nth_error (tm_step n) (k * 2^m) <> nth_error (tm_step n) (k * 2^m + 2^j).
Proof.
intros n m k j. intros H I.
assert (L: nth_error (tm_step m) 0 = Some false).
rewrite tm_step_head_1. reflexivity.
assert (M: 2^j < 2^m).
apply Nat.pow_lt_mono_r. apply Nat.lt_1_2. assumption.
assert (N: nth_error (tm_step m) (2^j) = Some true).
replace (nth_error (tm_step m) (2^j)) with (nth_error (tm_step (S j)) (2^j)).
apply tm_step_single_bit_index.
apply tm_step_stable.
apply Nat.pow_lt_mono_r. apply Nat.lt_1_2. apply Nat.lt_succ_diag_r.
assumption.
assert (G: k = 0 \/ 0 < k). apply Nat.eq_0_gt_0_cases. destruct G as [G1|G2].
(* k = 0 *)
rewrite G1. rewrite Nat.mul_0_l. rewrite Nat.add_0_l.
rewrite tm_step_head_1 at 1.
assert (S: n < S j \/ S j <= n). apply Nat.lt_ge_cases.
destruct S as [S1|S2]. rewrite Nat.lt_succ_r in S1.
apply Nat.pow_le_mono_r with (a := 2) in S1.
rewrite <- tm_size_power2 in S1. rewrite <- nth_error_None in S1.
rewrite S1. easy. easy.
rewrite Nat.le_succ_l in S2. apply Nat.pow_lt_mono_r with (a := 2) in S2.
rewrite tm_step_stable with (m := m). rewrite N. easy. assumption. assumption.
apply Nat.lt_1_2.
(* k < 0 *)
assert (O: k*2^m + 2^j < 2^n). apply lt_split_bits; assumption.
assert (P: 2^n <= 2^(m+n)). apply Nat.pow_le_mono_r. easy. apply Nat.le_add_l.
assert ( nth_error (tm_step m) 0
= nth_error (tm_step m) (2^j)
<-> nth_error (tm_step (m+n)) (k * 2^m + 0)
= nth_error (tm_step (m+n)) (k * 2^m + (2^j)) ).
apply tm_step_repeating_patterns.
rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
apply Nat.pow_lt_mono_r. apply Nat.lt_1_2. assumption.
assert (1 * k <= (2^m) * k). apply Nat.mul_le_mono_nonneg.
apply Nat.le_0_1. rewrite Nat.le_succ_l.
rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
apply Nat.le_0_l. apply Nat.le_refl. rewrite Nat.mul_1_l in H0.
rewrite Nat.mul_comm in H0.
generalize I. generalize H0. apply Nat.le_lt_trans.
rewrite Nat.add_0_r in H0.
replace (nth_error (tm_step (m + n)) (k * 2 ^ m))
with (nth_error (tm_step n) (k * 2 ^ m)) in H0.
replace (nth_error (tm_step (m + n)) (k * 2 ^ m + 2^j))
with (nth_error (tm_step n) (k * 2 ^ m + 2^j)) in H0.
rewrite L in H0. rewrite N in H0.
destruct (nth_error (tm_step n) (k * 2 ^ m)).
destruct (nth_error (tm_step n) (k * 2 ^ m + 2^j)).
destruct b; destruct b0; destruct H0.
assert (Some true = Some true). reflexivity.
apply H1 in H2. rewrite <- H2 at 1. easy. easy. easy.
assert (Some false = Some false). reflexivity.
apply H1 in H2. rewrite H2 at 1. easy. easy.
rewrite nth_error_nth' with (d := false). easy.
rewrite tm_size_power2. assumption.
apply tm_step_stable. assumption.
generalize P. generalize O. apply Nat.lt_le_trans.
apply tm_step_stable. assumption.
generalize P. generalize I. apply Nat.lt_le_trans.
Qed.
(**
The following lemmas and theorems are of general interest; they
come here because they use more specific previously defined
lemmas and theorems.
*)
Theorem tm_step_succ_double_index : forall (n k : nat),
k < 2^n -> nth_error (tm_step n) k <> nth_error (tm_step (S n)) (S (2*k)).
Proof.
intros n k. intro H. rewrite tm_step_double_index.
rewrite Nat.mul_comm. rewrite <- Nat.pow_1_r with (a := 2).
replace (S (k*2^1)) with (k*2^1 + 2^0).
apply tm_step_flip_low_bit. apply Nat.lt_0_1.
rewrite Nat.mul_comm. simpl. rewrite Nat.add_0_r. rewrite Nat.add_0_r.
apply Nat.add_lt_mono; assumption.
simpl. apply Nat.add_1_r.
Qed.
Lemma tm_step_pred : forall (n k m : nat),
S (2*k) * 2^m < 2^n ->
nth_error (tm_step n) (S (2*k) * 2^m)
= nth_error (tm_step n) (pred (S (2*k) * 2^m))
<-> odd m = true.
Proof.
intros n k m.
generalize n. induction m. rewrite Nat.pow_0_r. rewrite Nat.mul_1_r.
destruct n0. rewrite Nat.pow_0_r. rewrite Nat.lt_1_r.
intro H. apply Nat.neq_succ_0 in H. contradiction H.
rewrite Nat.odd_0. rewrite Nat.pred_succ.
rewrite <- tm_step_double_index. intro H. split; intro I.
symmetry in I. apply tm_step_succ_double_index in I. contradiction I.
apply Nat.lt_succ_l in H. rewrite Nat.pow_succ_r' in H.
rewrite <- Nat.mul_lt_mono_pos_l in H. assumption. apply Nat.lt_0_2.
inversion I.
intro n0. intro I.
destruct n0. rewrite Nat.pow_0_r in I. rewrite Nat.lt_1_r in I.
rewrite Nat.mul_eq_0 in I. destruct I.
apply Nat.neq_succ_0 in H. contradiction H.
apply Nat.pow_nonzero in H. contradiction H. easy.
rewrite Nat.pow_succ_r'. rewrite Nat.mul_assoc.
replace (S (2*k) * 2) with (2* (S (2*k))).
rewrite <- Nat.mul_assoc. rewrite <- tm_step_double_index.
rewrite Nat.pow_succ_r' in I.
rewrite Nat.pow_succ_r' in I.
rewrite Nat.mul_assoc in I.
replace (S (2*k) * 2) with (2* (S (2*k))) in I.
rewrite <- Nat.mul_assoc in I.
rewrite <- Nat.mul_lt_mono_pos_l in I.
assert (J := I). apply IHm in J.
assert (M: 0 < 2^m). rewrite <- Nat.neq_0_lt_0. apply Nat.pow_nonzero. easy.
assert (L: pred( S (2 * k) * 2 ^ m) < S (2 * k) * 2 ^ m).
apply Nat.lt_pred_l. apply Nat.neq_mul_0.
split. apply Nat.neq_succ_0. rewrite Nat.neq_0_lt_0. assumption.
assert (N: pred (2 * (S (2 * k) * 2 ^ m)) < length (tm_step (S n0))).
rewrite tm_size_power2.
rewrite <- Nat.le_succ_l. rewrite Nat.succ_pred_pos. rewrite Nat.pow_succ_r.
apply Nat.mul_le_mono_l. generalize I. apply Nat.lt_le_incl.
apply Nat.le_0_l. apply Nat.mul_pos_pos. apply Nat.lt_0_2.
apply Nat.mul_pos_pos. apply Nat.lt_0_succ. assumption.
assert(T: pred (S (2 * k) * 2 ^ m) < 2 ^ n0).
generalize I. generalize L. apply Nat.lt_trans.
assert (nth_error (tm_step n0) (pred (S (2 * k) * 2 ^ m))
<> nth_error (tm_step (S n0)) (S (2 * (pred(S (2 * k) * 2 ^ m))))).
apply tm_step_succ_double_index. assumption.
replace (S (2 * (pred(S (2 * k) * 2 ^ m)))) with (pred(2 * (S (2*k) * 2^m))) in H.
rewrite Nat.odd_succ. rewrite <- Nat.negb_odd. destruct (odd m).
split. intro K. rewrite <- K in H.
destruct (nth_error (tm_step n0) (S (2 * k) * 2 ^ m));
destruct (nth_error (tm_step n0) (pred(S (2 * k) * 2 ^ m))).
destruct J. replace (Some b) with (Some b0) in H. contradiction H.
reflexivity. symmetry. apply H1. reflexivity.
destruct J. replace (Some b) with (None : option bool) in H.
contradiction H. reflexivity. symmetry. apply H1. reflexivity.
destruct J. replace (None : option bool) with (Some b) in H.
contradiction H. reflexivity. symmetry. apply H1. reflexivity.
contradiction H. reflexivity.
destruct (nth_error (tm_step n0) (S (2 * k) * 2 ^ m));
destruct (nth_error (tm_step n0) (pred(S (2 * k) * 2 ^ m)));
intro K; simpl in K; inversion K.
rewrite nth_error_nth' with (d := false) in J.
rewrite nth_error_nth' with (d := false) in J.
rewrite nth_error_nth' with (d := false) in H.
rewrite nth_error_nth' with (d := false) in H.
rewrite nth_error_nth' with (d := false).
rewrite nth_error_nth' with (d := false).
destruct (nth (S (2 * k) * 2 ^ m) (tm_step n0) false);
destruct (nth (pred (S (2 * k) * 2 ^ m)) (tm_step n0) false);
destruct (nth (pred (2 * (S (2 * k) * 2 ^ m))) (tm_step (S n0)) false).
simpl; split; reflexivity.
destruct J. rewrite H0 in H. contradiction H. reflexivity.
reflexivity.
simpl; split; reflexivity. contradiction H. reflexivity.
contradiction H. reflexivity.
simpl; split; reflexivity.
destruct J. rewrite H0 in H. contradiction H. reflexivity.
reflexivity.
simpl; split; reflexivity.
assumption. rewrite tm_size_power2. assumption. assumption.
rewrite tm_size_power2. assumption.
rewrite tm_size_power2. assumption.
rewrite tm_size_power2. assumption.
rewrite <- Nat.add_1_r at 4.
rewrite Nat.mul_add_distr_r. rewrite Nat.mul_1_l.
rewrite <- Nat.add_1_r at 1.
rewrite Nat.mul_add_distr_r. rewrite Nat.mul_1_l.
rewrite <- Nat.add_succ_l. rewrite Nat.succ_pred_pos. rewrite <- Nat.add_pred_r.
reflexivity. apply Nat.neq_mul_0. split. apply Nat.neq_succ_0. rewrite Nat.neq_0_lt_0.
assumption. apply Nat.mul_pos_pos. apply Nat.lt_0_succ. assumption.
apply Nat.lt_0_2.
apply Nat.mul_comm. apply Nat.mul_comm.
Qed.
(**
The following lemmas and theorems are related to the sequence being
cubefree. Only the final theorem is of general interest; all other
lemmas are defined for the very specific purpose of being used in the
final proof.
*)
Lemma tm_step_cube1 : forall (n : nat) (a hd tl: list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl -> even (length a) = true.
Proof.
intros n a hd tl. intro H.
assert (Nat.Even (length hd) \/ Nat.Odd (length hd)). apply Nat.Even_or_Odd.
assert (Nat.Even (length a) \/ Nat.Odd (length a)). apply Nat.Even_or_Odd.
destruct H1.
- apply Nat.EvenT_even. apply Nat.Even_EvenT. assumption.
- destruct H0.
assert (count_occ Bool.bool_dec hd true = count_occ Bool.bool_dec hd false).
assert (Nat.even (length hd) = true).
apply Nat.EvenT_even. apply Nat.Even_EvenT. assumption.
generalize H2. generalize H. apply tm_step_count_occ.
assert (I := H). replace (hd++a++a++a++tl) with ((hd++a++a)++(a++tl)) in I.
assert (count_occ Bool.bool_dec (hd++a++a) true = count_occ Bool.bool_dec (hd++a++a) false).
assert (even (length (hd++a++a)) = true).
rewrite app_length. rewrite Nat.even_add_even.
apply Nat.EvenT_even. apply Nat.Even_EvenT. assumption.
rewrite app_length. replace (length a) with (1*(length a)).
rewrite <- Nat.mul_add_distr_r. rewrite Nat.add_1_r.
rewrite <- Nat.add_0_l. apply Nat.EvenT_Even.
apply Nat.even_EvenT.
rewrite Nat.even_add_mul_2. reflexivity.
apply Nat.mul_1_l.
generalize H3. generalize I. apply tm_step_count_occ.
rewrite count_occ_app in H3. symmetry in H3.
rewrite count_occ_app in H3. rewrite H2 in H3.
rewrite Nat.add_cancel_l in H3.
rewrite count_occ_app in H3. rewrite count_occ_app in H3.
replace (count_occ bool_dec a false) with (1*(count_occ bool_dec a false)) in H3.
replace (count_occ bool_dec a true) with (1*(count_occ bool_dec a true)) in H3.
rewrite <- Nat.mul_add_distr_r in H3. rewrite <- Nat.mul_add_distr_r in H3.
rewrite Nat.mul_cancel_l in H3. apply count_occ_bool_list2 in H3.
assumption. easy. apply Nat.mul_1_l. apply Nat.mul_1_l.
rewrite app_assoc_reverse. rewrite app_inv_head_iff.
apply app_assoc_reverse.
assert (I := H). replace (hd++a++a++a++tl) with ((hd++a)++(a++a++tl)) in I.
assert (count_occ Bool.bool_dec (hd++a) true = count_occ Bool.bool_dec (hd++a) false).
assert (even (length (hd++a)) = true).
rewrite Nat.EvenT_even. reflexivity. apply Nat.Even_EvenT.
rewrite app_length. apply Nat.Odd_Odd_add; assumption.
generalize H2. generalize I. apply tm_step_count_occ.
assert (J := H). replace (hd++a++a++a++tl) with ((hd++a++a++a)++tl) in J.
assert (count_occ Bool.bool_dec (hd++a++a++a) true = count_occ Bool.bool_dec (hd++a++a++a) false).
assert (even (length (hd++a++a++a)) = true).
rewrite Nat.EvenT_even. reflexivity. apply Nat.Even_EvenT.
rewrite app_length. rewrite app_length. rewrite Nat.add_assoc. rewrite <- app_length.
apply Nat.Even_Even_add.
rewrite app_length. apply Nat.Odd_Odd_add; assumption.
rewrite app_length. apply Nat.Odd_Odd_add; assumption.
generalize H3. generalize J. apply tm_step_count_occ.
replace (hd++a++a++a) with ((hd++a)++(a++a)) in H3.
rewrite count_occ_app in H3. symmetry in H3.
rewrite count_occ_app in H3. rewrite H2 in H3.
rewrite Nat.add_cancel_l in H3.
rewrite count_occ_app in H3. rewrite count_occ_app in H3.
replace (count_occ bool_dec a false) with (1*(count_occ bool_dec a false)) in H3.
replace (count_occ bool_dec a true) with (1*(count_occ bool_dec a true)) in H3.
rewrite <- Nat.mul_add_distr_r in H3. rewrite <- Nat.mul_add_distr_r in H3.
rewrite Nat.mul_cancel_l in H3. apply count_occ_bool_list2 in H3.
assumption. easy. apply Nat.mul_1_l. apply Nat.mul_1_l.
apply app_assoc_reverse.
rewrite app_assoc_reverse. rewrite app_inv_head_iff.
rewrite app_assoc_reverse. rewrite app_inv_head_iff.
apply app_assoc_reverse.
apply app_assoc_reverse.
Qed.
Lemma tm_step_cube2 : forall (n : nat) (a hd tl: list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl -> 0 < length a -> 0 < n.
Proof.
intros n a hd tl. intros H I.
destruct n.
- assert (3 <= length (a ++ a ++ a)).
rewrite app_length. rewrite app_length.
rewrite <- Nat.le_succ_l in I.
assert (2 <= length a + length a).
generalize I. generalize I. apply Nat.add_le_mono.
generalize H0. generalize I. apply Nat.add_le_mono.
assert (length (tm_step 0) = length (tm_step 0)). reflexivity.
rewrite H in H1 at 2.
assert (0 <= length hd). apply Nat.le_0_l.
assert (0 + 3 <= length hd + length (a ++ a ++ a)).
generalize H0. generalize H2. apply Nat.add_le_mono.
simpl in H3. rewrite <- app_length in H3.
assert (0 <= length tl). apply Nat.le_0_l.
assert (3 + 0 <= length (hd ++ a ++ a ++ a) + length (tl)).
generalize H4. generalize H3. apply Nat.add_le_mono.
rewrite <- app_length in H5. rewrite Nat.add_0_r in H5.
replace ((hd++a++a++a)++tl) with (hd++a++a++a++tl) in H5.
rewrite <- H1 in H5. simpl in H5. apply le_S_n in H5.
apply Nat.nle_succ_0 in H5. contradiction H5.
rewrite app_assoc_reverse. rewrite app_inv_head_iff.
rewrite app_assoc_reverse. rewrite app_inv_head_iff.
rewrite app_assoc_reverse. reflexivity.
- apply Nat.lt_0_succ.
Qed.
Lemma tm_step_cube3 : forall (n : nat) (a hd tl: list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl
-> 0 < length a
-> even (length hd) = even (length tl).
Proof.
intros n a hd tl. intros H J.
assert (K : 0 < n). generalize J. generalize H. apply tm_step_cube2.
destruct n.
- apply Nat.lt_irrefl in K. contradiction K.
- assert (Nat.Even (length (tm_step (S n)))).
rewrite tm_size_power2. rewrite Nat.pow_succ_r'.
apply Nat.Even_mul_l. apply Nat.EvenT_Even.
apply Nat.EvenT_2. apply Nat.EvenT_0.
rewrite H in H0. rewrite app_length in H0. rewrite app_length in H0.
rewrite Nat.add_shuffle3 in H0.
assert (I := H). apply tm_step_cube1 in I.
apply Nat.even_EvenT in I. apply Nat.EvenT_Even in I.
assert (Nat.Even (length hd + length (a ++ a ++ tl))).
generalize I. generalize H0. apply Nat.Even_add_Even_inv_r.
rewrite app_length in H1. rewrite Nat.add_shuffle3 in H1.
assert (Nat.Even (length hd + length (a ++ tl))).
generalize I. generalize H1. apply Nat.Even_add_Even_inv_r.
rewrite app_length in H2. rewrite Nat.add_shuffle3 in H2.
assert (Nat.Even (length hd + length tl)).
generalize I. generalize H2. apply Nat.Even_add_Even_inv_r.
apply Nat.Even_EvenT in H3. apply Nat.EvenT_even in H3.
rewrite Nat.even_add in H3.
destruct (even (length hd)); destruct (even (length tl)).
reflexivity. simpl in H3. inversion H3.
simpl in H3. inversion H3. reflexivity.
Qed.
Lemma tm_step_cube4 : forall (n : nat) (a hd tl: list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl -> even (length hd) = false
-> 0 < length a
-> hd_error a = hd_error tl.
Proof.
intros n a hd tl. intros H I J.
assert (even (length hd) = even (length tl)).
generalize J. generalize H. apply tm_step_cube3.
assert (even (length a) = true). generalize H. apply tm_step_cube1.
rewrite I in H0.
destruct a.
- simpl in J. apply Nat.lt_irrefl in J. contradiction J.
- destruct tl. simpl in H0. inversion H0.
simpl. replace (b::a) with ((b::nil) ++ a) in H.
replace (hd ++ ([b] ++ a) ++ ([b] ++ a) ++ ([b] ++ a) ++ (b0::tl))
with ((hd ++ (b::nil)) ++ (a ++ (b::nil)) ++ (a ++ (b::nil)) ++ (a ++ (b0::nil)) ++ tl) in H.
assert (even (length (hd ++ (b::nil))) = true).
rewrite last_length.
rewrite Nat.even_succ. rewrite <- Nat.negb_even. rewrite I. reflexivity.
assert (count_occ Bool.bool_dec (hd ++ (b::nil)) true
= count_occ Bool.bool_dec (hd ++ (b::nil)) false).
generalize H2. generalize H. apply tm_step_count_occ.
assert (even (length ((hd ++ (b::nil)) ++ (a++ (b::nil)))) = true).
rewrite app_length. rewrite Nat.even_add. rewrite H2.
rewrite last_length.
replace (length (b::a)) with (S (length a)) in H1. rewrite H1. reflexivity.
reflexivity.
assert (count_occ Bool.bool_dec ((hd ++ [b]) ++ a ++ [b]) true
= count_occ Bool.bool_dec ((hd ++ [b]) ++ a ++ [b]) false).
generalize H4. rewrite app_assoc in H. generalize H. apply tm_step_count_occ.
assert (K := H5).
rewrite count_occ_app in H5. symmetry in H5. rewrite count_occ_app in H5.
rewrite H3 in H5. rewrite Nat.add_cancel_l in H5.
assert (even (length ((hd ++ (b::nil)) ++ (a++ (b::nil)) ++ (a++ (b::nil)))) = true).
rewrite app_assoc. rewrite app_length. rewrite Nat.even_add. rewrite H4.
rewrite last_length.
replace (length (b::a)) with (S (length a)) in H1. rewrite H1. reflexivity.
reflexivity.
assert (count_occ Bool.bool_dec ((hd ++ [b]) ++ (a ++ [b]) ++ (a ++ [b])) true
= count_occ Bool.bool_dec ((hd ++ [b]) ++ (a ++ [b]) ++ (a ++ [b])) false).
generalize H6.
rewrite app_assoc in H. rewrite app_assoc in H.
replace (((hd ++ [b]) ++ a ++ [b]) ++ a ++ [b])
with ((hd ++ [b]) ++ (a ++ [b]) ++ a ++ [b]) in H.
generalize H. apply tm_step_count_occ.
rewrite app_assoc_reverse. rewrite app_assoc_reverse. rewrite app_assoc_reverse.
rewrite app_assoc_reverse. apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse. reflexivity.
assert (even (length ((hd ++ (b::nil)) ++ (a++ (b::nil)) ++ (a++ (b::nil)) ++ (a++ (b0::nil)))) = true).
rewrite app_assoc. rewrite app_length. rewrite Nat.even_add. rewrite H4.
rewrite app_length. rewrite last_length.
replace (length (b::a)) with (S (length a)) in H1. rewrite Nat.even_add. rewrite H1.
rewrite last_length. rewrite H1. reflexivity. reflexivity.
assert (count_occ Bool.bool_dec ((hd ++ [b]) ++ (a ++ [b]) ++ (a ++ [b]) ++ (a ++ [b0])) true
= count_occ Bool.bool_dec ((hd ++ [b]) ++ (a ++ [b]) ++ (a ++ [b]) ++ (a ++ [b0])) false).
generalize H8.
rewrite app_assoc in H. rewrite app_assoc in H. rewrite app_assoc in H.
replace ((((hd ++ [b]) ++ a ++ [b]) ++ a ++ [b]) ++ a ++ [b0])
with ((hd ++ [b]) ++ (a ++ [b]) ++ (a ++ [b]) ++ (a ++ [b0])) in H.
generalize H. apply tm_step_count_occ.
rewrite app_assoc_reverse. rewrite app_assoc_reverse. rewrite app_assoc_reverse.
rewrite app_assoc_reverse. rewrite app_assoc_reverse. rewrite app_assoc_reverse.
apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse. apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse. reflexivity.
rewrite count_occ_app in H9. symmetry in H9. rewrite count_occ_app in H9.
rewrite H3 in H9. rewrite Nat.add_cancel_l in H9.
rewrite count_occ_app in H9. symmetry in H9. rewrite count_occ_app in H9.
rewrite H5 in H9. rewrite Nat.add_cancel_l in H9.
rewrite count_occ_app in H9. symmetry in H9. rewrite count_occ_app in H9.
rewrite H5 in H9. rewrite Nat.add_cancel_l in H9.
destruct b; destruct b0.
+ reflexivity.
+ rewrite count_occ_app in H9. rewrite count_occ_app in H9.
rewrite count_occ_cons_eq in H9. rewrite count_occ_cons_neq in H9.
rewrite count_occ_nil in H9. rewrite count_occ_nil in H9.
rewrite Nat.add_1_r in H9. rewrite Nat.add_0_r in H9.
rewrite count_occ_app in H5. rewrite count_occ_app in H5.
rewrite count_occ_cons_neq in H5. rewrite count_occ_cons_eq in H5.
rewrite count_occ_nil in H5. rewrite count_occ_nil in H5.
rewrite Nat.add_1_r in H5. rewrite Nat.add_0_r in H5.
rewrite H5 in H9.
rewrite <- Nat.add_1_r in H9. rewrite <- Nat.add_1_r in H9.
rewrite <- Nat.add_0_r in H9. rewrite <- Nat.add_assoc in H9.
rewrite Nat.add_cancel_l in H9. inversion H9.
reflexivity. easy. easy. reflexivity.
+ rewrite count_occ_app in H9. rewrite count_occ_app in H9.
rewrite count_occ_cons_neq in H9. rewrite count_occ_cons_eq in H9.
rewrite count_occ_nil in H9. rewrite count_occ_nil in H9.
rewrite Nat.add_1_r in H9. rewrite Nat.add_0_r in H9.
rewrite count_occ_app in H5. rewrite count_occ_app in H5.
rewrite count_occ_cons_eq in H5. rewrite count_occ_cons_neq in H5.
rewrite count_occ_nil in H5. rewrite count_occ_nil in H5.
rewrite Nat.add_1_r in H5. rewrite Nat.add_0_r in H5.
rewrite <- H5 in H9.
rewrite <- Nat.add_1_r in H9. rewrite <- Nat.add_1_r in H9.
rewrite <- Nat.add_0_r in H9 at 1. rewrite <- Nat.add_assoc in H9.
rewrite Nat.add_cancel_l in H9. inversion H9.
easy. reflexivity. reflexivity. easy.
+ reflexivity.
+ rewrite app_assoc_reverse. apply app_inv_head_iff.
rewrite app_assoc_reverse. rewrite app_assoc_reverse.
rewrite app_assoc_reverse. rewrite app_assoc_reverse.
apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse.
apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse.
reflexivity.
+ reflexivity.
Qed.
Lemma tm_step_cube5 : forall (n : nat) (a hd tl: list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl
-> 0 < length a
-> exists (hd2 b tl2 : list bool), tm_step n = hd2 ++ b ++ b ++ b ++ tl2
/\ length a = length b
/\ even (length hd2) = true.
Proof.
intros n a hd tl. intros H I.
assert (J: Nat.Even (length hd) \/ Nat.Odd (length hd)).
apply Nat.Even_or_Odd.
destruct J.
- exists hd. exists a. exists tl.
split. assumption. split. reflexivity.
apply Nat.Even_EvenT in H0.
apply Nat.EvenT_even in H0. assumption.
- apply Nat.Odd_OddT in H0.
apply Nat.OddT_odd in H0.
rewrite <- Nat.negb_even in H0. rewrite negb_true_iff in H0.
destruct a.
+ simpl in I. apply Nat.lt_irrefl in I. contradiction I.
+ assert (Nat.even (length hd) = Nat.even (length tl)).
generalize I. generalize H. apply tm_step_cube3.
rewrite H0 in H1.
destruct tl.
* simpl in H1. inversion H1.
* assert (hd_error (b::a) = hd_error (b0::tl)).
generalize I. generalize H0. generalize H. apply tm_step_cube4.
simpl in H2. inversion H2. rewrite <- H4 in H.
exists (hd ++ (b::nil)). exists (a ++ (b::nil)). exists tl.
split. rewrite H.
rewrite app_assoc_reverse. apply app_inv_head_iff.
replace (b::a) with ([b] ++ a).
rewrite app_assoc_reverse. apply app_inv_head_iff.
rewrite app_assoc_reverse. rewrite app_assoc_reverse.
rewrite app_assoc_reverse. apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse. apply app_inv_head_iff. apply app_inv_head_iff.
rewrite app_assoc_reverse. reflexivity.
reflexivity.
split. rewrite last_length. reflexivity.
rewrite last_length.
rewrite Nat.even_succ. rewrite <- Nat.negb_even. rewrite H0.
reflexivity.
Qed.
Lemma tm_step_cube6 : forall (n : nat) (a hd tl: list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl
-> 0 < length a
-> exists (hd2 b tl2 : list bool),
tm_step (Nat.pred n) = hd2 ++ b ++ b ++ b ++ tl2 /\ 0 < length b.
Proof.
intros n a hd tl. intros H I.
assert(J: exists (hd2 b tl2 : list bool),
tm_step n = hd2 ++ b ++ b ++ b ++ tl2
/\ length a = length b /\ even (length hd2) = true).
generalize I. generalize H. apply tm_step_cube5.
destruct J as [ hd2 J0]. destruct J0 as [ b J1]. destruct J1 as [ tl2 J2].
destruct J2 as [J3 J4]. destruct J4 as [J5 J6].
assert (J: even (length b) = true). generalize J3. apply tm_step_cube1.
assert (K: 0 < n). generalize I. generalize H. apply tm_step_cube2.
destruct n.
- apply Nat.lt_irrefl in K. contradiction K.
- rewrite <- tm_step_lemma in J3.
assert (L: hd2 = tm_morphism (firstn (Nat.div2 (length hd2)) (tm_step n))).
generalize J6. generalize J3. apply tm_morphism_app2.
assert (M: b ++ b ++ b ++ tl2
= tm_morphism (skipn (Nat.div2 (length hd2)) (tm_step n))).
generalize J6. generalize J3. apply tm_morphism_app3.
assert (N: b = tm_morphism (firstn (Nat.div2 (length b))
(skipn (Nat.div2 (length hd2))
(tm_step n)))).
generalize J. symmetry in M. generalize M. apply tm_morphism_app2.
assert (even (length (b++b++b)) = true).
rewrite app_length. rewrite app_length.
rewrite Nat.even_add_even. assumption.
apply Nat.EvenT_Even. apply Nat.even_EvenT.
rewrite Nat.even_add_even. assumption.
apply Nat.EvenT_Even. apply Nat.even_EvenT. assumption.
assert (O: tl2 = tm_morphism (skipn (Nat.div2 (length (b++b++b)))
(skipn (Nat.div2 (length hd2))
(tm_step n)))).
generalize H0. symmetry in M. generalize M.
replace (b++b++b++tl2) with ((b++b++b)++tl2). apply tm_morphism_app3.
rewrite app_assoc_reverse. apply app_inv_head_iff.
apply app_assoc_reverse.
assert (hd2 ++ b ++ b ++ b ++ tl2
= (tm_morphism (firstn (Nat.div2 (length hd2)) (tm_step n)))
++ (tm_morphism (firstn (Nat.div2 (length b))
(skipn (Nat.div2 (length hd2)) (tm_step n))))
++ (tm_morphism (firstn (Nat.div2 (length b))
(skipn (Nat.div2 (length hd2)) (tm_step n))))
++ (tm_morphism (firstn (Nat.div2 (length b))
(skipn (Nat.div2 (length hd2)) (tm_step n))))
++ (tm_morphism (skipn (Nat.div2 (length (b ++ b ++ b)))
(skipn (Nat.div2 (length hd2)) (tm_step n))))).
rewrite <- L. rewrite <- N. rewrite <- O. reflexivity.
rewrite <- tm_morphism_app in H1. rewrite <- tm_morphism_app in H1.
rewrite <- tm_morphism_app in H1. rewrite <- tm_morphism_app in H1.
rewrite <- J3 in H1.
rewrite Nat.pred_succ. rewrite <- tm_morphism_eq in H1.
exists (firstn (Nat.div2 (length hd2)) (tm_step n)).
exists (firstn (Nat.div2 (length b))
(skipn (Nat.div2 (length hd2)) (tm_step n))).
exists (skipn (Nat.div2 (length (b ++ b ++ b)))
(skipn (Nat.div2 (length hd2)) (tm_step n))).
split. assumption.
assert (2 <= length b). destruct b. simpl in J5. rewrite J5 in I.
apply Nat.lt_irrefl in I. contradiction I.
destruct b0. simpl in J. inversion J. simpl. rewrite <- Nat.succ_le_mono.
rewrite <- Nat.succ_le_mono. apply Nat.le_0_l.
assert (length (b++b++b++tl2)
= 2 * length (skipn (Nat.div2 (length hd2)) (tm_step n))).
rewrite M. apply tm_morphism_length.
assert (2 <= length (b++b++b++tl2)).
rewrite app_length. rewrite <- Nat.add_0_r at 1.
apply Nat.add_le_mono. assumption. apply Nat.le_0_l.
rewrite H3 in H4. rewrite <- Nat.mul_1_r in H4 at 1.
rewrite <- Nat.mul_le_mono_pos_l in H4.
rewrite firstn_length. rewrite <- Nat.le_succ_l.
assert (1 <= Nat.div2 (length b)).
rewrite Nat.mul_le_mono_pos_l with (p:= 2). rewrite Nat.mul_1_r.
replace (2 * Nat.div2 (length b))
with (2 * Nat.div2 (length b) + Nat.b2n (Nat.odd (length b))).
rewrite <- Nat.div2_odd. assumption.
rewrite <- Nat.negb_even. rewrite J. simpl. rewrite Nat.add_0_r. reflexivity.
apply Nat.lt_0_2.
generalize H4. generalize H5. apply Nat.min_glb.
apply Nat.lt_0_2.
Qed.
Lemma tm_step_cube7 : forall (n : nat),
(exists (hd a tl : list bool), tm_step n = hd ++ a ++ a ++ a ++ tl
/\ 0 < length a)
-> exists (hd2 b tl2 : list bool), tm_step 0 = hd2 ++ b ++ b ++ b ++ tl2
/\ 0 < length b.
Proof.
intros n. intro H.
induction n; destruct H; destruct H; destruct H; destruct H.
- exists x. exists x0. exists x1. split; assumption.
- assert (J: exists (hd2 b2 tl2 : list bool),
tm_step (Nat.pred (S n)) = hd2 ++ b2 ++ b2 ++ b2 ++ tl2
/\ 0 < length b2).
generalize H0. generalize H. apply tm_step_cube6.
rewrite Nat.pred_succ in J. apply IHn. apply J.
Qed.
Theorem tm_step_cubefree : forall (n : nat) (hd a b tl : list bool),
tm_step n = hd ++ a ++ a ++ b ++ tl -> 0 < length a -> a <> b.
Proof.
intros n hd a b tl. intros H I.
assert (J: {a=b} + {~ a=b}). apply list_eq_dec. apply bool_dec.
destruct J.
- rewrite <- e in H.
assert (J: exists (hd a tl : list bool),
tm_step n = hd ++ a ++ a ++ a ++ tl /\ 0 < length a).
exists hd. exists a. exists tl. split; assumption.
apply tm_step_cube7 in J. destruct J. destruct H0. destruct H0. destruct H0.
assert (0 < 0). generalize H1. generalize H0. apply tm_step_cube2.
apply Nat.lt_irrefl in H2. contradiction H2.
- assumption.
Qed.