Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Require Import Decimal.d, d':uint{d = d'} + {d <> d'}decide equality. Defined.d, d':uint{d = d'} + {d <> d'}d, d':uintrev (revapp d d') = revapp d' dd, d':uintrev (revapp d d') = revapp d' dinduction d; simpl; intros; now rewrite ?IHd. Qed.d:uintforall d' : uint, rev (revapp d d') = revapp d' dd:uintrev (rev d) = dapply rev_revapp. Qed.d:uintrev (rev d) = d
Normalization on little-endian numbers
Fixpoint nztail d := match d with | Nil => Nil | D0 d => match nztail d with Nil => Nil | d' => D0 d' end | D1 d => D1 (nztail d) | D2 d => D2 (nztail d) | D3 d => D3 (nztail d) | D4 d => D4 (nztail d) | D5 d => D5 (nztail d) | D6 d => D6 (nztail d) | D7 d => D7 (nztail d) | D8 d => D8 (nztail d) | D9 d => D9 (nztail d) end. Definition lnorm d := match nztail d with | Nil => zero | d => d end.d, d':uintnztail d = Nil -> nzhead (revapp d d') = nzhead d'd, d':uintnztail d = Nil -> nzhead (revapp d d') = nzhead d'd:uintforall d' : uint, nztail d = Nil -> nzhead (revapp d d') = nzhead d'destruct (nztail d); now rewrite IHd. Qed.d:uintIHd:forall d'0 : uint, nztail d = Nil -> nzhead (revapp d d'0) = nzhead d'0d':uintH0:match nztail d with | Nil => Nil | D0 u => D0 (D0 u) | D1 u => D0 (D1 u) | D2 u => D0 (D2 u) | D3 u => D0 (D3 u) | D4 u => D0 (D4 u) | D5 u => D0 (D5 u) | D6 u => D0 (D6 u) | D7 u => D0 (D7 u) | D8 u => D0 (D8 u) | D9 u => D0 (D9 u) end = Nilnzhead (revapp d (D0 d')) = nzhead d'd, d':uintnztail d <> Nil -> nzhead (revapp d d') = revapp (nztail d) d'd, d':uintnztail d <> Nil -> nzhead (revapp d d') = revapp (nztail d) d'induction d; intros d' H; simpl in *; try destruct (nztail d) eqn:E; (now rewrite ?nzhead_revapp_0) || (now rewrite IHd). Qed.d:uintforall d' : uint, nztail d <> Nil -> nzhead (revapp d d') = revapp (nztail d) d'd:uintnztail d <> Nil -> nzhead (rev d) = rev (nztail d)apply nzhead_revapp. Qed.d:uintnztail d <> Nil -> nzhead (rev d) = rev (nztail d)d:uintrev (nztail (rev d)) = nzhead dd:uintrev (nztail (rev d)) = nzhead dd:uintH:nztail (rev d) = Nilrev (nztail (rev d)) = nzhead dd:uintH:nztail (rev d) <> Nilrev (nztail (rev d)) = nzhead dd:uintH:nztail (rev d) = Nilrev (nztail (rev d)) = nzhead dd:uintH:nztail (rev d) = Nilrev Nil = nzhead dd:uintH:nztail (rev d) = NilNil = nzhead dd:uintH:nztail (rev d) = NilNil = nzhead (rev (rev d))now apply nzhead_revapp_0.d:uintH:nztail (rev d) = Nilnzhead (rev (rev d)) = Nilnow rewrite <- nzhead_rev, rev_rev. Qed.d:uintH:nztail (rev d) <> Nilrev (nztail (rev d)) = nzhead dd, d':uintrevapp d d' = Nil -> d = Nil /\ d' = Nild, d':uintrevapp d d' = Nil -> d = Nil /\ d' = Nilinduction d; simpl; intros d' H; auto; now apply IHd in H. Qed.d:uintforall d' : uint, revapp d d' = Nil -> d = Nil /\ d' = Nild:uintrev d = Nil -> d = Nilapply revapp_nil_inv. Qed.d:uintrev d = Nil -> d = Nild:uintrev (lnorm (rev d)) = unorm dd:uintrev (lnorm (rev d)) = unorm dd:uintrev match nztail (rev d) with | Nil => 0 | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = match nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u enddestruct nztail; simpl; trivial; destruct rev eqn:E; trivial; now apply rev_nil_inv in E. Qed.d:uintrev match nztail (rev d) with | Nil => 0 | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = match rev (nztail (rev d)) with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u endd, d':uintnzhead d <> D0 d'induction d; easy. Qed.d, d':uintnzhead d <> D0 d'd:uintunorm d = 0%uint <-> nzhead d = Nild:uintunorm d = 0%uint <-> nzhead d = Nild:uintmatch nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = 0%uint <-> nzhead d = Nild:uintmatch nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = 0%uint -> nzhead d = Nild:uintnzhead d = Nil -> match nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = 0%uintd:uintmatch nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = 0%uint -> nzhead d = Nild:uint(forall d' : uint, nzhead d <> D0 d') -> match nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = 0%uint -> nzhead d = Nilnow destruct (H u).d, u:uintH:forall d' : uint, D0 u <> D0 d'H1:u = NilD0 u = Nilnow intros ->. Qed.d:uintnzhead d = Nil -> match nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = 0%uintd:uintunorm d <> Nild:uintunorm d <> Nilnow destruct nzhead. Qed.d:uintmatch nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end <> Nild:uintnzhead (nzhead d) = nzhead dnow induction d. Qed.d:uintnzhead (nzhead d) = nzhead dd:uintunorm (unorm d) = unorm dd:uintunorm (unorm d) = unorm dd:uintmatch nzhead match nzhead d with | Nil => 0 | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u end = match nzhead d with | Nil => 0%uint | D0 u => D0 u | D1 u => D1 u | D2 u => D2 u | D3 u => D3 u | D4 u => D4 u | D5 u => D5 u | D6 u => D6 u | D7 u => D7 u | D8 u => D8 u | D9 u => D9 u enddestruct (nzhead_nonzero _ _ E). Qed.d, u:uintE:nzhead d = D0 umatch nzhead (D0 u) with | Nil => 0%uint | D0 u0 => D0 u0 | D1 u0 => D1 u0 | D2 u0 => D2 u0 | D3 u0 => D3 u0 | D4 u0 => D4 u0 | D5 u0 => D5 u0 | D6 u0 => D6 u0 | D7 u0 => D7 u0 | D8 u0 => D8 u0 | D9 u0 => D9 u0 end = D0 ud:intnorm (norm d) = norm dd:intnorm (norm d) = norm dd:intmatch match d with | Pos d0 => Pos (unorm d0) | Neg d0 => match nzhead d0 with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end end with | Pos d0 => Pos (unorm d0) | Neg d0 => match nzhead d0 with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end end = match d with | Pos d0 => Pos (unorm d0) | Neg d0 => match nzhead d0 with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end endd:uintPos (unorm (unorm d)) = Pos (unorm d)d:uintmatch match nzhead d with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end with | Pos d0 => Pos (unorm d0) | Neg d0 => match nzhead d0 with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end end = match nzhead d with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) endd:uintPos (unorm (unorm d)) = Pos (unorm d)apply unorm_invol.d:uintunorm (unorm d) = unorm dd:uintmatch match nzhead d with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end with | Pos d0 => Pos (unorm d0) | Neg d0 => match nzhead d0 with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) end end = match nzhead d with | Nil => 0%int | D0 u => Neg (D0 u) | D1 u => Neg (D1 u) | D2 u => Neg (D2 u) | D3 u => Neg (D3 u) | D4 u => Neg (D4 u) | D5 u => Neg (D5 u) | D6 u => Neg (D6 u) | D7 u => Neg (D7 u) | D8 u => Neg (D8 u) | D9 u => Neg (D9 u) enddestruct (nzhead_nonzero _ _ E). Qed.d, u:uintE:nzhead d = D0 umatch nzhead (D0 u) with | Nil => 0%int | D0 u0 => Neg (D0 u0) | D1 u0 => Neg (D1 u0) | D2 u0 => Neg (D2 u0) | D3 u0 => Neg (D3 u0) | D4 u0 => Neg (D4 u0) | D5 u0 => Neg (D5 u0) | D6 u0 => Neg (D6 u0) | D7 u0 => Neg (D7 u0) | D8 u0 => Neg (D8 u0) | D9 u0 => Neg (D9 u0) end = Neg (D0 u)