Tealeaves.Backends.LN.Parallel

From Tealeaves.Backends.Common Require Import
  Names AtomSet.
From Tealeaves Require Import
  Misc.NaturalNumbers
  Functors.Option
  Classes.Kleisli.DecoratedTraversableMonad.
From Tealeaves.Theory Require Import
  TraversableFunctor
  DecoratedTraversableMonad.

#[local] Generalizable Variable T.

Import DecoratedTraversableMonad.Notations.
Import DecoratedContainerFunctor.Notations.
Import AtomSet.Notations.
Open Scope tealeaves_scope.
Open Scope set_scope.

Import DecoratedTraversableMonad.UsefulInstances.

Locally nameless leaves

Inductive leaf :=
| Fr: atom leaf
| Bd: nat nat leaf.
(* Bd group index, individual index *)

Theorem eq_dec_leaf: l1 l2: leaf, {l1 = l2} + {l1 l2}.
Proof.
  decide equality.
  - compare values n and n0; auto.
  - compare values n and n0; auto.
    compare values n0 and n2; auto.
    compare values n0 and n2; auto.
  - compare values n and n1; auto.
Qed.

#[export] Instance EqDec_leaf: EquivDec.EqDec leaf eq := eq_dec_leaf.

Fixpoint nth {A} (n: nat) (l: list A): option A :=
  match n, l with
  | O, x :: l'Some x
  | O, otherNone
  | S m, nilNone
  | S m, x :: tnth m t
  end.

Lemma nth1: (A: Type) (n: nat), nth n (@nil A) = None.
Proof.
  intros. now induction n.
Qed.

Lemma nth2: (A: Type) (n: nat) (w: list A),
    Nat.compare n (length w) = Gt nth n w = None.
Proof.
  intros. generalize dependent n. induction w.
  - intros. now rewrite nth1.
  - intros. destruct n.
    + cbv in H. inversion H.
    + cbn in ×. auto.
Qed.

Lemma nth3: (A: Type) (w: list A),
    nth (length w) w = None.
Proof.
  intros. induction w.
  - cbn. reflexivity.
  - cbn. auto.
Qed.

Operations for locally nameless

Local operations

Section local_operations.

  Context
    `{Return T}.

  Implicit Types (x: atom).

  Definition free_loc: leaf list atom :=
    fun lmatch l with
             | Fr xcons x List.nil
             | _List.nil
             end.

  Definition subst_loc x (u: T leaf): leaf T leaf :=
    fun lmatch l with
             | Fr yif x == y then u else ret (T := T) (Fr y)
             | Bd grp ixret (T := T) (Bd grp ix)
             end.

  Definition open_loc (binders: list (T leaf)): list nat × leaf option (T leaf) :=
    fun pmatch p with
             | (w, l)
                 match l with
                 | Fr xSome (ret (T := T) (Fr x))
                 | Bd grp ix
                     match Nat.compare grp (length w) with
                     | LtSome (ret (T := T) (Bd grp ix))
                     | Eqnth ix binders
                     | GtSome (ret (T := T) (Bd (grp - 1) ix))
                     end
                 end
             end.

  Definition is_bound_or_free: list nat × leaf Prop :=
    fun pmatch p with
             | (w, l)
                 match l with
                 | Fr xTrue
                 | Bd grp ix
                     match nth grp w with
                     | Some sizeix < size
                     | NoneFalse
                     end
                 end
             end.

End local_operations.

Lifted operations

Section LocallyNamelessOperations.

  Context
    (T: Type Type)
    `{DecoratedTraversableMonad (list nat)
    (op := @List.app nat) (unit := nil) T}.

  Definition open (binders: list (T leaf)): T leaf option (T leaf) :=
    binddt (T := T) (open_loc binders).

  Definition locally_closed: T leaf Prop :=
    fun t w l, (w, l) d t is_bound_or_free (w, l).

  Corollary open_respectful_id (us: list (T leaf)): (t: T leaf),
      ( w a,
          (w, a) d t open_loc us (w, a) = Some (ret (T := T) a))
      binddt (open_loc us) t = pure t.
  Proof.
    intros.
    now apply (binddt_respectful_pure).
  Qed.

  Theorem correct: (t: T leaf) (us: list (T leaf)),
      locally_closed t open us t = Some t.
  Proof.
    introv LC. unfold locally_closed in LC.
    apply open_respectful_id.
    intros w l Hin. specialize (LC w l Hin).
    destruct l; cbn in LC.
    - reflexivity.
    - cbn. compare naturals n and (length w).
      + rewrite nth3 in LC. inversion LC.
      + assert (lemma: nth n w = None) by auto using nth2.
        rewrite lemma in LC. inversion LC.
  Qed.

End LocallyNamelessOperations.