phanerozoic's picture
Replace the two-bank machine with a K-bank ring, prove its reproduction in Rocq, and revise the paper
a9ea017
Raw History Blame Contribute Delete
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.