From Undecidability.L Require Export Util.L_facts.
From Undecidability.L.Tactics Require Export LClos_Eval.
From Undecidability.L.Tactics Require Import mixedTactics.
(* *** Reflexted closure calculus *)
(* This moduel provides definitions of an symbolic simplifier for reflected L-terms used in Lbeta *)
Open Scope LClos.
Inductive rTerm : Type :=
| rVar (x : nat) : rTerm
| rApp (s : rTerm) (t : rTerm) : rTerm
| rLam (s : rTerm)
| rConst (x : nat) : rTerm
| rRho (s : rTerm).
Coercion rApp : rTerm >-> Funclass.
Definition denoteTerm (phi : nat -> term) :rTerm->term :=
fix denoteTerm s :=
match s with
| rVar n => var n
| rApp s t=> app (denoteTerm s) (denoteTerm t)
| rLam s => lam (denoteTerm s)
| rConst n => phi n
| rRho s => rho (denoteTerm s)
end.
Definition Proc phi := forall (n:nat) , proc (phi n).
Definition rClosed phi s:= Proc phi /\ closed (denoteTerm phi s).
Definition rPow phi n s t :=
denoteTerm phi s >(n) denoteTerm phi t.
unfold rPow;tauto.
Qed.
Inductive rComp : Type :=
| rCompVar (x:nat)
| rCompApp (s : rComp) (t : rComp) : rComp
| rCompClos (s : rTerm) (A : list rComp) : rComp.
Coercion rCompApp : rComp >-> Funclass.
Definition denoteComp (phi : nat -> term) :rComp -> Comp:=
fix denoteComp s :=
match s with
| rCompVar x => CompVar x
| rCompApp s t => (denoteComp s) (denoteComp t)
| rCompClos s A => CompClos (denoteTerm phi s) (map denoteComp A)
end.
Fixpoint rSubstList (s:rTerm) (x:nat) (A: list rTerm): rTerm :=
match s with
| rVar n => if Dec ( n < x )then rVar n else nth (n-x) A (rVar n)
| rApp s t => (rSubstList s x A) (rSubstList t x A)
| rLam s => rLam (rSubstList s (S x) A)
| rRho s => rRho (rSubstList s (S x) A)
| rConst x => rConst x
end.
Fixpoint rDeClos (s:rComp) : rTerm :=
match s with
| rCompVar x => rVar x
| rCompApp s t => (rDeClos s) (rDeClos t)
| rCompClos s A => rSubstList s 0 (map rDeClos A)
end.
Definition rComp_ind_deep'
(P : rComp -> Prop)
(Pl : list rComp -> Prop)
(IHVar : forall x : nat, P (rCompVar x))
(IHApp : forall s : rComp, P s -> forall t : rComp, P t -> P (s t))
(IHClos : forall (s : rTerm) (A : list rComp),
Pl A -> P (rCompClos s A))
(IHNil : Pl nil)
(IHCons : forall (a:rComp) (A : list rComp),
P a -> Pl A -> Pl (a::A))
(x:rComp) : P x :=
(fix f c : P c:=
match c with
| rCompVar x => IHVar x
| rCompApp s t => IHApp s (f s) t (f t)
| rCompClos s A => IHClos s A
((fix g A : Pl A :=
match A with
[] => IHNil
| a::A => IHCons a A (f a) (g A)
end) A)
end) x
.
Definition rComp_ind_deep
(P : rComp -> Prop)
(IHVar : forall x : nat, P (rCompVar x))
(IHApp : forall s : rComp, P s -> forall t : rComp, P t -> P (s t))
(IHClos : forall (s : rTerm) (A : list rComp),
(forall a, a el A -> P a) -> P (rCompClos s A)) : forall x, P x.
Definition rValidComp phi s := Proc phi /\validComp (denoteComp phi s).

Lemma map_ext' : forall (A B : Type) (f g : A -> B) (l:list A),
(forall a : A, a el l -> f a = g a) ->  map f l = map g l.