Library base

Require Export List.
Require Export EqNat.
Require Export Relations.
Require Export ZArith.
Require Export ZArith_dec.
This file collects some axioms used throughout the Mechanized Semantic Library development. This file was developed in 2010 by Andrew W. Appel and Xavier Leroy, and harmonizes the axioms used by MSL and by the CompCert project.
Require ClassicalFacts.

Extensionality axioms

The following Require Export gives us functional extensionality for dependent function types:
Axiom functional_extensionality_dep : forall {A} {B : A -> Type}, 
  forall (f g : forall x : A, B x), 
  (forall x, f x = g x) -> f = g.
and, as a corollary, functional extensionality for non-dependent functions:
Lemma functional_extensionality {A B} (f g : A -> B) : 
  (forall x, f x = g x) -> f = g.
Require Export FunctionalExtensionality.
For compatibility with earlier developments, extensionality is an alias for functional_extensionality.
Lemma extensionality:
  forall (A B: Type) (f g : A -> B), (forall x, f x = g x) -> f = g.

Implicit Arguments extensionality.

We also assert propositional extensionality.

Proof irrelevance


We also use proof irrelevance, which is a consequence of propositional extensionality.

Lemma proof_irr: ClassicalFacts.proof_irrelevance.
Implicit Arguments proof_irr.


Require Import EqdepFacts.

Module EqdepElim <: EqdepElimination.
Lemma eq_rect_eq :
    forall (U:Type) (p:U) (Q:U -> Type) (x:Q p) (h:p = p),
      x = eq_rect p Q x p h.
End EqdepElim.

Module EqdepTh := EqdepTheory EqdepElim.
Export EqdepTh.

Tactic Notation "extensionality" :=
 let x := fresh "x" in extensionality x.

Tactic Notation "extensionality" ident(x) ident(y) :=
    extensionality x; extensionality y.

Tactic Notation "extensionality" ident(x) ident(y) ident(z):=
    extensionality x; extensionality y z.

Lemma imp_ext: forall (A A' B B' : Prop), (A=A') -> (A -> (B=B')) -> ((A->B)=(A'->B')).

Lemma exists_ext: forall (A: Type) F G, (forall x: A, F x = G x) -> (Logic.ex F = Logic.ex G).

Lemma and_ext: forall A B C D, A=B -> C=D -> (A /\ C) = (B /\ D).

Lemma and_ext': forall (A: Prop) B C D, A=B -> (A -> (C=D)) -> (A /\ C) = (B /\ D).

Lemma or_ext: forall A B C D, A=B -> C=D -> (A \/ C) = (B \/ D).

Lemma forall_ext: forall (A: Type) (F: A -> Prop) G, (forall x:A, F x = G x) -> (forall x, F x) = (forall x, G x).

Lemma existT_ext:
  forall (A: Type) (P: A -> Prop) (x y: A) (Hx: P x) (Hy: P y),
     x = y -> existT _ x Hx = existT _ y Hy.

Lemma exist_ext:
  forall (A: Type) (P: A -> Prop) (x y: A) (Hx: P x) (Hy: P y),
     x = y -> exist _ x Hx = exist _ y Hy.

Hint Extern 1 (@eq _ _ _) => exact (proof_irr _ _).

Hint Extern 2 (eq _ _) => apply exist_ext.

Hint Extern 2 (@eq _ (@existT _ _ _ _) (@existT _ _ _ _)) => apply existT_ext.

Ltac proof_irr := match goal with H: ?A, H' : ?A |- _ => generalize (proof_irr H H'); intro; subst H' end.

Tactic Notation "spec" hyp(H) :=
  match type of H with ?a -> _ =>
    let H1 := fresh in (assert (H1: a); [auto |generalize (H H1); clear H H1; intro H]) end.

Tactic Notation "spec" hyp(H) constr(a) :=
  (generalize (H a); clear H; intro H).

Tactic Notation "spec" hyp(H) constr(a) constr(b) :=
  (generalize (H a b); clear H; intro H).

 Tactic Notation "spec" hyp(H) constr(a) constr(b) constr(c) :=
  (generalize (H a b c); clear H; intro H).

Tactic Notation "spec" hyp(H) constr(a) constr(b) constr(c) constr(d) :=
  (generalize (H a b c d); clear H; intro H).

Tactic Notation "spec" hyp(H) constr(a) constr(b) constr(c) constr(d) constr(e) :=
  (generalize (H a b c d e); clear H; intro H).

Ltac inv H := inversion H; clear H; subst.

Lemma rt_mono A (R1 R2:A -> A -> Prop) :
  (forall x y, R1 x y -> R2 x y) ->
  (forall x y,
    clos_refl_trans A R1 x y ->
    clos_refl_trans A R2 x y).

Section closures.
  Variables X:Type.
  Variable R:X -> X -> Prop.

  Lemma t_rt : forall x1 x2,
    clos_trans X R x1 x2 ->
    clos_refl_trans X R x1 x2.

  Lemma rt_inv : forall x1 x2,
    clos_refl_trans X R x1 x2 ->
    x1 = x2 \/ clos_trans X R x1 x2.

  Lemma t_inv_left : forall x1 x2,
    clos_trans X R x1 x2 ->
    exists x', R x1 x' /\ clos_refl_trans X R x' x2.

  Lemma t_inv_right : forall x1 x2,
    clos_trans X R x1 x2 ->
    exists x', clos_refl_trans X R x1 x' /\ R x' x2.

  Lemma t_rt_trans : forall x1 x2 x3,
    clos_trans X R x1 x2 ->
    clos_refl_trans X R x2 x3 ->
    clos_trans X R x1 x3.

  Lemma rt_t_trans : forall x1 x2 x3,
    clos_refl_trans X R x1 x2 ->
    clos_trans X R x2 x3 ->
    clos_trans X R x1 x3.

  Inductive rt_left : X -> X -> Prop :=
    | rtl_refl : forall x, rt_left x x
    | rtl_step : forall x y z,
         R x y ->
         rt_left y z ->
         rt_left x z.

  Inductive rt_right : X -> X -> Prop :=
    | rtr_refl : forall x, rt_right x x
    | rtr_step : forall x y z,
         rt_right x y ->
         R y z ->
         rt_right x z.

  Lemma rtl_trans : forall x1 x2 x3,
    rt_left x1 x2 -> rt_left x2 x3 -> rt_left x1 x3.

  Lemma rtr_trans : forall x1 x2 x3,
    rt_right x1 x2 -> rt_right x2 x3 -> rt_right x1 x3.

  Lemma rt_to_left : forall x1 x2,
    clos_refl_trans X R x1 x2 -> rt_left x1 x2.

  Lemma left_to_rt : forall x1 x2,
    rt_left x1 x2 -> clos_refl_trans X R x1 x2.

  Lemma rt_to_right : forall x1 x2,
    clos_refl_trans X R x1 x2 -> rt_right x1 x2.

  Lemma right_to_rt : forall x1 x2,
    rt_right x1 x2 -> clos_refl_trans X R x1 x2.
End closures.