proposition: Lemma AlignedEncoder_append_inv {S} {cache : Cache} (enc1' : EncodeM S ByteString) (enc1 : forall sz, AlignedEncodeM sz) (enc1_OK : EncodeMEquivAlignedEncodeM enc1' enc1) (enc1'_aligned : forall s ce t ce', enc1' s ce = Some (t, ce') -> padding t = 0) (enc2' : EncodeM S ByteString) (enc2 : forall sz, AlignedEncodeM sz) (enc2_OK : EncodeMEquivAlignedEncodeM enc2' enc2) (enc2'_aligned : forall s ce t ce', enc2' s ce = Some (t, ce') -> padding t = 0) n : forall (t : Vector.t Core.char n) s ce v idx ce', (enc1 n >> enc2 n)%AlignedEncodeM t 0 s ce = Some (v, idx, ce') -> exists n1 n2 n3 (t1 : Vector.t Core.char n1) (t23 : Vector.t Core.char (n2+n3)) v1 v23 ce'' (pf : n1 + (n2+n3) = n), enc1 _ t1 0 s ce = Some (v1, n1, ce'') /\ enc2 _ t23 0 s ce'' = Some (v23, n2, ce') /\ idx = n1 + n2 /\ t = eq_rect _ _ (t1 ++ t23) _ pf /\ v = eq_rect _ _ (v1 ++ v23) _ pf.
proof: Proof. unfold AppendAlignedEncodeM. intros. destruct enc1 eqn:?; [| discriminate]; destruct_conjs; simpl in *. destruct enc2 eqn:?; [| discriminate]; destruct_conjs; simpl in *. injections. rename n0 into n1. rename t0 into v0. edestruct @AlignedEncoder_inv as [n1' [n23 [tnil [t1 [t23 [v1 ?]]]]]]; try apply enc1_OK; eauto. destruct_conjs. subst. simpl in *. revert dependent tnil. intros tnil. apply Vector.case0 with (v:=tnil). clear tnil. simpl. intros. rename n1' into n1. edestruct @AlignedEncoder_inv2 as [n2 [n3 [v1' [t23' [v23 ?]]]]]; try apply enc2_OK; eauto. destruct_conjs. assert (n2 + n3 = n23) by omega. destruct H6. rewrite <- Eqdep_dec.eq_rect_eq_dec in H3 by (apply Nat.eq_dec). rewrite <- Eqdep_dec.eq_rect_eq_dec in H5 by (apply Nat.eq_dec). subst. apply Vector_append_inj in H3. destruct_conjs. subst. repeat eexists; eauto. instantiate (1:=eq_refl). all : eauto. Qed.
imports: Fiat.Common.Coq__8_4__8_5__Compat Bedrock.Word Coq.ZArith.ZArith Coq.NArith.NArith Coq.Arith.Arith Coq.Numbers.Natural.Peano.NPeano Coq.Logic.Eqdep_dec Fiat.Common.BoundedLookup Fiat.Narcissus.Common.Specs Fiat.Narcissus.Common.ComposeOpt Fiat.Narcissus.Common.ComposeIf Fiat.Narcissus.BaseFormats Fiat.Narcissus.BinLib.Core Fiat.Narcissus.BinLib.AlignedByteString