%% Disjoint partitioning of lambda terms into normal and non-normal form

%% The ctxs predicate encodes the relationship between the context
%% of the judgements (term T) and (normal T).

Specification "normal".

Define name : tm -> prop by
  nabla x, name x.

Define ctxs : olist -> olist -> prop by
  ctxs nil nil ;
  nabla x, ctxs (term x :: L) (neutral x :: K) := ctxs L K.


%% Lemmas about contexts

Theorem ctxs_member_term : forall L K E,
  ctxs L K -> member E L ->
  exists X, E = term X /\ member (neutral X) K /\ name X.
induction on 1. intros. case H1.
  case H2.
  case H2.
    search.
    apply IH to H3 H4.
      search.

Theorem ctxs_var : forall E L K,
  ctxs L K -> member E K -> 
  exists X, E = neutral X /\ name X.
induction on 1. intros. case H1.
  case H2.
  case H2.
    search.
    apply IH to H3 H4. search.


%% Partitioning is total

Theorem total_ext : forall T L K,
  ctxs L K -> {L |- term T} -> {K |- normal T} \/ {non_normal T}.
induction on 2. intros. case H2.
  apply IH to H1 H3. apply IH to H1 H4. case H5.
    case H6.
      case H7.
        search.
        search.
        apply ctxs_var to H1 H10. case H9.
      search.
    search.
  apply IH to _ H3. case H4.
    search.
    search.
  apply ctxs_member_term to H1 H4. case H3. search.

Theorem total : forall T,
  {term T} -> {normal T} \/ {non_normal T}.
intros. apply total_ext to _ H1. search.


%% Partitioning is disjoint

Theorem neutral_abs_absurd : forall L K R,
  ctxs L K -> {K |- neutral (abs R)} -> false.
intros. case H2. 
 apply ctxs_var to H1 H4. case H3. case H5.

Theorem disjoint_ext : forall L K T,
  ctxs L K -> {K |- normal T} -> {non_normal T} -> false.
induction on 3. intros. case H2.
  case H3. apply IH to _ H4 H5.
  case H4.
    case H3.
      apply neutral_abs_absurd to H1 H5.
      apply IH to H1 _ H7.
      apply IH to H1 H6 H7.
    apply ctxs_var to H1 H6. case H5. case H7. case H3.
  apply ctxs_var to H1 H5. case H4.

Theorem disjoint : forall T,
  {normal T} -> {non_normal T} -> false.
intros. apply disjoint_ext to _ H1 H2.
