Library Basic
Require Export Bool.
Require Export List.
Require Export ListSet.
Require Export Sorting.Permutation.
Require Export Arith.
Ltac destroy H := repeat (elim H; intro; clear H; intro H).
Require Export List.
Require Export ListSet.
Require Export Sorting.Permutation.
Require Export Arith.
Ltac destroy H := repeat (elim H; intro; clear H; intro H).
Section Natural_Numbers.
Lemma minus_S : forall m n, n - S m = pred (n - m).
Lemma minus_is_S : forall m n, m < n -> exists k, n - m = S k.
Lemma not_lt_minus_0 n m : ~ m < n -> n - m = 0.
Lemma max_lt_l : forall k m n, max m n < k -> m < k.
Lemma max_lt_r : forall k m n, max m n < k -> n < k.
Theorem beq_sym: forall n m : nat, (n =? m) = (m =? n).
Lemma O_plus_O : forall {n m}, n+m = 0 -> n = 0.
Lemma O_plus_O' : forall {n m}, n+m = 0 -> m = 0.
Lemma lt_neq : forall m n, m < n -> m <> n.
Lemma gt_neq : forall m n, m > n -> m <> n.
Lemma Some_or_None : forall (n:option nat), {n = None} + {exists m, n = Some m}.
End Natural_Numbers.
Lemma minus_S : forall m n, n - S m = pred (n - m).
Lemma minus_is_S : forall m n, m < n -> exists k, n - m = S k.
Lemma not_lt_minus_0 n m : ~ m < n -> n - m = 0.
Lemma max_lt_l : forall k m n, max m n < k -> m < k.
Lemma max_lt_r : forall k m n, max m n < k -> n < k.
Theorem beq_sym: forall n m : nat, (n =? m) = (m =? n).
Lemma O_plus_O : forall {n m}, n+m = 0 -> n = 0.
Lemma O_plus_O' : forall {n m}, n+m = 0 -> m = 0.
Lemma lt_neq : forall m n, m < n -> m <> n.
Lemma gt_neq : forall m n, m > n -> m <> n.
Lemma Some_or_None : forall (n:option nat), {n = None} + {exists m, n = Some m}.
End Natural_Numbers.
Definition list_max l := fold_right max 0 l.
Lemma list_max_app : forall l1 l2,
list_max (l1 ++ l2) = max (list_max l1) (list_max l2).
Lemma list_max_le : forall l n,
list_max l <= n <-> Forall (fun k => k <= n) l.
Lemma list_max_lt : forall l n, l <> nil ->
list_max l < n <-> Forall (fun k => k < n) l.
Lemma le_list_max : forall l n x, In x l ->
n <= x -> n <= list_max l.
Lemma lt_list_max : forall l n x, In x l ->
n < x -> n < list_max l.
Lemma NoDup_app_char : forall l l':list T, NoDup l -> NoDup l' ->
(forall x, In x l -> ~In x l') -> NoDup (l++l').
Lemma NoDup_app_elim_1 : forall l l':list T, NoDup (l++l') -> NoDup l.
Lemma NoDup_app_elim_2 : forall l l':list T, NoDup (l++l') -> NoDup l'.
Lemma NoDup_app_both : forall l l':list T, NoDup (l++l') ->
forall x, ~(In x l /\ In x l').
Lemma NoDup_app_sym : forall l l':list T, NoDup (l++l') -> NoDup (l'++l).
Lemma NoDup_app :
forall A (P Q:list A),
(NoDup (P ++ Q)) -> (NoDup P) /\ (NoDup Q).
Lemma NoDup_app_not_in : forall l l':list T, NoDup (l ++ l') ->
forall x, In x l -> ~In x l'.
Lemma not_in_app : forall (xs ys : list T) (x : T),
~ In x (xs ++ ys) -> ~ In x xs /\ ~ In x ys.
Lemma not_in_app' : forall (xs ys : list T) (x : T),
~ In x xs /\ ~ In x ys -> ~ In x (xs ++ ys).
Lemma not_in_app_iff : forall (xs ys : list T) (x : T),
~ In x (xs ++ ys) <-> ~ In x xs /\ ~ In x ys.
Definition disjoint {A:Type} (l l':list A) :=
forall a, ~(In a l /\ In a l').
Lemma disjoint_dec : forall A (A_dec:forall x y:A,{x=y}+{x<>y}) l l',
{disjoint (A:=A) l l'} + {~disjoint l l'}.
Lemma disjoint_not_in_fst : forall A (l l':list A),
disjoint l l' -> forall a, In a l -> ~In a l'.
Lemma disjoint_not_in_snd : forall A (l l':list A),
disjoint l l' -> forall a, In a l' -> ~In a l.
Lemma disjoint_char : forall A (l l':list A),
(forall a, In a l -> ~In a l') -> disjoint l l'.
Lemma disjoint_sym : forall A (l l':list A),
disjoint l l' -> disjoint l' l.
Fixpoint all_defined {T} (l:list (option T)) : Prop :=
match l with
| nil => True
| (Some _) :: l' => all_defined l'
| None :: _ => False
end.
Set Implicit Arguments.
Lemma set_union_elim : forall T T_dec (x:T) (X Y:set T),
In x (set_union T_dec X Y) -> {In x X} + {In x Y}.
Equality and inclusion
Hypothesis T_dec : forall x y:T, {x=y}+{x<>y}.
Definition set_equals (T_dec : forall x y:T, {x=y}+{x<>y})
(X Y:set T) := forall z, In z X <-> In z Y.
Definition set_incl (T_dec : forall x y:T, {x=y}+{x<>y})
(X Y:set T) := forall z, In z X -> In z Y.
Lemma set_incl_dec :
forall X Y, {set_incl T_dec X Y}+{~set_incl T_dec X Y}.
Lemma set_equals_char : forall X Y, set_equals T_dec X Y <-> (set_incl T_dec X Y /\ set_incl T_dec Y X).
Lemma set_equals_dec :
forall X Y, {set_equals T_dec X Y}+{~set_equals T_dec X Y}.
More robust remove
Fixpoint set_remove' x (X:set T) :=
match X with
| nil => nil
| y::Y => if T_dec x y then (set_remove' x Y) else (y::set_remove' x Y)
end.
Lemma set_remove'_not_In : forall x (X:set T), ~In x X -> set_remove' x X = X.
Lemma set_remove'_1: forall x y (X : set T), In x (set_remove' y X) -> In x X.
Lemma set_remove'_2: forall x y (X:set T), In x (set_remove' y X) -> x <> y.
Lemma set_remove'_3: forall x y (X:set T), x<>y -> In x X -> In x (set_remove' y X).
Lemma set_remove'_cross : forall x y (X:set T),
In x X -> set_remove' x X = set_remove' y X -> x = y.
Lemma set_remove'_remove' : forall x y (X:set T),
set_remove' x (set_remove' y X) = set_remove' y (set_remove' x X).
Lemma set_remove'_out : forall x y (X:set T),
~In x (set_remove' y X) -> In x X -> x = y.
Size
Fixpoint set_size (X:set T) :=
match X with
| nil => 0
| x::Y => if In_dec T_dec x Y then set_size Y else S (set_size Y)
end.
Lemma set_size_0 : forall X, set_size X = 0 -> X = nil.
Lemma set_size_remove' : forall X x, In x X ->
set_size X = S (set_size (set_remove' x X)).
Lemma set_size_1 : forall X, set_size X = 1 ->
forall x y, In x X -> In y X -> x = y.
Lemma set_size_remove'_lt : forall x (X:set T),
set_size X <= S (set_size (set_remove' x X)).
Lemma set_size_neq_2 : forall x y (X:set T), x<>y ->
In x X -> In y X -> set_size X <> 2 -> set_size (set_remove' x X) > 1.
Lemma set_size_incl_le : forall (X Y:set T),
set_incl T_dec X Y -> set_size X <= set_size Y.
End Lists.
Require Import Vector.
Import VectorNotations.
Characterization results for vectors of length up to 3.
Lemma vector_1_equal : forall {A} (x y:A), x = y -> forall Hi, [x][@Hi] = [y][@Hi].
Lemma vector_2_equal : forall {A} (x x' y y':A), x = x' -> y = y' ->
forall Hi, [x; y][@Hi] = [x'; y'][@Hi].
Lemma vector_3_equal : forall {A} (x x' y y' z z':A), x = x' -> y = y' -> z = z' ->
forall Hi, [x; y; z][@Hi] = [x'; y'; z'][@Hi].
Lemma vector_0_inv : forall {A} (v:t A 0), [] = v.
Lemma vector_1_inv : forall {A} (v:t A 1), [hd v] = v.
Lemma vector_2_inv : forall {A} (v:t A 2), [hd v; hd (tl v)] = v.
Lemma vector_3_inv : forall {A} (v:t A 3), [hd v; hd (tl v); hd (tl (tl v))] = v.
On heads and tails.
Lemma nth_hd : forall {A} {n} (v:t A (S n)), v[@Fin.F1] = hd v.
Lemma nth_hd' : forall {A} (v:t A 1) Hi, v[@Hi] = hd v.
Lemma nth_tl : forall {A} {n} (v:t A (S n)) Hi, v[@Fin.FS Hi] = (tl v)[@Hi].
Lemma nth_In : forall {A} {n} (v:t A n) H x, v[@H] = x -> In x v.
Lemma In_tail : forall {A} {n} (v:t A (S n)) x, In x (tl v) -> In x v.
Lemma In_elim : forall {A} {n} (v:t A n) x y, In y (x::v) -> x = y \/ In y v.
Lemma In_nth : forall {A} {n} (v:t A n) x, In x v -> exists H, v[@H] = x.
Lemma In_induction : forall {A} {n} (P:A -> Prop) (v:t A n),
(forall x, In x v -> P x) -> forall H, P (v[@H]).
Lemma shiftin_elim : forall {A} {n} (v:t A n) x y, In y (shiftin x v) -> x = y \/ In y v.
Lemma In_shiftin : forall {A} {n} (v:t A n) x y, In y v -> In y (shiftin x v).
Lemma In_shiftin' : forall {A} {n} (v:t A n) y, In y (shiftin y v).
Definition eta_elim_aux {A n} (v:t A (S n)) H :=
match H with
| Fin.F1 => hd v
| Fin.FS H' => (tl v)[@H]
end.
Lemma hd_tl_eq : forall {A} {n} (v v':t A (S n)),
hd v = hd v' -> (forall H, (tl v)[@H] = (tl v')[@H]) ->
forall H, v[@H] = v'[@H].
Lemma nth_hd' : forall {A} (v:t A 1) Hi, v[@Hi] = hd v.
Lemma nth_tl : forall {A} {n} (v:t A (S n)) Hi, v[@Fin.FS Hi] = (tl v)[@Hi].
Lemma nth_In : forall {A} {n} (v:t A n) H x, v[@H] = x -> In x v.
Lemma In_tail : forall {A} {n} (v:t A (S n)) x, In x (tl v) -> In x v.
Lemma In_elim : forall {A} {n} (v:t A n) x y, In y (x::v) -> x = y \/ In y v.
Lemma In_nth : forall {A} {n} (v:t A n) x, In x v -> exists H, v[@H] = x.
Lemma In_induction : forall {A} {n} (P:A -> Prop) (v:t A n),
(forall x, In x v -> P x) -> forall H, P (v[@H]).
Lemma shiftin_elim : forall {A} {n} (v:t A n) x y, In y (shiftin x v) -> x = y \/ In y v.
Lemma In_shiftin : forall {A} {n} (v:t A n) x y, In y v -> In y (shiftin x v).
Lemma In_shiftin' : forall {A} {n} (v:t A n) y, In y (shiftin y v).
Definition eta_elim_aux {A n} (v:t A (S n)) H :=
match H with
| Fin.F1 => hd v
| Fin.FS H' => (tl v)[@H]
end.
Lemma hd_tl_eq : forall {A} {n} (v v':t A (S n)),
hd v = hd v' -> (forall H, (tl v)[@H] = (tl v')[@H]) ->
forall H, v[@H] = v'[@H].
Hopefully self-explanatory.
Lemma map_shiftin : forall {A} {B} {n} (f:A->B) (v:t A n) x,
map f (shiftin x v) = shiftin (f x) (map f v).
Lemma shiftin_eq : forall {A} {n} (v v':t A n) x x',
x = x' -> (forall H, v[@H] = v'[@H]) ->
forall H, (shiftin x v)[@H] = (shiftin x' v')[@H].
map f (shiftin x v) = shiftin (f x) (map f v).
Lemma shiftin_eq : forall {A} {n} (v v':t A n) x x',
x = x' -> (forall H, v[@H] = v'[@H]) ->
forall H, (shiftin x v)[@H] = (shiftin x' v')[@H].
Fixpoint map_inv {A} {B} {n} (f:t (A->B) n) (x:A) : t B n :=
match f with
| [] => []
| (f0 :: fs) => (f0 x) :: (map_inv fs x)
end.
match f with
| [] => []
| (f0 :: fs) => (f0 x) :: (map_inv fs x)
end.
The results about map_inv are the same as those for map in the standard library, with analogous
names. We add a specialization of nth_map.
Lemma nth_map' {A B} (f: A -> B) {n} v (p: Fin.t n) : (map f v) [@p] = f (v [@p]).
Lemma nth_map_inv {A} {B} {n} (f:t (A->B) n) v (p1 p2: Fin.t n) (eq: p1 = p2) :
(map_inv f v) [@ p1] = f[@ p2] v.
Lemma nth_map_inv' {A} {B} {n} (f:t (A->B) n) v (p: Fin.t n) :
(map_inv f v) [@p] = f[@p] v.
Lemma nth_map_inv {A} {B} {n} (f:t (A->B) n) v (p1 p2: Fin.t n) (eq: p1 = p2) :
(map_inv f v) [@ p1] = f[@ p2] v.
Lemma nth_map_inv' {A} {B} {n} (f:t (A->B) n) v (p: Fin.t n) :
(map_inv f v) [@p] = f[@p] v.
More about map.
Lemma hd_map : forall {A B} (f:A->B) n (v:t A (S n)), hd (map f v) = f (hd v).
Lemma tl_map : forall {A B} (f:A->B) n (v:t A (S n)), tl (map f v) = map f (tl v).
Lemma tl_map : forall {A B} (f:A->B) n (v:t A (S n)), tl (map f v) = map f (tl v).
Two interesting induction principles.
Lemma hd_tl_induction : forall {A} {n} (P:A -> Prop) (v:t A (S n)),
P (hd v) -> (forall H, P (tl v)[@H]) -> forall H, P v[@H].
Definition vpair {A B n} (v:t A n) (v':t B n) := map2 (fun a b => (a,b)) v v'.
Lemma vpair_fst : forall A B n (v:t A n) (v':t B n),
map fst (vpair v v') = v.
Lemma vpair_snd : forall A B n (v:t A n) (v':t B n),
map snd (vpair v v') = v'.
Lemma nth_vpair : forall A B n (v:t A n) (v':t B n) H,
(vpair v v')[@H] = (v[@H],v'[@H]).
Lemma hd_tl_induction' : forall {A B} {n} (P:A -> B -> Prop)
(v:t A (S n)) (v':t B (S n)),
P (hd v) (hd v') -> (forall H, P (tl v)[@H] (tl v')[@H]) -> forall H, P v[@H] v'[@H].
P (hd v) -> (forall H, P (tl v)[@H]) -> forall H, P v[@H].
Definition vpair {A B n} (v:t A n) (v':t B n) := map2 (fun a b => (a,b)) v v'.
Lemma vpair_fst : forall A B n (v:t A n) (v':t B n),
map fst (vpair v v') = v.
Lemma vpair_snd : forall A B n (v:t A n) (v':t B n),
map snd (vpair v v') = v'.
Lemma nth_vpair : forall A B n (v:t A n) (v':t B n) H,
(vpair v v')[@H] = (v[@H],v'[@H]).
Lemma hd_tl_induction' : forall {A B} {n} (P:A -> B -> Prop)
(v:t A (S n)) (v':t B (S n)),
P (hd v) (hd v') -> (forall H, P (tl v)[@H] (tl v')[@H]) -> forall H, P v[@H] v'[@H].
Destruction of nth.
Lemma eta_elim : forall {A} {n} (v:t A (S n)) x Hi, v[@Hi] = x -> hd v = x \/ exists Hi', (tl v)[@Hi'] = x.
Maximum of a vector of natural numbers.
Fixpoint vmax {n} (v:t nat n) :=
match v with
| [] => 0
| x :: xs => Nat.max x (vmax xs)
end.
Lemma vmax_leq : forall n v x, vmax (n:=n) v <= x -> forall p, v[@p] <= x.
Lemma vmax_lt : forall n v x, vmax (n:=n) v < x -> forall p, v[@p] < x.
Lemma vmax_lt_map : forall {A n} (v:t A n) f x,
vmax (map f v) < x -> forall i, f v[@i] < x.
Lemma vmax_In : forall n v p, In p v -> p <= vmax (n:=n) v.
match v with
| [] => 0
| x :: xs => Nat.max x (vmax xs)
end.
Lemma vmax_leq : forall n v x, vmax (n:=n) v <= x -> forall p, v[@p] <= x.
Lemma vmax_lt : forall n v x, vmax (n:=n) v < x -> forall p, v[@p] < x.
Lemma vmax_lt_map : forall {A n} (v:t A n) f x,
vmax (map f v) < x -> forall i, f v[@i] < x.
Lemma vmax_In : forall n v p, In p v -> p <= vmax (n:=n) v.
Vector containing the numbers k to k+n.
Fixpoint vec_k_to_n n k : t nat n :=
match n with
| 0 => []
| S m => k :: vec_k_to_n m (S k)
end.
Definition vec_1_to_n n : t nat n := vec_k_to_n n 1.
Lemma in_vec_k_to_n : forall n k m, In m (vec_k_to_n n k) ->
k <= m /\ m < k + n.
match n with
| 0 => []
| S m => k :: vec_k_to_n m (S k)
end.
Definition vec_1_to_n n : t nat n := vec_k_to_n n 1.
Lemma in_vec_k_to_n : forall n k m, In m (vec_k_to_n n k) ->
k <= m /\ m < k + n.
Vector of vectors with values [m; ...; m+n-1] [m+n; ...; m+2n-1] ... [m+(k-1)n; ...; m+kn-1].
Fixpoint vec_m_with_k m k n :=
match k with
| 0 => []
| S k' => (vec_k_to_n n m :: vec_m_with_k (m+n) k' n)
end.
match k with
| 0 => []
| S k' => (vec_k_to_n n m :: vec_m_with_k (m+n) k' n)
end.
Sum of a vector of natural numbers.