GhostTT.autosubst.CCAST_rasimpl

CCAST support for rasimpl

From Coq Require Import Utf8 List.
From GhostTT.autosubst Require Import core unscoped CCAST RAsimpl.
From Coq Require Import Setoid Morphisms Relation_Definitions.
Import ListNotations.

Inductive quoted_subst :=
| qsubst_atom (σ : nat cterm)
| qsubst_comp (s t : quoted_subst)
| qsubst_compr (s : quoted_subst) (r : quoted_ren)
| qsubst_rcomp (r : quoted_ren) (s : quoted_subst)
| qsubst_cons (t : quoted_cterm) (s : quoted_subst)
| qsubst_id
| qsubst_ren (r : quoted_ren)

with quoted_cterm :=
| qatom (t : cterm)
| qren (r : quoted_ren) (t : quoted_cterm)
| qsubst (s : quoted_subst) (t : quoted_cterm).

Fixpoint unquote_subst q :=
  match q with
  | qsubst_atom σ ⇒ σ
  | qsubst_comp s tfuncomp (subst_cterm (unquote_subst s)) (unquote_subst t)
  | qsubst_compr s rfuncomp (unquote_subst s) (unquote_ren r)
  | qsubst_rcomp r sfuncomp (ren_cterm (unquote_ren r)) (unquote_subst s)
  | qsubst_cons t sscons (unquote_cterm t) (unquote_subst s)
  | qsubst_idcvar
  | qsubst_ren rfuncomp cvar (unquote_ren r)
  end

with unquote_cterm q :=
  match q with
  | qatom tt
  | qren r tren_cterm (unquote_ren r) (unquote_cterm t)
  | qsubst s tsubst_cterm (unquote_subst s) (unquote_cterm t)
  end.

Evaluation

Inductive eval_subst_comp_view : quoted_subst quoted_subst Type :=
| es_id_l s : eval_subst_comp_view qsubst_id s
| es_id_r s : eval_subst_comp_view s qsubst_id
| es_comp_r s u v : eval_subst_comp_view s (qsubst_comp u v)
| es_compr_r s x y : eval_subst_comp_view s (qsubst_compr x y)
| es_rcomp_r s x y : eval_subst_comp_view s (qsubst_rcomp x y)
| es_cons_r s t s' : eval_subst_comp_view s (qsubst_cons t s')
| es_ren_l r s : eval_subst_comp_view (qsubst_ren r) s
| es_ren_r s r : eval_subst_comp_view s (qsubst_ren r)
| es_other u v : eval_subst_comp_view u v.

Definition eval_subst_comp_c u v : eval_subst_comp_view u v :=
  match u, v with
  | qsubst_id, ves_id_l v
  | u, qsubst_ides_id_r u
  | u, qsubst_comp x yes_comp_r u x y
  | u, qsubst_compr x yes_compr_r u x y
  | u, qsubst_rcomp x yes_rcomp_r u x y
  | u, qsubst_cons t ses_cons_r u t s
  | qsubst_ren r, ses_ren_l r s
  | u, qsubst_ren res_ren_r u r
  | u, ves_other u v
  end.

Inductive eval_subst_compr_view : quoted_subst quoted_ren Type :=
| esr_id_l r : eval_subst_compr_view qsubst_id r
| esr_id_r s : eval_subst_compr_view s qren_id
| esr_comp_r s x y : eval_subst_compr_view s (qren_comp x y)
| esr_cons_r s n r : eval_subst_compr_view s (qren_cons n r)
| esr_ren_l s r : eval_subst_compr_view (qsubst_ren s) r
| esr_cons_shift t s : eval_subst_compr_view (qsubst_cons t s) qren_shift
| esr_other s r : eval_subst_compr_view s r.

Definition eval_subst_compr_c s r : eval_subst_compr_view s r :=
  match s, r with
  | qsubst_id, resr_id_l r
  | s, qren_idesr_id_r s
  | s, qren_comp x yesr_comp_r s x y
  | s, qren_cons n resr_cons_r s n r
  | qsubst_ren s, resr_ren_l s r
  | qsubst_cons t s, qren_shiftesr_cons_shift t s
  | s, resr_other s r
  end.

Inductive eval_subst_rcomp_view : quoted_ren quoted_subst Type :=
| ers_id_l s : eval_subst_rcomp_view qren_id s
| ers_id_r r : eval_subst_rcomp_view r qsubst_id
| ers_comp_r r x y : eval_subst_rcomp_view r (qsubst_comp x y)
| ers_compr_r r x y : eval_subst_rcomp_view r (qsubst_compr x y)
| ers_rcomp_r r x y : eval_subst_rcomp_view r (qsubst_rcomp x y)
| ers_cons_r r t s : eval_subst_rcomp_view r (qsubst_cons t s)
| ers_ren_r r s : eval_subst_rcomp_view r (qsubst_ren s)
| ers_other r s : eval_subst_rcomp_view r s.

Definition eval_subst_rcomp_c r s : eval_subst_rcomp_view r s :=
  match r, s with
  | qren_id, sers_id_l s
  | r, qsubst_iders_id_r r
  | r, qsubst_comp x yers_comp_r r x y
  | r, qsubst_compr x yers_compr_r r x y
  | r, qsubst_rcomp x yers_rcomp_r r x y
  | r, qsubst_cons t sers_cons_r r t s
  | r, qsubst_ren sers_ren_r r s
  | r, sers_other r s
  end.

Inductive qsubst_ren_id_view : quoted_subst Type :=
| is_qsubst_ren r : qsubst_ren_id_view (qsubst_ren r)
| is_qsubst_id : qsubst_ren_id_view qsubst_id
| not_qsubst_ren_id s : qsubst_ren_id_view s.

Definition test_qsubst_ren_id s : qsubst_ren_id_view s :=
  match s with
  | qsubst_ren ris_qsubst_ren r
  | qsubst_idis_qsubst_id
  | snot_qsubst_ren_id s
  end.

(* TODO Could be improved like apply_ren *)
Fixpoint apply_subst (s : quoted_subst) (n : quoted_nat) : quoted_cterm :=
  match s, n with
  | qsubst_atom s, _qatom (s (unquote_nat n))
  | qsubst_id, _qatom (cvar (unquote_nat n))
  | _, qnat_atom nqatom (unquote_subst s n)
  | qsubst_comp s1 s2, _qsubst s1 (apply_subst s2 n)
  | qsubst_compr s r, _apply_subst s (apply_ren r n)
  | qsubst_rcomp r s, _qren r (apply_subst s n)
  | qsubst_cons t s, q0t
  | qsubst_cons t s, qS napply_subst s n
  | qsubst_ren r, nqatom (cvar (unquote_nat (apply_ren r n)))
  end.

Fixpoint eval_subst (s : quoted_subst) : quoted_subst :=
  match s with
  | qsubst_comp u v
    let u := eval_subst u in
    let v := eval_subst v in
    match eval_subst_comp_c u v with
    | es_id_l vv
    | es_id_r uu
    | es_comp_r u x yqsubst_comp (qsubst_comp u x) y
    | es_compr_r u x yqsubst_compr (qsubst_comp u x) y
    | es_rcomp_r u x yqsubst_comp (qsubst_compr u x) y
    | es_cons_r u t sqsubst_cons (qsubst u t) (qsubst_comp u s)
    | es_ren_l r sqsubst_rcomp r s
    | es_ren_r u rqsubst_compr u r
    | es_other u vqsubst_comp u v
    end
  | qsubst_compr s r
    let s := eval_subst s in
    let r := eval_ren r in
    match eval_subst_compr_c s r with
    | esr_id_l rqsubst_ren r
    | esr_id_r ss
    | esr_comp_r s x yqsubst_compr (qsubst_compr s x) y
    | esr_cons_r s n rqsubst_cons (apply_subst s n) (qsubst_compr s r)
    | esr_ren_l s rqsubst_ren (qren_comp s r)
    | esr_cons_shift t ss
    | esr_other s rqsubst_compr s r
    end
  | qsubst_rcomp r s
    let r := eval_ren r in
    let s := eval_subst s in
    match eval_subst_rcomp_c r s with
    | ers_id_l ss
    | ers_id_r rqsubst_ren r
    | ers_comp_r r x yqsubst_comp (qsubst_rcomp r x) y
    | ers_compr_r r x yqsubst_compr (qsubst_rcomp r x) y
    | ers_rcomp_r r x yqsubst_rcomp (qren_comp r x) y
    | ers_cons_r r t sqsubst_cons (qren r t) (qsubst_rcomp r s)
    | ers_ren_r r sqsubst_ren (qren_comp r s)
    | ers_other r sqsubst_rcomp r s
    end
  | qsubst_cons t s
    let t := eval_cterm t in
    let s := eval_subst s in
    qsubst_cons t s
  | qsubst_ren r
    let r := eval_ren r in
    match test_qren_id r with
    | is_qren_idqsubst_id
    | not_qren_id rqsubst_ren r
    end
  | _s
  end

with eval_cterm (t : quoted_cterm) : quoted_cterm :=
  match t with
  | qren r t
    let r := eval_ren r in
    let t := eval_cterm t in
    match t with
    | qsubst s tqsubst (qsubst_comp (qsubst_ren r) s) t
    | qren r' tqren (qren_comp r r') t
    | _
      match test_qren_id r with
      | is_qren_idt
      | not_qren_id rqren r t
      end
    end
  | qsubst s t
    let s := eval_subst s in
    let t := eval_cterm t in
    match t with
    | qsubst s' tqsubst (qsubst_comp s s') t
    | qren r tqsubst (qsubst_compr s r) t
    | _
      match test_qsubst_ren_id s with
      | is_qsubst_ren rqren r t
      | is_qsubst_idt
      | not_qsubst_ren_id sqsubst s t
      end
    end
  | _t
  end.

Correctness

Lemma apply_subst_sound :
   s n,
    unquote_cterm (apply_subst s n) = unquote_subst s (unquote_nat n).
Proof.
  intros s n.
  induction s in n |- ×.
  all: try reflexivity.
  - cbn. destruct n.
    + reflexivity.
    + cbn. rewrite IHs2. reflexivity.
    + cbn. rewrite IHs2. reflexivity.
  - cbn. destruct n.
    + reflexivity.
    + rewrite IHs. rewrite apply_ren_sound. reflexivity.
    + cbn. rewrite IHs. rewrite apply_ren_sound. reflexivity.
  - cbn. destruct n.
    + reflexivity.
    + cbn. rewrite IHs. reflexivity.
    + cbn. rewrite IHs. reflexivity.
  - cbn. destruct n.
    + reflexivity.
    + reflexivity.
    + cbn. rewrite IHs. reflexivity.
  - cbn. destruct n.
    + reflexivity.
    + cbn. rewrite apply_ren_sound. reflexivity.
    + cbn. rewrite apply_ren_sound. reflexivity.
Qed.

Ltac set_eval_subst na :=
  lazymatch goal with
  | eval_subst_sound : s : quoted_subst, _ |- context [ eval_subst ?s ] ⇒
    let IH := fresh "IH" in
    pose proof (eval_subst_sound s) as IH ;
    set (na := eval_subst s) in × ;
    clearbody na
  end.

Fixpoint eval_subst_sound s :
    pointwise_relation _ eq (unquote_subst s) (unquote_subst (eval_subst s))

with eval_cterm_sound t :
    unquote_cterm t = unquote_cterm (eval_cterm t).
Proof.
  {
    intros n.
    destruct s.
    all: try reflexivity.
    - cbn. set_eval_subst es1. set_eval_subst es2.
      destruct eval_subst_comp_c.
      + cbn in ×. unfold funcomp. rewrite IH, IH0.
        asimpl. reflexivity.
      + cbn in ×. unfold funcomp. rewrite IH, IH0.
        asimpl. reflexivity.
      + cbn in ×. unfold funcomp in ×.
        erewrite subst_cterm_morphism. 2,3: eauto.
        asimpl. reflexivity.
      + cbn in ×. unfold funcomp in ×.
        erewrite subst_cterm_morphism. 2,3: eauto.
        asimpl. reflexivity.
      + cbn in ×. unfold funcomp in ×.
        erewrite subst_cterm_morphism. 2,3: eauto.
        asimpl. reflexivity.
      + cbn in ×. unfold funcomp.
        erewrite subst_cterm_morphism. 2,3: eauto.
        asimpl. destruct n. all: reflexivity.
      + cbn in ×. unfold funcomp in ×.
        rewrite IH, IH0.
        rewrite rinstInst'_cterm. reflexivity.
      + cbn in ×. unfold funcomp in ×.
        rewrite IH, IH0. reflexivity.
      + cbn in ×. unfold funcomp. rewrite IH, IH0. reflexivity.
    - cbn. set_eval_subst es.
      remember (eval_ren _) as er eqn:e.
      destruct eval_subst_compr_c.
      + subst. cbn. unfold funcomp. rewrite IH.
        cbn. rewrite <- eval_ren_sound. reflexivity.
      + unfold funcomp. rewrite eval_ren_sound, <- e. cbn.
        rewrite IH. reflexivity.
      + unfold funcomp. rewrite eval_ren_sound, <- e. cbn.
        rewrite IH. reflexivity.
      + unfold funcomp. rewrite eval_ren_sound, <- e. cbn.
        rewrite IH. destruct n. 2: reflexivity.
        cbn. rewrite apply_subst_sound. reflexivity.
      + subst. cbn. unfold funcomp. rewrite <- eval_ren_sound.
        rewrite IH. reflexivity.
      + unfold funcomp. rewrite eval_ren_sound, <- e. cbn.
        rewrite IH. cbn. reflexivity.
      + subst. cbn. unfold funcomp. rewrite <- eval_ren_sound.
        rewrite IH. reflexivity.
    - cbn. set_eval_subst es.
      remember (eval_ren _) as er eqn:e.
      destruct eval_subst_rcomp_c.
      + unfold funcomp.
        erewrite ren_cterm_morphism. 3: reflexivity.
        2:{ intro. rewrite eval_ren_sound, <- e. reflexivity. }
        cbn. asimpl. auto.
      + subst. unfold funcomp. rewrite IH. cbn. rewrite eval_ren_sound.
        reflexivity.
      + subst. unfold funcomp. rewrite IH. cbn. unfold funcomp.
        rewrite substRen_cterm. apply subst_cterm_morphism. 2: reflexivity.
        intro. unfold funcomp. apply ren_cterm_morphism. 2: reflexivity.
        intro. rewrite <- eval_ren_sound. reflexivity.
      + subst. unfold funcomp. rewrite IH. cbn. unfold funcomp.
        apply ren_cterm_morphism. 2: reflexivity.
        intro. rewrite <- eval_ren_sound. reflexivity.
      + subst. unfold funcomp. rewrite IH. cbn. unfold funcomp.
        rewrite renRen_cterm. apply ren_cterm_morphism. 2: reflexivity.
        intro. rewrite <- eval_ren_sound. reflexivity.
      + subst. unfold funcomp. rewrite IH. cbn.
        destruct n.
        × cbn. apply ren_cterm_morphism. 2: reflexivity.
          intro. rewrite eval_ren_sound. reflexivity.
        × cbn. unfold funcomp. apply ren_cterm_morphism. 2: reflexivity.
          intro. rewrite eval_ren_sound. reflexivity.
      + subst. unfold funcomp. rewrite IH. cbn. unfold funcomp.
        rewrite <- eval_ren_sound. reflexivity.
      + subst. cbn. unfold funcomp. rewrite IH.
        apply ren_cterm_morphism. 2: reflexivity.
        intro. rewrite eval_ren_sound. reflexivity.
    - cbn. erewrite scons_morphism. 2,3: eauto.
      reflexivity.
    - cbn. remember (eval_ren _) as er eqn:e.
      destruct test_qren_id.
      + cbn. unfold funcomp. rewrite eval_ren_sound, <- e.
        reflexivity.
      + subst. cbn. unfold funcomp. rewrite <- eval_ren_sound.
        reflexivity.
  }
  {
    destruct t.
    - reflexivity.
    - cbn. remember (eval_cterm _) as et eqn:e in ×.
      destruct et.
      + remember (eval_ren _) as rr eqn:er.
        destruct test_qren_id.
        × rewrite eval_cterm_sound, <- e.
          cbn. erewrite ren_cterm_morphism. 3: reflexivity.
          2:{ intro. rewrite eval_ren_sound, <- er. reflexivity. }
          cbn. asimpl. reflexivity.
        × subst. cbn. rewrite eval_cterm_sound, <- e. cbn.
          eapply ren_cterm_morphism. 2: reflexivity.
          intro. apply eval_ren_sound.
      + cbn. rewrite eval_cterm_sound, <- e. cbn. rewrite renRen_cterm.
        apply ren_cterm_morphism. 2: reflexivity.
        intro. unfold funcomp. rewrite <- eval_ren_sound. reflexivity.
      + cbn. rewrite eval_cterm_sound, <- e. cbn.
        rewrite substRen_cterm.
        apply subst_cterm_morphism. 2: reflexivity.
        intro. unfold funcomp.
        rewrite rinstInst'_cterm.
        apply subst_cterm_morphism. 2: reflexivity.
        intro. unfold funcomp.
        rewrite <- eval_ren_sound. reflexivity.
    - cbn. remember (eval_cterm _) as et eqn:e in ×.
      destruct et.
      + remember (eval_subst _) as ss eqn:es in ×.
        rewrite eval_cterm_sound, <- e. cbn.
        destruct test_qsubst_ren_id.
        × cbn. erewrite subst_cterm_morphism. 3: reflexivity.
          2:{ intro. rewrite eval_subst_sound, <- es. reflexivity. }
          cbn. rewrite rinstInst'_cterm. reflexivity.
        × cbn. erewrite subst_cterm_morphism. 3: reflexivity.
          2:{ intro. rewrite eval_subst_sound, <- es. reflexivity. }
          cbn. asimpl. reflexivity.
        × subst. cbn.
          eapply subst_cterm_morphism. 2: reflexivity.
          intro. apply eval_subst_sound.
      + cbn. rewrite eval_cterm_sound, <- e. cbn. rewrite renSubst_cterm.
        apply subst_cterm_morphism. 2: reflexivity.
        intro. unfold funcomp. rewrite <- eval_subst_sound. reflexivity.
      + cbn. rewrite eval_cterm_sound, <- e. cbn. rewrite substSubst_cterm.
        eapply subst_cterm_morphism. 2: reflexivity.
        intro. unfold funcomp.
        eapply subst_cterm_morphism. 2: reflexivity.
        intro. rewrite <- eval_subst_sound. reflexivity.
  }
Qed.

Quoting

Ltac quote_subst s :=
  lazymatch s with
  | funcomp cvar ?r
    let q := quote_ren r in
    constr:(qsubst_ren q)
  | funcomp (subst_cterm ?s) ?t
    let q := quote_subst s in
    let q' := quote_subst t in
    constr:(qsubst_comp q q')
  | funcomp (ren_cterm ?r) ?s
    let qr := quote_ren r in
    let qs := quote_subst s in
    constr:(qsubst_rcomp qr qs)
  | funcomp (Y := nat) ?s ?r
    let qs := quote_subst s in
    let qr := quote_ren r in
    constr:(qsubst_compr qs qr)
  | scons ?t ?s
    let qt := quote_cterm t in
    let q := quote_subst s in
    constr:(qsubst_cons qt q)
  | idsconstr:(qsubst_id)
  | cvarconstr:(qsubst_id)
  (* Instead of minimize *)
  | λ x, ?g (?f x) ⇒
    let t := constr:(funcomp g f) in
    quote_subst t
  | λ x, ?f x
    let t := constr:(f) in
    quote_subst t
  | _constr:(qsubst_atom s)
  end

with quote_cterm t :=
  lazymatch t with
  | ren_cterm ?r ?t
    let qr := quote_ren r in
    let qt := quote_cterm t in
    constr:(qren qr qt)
  | subst_cterm ?s ?t
    let qs := quote_subst s in
    let qt := quote_cterm t in
    constr:(qsubst qs qt)
  | _constr:(qatom t)
  end.

Unfoldings

#[export] Hint Unfold
  VarInstance_cterm Ren_cterm Up_cterm_cterm Up_cterm up_cterm Subst_cterm
  upRen_cterm_cterm up_cterm_cterm
  : asimpl_unfold.

Class CTermSimplification (t s : cterm) := MkSimplCTm {
  autosubst_simpl_cterm : t = s
}.

Arguments autosubst_simpl_cterm t {s _}.

Hint Mode CTermSimplification + - : typeclass_instances.

Declare Reduction asimpl_cbn_cterm :=
  cbn [
    unquote_cterm eval_cterm test_qren_id test_qsubst_ren_id
    unquote_ren eval_ren apply_ren eval_ren_comp_c
    unquote_subst eval_subst eval_subst_compr_c eval_subst_comp_c
    eval_subst_rcomp_c apply_subst
    unquote_nat
    ren_cterm subst_cterm scons
  ].

Declare Reduction asimpl_unfold_cterm :=
  unfold upRen_cterm_cterm, up_ren, up_cterm_cterm, var_zero.

#[export] Hint Extern 10 (CTermSimplification ?t _) ⇒
  let q := quote_cterm t in
  let s := eval asimpl_cbn_cterm in (unquote_cterm (eval_cterm q)) in
  let s := eval asimpl_unfold_cterm in s in
  exact (MkSimplCTm t s (eval_cterm_sound q))
  : typeclass_instances.

Class CSubstSimplification (r s : nat cterm) := MkSimplCSubst {
  autosubst_simpl_csubst : pointwise_relation _ eq r s
}.

Arguments autosubst_simpl_csubst r {s _}.

Hint Mode CSubstSimplification + - : typeclass_instances.

#[export] Hint Extern 10 (CSubstSimplification ?r _) ⇒
  let q := quote_subst r in
  let s := eval asimpl_cbn_cterm in (unquote_subst (eval_subst q)) in
  let s := eval asimpl_unfold_cterm in s in
  exact (MkSimplCSubst r s (eval_subst_sound q))
  : typeclass_instances.

Lemma autosubst_simpl_cterm_ren :
   r t s,
    CTermSimplification (ren_cterm r t) s
    ren_cterm r t = s.
Proof.
  intros r t s H.
  apply autosubst_simpl_cterm, _.
Qed.

Lemma autosubst_simpl_cterm_subst :
   r t s,
    CTermSimplification (subst_cterm r t) s
    subst_cterm r t = s.
Proof.
  intros r t s H.
  apply autosubst_simpl_cterm, _.
Qed.

Triggers

#[export] Hint Rewriteautosubst_simpl_cterm_ren : asimpl.
#[export] Hint Rewriteautosubst_simpl_cterm_subst : asimpl.