GhostTT.TermMode

From Coq Require Import Utf8 List.
From Equations Require Import Equations.

From GhostTT.autosubst Require Import GAST.
From GhostTT Require Import Util BasicAST ContextDecl Scoping.

Import ListNotations.

Set Default Goal Selector "!".

Reads the mode of a term.
The mode of a variable comes from the scope.

Section Mode.

  Let dummy := mType.

  Fixpoint md (Γ : scope) (t : term) : mode :=
    match t with
    | var xnth x Γ dummy
    | Sort m lmKind
    | Pi i j m mx A BmKind
    | lam mx A tmd (mx :: Γ) t
    | app u vmd Γ u
    | Erased AmKind
    | hide tmGhost
    | reveal t P p
      match md Γ p with
      | mGhostmGhost
      | _mProp
      end
    | Reveal t pmKind
    | toRev t p umProp
    | fromRev t p umProp
    | gheq A u vmKind
    | ghrefl A umProp
    | ghcast A u v e P tmd Γ t
    | tboolmKind
    | ttruemType
    | tfalsemType
    | tif m b P t fm
    | tnatmKind
    | tzeromType
    | tsucc nmType
    | tnat_elim m n P z sm
    | tvec A nmKind
    | tvnil AmType
    | tvcons a n vmType
    | tvec_elim m A n v P z sm
    | botmKind
    | bot_elim m A pm
    end.

End Mode.

(* Handy notation for the mode in a context *)

Notation mdc Γ t := (md (sc Γ) t).

Relation with scoping

Lemma scoping_md :
   Γ t m,
    scoping Γ t m
    md Γ t = m.
Proof.
  intros Γ t m h.
  induction h. all: try reflexivity. all: try solve [ auto ].
  - simpl. eapply nth_error_nth. assumption.
  - simpl. rewrite IHh3. cbn in ×. intuition eauto.
    + rewrite <- H0. reflexivity.
    + rewrite <- H. reflexivity.
Qed.

Ltac remd :=
  erewrite !scoping_md by eassumption.

Tactic Notation "remd" "in" hyp(h) :=
  erewrite !scoping_md in h by eassumption.

Consequence: scoping is functional

Lemma scoping_functional :
   Γ t m m',
    scoping Γ t m
    scoping Γ t m'
    m = m'.
Proof.
  intros Γ t m m' h h'.
  eapply scoping_md in h, h'. congruence.
Qed.

Useful tools

Definition mode_eqb (m m' : mode) : bool :=
  match m, m' with
  | mProp, mProp
  | mGhost, mGhost
  | mType, mType
  | mKind, mKindtrue
  | _,_false
  end.

Definition isProp m := mode_eqb m mProp.
Definition isGhost m := mode_eqb m mGhost.
Definition isType m := mode_eqb m mType.
Definition isKind m := mode_eqb m mKind.

Lemma isKind_eq :
   m, isKind m = true m = mKind.
Proof.
  intros [] e. all: try discriminate.
  reflexivity.
Qed.

Lemma isType_eq :
   m, isType m = true m = mType.
Proof.
  intros [] e. all: try discriminate.
  reflexivity.
Qed.

Lemma isGhost_eq :
   m, isGhost m = true m = mGhost.
Proof.
  intros [] e. all: try discriminate.
  reflexivity.
Qed.

Lemma isProp_eq :
   m, isProp m = true m = mProp.
Proof.
  intros [] e. all: try discriminate.
  reflexivity.
Qed.

Ltac mode_eqs :=
  repeat lazymatch goal with
  | e : isKind ?m = true |- _eapply isKind_eq in e ; try subst m
  | e : isType ?m = true |- _eapply isType_eq in e ; try subst m
  | e : isGhost ?m = true |- _eapply isGhost_eq in e ; try subst m
  | e : isProp ?m = true |- _eapply isProp_eq in e ; try subst m
  end.

Definition relm m :=
  match m with
  | mKind | mTypetrue
  | _false
  end.