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).

Natural numbers

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.

Lists


Section Lists.

Variable T:Type.

Maximum of a list - from Coq 8.12...


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.

A result about permutations

Miscellaneous about NoDup


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.

Disjoint lists


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.

Miscellaneous


Fixpoint all_defined {T} (l:list (option T)) : Prop :=
match l with
  | nil => True
  | (Some _) :: l' => all_defined l'
  | None :: _ => False
end.

On sets


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.

Vectors


Section Vectors.

Equality.

This is a specialization of a lemma from the standard library.
Lemma eq_nth_iff' {A} {n} (v1 v2:t A n) :
  (forall (p:Fin.t n), v1[@p] = v2[@p]) <-> v1 = v2.

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].

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].

Alternative map function

It maps a list of functions onto an argument, rather than the usual.
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.


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.

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).

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].

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.

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.

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.

Sum of a vector of natural numbers.
Fixpoint vsum {n} (v:t nat n) :=
  match v with
  | [] => 0
  | x :: xs => x + vsum xs
end.

End Vectors.