Replace the two-bank machine with a K-bank ring, prove its reproduction in Rocq, and revise the paper
a9ea017 Download rocq/Decoder.v from phanerozoic/threshold-computers: direct link, hf CLI and curl.
- Browser
- Download file 52.5 kB
-
https://huggingface.co/phanerozoic/threshold-computers/resolve/main/rocq/Decoder.v
- Command line
-
hf download hf://phanerozoic/threshold-computers/rocq/Decoder.v
-
curl -L -o Decoder.v https://huggingface.co/phanerozoic/threshold-computers/resolve/main/rocq/Decoder.v
52.5 kB
| (* The pass of the spec iterated over a generation. The read tape, the idle bank read as a tape of | |
| N cells and the copy tape keep their cells in place, each head at an absolute cell. *) | |
| From Stdlib Require Import List Bool Arith Lia. | |
| Import ListNotations. | |
| From TH Require Import TwoHead Abstract Spec PassCheck. | |
| Record dst := mkD { dc : cfg; dR : tape; dA : tape; dK : tape }. | |
| (* a tape holding the cells u and then z, its head on the first cell of z *) | |
| Definition past (n : nat) (u z : list bool) : tape := mkT (u ++ z) (length u mod n). | |
| Lemma upd_app_cons : forall u c z v, upd (u ++ c :: z) (length u) v = u ++ v :: z. | |
| Proof. induction u as [|x u IH]; intros c z v; cbn; [reflexivity | rewrite IH; reflexivity]. Qed. | |
| Lemma past_get : forall n u b z, length u < n -> tget (past n u (b :: z)) = b. | |
| Proof. | |
| intros n u b z H. unfold tget, past. cbn [td th]. rewrite (Nat.mod_small _ _ H). | |
| rewrite app_nth2 by lia. rewrite Nat.sub_diag. reflexivity. | |
| Qed. | |
| Lemma past_adv : forall n u b z, 1 <= n -> | |
| mkT (td (past n u (b :: z))) (succ_mod n (th (past n u (b :: z)))) = past n (u ++ [b]) z. | |
| Proof. | |
| intros n u b z H. unfold past. cbn [td th]. rewrite (succ_mod_mod n (length u) H). | |
| rewrite <- app_assoc, length_app. cbn [app length]. rewrite Nat.add_1_r. reflexivity. | |
| Qed. | |
| Lemma past_write : forall n u c z v, length u < n -> | |
| mkT (upd (td (past n u (c :: z))) (th (past n u (c :: z))) v) (succ_mod n (th (past n u (c :: z)))) | |
| = past n (u ++ [v]) z. | |
| Proof. | |
| intros n u c z v H. unfold past. cbn [td th]. rewrite (succ_mod_mod n (length u) ltac:(lia)). | |
| rewrite (Nat.mod_small _ _ H), upd_app_cons, <- app_assoc, length_app. cbn [app length]. | |
| rewrite Nat.add_1_r. reflexivity. | |
| Qed. | |
| Lemma past_home : forall n u z, mkT (td (past n u z)) 0 = past n [] (u ++ z). | |
| Proof. intros n u z. unfold past. cbn [td length app]. rewrite Nat.Div0.mod_0_l. reflexivity. Qed. | |
| Lemma skipn_repeat_false : forall a n, skipn a (repeat false n) = repeat false (n - a). | |
| Proof. | |
| induction a as [|a IH]; intros [|n]; cbn [skipn repeat]; try reflexivity. exact (IH n). | |
| Qed. | |
| (* ---- lists ---------------------------------------------------------------------------------- *) | |
| Lemma some_inj : forall (A : Type) (a b : A), Some a = Some b -> a = b. | |
| Proof. intros A a b H. injection H. auto. Qed. | |
| Lemma split_at : forall (l : list bool) n, n <= length l -> exists a c, l = a ++ c /\ length a = n. | |
| Proof. | |
| intros l n H. exists (firstn n l), (skipn n l). split; [symmetry; apply firstn_skipn|]. | |
| apply firstn_length_le. exact H. | |
| Qed. | |
| Lemma skipn_app_exact : forall (a b : list bool) n, length a = n -> skipn n (a ++ b) = b. | |
| Proof. intros a b n <-. induction a as [|x a IH]; [reflexivity|]. exact IH. Qed. | |
| Lemma firstn_app_exact : forall (a b : list bool) n, length a = n -> firstn n (a ++ b) = a. | |
| Proof. | |
| intros a b n <-. induction a as [|x a IH]; [reflexivity|]. cbn [length firstn app]. | |
| rewrite IH. reflexivity. | |
| Qed. | |
| Lemma translate_aux_long : forall f l X, translate_aux f l = Some X -> 4 <= length l. | |
| Proof. | |
| intros [|f] l X H; [discriminate|]. cbn [translate_aux] in H. | |
| destruct l as [|a [|b [|c [|d l]]]]; try discriminate. cbn [length]. lia. | |
| Qed. | |
| Lemma translate_aux_S : forall f c3 c2 s0 s1 rest, | |
| translate_aux (S f) (c3 :: c2 :: s0 :: s1 :: rest) = | |
| if c3 && c2 then | |
| if s0 && s1 then match rest with [] => Some [] | _ => None end | |
| else if Nat.eqb (length rest) 0 then None | |
| else option_map (fun t => firstn 26 rest ++ t) (translate_aux f (skipn 26 rest)) | |
| else option_map (fun t => gate_bits (if c3 then 2 else if c2 then 1 else 0) s0 s1 ++ firstn 18 rest ++ t) | |
| (translate_aux f (skipn 18 rest)). | |
| Proof. reflexivity. Qed. | |
| Fixpoint down (n : nat) : list nat := match n with O => [0] | S m => n :: down m end. | |
| Definition kind_of (e3 e2 : bool) : nat := if e3 then 2 else if e2 then 1 else 0. | |
| Lemma length_gate_bits : forall k s0 s1, length (gate_bits k s0 s1) = 8. | |
| Proof. intros [|[|[|k]]] s0 s1; reflexivity. Qed. | |
| Lemma table_gate : forall e3 e2 s0 s1, e3 && e2 = false -> | |
| map (table e3 e2 s0 s1) (down 7) = gate_bits (kind_of e3 e2) s0 s1. | |
| Proof. intros [] [] [] [] H; try discriminate; reflexivity. Qed. | |
| (* ---- the flags of a pass ---------------------------------------------------------------------- *) | |
| Lemma dpass_flags : forall cf r, | |
| (fresh (dpass cf r) = true -> home (dpass cf r) = true) | |
| /\ (home (dpass cf r) = true -> emit (dpass cf r) = false) | |
| /\ (fresh (dpass cf r) = true -> cw (dpass cf r) = false). | |
| Proof. | |
| intros [p n c3 c2 c1 c0 m] r. unfold dpass. cbn [ph Spec.z Spec.c3 Spec.c2 Spec.c1 Spec.c0 mo]. | |
| destruct p; repeat match goal with |- context [if ?b then _ else _] => destruct b end; | |
| cbn [fresh home emit cw]; repeat split; intro H; first [discriminate | reflexivity]. | |
| Qed. | |
| Lemma reach_step : forall cf r, reachable cf = true -> reachable (ncf (dpass cf r)) = true. | |
| Proof. | |
| intros [p n e3 e2 e1 e0 m] r H. unfold reachable in H. cbn [ph Spec.z] in H. | |
| unfold dpass. cbn [ph Spec.z Spec.c3 Spec.c2 Spec.c1 Spec.c0 mo]. | |
| destruct p; apply Nat.leb_le in H; destruct (Nat.eqb n 0) eqn:E; | |
| repeat match goal with |- context [if ?b then _ else _] => destruct b end; | |
| cbn [ncf reachable ph Spec.z]; apply Nat.leb_le; lia. | |
| Qed. | |
| Section Dec. | |
| Variables N L : nat. | |
| Hypotheses (HN : 1 <= N) (HL : 1 <= L). | |
| Definition dout (t : dst) : out := dpass (dc t) (tget (dR t)). | |
| (* one pass of the spec on the three tapes *) | |
| Definition dstep (t : dst) : dst := | |
| let r := tget (dR t) in | |
| let o := dpass (dc t) r in | |
| mkD (ncf o) (tape_eff L (expR o r) (dR t)) (tape_eff N (expA o (tget (dA t))) (dA t)) | |
| (tape_eff L (expK o r (tget (dK t))) (dK t)). | |
| Fixpoint dsteps (n : nat) (t : dst) : dst := match n with O => t | S m => dsteps m (dstep t) end. | |
| Lemma dsteps_add : forall a b t, dsteps (a + b) t = dsteps b (dsteps a t). | |
| Proof. induction a as [|a IH]; intros b t; cbn [dsteps Nat.add]; auto. Qed. | |
| (* no pass among the first n hands over *) | |
| Definition quiet (n : nat) (t : dst) : Prop := forall j, j < n -> ho (dout (dsteps j t)) = false. | |
| Lemma quiet_S : forall n t, ho (dout t) = false -> quiet n (dstep t) -> quiet (S n) t. | |
| Proof. intros n t H0 H [|j] Hj; [exact H0|]. cbn [dsteps]. apply H. lia. Qed. | |
| Lemma quiet_add : forall a b t, quiet a t -> quiet b (dsteps a t) -> quiet (a + b) t. | |
| Proof. | |
| intros a b t Ha Hb j Hj. destruct (Nat.lt_ge_cases j a) as [H|H]; [apply Ha; exact H|]. | |
| replace j with (a + (j - a)) by lia. rewrite dsteps_add. apply Hb. lia. | |
| Qed. | |
| Lemma quiet_0 : forall t, quiet 0 t. | |
| Proof. intros t j Hj. lia. Qed. | |
| (* the effect of a pass on each tape, by its flags *) | |
| Definition rmove (o : out) (t : tape) : tape := | |
| if rr o then mkT (td t) 0 else if cons o then mkT (td t) (succ_mod L (th t)) else t. | |
| Definition amove (o : out) (t : tape) : tape := | |
| if fresh o then mkT (repeat false N) 0 else if home o then mkT (td t) 0 | |
| else if emit o then mkT (upd (td t) (th t) (av o)) (succ_mod N (th t)) else t. | |
| Definition kmove (o : out) (r : bool) (t : tape) : tape := | |
| if fresh o then mkT (repeat false L) 0 | |
| else if home o then mkT (if cw o then upd (td t) (th t) r else td t) 0 | |
| else if cw o then mkT (upd (td t) (th t) r) (succ_mod L (th t)) else t. | |
| Lemma dstep_eq : forall t, dstep t = | |
| mkD (ncf (dout t)) (rmove (dout t) (dR t)) (amove (dout t) (dA t)) (kmove (dout t) (tget (dR t)) (dK t)). | |
| Proof. | |
| intros [c R A K]. unfold dstep, dout. cbn [dc dR dA dK]. | |
| destruct (dpass_flags c (tget R)) as (F1 & F2 & F3). | |
| set (o := dpass c (tget R)) in *. f_equal. | |
| - unfold tape_eff, expR, rmove. cbn [acl awr amv arw]. | |
| destruct (rr o), (cons o); cbn [iter]; try reflexivity. destruct R; reflexivity. | |
| - unfold tape_eff, expA, amove, tget. cbn [acl awr amv arw]. | |
| destruct (fresh o) eqn:Ef; [rewrite (F1 eq_refl); reflexivity|]. | |
| destruct (home o) eqn:Eh; [rewrite (F2 eq_refl), upd_same; reflexivity|]. | |
| destruct (emit o); cbn [iter]; [reflexivity|]. rewrite upd_same. destruct A; reflexivity. | |
| - unfold tape_eff, expK, kmove, tget. cbn [acl awr amv arw]. | |
| destruct (fresh o) eqn:Ef; [rewrite (F1 eq_refl); reflexivity|]. | |
| destruct (home o), (cw o); cbn [iter]; rewrite ?upd_same; try reflexivity. destruct K; reflexivity. | |
| Qed. | |
| (* ---- one pass in each phase ---------------------------------------------------------------- *) | |
| Lemma pass_PI : forall zc c3 c2 c1 c0 m R A K, | |
| ho (dout (mkD (mkC PI zc c3 c2 c1 c0 m) R A K)) = false | |
| /\ dstep (mkD (mkC PI zc c3 c2 c1 c0 m) R A K) | |
| = mkD (mkC PC 3 c3 c2 c1 c0 false) (mkT (td R) 0) (mkT (repeat false N) 0) (mkT (repeat false L) 0). | |
| Proof. intros. split; [reflexivity|]. rewrite dstep_eq. reflexivity. Qed. | |
| Lemma pass_PA : forall n e3 e2 e1 e0 m done b rest A K, length done < L -> | |
| ho (dout (mkD (mkC PA n e3 e2 e1 e0 m) (past L done (b :: rest)) A K)) = false | |
| /\ dstep (mkD (mkC PA n e3 e2 e1 e0 m) (past L done (b :: rest)) A K) | |
| = mkD (if Nat.eqb n 0 then mkC PC 3 e3 e2 e1 e0 m else mkC PA (n - 1) e3 e2 e1 e0 m) | |
| (past L (done ++ [b]) rest) | |
| (if m then A else mkT (upd (td A) (th A) b) (succ_mod N (th A))) | |
| (if m then mkT (upd (td K) (th K) b) (succ_mod L (th K)) else K). | |
| Proof. | |
| intros n e3 e2 e1 e0 m done b rest A K Hd. | |
| assert (Ho : dout (mkD (mkC PA n e3 e2 e1 e0 m) (past L done (b :: rest)) A K) | |
| = mkO (if Nat.eqb n 0 then mkC PC 3 e3 e2 e1 e0 m else mkC PA (n - 1) e3 e2 e1 e0 m) | |
| true (negb m) b m false false false false). | |
| { unfold dout. cbn [dc dR]. rewrite (past_get L done b rest Hd). reflexivity. } | |
| split; [rewrite Ho; reflexivity|]. | |
| rewrite dstep_eq, Ho. cbn [dR dA dK]. rewrite (past_get L done b rest Hd). | |
| unfold rmove, amove, kmove. cbn [ncf rr cons fresh home emit cw av]. | |
| rewrite (past_adv L done b rest HL). destruct m; reflexivity. | |
| Qed. | |
| Lemma pass_PG : forall n e3 e2 e1 e0 m R A K, | |
| ho (dout (mkD (mkC PG n e3 e2 e1 e0 m) R A K)) = false | |
| /\ dstep (mkD (mkC PG n e3 e2 e1 e0 m) R A K) | |
| = mkD (if Nat.eqb n 0 then mkC PA 17 e3 e2 e1 e0 m else mkC PG (n - 1) e3 e2 e1 e0 m) | |
| (if is_esc e3 e2 e1 e0 then mkT (td R) (succ_mod L (th R)) else R) | |
| (if m then A | |
| else mkT (upd (td A) (th A) (if is_esc e3 e2 e1 e0 then tget R else table e3 e2 e1 e0 n)) | |
| (succ_mod N (th A))) | |
| (if m && is_esc e3 e2 e1 e0 then mkT (upd (td K) (th K) (tget R)) (succ_mod L (th K)) else K). | |
| Proof. | |
| intros n e3 e2 e1 e0 m R A K. | |
| assert (Ho : dout (mkD (mkC PG n e3 e2 e1 e0 m) R A K) | |
| = mkO (if Nat.eqb n 0 then mkC PA 17 e3 e2 e1 e0 m else mkC PG (n - 1) e3 e2 e1 e0 m) | |
| (is_esc e3 e2 e1 e0) (negb m) | |
| (if is_esc e3 e2 e1 e0 then tget R else table e3 e2 e1 e0 n) | |
| (m && is_esc e3 e2 e1 e0) false false false false) by reflexivity. | |
| split; [rewrite Ho; reflexivity|]. | |
| rewrite dstep_eq, Ho. cbn [dR dA dK]. unfold rmove, amove, kmove. cbn [ncf rr cons fresh home emit cw av]. | |
| destruct (is_esc e3 e2 e1 e0), m; reflexivity. | |
| Qed. | |
| Lemma pass_PC : forall n e3 e2 e1 e0 m done b rest A K, length done < L -> | |
| ho (dout (mkD (mkC PC (S n) e3 e2 e1 e0 m) (past L done (b :: rest)) A K)) = false | |
| /\ dstep (mkD (mkC PC (S n) e3 e2 e1 e0 m) (past L done (b :: rest)) A K) | |
| = mkD (mkC PC n e2 e1 e0 b m) (past L (done ++ [b]) rest) A | |
| (if m then mkT (upd (td K) (th K) b) (succ_mod L (th K)) else K). | |
| Proof. | |
| intros n e3 e2 e1 e0 m done b rest A K Hd. | |
| assert (Ho : dout (mkD (mkC PC (S n) e3 e2 e1 e0 m) (past L done (b :: rest)) A K) | |
| = mkO (mkC PC n e2 e1 e0 b m) true false false m false false false false). | |
| { unfold dout. cbn [dc dR]. rewrite (past_get L done b rest Hd). unfold dpass. | |
| cbn [ph Spec.z Spec.c3 Spec.c2 Spec.c1 Spec.c0 mo Nat.eqb]. replace (S n - 1) with n by lia. reflexivity. } | |
| split; [rewrite Ho; reflexivity|]. | |
| rewrite dstep_eq, Ho. cbn [dR dA dK]. rewrite (past_get L done b rest Hd). | |
| unfold rmove, amove, kmove. cbn [ncf rr cons fresh home emit cw av]. | |
| rewrite (past_adv L done b rest HL). destruct m; reflexivity. | |
| Qed. | |
| (* the pass that ends a codon: the codon register then holds c2 c1 c0 b *) | |
| Lemma pass_PC0 : forall c3 c2 c1 c0 m done b rest A K, length done < L -> | |
| let o := dout (mkD (mkC PC 0 c3 c2 c1 c0 m) (past L done (b :: rest)) A K) in | |
| o = (if is_end c2 c1 c0 b then | |
| if m then mkO (mkC PI 1 c2 c1 c0 b false) true false false true false true false true | |
| else mkO (mkC PC 3 c2 c1 c0 b true) true false false false true false false false | |
| else if negb m || is_esc c2 c1 c0 b then mkO (mkC PG 7 c2 c1 c0 b m) true false false m false false false false | |
| else mkO (mkC PA 17 c2 c1 c0 b m) true false false m false false false false) | |
| /\ dstep (mkD (mkC PC 0 c3 c2 c1 c0 m) (past L done (b :: rest)) A K) | |
| = mkD (ncf o) (rmove o (past L done (b :: rest))) (amove o A) (kmove o b K). | |
| Proof. | |
| intros c3 c2 c1 c0 m done b rest A K Hd o. | |
| split. | |
| - unfold o, dout. cbn [dc dR]. rewrite (past_get L done b rest Hd). reflexivity. | |
| - rewrite dstep_eq. cbn [dR dA dK]. fold o. rewrite (past_get L done b rest Hd). reflexivity. | |
| Qed. | |
| (* ---- the phases ------------------------------------------------------------------------------ *) | |
| Lemma pa_construct : forall n e3 e2 e1 e0 done bs rest U W Z K, | |
| length bs = S n -> length W = S n -> length done + S n <= L -> length U + S n <= N -> | |
| quiet (S n) (mkD (mkC PA n e3 e2 e1 e0 false) (past L done (bs ++ rest)) (past N U (W ++ Z)) K) | |
| /\ dsteps (S n) (mkD (mkC PA n e3 e2 e1 e0 false) (past L done (bs ++ rest)) (past N U (W ++ Z)) K) | |
| = mkD (mkC PC 3 e3 e2 e1 e0 false) (past L (done ++ bs) rest) (past N (U ++ bs) Z) K. | |
| Proof. | |
| induction n as [|n IH]; intros e3 e2 e1 e0 done bs rest U W Z K Hb HW Hd HU; | |
| (destruct bs as [|b bs]; [discriminate|]); (destruct W as [|w W]; [discriminate|]); | |
| cbn [app length] in *; | |
| match goal with |- context [mkC PA ?k _ _ _ _ _] => | |
| destruct (pass_PA k e3 e2 e1 e0 false done b (bs ++ rest) (past N U (w :: W ++ Z)) K ltac:(lia)) as [Hq Hs] end; | |
| rewrite (past_write N U w (W ++ Z) b ltac:(lia)) in Hs. | |
| - destruct bs; [|discriminate]. destruct W; [|discriminate]. cbn [app Nat.eqb] in Hs, Hq |- *. | |
| split; [apply quiet_S; [exact Hq | apply quiet_0]|]. cbn [dsteps]. rewrite Hs. reflexivity. | |
| - cbn [Nat.eqb] in Hs. replace (S n - 1) with n in Hs by lia. | |
| destruct (IH e3 e2 e1 e0 (done ++ [b]) bs rest (U ++ [b]) W Z K ltac:(lia) ltac:(lia) | |
| ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia)) | |
| as [Q E]. | |
| rewrite <- Hs in Q, E. split; [apply quiet_S; [exact Hq | exact Q]|]. | |
| change (dsteps (S (S n)) ?t) with (dsteps (S n) (dstep t)). rewrite E, <- !app_assoc. reflexivity. | |
| Qed. | |
| Lemma pa_copy : forall n e3 e2 e1 e0 done bs rest A V W C, | |
| length bs = S n -> length W = S n -> length done + S n <= L -> length V + S n <= L -> | |
| quiet (S n) (mkD (mkC PA n e3 e2 e1 e0 true) (past L done (bs ++ rest)) A (past L V (W ++ C))) | |
| /\ dsteps (S n) (mkD (mkC PA n e3 e2 e1 e0 true) (past L done (bs ++ rest)) A (past L V (W ++ C))) | |
| = mkD (mkC PC 3 e3 e2 e1 e0 true) (past L (done ++ bs) rest) A (past L (V ++ bs) C). | |
| Proof. | |
| induction n as [|n IH]; intros e3 e2 e1 e0 done bs rest A V W C Hb HW Hd HV; | |
| (destruct bs as [|b bs]; [discriminate|]); (destruct W as [|w W]; [discriminate|]); | |
| cbn [app length] in *; | |
| match goal with |- context [mkC PA ?k _ _ _ _ _] => | |
| destruct (pass_PA k e3 e2 e1 e0 true done b (bs ++ rest) A (past L V (w :: W ++ C)) ltac:(lia)) as [Hq Hs] end; | |
| rewrite (past_write L V w (W ++ C) b ltac:(lia)) in Hs. | |
| - destruct bs; [|discriminate]. destruct W; [|discriminate]. cbn [app Nat.eqb] in Hs, Hq |- *. | |
| split; [apply quiet_S; [exact Hq | apply quiet_0]|]. cbn [dsteps]. rewrite Hs. reflexivity. | |
| - cbn [Nat.eqb] in Hs. replace (S n - 1) with n in Hs by lia. | |
| destruct (IH e3 e2 e1 e0 (done ++ [b]) bs rest A (V ++ [b]) W C ltac:(lia) ltac:(lia) | |
| ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia)) | |
| as [Q E]. | |
| rewrite <- Hs in Q, E. split; [apply quiet_S; [exact Hq | exact Q]|]. | |
| change (dsteps (S (S n)) ?t) with (dsteps (S n) (dstep t)). rewrite E, <- !app_assoc. reflexivity. | |
| Qed. | |
| Lemma pg_gate : forall n e3 e2 e1 e0 R U W Z K, is_esc e3 e2 e1 e0 = false -> | |
| length W = S n -> length U + S n <= N -> | |
| quiet (S n) (mkD (mkC PG n e3 e2 e1 e0 false) R (past N U (W ++ Z)) K) | |
| /\ dsteps (S n) (mkD (mkC PG n e3 e2 e1 e0 false) R (past N U (W ++ Z)) K) | |
| = mkD (mkC PA 17 e3 e2 e1 e0 false) R (past N (U ++ map (table e3 e2 e1 e0) (down n)) Z) K. | |
| Proof. | |
| induction n as [|n IH]; intros e3 e2 e1 e0 R U W Z K He HW HU; | |
| (destruct W as [|w W]; [discriminate|]); cbn [app length] in *; | |
| match goal with |- context [mkC PG ?k _ _ _ _ _] => | |
| destruct (pass_PG k e3 e2 e1 e0 false R (past N U (w :: W ++ Z)) K) as [Hq Hs] end; | |
| rewrite He in Hs; cbn [andb negb] in Hs; | |
| rewrite (past_write N U w (W ++ Z) _ ltac:(lia)) in Hs. | |
| - destruct W; [|discriminate]. cbn [app Nat.eqb] in Hs, Hq |- *. | |
| split; [apply quiet_S; [exact Hq | apply quiet_0]|]. cbn [dsteps]. rewrite Hs. reflexivity. | |
| - cbn [Nat.eqb] in Hs. replace (S n - 1) with n in Hs by lia. | |
| destruct (IH e3 e2 e1 e0 R (U ++ [table e3 e2 e1 e0 (S n)]) W Z K He ltac:(lia) | |
| ltac:(rewrite length_app; cbn [length]; lia)) as [Q E]. | |
| rewrite <- Hs in Q, E. split; [apply quiet_S; [exact Hq | exact Q]|]. | |
| change (dsteps (S (S n)) ?t) with (dsteps (S n) (dstep t)). rewrite E, <- !app_assoc. reflexivity. | |
| Qed. | |
| Lemma pg_esc_construct : forall n e3 e2 e1 e0 done bs rest U W Z K, is_esc e3 e2 e1 e0 = true -> | |
| length bs = S n -> length W = S n -> length done + S n <= L -> length U + S n <= N -> | |
| quiet (S n) (mkD (mkC PG n e3 e2 e1 e0 false) (past L done (bs ++ rest)) (past N U (W ++ Z)) K) | |
| /\ dsteps (S n) (mkD (mkC PG n e3 e2 e1 e0 false) (past L done (bs ++ rest)) (past N U (W ++ Z)) K) | |
| = mkD (mkC PA 17 e3 e2 e1 e0 false) (past L (done ++ bs) rest) (past N (U ++ bs) Z) K. | |
| Proof. | |
| induction n as [|n IH]; intros e3 e2 e1 e0 done bs rest U W Z K He Hb HW Hd HU; | |
| (destruct bs as [|b bs]; [discriminate|]); (destruct W as [|w W]; [discriminate|]); | |
| cbn [app length] in *; | |
| match goal with |- context [mkC PG ?k _ _ _ _ _] => | |
| destruct (pass_PG k e3 e2 e1 e0 false (past L done (b :: bs ++ rest)) (past N U (w :: W ++ Z)) K) | |
| as [Hq Hs] end; | |
| rewrite He in Hs; cbn [andb negb] in Hs; | |
| rewrite (past_get L done b (bs ++ rest) ltac:(lia)), (past_adv L done b (bs ++ rest) HL), | |
| (past_write N U w (W ++ Z) b ltac:(lia)) in Hs. | |
| - destruct bs; [|discriminate]. destruct W; [|discriminate]. cbn [app Nat.eqb] in Hs, Hq |- *. | |
| split; [apply quiet_S; [exact Hq | apply quiet_0]|]. cbn [dsteps]. rewrite Hs. reflexivity. | |
| - cbn [Nat.eqb] in Hs. replace (S n - 1) with n in Hs by lia. | |
| destruct (IH e3 e2 e1 e0 (done ++ [b]) bs rest (U ++ [b]) W Z K He ltac:(lia) ltac:(lia) | |
| ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia)) | |
| as [Q E]. | |
| rewrite <- Hs in Q, E. split; [apply quiet_S; [exact Hq | exact Q]|]. | |
| change (dsteps (S (S n)) ?t) with (dsteps (S n) (dstep t)). rewrite E, <- !app_assoc. reflexivity. | |
| Qed. | |
| Lemma pg_esc_copy : forall n e3 e2 e1 e0 done bs rest A V W C, is_esc e3 e2 e1 e0 = true -> | |
| length bs = S n -> length W = S n -> length done + S n <= L -> length V + S n <= L -> | |
| quiet (S n) (mkD (mkC PG n e3 e2 e1 e0 true) (past L done (bs ++ rest)) A (past L V (W ++ C))) | |
| /\ dsteps (S n) (mkD (mkC PG n e3 e2 e1 e0 true) (past L done (bs ++ rest)) A (past L V (W ++ C))) | |
| = mkD (mkC PA 17 e3 e2 e1 e0 true) (past L (done ++ bs) rest) A (past L (V ++ bs) C). | |
| Proof. | |
| induction n as [|n IH]; intros e3 e2 e1 e0 done bs rest A V W C He Hb HW Hd HV; | |
| (destruct bs as [|b bs]; [discriminate|]); (destruct W as [|w W]; [discriminate|]); | |
| cbn [app length] in *; | |
| match goal with |- context [mkC PG ?k _ _ _ _ _] => | |
| destruct (pass_PG k e3 e2 e1 e0 true (past L done (b :: bs ++ rest)) A (past L V (w :: W ++ C))) | |
| as [Hq Hs] end; | |
| rewrite He in Hs; cbn [andb negb] in Hs; | |
| rewrite (past_get L done b (bs ++ rest) ltac:(lia)), (past_adv L done b (bs ++ rest) HL), | |
| (past_write L V w (W ++ C) b ltac:(lia)) in Hs. | |
| - destruct bs; [|discriminate]. destruct W; [|discriminate]. cbn [app Nat.eqb] in Hs, Hq |- *. | |
| split; [apply quiet_S; [exact Hq | apply quiet_0]|]. cbn [dsteps]. rewrite Hs. reflexivity. | |
| - cbn [Nat.eqb] in Hs. replace (S n - 1) with n in Hs by lia. | |
| destruct (IH e3 e2 e1 e0 (done ++ [b]) bs rest A (V ++ [b]) W C He ltac:(lia) ltac:(lia) | |
| ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia)) | |
| as [Q E]. | |
| rewrite <- Hs in Q, E. split; [apply quiet_S; [exact Hq | exact Q]|]. | |
| change (dsteps (S (S n)) ?t) with (dsteps (S n) (dstep t)). rewrite E, <- !app_assoc. reflexivity. | |
| Qed. | |
| (* the first three passes of a codon *) | |
| Lemma codon3_construct : forall b3 b2 b1 b0 e3 e2 e1 e0 done rest A K, length done + 3 < L -> | |
| quiet 3 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done ([e3; e2; e1; e0] ++ rest)) A K) | |
| /\ dsteps 3 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done ([e3; e2; e1; e0] ++ rest)) A K) | |
| = mkD (mkC PC 0 b0 e3 e2 e1 false) (past L (done ++ [e3; e2; e1]) (e0 :: rest)) A K. | |
| Proof. | |
| intros b3 b2 b1 b0 e3 e2 e1 e0 done rest A K Hd. cbn [app]. | |
| destruct (pass_PC 2 b3 b2 b1 b0 false done e3 (e2 :: e1 :: e0 :: rest) A K ltac:(lia)) as [Q1 E1]. | |
| destruct (pass_PC 1 b2 b1 b0 e3 false (done ++ [e3]) e2 (e1 :: e0 :: rest) A K | |
| ltac:(rewrite length_app; cbn [length]; lia)) as [Q2 E2]. | |
| destruct (pass_PC 0 b1 b0 e3 e2 false ((done ++ [e3]) ++ [e2]) e1 (e0 :: rest) A K | |
| ltac:(rewrite !length_app; cbn [length]; lia)) as [Q3 E3]. | |
| split. | |
| - apply quiet_S; [exact Q1|]. rewrite E1. apply quiet_S; [exact Q2|]. rewrite E2. | |
| apply quiet_S; [exact Q3|]. apply quiet_0. | |
| - cbn [dsteps]. rewrite E1, E2, E3, <- !app_assoc. reflexivity. | |
| Qed. | |
| Lemma codon3_copy : forall b3 b2 b1 b0 e3 e2 e1 e0 done rest A V w1 w2 w3 C, | |
| length done + 3 < L -> length V + 3 < L -> | |
| quiet 3 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done ([e3; e2; e1; e0] ++ rest)) A | |
| (past L V (w1 :: w2 :: w3 :: C))) | |
| /\ dsteps 3 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done ([e3; e2; e1; e0] ++ rest)) A | |
| (past L V (w1 :: w2 :: w3 :: C))) | |
| = mkD (mkC PC 0 b0 e3 e2 e1 true) (past L (done ++ [e3; e2; e1]) (e0 :: rest)) A | |
| (past L (V ++ [e3; e2; e1]) C). | |
| Proof. | |
| intros b3 b2 b1 b0 e3 e2 e1 e0 done rest A V w1 w2 w3 C Hd HV. cbn [app]. | |
| destruct (pass_PC 2 b3 b2 b1 b0 true done e3 (e2 :: e1 :: e0 :: rest) A (past L V (w1 :: w2 :: w3 :: C)) | |
| ltac:(lia)) as [Q1 E1]. | |
| rewrite (past_write L V w1 (w2 :: w3 :: C) e3 ltac:(lia)) in E1. | |
| destruct (pass_PC 1 b2 b1 b0 e3 true (done ++ [e3]) e2 (e1 :: e0 :: rest) A (past L (V ++ [e3]) (w2 :: w3 :: C)) | |
| ltac:(rewrite length_app; cbn [length]; lia)) as [Q2 E2]. | |
| rewrite (past_write L (V ++ [e3]) w2 (w3 :: C) e2 ltac:(rewrite length_app; cbn [length]; lia)) in E2. | |
| destruct (pass_PC 0 b1 b0 e3 e2 true ((done ++ [e3]) ++ [e2]) e1 (e0 :: rest) A | |
| (past L ((V ++ [e3]) ++ [e2]) (w3 :: C)) ltac:(rewrite !length_app; cbn [length]; lia)) as [Q3 E3]. | |
| rewrite (past_write L ((V ++ [e3]) ++ [e2]) w3 C e1 ltac:(rewrite !length_app; cbn [length]; lia)) in E3. | |
| split. | |
| - apply quiet_S; [exact Q1|]. rewrite E1. apply quiet_S; [exact Q2|]. rewrite E2. | |
| apply quiet_S; [exact Q3|]. apply quiet_0. | |
| - cbn [dsteps]. rewrite E1, E2, E3, <- !app_assoc. reflexivity. | |
| Qed. | |
| (* ---- composing passes ------------------------------------------------------------------------ *) | |
| Lemma one : forall t t', ho (dout t) = false -> dstep t = t' -> quiet 1 t /\ dsteps 1 t = t'. | |
| Proof. intros t t' H E. split; [apply quiet_S; [exact H | apply quiet_0] | cbn [dsteps]; exact E]. Qed. | |
| Lemma chain : forall a b t t' t'', quiet a t /\ dsteps a t = t' -> quiet b t' /\ dsteps b t' = t'' -> | |
| quiet (a + b) t /\ dsteps (a + b) t = t''. | |
| Proof. | |
| intros a b t t' t'' [Qa Ea] [Qb Eb]. split. | |
| - apply quiet_add; [exact Qa|]. rewrite Ea. exact Qb. | |
| - rewrite dsteps_add, Ea. exact Eb. | |
| Qed. | |
| (* a run of passes whose last pass, and only that one, hands over *) | |
| Lemma chain_last : forall a b t t' t'', quiet a t /\ dsteps a t = t' -> | |
| quiet (b - 1) t' /\ ho (dout (dsteps (b - 1) t')) = true /\ dsteps b t' = t'' -> 1 <= b -> | |
| quiet (a + b - 1) t /\ ho (dout (dsteps (a + b - 1) t)) = true /\ dsteps (a + b) t = t''. | |
| Proof. | |
| intros a b t t' t'' [Qa Ea] (Qb & Hb & Eb) H1. | |
| replace (a + b - 1) with (a + (b - 1)) by lia. | |
| split; [apply quiet_add; [exact Qa | rewrite Ea; exact Qb]|]. | |
| split; rewrite dsteps_add, Ea; assumption. | |
| Qed. | |
| Lemma skipn_app_plus : forall (a b : list bool) k, skipn (length a + k) (a ++ b) = skipn k b. | |
| Proof. induction a as [|x a IH]; intros b k; [reflexivity|]. exact (IH b k). Qed. | |
| (* lists of cells to the right-nested form with the known cells first *) | |
| Ltac norm_in H := repeat (first [rewrite <- app_assoc in H | progress (cbn [app] in H)]). | |
| Ltac norm_goal := repeat (first [rewrite <- app_assoc | progress (cbn [app])]). | |
| (* ---- the pass that ends a codon ------------------------------------------------------------- *) | |
| Lemma pc0_construct_go : forall c3 c2 c1 c0 done b rest A K, length done < L -> is_end c2 c1 c0 b = false -> | |
| quiet 1 (mkD (mkC PC 0 c3 c2 c1 c0 false) (past L done (b :: rest)) A K) | |
| /\ dsteps 1 (mkD (mkC PC 0 c3 c2 c1 c0 false) (past L done (b :: rest)) A K) | |
| = mkD (mkC PG 7 c2 c1 c0 b false) (past L (done ++ [b]) rest) A K. | |
| Proof. | |
| intros c3 c2 c1 c0 done b rest A K Hd Hn. | |
| destruct (pass_PC0 c3 c2 c1 c0 false done b rest A K Hd) as [O E]. | |
| rewrite Hn in O. cbn [negb orb] in O. | |
| apply one; [rewrite O; reflexivity|]. rewrite E, O. unfold rmove, amove, kmove. | |
| cbn [ncf rr cons fresh home emit cw]. rewrite (past_adv L done b rest HL). reflexivity. | |
| Qed. | |
| Lemma pc0_construct_end : forall c3 c2 c1 c0 done b rest A K, length done < L -> is_end c2 c1 c0 b = true -> | |
| quiet 1 (mkD (mkC PC 0 c3 c2 c1 c0 false) (past L done (b :: rest)) A K) | |
| /\ dsteps 1 (mkD (mkC PC 0 c3 c2 c1 c0 false) (past L done (b :: rest)) A K) | |
| = mkD (mkC PC 3 c2 c1 c0 b true) (past L [] (done ++ b :: rest)) A K. | |
| Proof. | |
| intros c3 c2 c1 c0 done b rest A K Hd Hn. | |
| destruct (pass_PC0 c3 c2 c1 c0 false done b rest A K Hd) as [O E]. | |
| rewrite Hn in O. | |
| apply one; [rewrite O; reflexivity|]. rewrite E, O. unfold rmove, amove, kmove. | |
| cbn [ncf rr cons fresh home emit cw]. rewrite past_home. reflexivity. | |
| Qed. | |
| Lemma pc0_copy_go : forall c3 c2 c1 c0 done b rest A V w C, length done < L -> length V < L -> | |
| is_end c2 c1 c0 b = false -> | |
| quiet 1 (mkD (mkC PC 0 c3 c2 c1 c0 true) (past L done (b :: rest)) A (past L V (w :: C))) | |
| /\ dsteps 1 (mkD (mkC PC 0 c3 c2 c1 c0 true) (past L done (b :: rest)) A (past L V (w :: C))) | |
| = mkD (if is_esc c2 c1 c0 b then mkC PG 7 c2 c1 c0 b true else mkC PA 17 c2 c1 c0 b true) | |
| (past L (done ++ [b]) rest) A (past L (V ++ [b]) C). | |
| Proof. | |
| intros c3 c2 c1 c0 done b rest A V w C Hd HV Hn. | |
| destruct (pass_PC0 c3 c2 c1 c0 true done b rest A (past L V (w :: C)) Hd) as [O E]. | |
| rewrite Hn in O. cbn [negb orb] in O. | |
| apply one; [rewrite O; destruct (is_esc c2 c1 c0 b); reflexivity|]. | |
| rewrite E, O. destruct (is_esc c2 c1 c0 b); unfold rmove, amove, kmove; | |
| cbn [ncf rr cons fresh home emit cw]; | |
| rewrite (past_adv L done b rest HL), (past_write L V w C b HV); reflexivity. | |
| Qed. | |
| Lemma pc0_copy_end : forall c3 c2 c1 c0 done b rest A V w C, length done < L -> length V < L -> | |
| is_end c2 c1 c0 b = true -> | |
| ho (dout (mkD (mkC PC 0 c3 c2 c1 c0 true) (past L done (b :: rest)) A (past L V (w :: C)))) = true | |
| /\ dstep (mkD (mkC PC 0 c3 c2 c1 c0 true) (past L done (b :: rest)) A (past L V (w :: C))) | |
| = mkD (mkC PI 1 c2 c1 c0 b false) (past L (done ++ [b]) rest) (mkT (td A) 0) (mkT (V ++ b :: C) 0). | |
| Proof. | |
| intros c3 c2 c1 c0 done b rest A V w C Hd HV Hn. | |
| destruct (pass_PC0 c3 c2 c1 c0 true done b rest A (past L V (w :: C)) Hd) as [O E]. | |
| rewrite Hn in O. | |
| split; [rewrite O; reflexivity|]. | |
| assert (Hk : upd (td (past L V (w :: C))) (th (past L V (w :: C))) b = V ++ b :: C) | |
| by (unfold past; cbn [td th]; rewrite (Nat.mod_small _ _ HV); apply upd_app_cons). | |
| rewrite E, O. unfold rmove, amove, kmove. cbn [ncf rr cons fresh home emit cw]. | |
| rewrite (past_adv L done b rest HL), Hk. reflexivity. | |
| Qed. | |
| (* ---- a whole codon ------------------------------------------------------------------------------ *) | |
| Lemma codon_construct_go : forall b3 b2 b1 b0 e3 e2 e1 e0 done rest A K, length done + 4 <= L -> | |
| is_end e3 e2 e1 e0 = false -> | |
| quiet 4 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (e3 :: e2 :: e1 :: e0 :: rest)) A K) | |
| /\ dsteps 4 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (e3 :: e2 :: e1 :: e0 :: rest)) A K) | |
| = mkD (mkC PG 7 e3 e2 e1 e0 false) (past L (done ++ [e3; e2; e1; e0]) rest) A K. | |
| Proof. | |
| intros b3 b2 b1 b0 e3 e2 e1 e0 done rest A K Hd Hn. | |
| destruct (pc0_construct_go b0 e3 e2 e1 (done ++ [e3; e2; e1]) e0 rest A K | |
| ltac:(rewrite length_app; cbn [length]; lia) Hn) as [Q E]. | |
| rewrite <- app_assoc in E. cbn [app] in E. | |
| exact (chain 3 1 _ _ _ (codon3_construct b3 b2 b1 b0 e3 e2 e1 e0 done rest A K ltac:(lia)) (conj Q E)). | |
| Qed. | |
| Lemma codon_construct_end : forall b3 b2 b1 b0 done rest A K, length done + 4 <= L -> | |
| quiet 4 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (true :: true :: true :: true :: rest)) A K) | |
| /\ dsteps 4 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (true :: true :: true :: true :: rest)) A K) | |
| = mkD (mkC PC 3 true true true true true) (past L [] (done ++ true :: true :: true :: true :: rest)) A K. | |
| Proof. | |
| intros b3 b2 b1 b0 done rest A K Hd. | |
| destruct (pc0_construct_end b0 true true true (done ++ [true; true; true]) true rest A K | |
| ltac:(rewrite length_app; cbn [length]; lia) eq_refl) as [Q E]. | |
| rewrite <- app_assoc in E. cbn [app] in E. | |
| exact (chain 3 1 _ _ _ (codon3_construct b3 b2 b1 b0 true true true true done rest A K ltac:(lia)) (conj Q E)). | |
| Qed. | |
| Lemma codon_copy_go : forall b3 b2 b1 b0 e3 e2 e1 e0 done rest A V w1 w2 w3 w4 C, | |
| length done + 4 <= L -> length V + 4 <= L -> is_end e3 e2 e1 e0 = false -> | |
| quiet 4 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (e3 :: e2 :: e1 :: e0 :: rest)) A | |
| (past L V (w1 :: w2 :: w3 :: w4 :: C))) | |
| /\ dsteps 4 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (e3 :: e2 :: e1 :: e0 :: rest)) A | |
| (past L V (w1 :: w2 :: w3 :: w4 :: C))) | |
| = mkD (if is_esc e3 e2 e1 e0 then mkC PG 7 e3 e2 e1 e0 true else mkC PA 17 e3 e2 e1 e0 true) | |
| (past L (done ++ [e3; e2; e1; e0]) rest) A (past L (V ++ [e3; e2; e1; e0]) C). | |
| Proof. | |
| intros b3 b2 b1 b0 e3 e2 e1 e0 done rest A V w1 w2 w3 w4 C Hd HV Hn. | |
| destruct (pc0_copy_go b0 e3 e2 e1 (done ++ [e3; e2; e1]) e0 rest A (V ++ [e3; e2; e1]) w4 C | |
| ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia) Hn) | |
| as [Q E]. | |
| rewrite <- !app_assoc in E. cbn [app] in E. | |
| exact (chain 3 1 _ _ _ (codon3_copy b3 b2 b1 b0 e3 e2 e1 e0 done rest A V w1 w2 w3 (w4 :: C) | |
| ltac:(lia) ltac:(lia)) (conj Q E)). | |
| Qed. | |
| Lemma codon_copy_end : forall b3 b2 b1 b0 done rest A V w1 w2 w3 w4 C, | |
| length done + 4 <= L -> length V + 4 <= L -> | |
| quiet 3 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (true :: true :: true :: true :: rest)) A | |
| (past L V (w1 :: w2 :: w3 :: w4 :: C))) | |
| /\ ho (dout (dsteps 3 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (true :: true :: true :: true :: rest)) A | |
| (past L V (w1 :: w2 :: w3 :: w4 :: C))))) = true | |
| /\ dsteps 4 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (true :: true :: true :: true :: rest)) A | |
| (past L V (w1 :: w2 :: w3 :: w4 :: C))) | |
| = mkD (mkC PI 1 true true true true false) (past L (done ++ [true; true; true; true]) rest) | |
| (mkT (td A) 0) (mkT (V ++ true :: true :: true :: true :: C) 0). | |
| Proof. | |
| intros b3 b2 b1 b0 done rest A V w1 w2 w3 w4 C Hd HV. | |
| destruct (codon3_copy b3 b2 b1 b0 true true true true done rest A V w1 w2 w3 (w4 :: C) ltac:(lia) ltac:(lia)) | |
| as [Q E]. | |
| cbn [app] in Q, E. | |
| destruct (pc0_copy_end b0 true true true (done ++ [true; true; true]) true rest A (V ++ [true; true; true]) w4 C | |
| ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia) eq_refl) | |
| as [H4 E4]. | |
| rewrite <- !app_assoc in E4. cbn [app] in E4. | |
| split; [exact Q|]. split; [rewrite E; exact H4|]. | |
| change 4 with (3 + 1). rewrite dsteps_add, E. cbn [dsteps]. exact E4. | |
| Qed. | |
| (* ---- one record of the description, and its end -------------------------------------------- *) | |
| Lemma seg_gate : forall b3 b2 b1 b0 e3 e2 s0 s1 addr rest done U W Z K, | |
| e3 && e2 = false -> length addr = 18 -> length W = 26 -> length done + 22 <= L -> length U + 26 <= N -> | |
| quiet 30 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (e3 :: e2 :: s0 :: s1 :: addr ++ rest)) | |
| (past N U (W ++ Z)) K) | |
| /\ dsteps 30 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (e3 :: e2 :: s0 :: s1 :: addr ++ rest)) | |
| (past N U (W ++ Z)) K) | |
| = mkD (mkC PC 3 e3 e2 s0 s1 false) (past L (done ++ e3 :: e2 :: s0 :: s1 :: addr) rest) | |
| (past N (U ++ gate_bits (kind_of e3 e2) s0 s1 ++ addr) Z) K. | |
| Proof. | |
| intros b3 b2 b1 b0 e3 e2 s0 s1 addr rest done U W Z K H32 Ha HW Hd HU. | |
| assert (He : is_esc e3 e2 s0 s1 = false) by (unfold is_esc; rewrite H32; reflexivity). | |
| assert (Hn : is_end e3 e2 s0 s1 = false) by (unfold is_end; rewrite H32; reflexivity). | |
| destruct (split_at W 8 ltac:(lia)) as (W1 & W2 & -> & HW1). rewrite length_app in HW. | |
| rewrite <- (app_assoc W1 W2 Z). | |
| destruct (codon_construct_go b3 b2 b1 b0 e3 e2 s0 s1 done (addr ++ rest) (past N U (W1 ++ W2 ++ Z)) K | |
| ltac:(lia) Hn) as [Q1 E1]. | |
| destruct (pg_gate 7 e3 e2 s0 s1 (past L (done ++ [e3; e2; s0; s1]) (addr ++ rest)) U W1 (W2 ++ Z) K He | |
| HW1 ltac:(lia)) as [Q2 E2]. | |
| rewrite table_gate in E2 by exact H32. | |
| destruct (pa_construct 17 e3 e2 s0 s1 (done ++ [e3; e2; s0; s1]) addr rest | |
| (U ++ gate_bits (kind_of e3 e2) s0 s1) W2 Z K Ha ltac:(lia) | |
| ltac:(rewrite length_app; cbn [length]; lia) | |
| ltac:(rewrite length_app, length_gate_bits; lia)) as [Q3 E3]. | |
| norm_in E2. norm_in Q3. norm_in E3. norm_goal. | |
| replace 30 with (4 + (8 + 18)) by reflexivity. | |
| exact (chain 4 (8 + 18) _ _ _ (conj Q1 E1) (chain 8 18 _ _ _ (conj Q2 E2) (conj Q3 E3))). | |
| Qed. | |
| Lemma seg_esc : forall b3 b2 b1 b0 s0 s1 lit addr rest done U W Z K, | |
| s0 && s1 = false -> length lit = 8 -> length addr = 18 -> length W = 26 -> length done + 30 <= L -> | |
| length U + 26 <= N -> | |
| quiet 30 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (true :: true :: s0 :: s1 :: lit ++ addr ++ rest)) | |
| (past N U (W ++ Z)) K) | |
| /\ dsteps 30 (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (true :: true :: s0 :: s1 :: lit ++ addr ++ rest)) | |
| (past N U (W ++ Z)) K) | |
| = mkD (mkC PC 3 true true s0 s1 false) (past L (done ++ true :: true :: s0 :: s1 :: lit ++ addr) rest) | |
| (past N (U ++ lit ++ addr) Z) K. | |
| Proof. | |
| intros b3 b2 b1 b0 s0 s1 lit addr rest done U W Z K Hs Hl Ha HW Hd HU. | |
| assert (He : is_esc true true s0 s1 = true) by (unfold is_esc; cbn [andb]; rewrite Hs; reflexivity). | |
| assert (Hn : is_end true true s0 s1 = false) by (unfold is_end; cbn [andb]; exact Hs). | |
| destruct (split_at W 8 ltac:(lia)) as (W1 & W2 & -> & HW1). rewrite length_app in HW. | |
| rewrite <- (app_assoc W1 W2 Z). | |
| destruct (codon_construct_go b3 b2 b1 b0 true true s0 s1 done (lit ++ addr ++ rest) (past N U (W1 ++ W2 ++ Z)) K | |
| ltac:(lia) Hn) as [Q1 E1]. | |
| destruct (pg_esc_construct 7 true true s0 s1 (done ++ [true; true; s0; s1]) lit (addr ++ rest) U W1 (W2 ++ Z) K | |
| He Hl HW1 ltac:(rewrite length_app; cbn [length]; lia) ltac:(lia)) as [Q2 E2]. | |
| destruct (pa_construct 17 true true s0 s1 ((done ++ [true; true; s0; s1]) ++ lit) addr rest (U ++ lit) W2 Z K | |
| Ha ltac:(lia) ltac:(rewrite !length_app; cbn [length]; lia) ltac:(rewrite length_app; lia)) as [Q3 E3]. | |
| norm_in E2. norm_in Q3. norm_in E3. norm_goal. | |
| replace 30 with (4 + (8 + 18)) by reflexivity. | |
| exact (chain 4 (8 + 18) _ _ _ (conj Q1 E1) (chain 8 18 _ _ _ (conj Q2 E2) (conj Q3 E3))). | |
| Qed. | |
| Lemma seg_copy_gate : forall b3 b2 b1 b0 e3 e2 s0 s1 addr rest done A V W C, | |
| e3 && e2 = false -> length addr = 18 -> length W = 22 -> length done + 22 <= L -> length V + 22 <= L -> | |
| quiet 22 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (e3 :: e2 :: s0 :: s1 :: addr ++ rest)) A | |
| (past L V (W ++ C))) | |
| /\ dsteps 22 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (e3 :: e2 :: s0 :: s1 :: addr ++ rest)) A | |
| (past L V (W ++ C))) | |
| = mkD (mkC PC 3 e3 e2 s0 s1 true) (past L (done ++ e3 :: e2 :: s0 :: s1 :: addr) rest) A | |
| (past L (V ++ e3 :: e2 :: s0 :: s1 :: addr) C). | |
| Proof. | |
| intros b3 b2 b1 b0 e3 e2 s0 s1 addr rest done A V W C H32 Ha HW Hd HV. | |
| assert (He : is_esc e3 e2 s0 s1 = false) by (unfold is_esc; rewrite H32; reflexivity). | |
| assert (Hn : is_end e3 e2 s0 s1 = false) by (unfold is_end; rewrite H32; reflexivity). | |
| destruct W as [|w1 [|w2 [|w3 [|w4 W]]]]; cbn [length] in HW; try lia. | |
| destruct (codon_copy_go b3 b2 b1 b0 e3 e2 s0 s1 done (addr ++ rest) A V w1 w2 w3 w4 (W ++ C) | |
| ltac:(lia) ltac:(lia) Hn) as [Q1 E1]. | |
| rewrite He in E1. | |
| destruct (pa_copy 17 e3 e2 s0 s1 (done ++ [e3; e2; s0; s1]) addr rest A (V ++ [e3; e2; s0; s1]) W C Ha | |
| ltac:(lia) ltac:(rewrite length_app; cbn [length]; lia) ltac:(rewrite length_app; cbn [length]; lia)) | |
| as [Q2 E2]. | |
| norm_in E2. | |
| replace 22 with (4 + 18) by reflexivity. | |
| exact (chain 4 18 _ _ _ (conj Q1 E1) (conj Q2 E2)). | |
| Qed. | |
| Lemma seg_copy_esc : forall b3 b2 b1 b0 s0 s1 lit addr rest done A V W C, | |
| s0 && s1 = false -> length lit = 8 -> length addr = 18 -> length W = 30 -> length done + 30 <= L -> | |
| length V + 30 <= L -> | |
| quiet 30 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (true :: true :: s0 :: s1 :: lit ++ addr ++ rest)) A | |
| (past L V (W ++ C))) | |
| /\ dsteps 30 (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (true :: true :: s0 :: s1 :: lit ++ addr ++ rest)) A | |
| (past L V (W ++ C))) | |
| = mkD (mkC PC 3 true true s0 s1 true) (past L (done ++ true :: true :: s0 :: s1 :: lit ++ addr) rest) A | |
| (past L (V ++ true :: true :: s0 :: s1 :: lit ++ addr) C). | |
| Proof. | |
| intros b3 b2 b1 b0 s0 s1 lit addr rest done A V W C Hs Hl Ha HW Hd HV. | |
| assert (He : is_esc true true s0 s1 = true) by (unfold is_esc; cbn [andb]; rewrite Hs; reflexivity). | |
| assert (Hn : is_end true true s0 s1 = false) by (unfold is_end; cbn [andb]; exact Hs). | |
| destruct W as [|w1 [|w2 [|w3 [|w4 W]]]]; cbn [length] in HW; try lia. | |
| destruct (split_at W 8 ltac:(lia)) as (W1 & W2 & -> & HW1). rewrite length_app in HW. | |
| destruct (codon_copy_go b3 b2 b1 b0 true true s0 s1 done (lit ++ addr ++ rest) A V w1 w2 w3 w4 ((W1 ++ W2) ++ C) | |
| ltac:(lia) ltac:(lia) Hn) as [Q1 E1]. | |
| rewrite He in E1. norm_in Q1. norm_in E1. | |
| destruct (pg_esc_copy 7 true true s0 s1 (done ++ [true; true; s0; s1]) lit (addr ++ rest) A | |
| (V ++ [true; true; s0; s1]) W1 (W2 ++ C) He Hl HW1 ltac:(rewrite length_app; cbn [length]; lia) | |
| ltac:(rewrite length_app; cbn [length]; lia)) as [Q2 E2]. | |
| destruct (pa_copy 17 true true s0 s1 ((done ++ [true; true; s0; s1]) ++ lit) addr rest A | |
| ((V ++ [true; true; s0; s1]) ++ lit) W2 C Ha ltac:(lia) ltac:(rewrite !length_app; cbn [length]; lia) | |
| ltac:(rewrite !length_app; cbn [length]; lia)) as [Q3 E3]. | |
| norm_in E2. norm_in Q3. norm_in E3. norm_goal. | |
| replace 30 with (4 + (8 + 18)) by reflexivity. | |
| exact (chain 4 (8 + 18) _ _ _ (conj Q1 E1) (chain 8 18 _ _ _ (conj Q2 E2) (conj Q3 E3))). | |
| Qed. | |
| (* ---- the description read in construct mode ------------------------------------------------- *) | |
| Lemma construct_phase : forall f rest Xr done tail U Z K b3 b2 b1 b0, | |
| translate_aux f rest = Some Xr -> length done + length rest <= L -> | |
| length U + length Xr <= N -> length Xr <= length Z -> | |
| exists nrec, length Xr = 26 * nrec | |
| /\ quiet (30 * nrec + 4) (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (rest ++ tail)) (past N U Z) K) | |
| /\ dsteps (30 * nrec + 4) (mkD (mkC PC 3 b3 b2 b1 b0 false) (past L done (rest ++ tail)) (past N U Z) K) | |
| = mkD (mkC PC 3 true true true true true) (past L [] (done ++ rest ++ tail)) | |
| (past N (U ++ Xr) (skipn (length Xr) Z)) K. | |
| Proof. | |
| induction f as [|f IH]; intros rest Xr done tail U Z K b3 b2 b1 b0 Ht Hd HU HZ; [discriminate|]. | |
| destruct rest as [|e3 [|e2 [|s0 [|s1 rest1]]]]; try discriminate. | |
| rewrite translate_aux_S in Ht. | |
| destruct (e3 && e2) eqn:E32. | |
| - apply andb_prop in E32 as [-> ->]. | |
| destruct (s0 && s1) eqn:Es. | |
| + (* the end codon *) | |
| destruct rest1; [|discriminate]. apply some_inj in Ht. subst Xr. | |
| apply andb_prop in Es as [-> ->]. | |
| exists 0. split; [reflexivity|]. rewrite app_nil_r. | |
| cbn [length] in Hd. exact (codon_construct_end b3 b2 b1 b0 done tail (past N U Z) K ltac:(lia)). | |
| + (* an escaped record *) | |
| destruct (Nat.eqb (length rest1) 0) eqn:El; [discriminate|]. | |
| destruct (translate_aux f (skipn 26 rest1)) as [X'|] eqn:Ht'; [|discriminate]. | |
| cbn [option_map] in Ht. apply some_inj in Ht. subst Xr. | |
| pose proof (translate_aux_long _ _ _ Ht') as Hlong. rewrite length_skipn in Hlong. | |
| destruct (split_at rest1 8 ltac:(lia)) as (lit & r1 & -> & Hl). | |
| destruct (split_at r1 18 ltac:(rewrite length_app in Hlong; lia)) as (addr & rest2 & -> & Ha). | |
| assert (Hs26 : skipn 26 (lit ++ addr ++ rest2) = rest2) | |
| by (rewrite app_assoc; apply skipn_app_exact; rewrite length_app; lia). | |
| assert (Hf26 : firstn 26 (lit ++ addr ++ rest2) = lit ++ addr) | |
| by (rewrite app_assoc; apply firstn_app_exact; rewrite length_app; lia). | |
| rewrite Hs26 in Ht'. rewrite Hf26 in HU, HZ |- *. | |
| rewrite !length_app in HU, HZ. cbn [length] in Hd. rewrite !length_app in Hd. | |
| destruct (split_at Z 26 ltac:(lia)) as (W & Z' & -> & HW). | |
| destruct (seg_esc b3 b2 b1 b0 s0 s1 lit addr (rest2 ++ tail) done U W Z' K Es Hl Ha HW ltac:(lia) ltac:(lia)) | |
| as [Q1 E1]. | |
| destruct (IH rest2 X' (done ++ true :: true :: s0 :: s1 :: lit ++ addr) tail (U ++ lit ++ addr) Z' K | |
| true true s0 s1 Ht' ltac:(rewrite length_app; cbn [length]; rewrite !length_app; lia) | |
| ltac:(rewrite !length_app; lia) ltac:(rewrite length_app in HZ; lia)) as (nrec & Hn & Q2 & E2). | |
| norm_in E2. | |
| exists (S nrec). split; [rewrite !length_app; lia|]. | |
| assert (Hsk : skipn (length ((lit ++ addr) ++ X')) (W ++ Z') = skipn (length X') Z'). | |
| { replace (length ((lit ++ addr) ++ X')) with (length W + length X') by (rewrite !length_app; lia). | |
| apply skipn_app_plus. } | |
| rewrite Hsk. norm_goal. | |
| replace (30 * S nrec + 4) with (30 + (30 * nrec + 4)) by lia. | |
| exact (chain 30 (30 * nrec + 4) _ _ _ (conj Q1 E1) (conj Q2 E2)). | |
| - (* a record named by its gate codon *) | |
| destruct (translate_aux f (skipn 18 rest1)) as [X'|] eqn:Ht'; [|discriminate]. | |
| cbn [option_map] in Ht. apply some_inj in Ht. subst Xr. | |
| pose proof (translate_aux_long _ _ _ Ht') as Hlong. rewrite length_skipn in Hlong. | |
| destruct (split_at rest1 18 ltac:(lia)) as (addr & rest2 & -> & Ha). | |
| rewrite (skipn_app_exact addr rest2 18 Ha) in Ht'. | |
| rewrite (firstn_app_exact addr rest2 18 Ha) in HU, HZ |- *. | |
| change (if e3 then 2 else if e2 then 1 else 0) with (kind_of e3 e2) in HU, HZ |- *. | |
| rewrite !length_app, length_gate_bits in HU, HZ. cbn [length] in Hd. rewrite length_app in Hd. | |
| destruct (split_at Z 26 ltac:(lia)) as (W & Z' & -> & HW). | |
| destruct (seg_gate b3 b2 b1 b0 e3 e2 s0 s1 addr (rest2 ++ tail) done U W Z' K E32 Ha HW ltac:(lia) ltac:(lia)) | |
| as [Q1 E1]. | |
| destruct (IH rest2 X' (done ++ e3 :: e2 :: s0 :: s1 :: addr) tail (U ++ gate_bits (kind_of e3 e2) s0 s1 ++ addr) | |
| Z' K e3 e2 s0 s1 Ht' ltac:(rewrite length_app; cbn [length]; rewrite ?length_app; lia) | |
| ltac:(rewrite !length_app, length_gate_bits; lia) ltac:(rewrite length_app in HZ; lia)) | |
| as (nrec & Hn & Q2 & E2). | |
| norm_in E2. | |
| exists (S nrec). split; [rewrite !length_app, length_gate_bits; lia|]. | |
| assert (Hsk : skipn (length (gate_bits (kind_of e3 e2) s0 s1 ++ addr ++ X')) (W ++ Z') = skipn (length X') Z'). | |
| { replace (length (gate_bits (kind_of e3 e2) s0 s1 ++ addr ++ X')) with (length W + length X') | |
| by (rewrite !length_app, length_gate_bits; lia). | |
| apply skipn_app_plus. } | |
| rewrite Hsk. norm_goal. | |
| replace (30 * S nrec + 4) with (30 + (30 * nrec + 4)) by lia. | |
| exact (chain 30 (30 * nrec + 4) _ _ _ (conj Q1 E1) (conj Q2 E2)). | |
| Qed. | |
| (* ---- the description read again in copy mode ------------------------------------------------- *) | |
| Lemma copy_phase : forall f rest Xr done tail A V Z b3 b2 b1 b0, | |
| translate_aux f rest = Some Xr -> length done + length rest <= L -> length V + length rest <= L -> | |
| length rest <= length Z -> | |
| quiet (length rest - 1) (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (rest ++ tail)) A (past L V Z)) | |
| /\ ho (dout (dsteps (length rest - 1) (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (rest ++ tail)) A | |
| (past L V Z)))) = true | |
| /\ dsteps (length rest) (mkD (mkC PC 3 b3 b2 b1 b0 true) (past L done (rest ++ tail)) A (past L V Z)) | |
| = mkD (mkC PI 1 true true true true false) (past L (done ++ rest) tail) (mkT (td A) 0) | |
| (mkT (V ++ rest ++ skipn (length rest) Z) 0). | |
| Proof. | |
| induction f as [|f IH]; intros rest Xr done tail A V Z b3 b2 b1 b0 Ht Hd HV HZ; [discriminate|]. | |
| destruct rest as [|e3 [|e2 [|s0 [|s1 rest1]]]]; try discriminate. | |
| rewrite translate_aux_S in Ht. | |
| destruct (e3 && e2) eqn:E32. | |
| - apply andb_prop in E32 as [-> ->]. | |
| destruct (s0 && s1) eqn:Es. | |
| + (* the end codon *) | |
| destruct rest1; [|discriminate]. apply andb_prop in Es as [-> ->]. | |
| cbn [length] in Hd, HV, HZ. | |
| destruct Z as [|w1 [|w2 [|w3 [|w4 Z]]]]; cbn [length] in HZ; try lia. | |
| exact (codon_copy_end b3 b2 b1 b0 done tail A V w1 w2 w3 w4 Z ltac:(lia) ltac:(lia)). | |
| + (* an escaped record *) | |
| destruct (Nat.eqb (length rest1) 0) eqn:El; [discriminate|]. | |
| destruct (translate_aux f (skipn 26 rest1)) as [X'|] eqn:Ht'; [|discriminate]. | |
| pose proof (translate_aux_long _ _ _ Ht') as Hlong. rewrite length_skipn in Hlong. | |
| destruct (split_at rest1 8 ltac:(lia)) as (lit & r1 & -> & Hl). | |
| destruct (split_at r1 18 ltac:(rewrite length_app in Hlong; lia)) as (addr & rest2 & -> & Ha). | |
| assert (Hs26 : skipn 26 (lit ++ addr ++ rest2) = rest2) | |
| by (rewrite app_assoc; apply skipn_app_exact; rewrite length_app; lia). | |
| rewrite Hs26 in Ht'. pose proof (translate_aux_long _ _ _ Ht') as H4. | |
| assert (Hlen : length (true :: true :: s0 :: s1 :: lit ++ addr ++ rest2) = 30 + length rest2) | |
| by (cbn [length]; rewrite !length_app; lia). | |
| rewrite Hlen in Hd, HV, HZ |- *. | |
| destruct (split_at Z 30 ltac:(lia)) as (W & Z' & -> & HW). | |
| destruct (seg_copy_esc b3 b2 b1 b0 s0 s1 lit addr (rest2 ++ tail) done A V W Z' Es Hl Ha HW | |
| ltac:(lia) ltac:(lia)) as [Q1 E1]. | |
| destruct (IH rest2 X' (done ++ true :: true :: s0 :: s1 :: lit ++ addr) tail A | |
| (V ++ true :: true :: s0 :: s1 :: lit ++ addr) Z' true true s0 s1 Ht' | |
| ltac:(rewrite length_app; cbn [length]; rewrite !length_app; lia) | |
| ltac:(rewrite length_app; cbn [length]; rewrite !length_app; lia) | |
| ltac:(rewrite length_app in HZ; lia)) as (Q2 & H2 & E2). | |
| norm_in E2. | |
| assert (Hsk : skipn (30 + length rest2) (W ++ Z') = skipn (length rest2) Z') by (rewrite <- HW; apply skipn_app_plus). | |
| rewrite Hsk. norm_goal. | |
| exact (chain_last 30 (length rest2) _ _ _ (conj Q1 E1) (conj Q2 (conj H2 E2)) ltac:(lia)). | |
| - (* a record named by its gate codon *) | |
| destruct (translate_aux f (skipn 18 rest1)) as [X'|] eqn:Ht'; [|discriminate]. | |
| pose proof (translate_aux_long _ _ _ Ht') as Hlong. rewrite length_skipn in Hlong. | |
| destruct (split_at rest1 18 ltac:(lia)) as (addr & rest2 & -> & Ha). | |
| rewrite (skipn_app_exact addr rest2 18 Ha) in Ht'. pose proof (translate_aux_long _ _ _ Ht') as H4. | |
| assert (Hlen : length (e3 :: e2 :: s0 :: s1 :: addr ++ rest2) = 22 + length rest2) | |
| by (cbn [length]; rewrite length_app; lia). | |
| rewrite Hlen in Hd, HV, HZ |- *. | |
| destruct (split_at Z 22 ltac:(lia)) as (W & Z' & -> & HW). | |
| destruct (seg_copy_gate b3 b2 b1 b0 e3 e2 s0 s1 addr (rest2 ++ tail) done A V W Z' E32 Ha HW | |
| ltac:(lia) ltac:(lia)) as [Q1 E1]. | |
| destruct (IH rest2 X' (done ++ e3 :: e2 :: s0 :: s1 :: addr) tail A (V ++ e3 :: e2 :: s0 :: s1 :: addr) Z' | |
| e3 e2 s0 s1 Ht' ltac:(rewrite length_app; cbn [length]; rewrite ?length_app; lia) | |
| ltac:(rewrite length_app; cbn [length]; rewrite ?length_app; lia) | |
| ltac:(rewrite length_app in HZ; lia)) as (Q2 & H2 & E2). | |
| norm_in E2. | |
| assert (Hsk : skipn (22 + length rest2) (W ++ Z') = skipn (length rest2) Z') by (rewrite <- HW; apply skipn_app_plus). | |
| rewrite Hsk. norm_goal. | |
| exact (chain_last 22 (length rest2) _ _ _ (conj Q1 E1) (conj Q2 (conj H2 E2)) ltac:(lia)). | |
| Qed. | |
| (* ---- one generation -------------------------------------------------------------------------- *) | |
| (* From phase I, with a description d of the image X at the start of the read tape and whatever the | |
| arm and the copy tape hold, a generation is one pass of phase I, 30 passes per record of X and 4 | |
| on the end codon in construct mode, and one pass per bit of d in copy mode. Only its last pass | |
| hands over. The arm then holds X from its first cell and the copy tape d, both heads at cell 0. *) | |
| Theorem generation : forall d X tail R A K zc c3 c2 c1 c0 m, | |
| translate d = Some X -> td R = d ++ tail -> length d <= L -> length X <= N -> | |
| exists nrec, length X = 26 * nrec | |
| /\ quiet (30 * nrec + 4 + length d) (mkD (mkC PI zc c3 c2 c1 c0 m) R A K) | |
| /\ ho (dout (dsteps (30 * nrec + 4 + length d) (mkD (mkC PI zc c3 c2 c1 c0 m) R A K))) = true | |
| /\ dsteps (S (30 * nrec + 4 + length d)) (mkD (mkC PI zc c3 c2 c1 c0 m) R A K) | |
| = mkD (mkC PI 1 true true true true false) (past L d tail) | |
| (mkT (X ++ repeat false (N - length X)) 0) (mkT (d ++ repeat false (L - length d)) 0). | |
| Proof. | |
| intros d X tail R A K zc c3 c2 c1 c0 m Ht HR HdL HXN. unfold translate in Ht. | |
| pose proof (translate_aux_long _ _ _ Ht) as Hd4. | |
| destruct (pass_PI zc c3 c2 c1 c0 m R A K) as [Q0 E0]. | |
| assert (E0' : dstep (mkD (mkC PI zc c3 c2 c1 c0 m) R A K) | |
| = mkD (mkC PC 3 c3 c2 c1 c0 false) (past L [] (d ++ tail)) (past N [] (repeat false N)) | |
| (past L [] (repeat false L))). | |
| { rewrite E0, HR. unfold past. cbn [length app]. rewrite !Nat.Div0.mod_0_l. reflexivity. } | |
| destruct (construct_phase (length d) d X [] tail [] (repeat false N) (past L [] (repeat false L)) c3 c2 c1 c0 Ht | |
| ltac:(cbn [length]; lia) ltac:(cbn [length]; lia) ltac:(rewrite repeat_length; lia)) | |
| as (nrec & Hn & Q1 & E1). | |
| cbn [app] in E1. | |
| destruct (copy_phase (length d) d X [] tail (past N X (skipn (length X) (repeat false N))) [] (repeat false L) | |
| true true true true Ht ltac:(cbn [length]; lia) ltac:(cbn [length]; lia) | |
| ltac:(rewrite repeat_length; lia)) as (Q2 & H2 & E2). | |
| cbn [app] in E2. | |
| assert (Htd : td (past N X (skipn (length X) (repeat false N))) = X ++ repeat false (N - length X)) | |
| by (unfold past; cbn [td]; rewrite skipn_repeat_false; reflexivity). | |
| rewrite Htd, (skipn_repeat_false (length d) L) in E2. | |
| destruct (chain_last (1 + (30 * nrec + 4)) (length d) _ _ _ | |
| (chain 1 (30 * nrec + 4) _ _ _ (one _ _ Q0 E0') (conj Q1 E1)) (conj Q2 (conj H2 E2)) ltac:(lia)) | |
| as (Q & H & E). | |
| exists nrec. split; [exact Hn|]. | |
| replace (1 + (30 * nrec + 4) + length d - 1) with (30 * nrec + 4 + length d) in Q, H by lia. | |
| replace (1 + (30 * nrec + 4) + length d) with (S (30 * nrec + 4 + length d)) in E by lia. | |
| exact (conj Q (conj H E)). | |
| Qed. | |
| End Dec. | |