(** * Natural Deduction *)
Require Export Semantics.
(** ** Definition *)
Inductive nd := intu | class.
Existing Class nd.
Inductive prv : forall {s : nd} {b : logic} (A : list (form b)), form b -> Prop :=
| Ctx {b} {s : nd} (A : list (form b)) phi : In phi A -> prv A phi
| ImpI {b} {s : nd} (A : list (form b)) phi1 phi2 : prv (phi1::A) phi2 -> prv A (phi1 --> phi2)
| ImpE {b} {s : nd} (A : list (form b)) phi1 phi2 : prv A (phi1 --> phi2) -> prv A phi1 -> prv A phi2
| AllI {b} {s : nd} (A : list (form b)) x y phi : fresh y (consts phi ++ consts_l A) -> prv A (subst x (P y) phi) -> prv A (∀ x ; phi)
| AllE {b} {s : nd} (A : list (form b)) x t phi : vars_t t = []
-> prv A (All x phi) -> prv A (subst x t phi)
| Exp A phi : @prv intu full A Fal -> @prv intu full A phi
| DN A phi : @prv class full A (¬¬ phi) -> @prv class full A phi.
Notation "A ⊢ phi" := (prv A phi) (at level 30).
Definition prv_min := @prv intu frag.
Definition prv_class := @prv class full.
Definition prv_intu := @prv intu full.
Notation "A ⊢M phi" := (prv_min A phi) (at level 30).
Notation "A ⊢I phi" := (@prv intu _ A phi) (at level 30).
Notation "A ⊢C phi" := (@prv class _ A phi) (at level 30).

(* Specifications: *)
Lemma prv_ind_min :
forall p : list (form frag) -> form frag -> Prop,
(forall  (A : list (form frag)) (phi : form frag), phi el A -> p A phi) ->
(forall  (A : list (form frag)) (phi1 phi2 : form frag),
(phi1 :: A) ⊢I phi2 -> p (phi1 :: A) phi2 -> p A (phi1 --> phi2)) ->
(forall  (A : list (form frag)) (phi1 phi2 : form frag),
A ⊢I (phi1 --> phi2) -> p A (phi1 --> phi2) -> A ⊢I phi1 -> p A phi1 -> p A phi2) ->
(forall  (A : list (form frag)) (x y : nat) (phi : form frag),
fresh y (consts phi ++ consts_l A) ->
A ⊢I subst x (P y) phi -> p A (subst x (P y) phi) -> p A (∀ x; phi)) ->
(forall  (A : list (form frag)) (x : nat) (t : term) (phi : form frag),
vars_t t = [] ->
A ⊢I (∀ x; phi) -> p A (∀ x; phi) -> p A (subst x t phi)) ->
forall (A : list (form frag)) (f9 : form frag), A ⊢I f9 -> p A f9.