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) *)
(************************************************************************)
Equalities and Vector relations
Author: Pierre Boutillier
Institution: PPS, INRIA 07/2012
Require Import VectorDef. Require Import VectorSpec. Import VectorNotations. Section BEQ. Variables (A: Type) (A_beq: A -> A -> bool). Hypothesis A_eqb_eq: forall x y, A_beq x y = true <-> x = y. Definition eqb: forall {m n} (v1: t A m) (v2: t A n), bool := fix fix_beq {m n} v1 v2 := match v1, v2 with |[], [] => true |_ :: _, [] |[], _ :: _ => false |h1 :: t1, h2 :: t2 => A_beq h1 h2 && fix_beq t1 t2 end%bool.A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yforall (m n : nat) (v1 : t A m) (v2 : t A n), eqb v1 v2 = true -> m = nA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yforall (m n : nat) (v1 : t A m) (v2 : t A n), eqb v1 v2 = true -> m = nA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = ym:natv1:t A mforall (n : nat) (v2 : t A n), eqb v1 v2 = true -> m = nA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yh:An:natv1:t A nIHv1:forall (n1 : nat) (v0 : t A n1), eqb v1 v0 = true -> n = n1h0:An0:natv2:t A n0(A_beq h h0 && eqb v1 v2)%bool = true -> S n = S n0f_equal; eauto. Qed.A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yh:An:natv1:t A nIHv1:forall (n1 : nat) (v0 : t A n1), eqb v1 v0 = true -> n = n1h0:An0:natv2:t A n0H:A_beq h h0 = trueH0:eqb v1 v2 = trueS n = S n0A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yforall (n : nat) (v1 v2 : t A n), eqb v1 v2 = true <-> v1 = v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yforall (n : nat) (v1 v2 : t A n), eqb v1 v2 = true <-> v1 = v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yforall (n : nat) (v1 v2 : t A n), eqb v1 v2 = true <-> v1 = v2 -> forall a b : A, (A_beq a b && eqb v1 v2)%bool = true <-> a :: v1 = b :: v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = true(A_beq h1 h2 && eqb v1 v2)%bool = true -> h1 :: v1 = h2 :: v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueh1 :: v1 = h2 :: v2 -> (A_beq h1 h2 && eqb v1 v2)%bool = trueA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = true(A_beq h1 h2 && eqb v1 v2)%bool = true -> h1 :: v1 = h2 :: v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueHbeq:(A_beq h1 h2 && eqb v1 v2)%bool = trueh1 :: v1 = h2 :: v2f_equal; now auto.A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueH3:A_beq h1 h2 = trueH4:eqb v1 v2 = trueh1 :: v1 = h2 :: v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueh1 :: v1 = h2 :: v2 -> (A_beq h1 h2 && eqb v1 v2)%bool = trueA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueHeq:h1 :: v1 = h2 :: v2(A_beq h1 h2 && eqb v1 v2)%bool = trueA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueHeq:h1 :: v1 = h2 :: v2H3:h1 = h2H4:v1 = v2(A_beq h1 h2 && eqb v1 v2)%bool = truesplit; now auto. Qed.A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true -> v1 = v2H0:v1 = v2 -> eqb v1 v2 = trueh1, h2:AH1:A_beq h1 h2 = true -> h1 = h2H2:h1 = h2 -> A_beq h1 h2 = trueHeq:h1 :: v1 = h2 :: v2H3:h1 = h2H4:v1 = v2A_beq h1 h2 = true /\ eqb v1 v2 = trueA:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A n{v1 = v2} + {v1 <> v2}A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A n{v1 = v2} + {v1 <> v2}A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true{v1 = v2} + {v1 <> v2}A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = false{v1 = v2} + {v1 <> v2}left; now apply eqb_eq.A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = true{v1 = v2} + {v1 <> v2}A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = false{v1 = v2} + {v1 <> v2}A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = falsev1 <> v2A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = falseHeq:v1 = v2Falsecongruence. Defined. End BEQ. Section CAST.A:TypeA_beq:A -> A -> boolA_eqb_eq:forall x y : A, A_beq x y = true <-> x = yn:natv1, v2:t A nH:eqb v1 v2 = falseHeq:eqb v1 v2 = trueFalseforall (A : Type) (m : nat), t A m -> forall n : nat, m = n -> t A nrefine (fix cast {A m} (v: t A m) {struct v} := match v in t _ m' return forall n, m' = n -> t A n with |[] => fun n => match n with | 0 => fun _ => [] | S _ => fun H => False_rect _ _ end |h :: w => fun n => match n with | 0 => fun H => False_rect _ _ | S n' => fun H => h :: (cast w n' (f_equal pred H)) end end); discriminate. Defined. End CAST.forall (A : Type) (m : nat), t A m -> forall n : nat, m = n -> t A n