Library CTPC.Contify

Translation into the continuation-only language

Require Import List.

Require Import LambdaTamer.LambdaTamer.
Require Import LambdaTamer.Tactics.

Require Import CTPC.Continuation.
Require Import CTPC.Source.
Require Import CTPC.CPS.
Require Import CTPC.Cont.

Set Implicit Arguments.

Auxiliary syntactic functions


Definition swap t1 t2 G (lin : olinear (t1 :: t2 :: G) tt) : olinear (t2 :: t1 :: G) tt :=
  Olinear.permute nil _ _ _ lin.

Theorem swap_sound : forall t1 t2 G (lin : olinear (t1 :: t2 :: G) tt) x1 x2 s,
  olinearDenote (swap lin) (SCons _ x1 (SCons _ x2 s))
  = olinearDenote lin (SCons _ x2 (SCons _ x1 s)).

The translation


Fixpoint contifyTy (t : sty) : oty :=
  match t with
    | SNat => ONat
    | SArrow dom ran => OCont (contifyTy dom :: OCont (contifyTy ran :: nil) :: nil)
  end.

Section ifVar.
   Variables (G : list sty) (t : sty)
    (T : Set) (varCase : Var G t -> T) (defaultCase : T).

  Definition ifVar (op : pprimop G t) : T.

  Theorem ifVar_sound : forall (P : T -> Prop)
    (op : pprimop G t),
    (forall v, op = PVar v -> P (varCase v))
    -> P defaultCase
    -> P (ifVar op).
End ifVar.

Fixpoint contifyPrimop (G : list sty) (t : sty) (op : pprimop G t) {struct op}
  : oprimop (map contifyTy G) (contifyTy t) :=
  match op in (pprimop G t) return (oprimop (map contifyTy G) (contifyTy t)) with
    | PConst _ n => OConst _ n
    | PVar _ _ v => OVar (VarConvert _ v)
    | PLam _ _ _ lin => OLam (OCCons (OCCons (OCNil (contifyLinear lin))))
  end

  with contifyLinear (G : list sty) (t : sty) (lin : plinear G t) {struct lin}
  : olinear (OCont (contifyTy t :: nil) :: map contifyTy G) tt :=
  match lin in (plinear G t) return (olinear (OCont (contifyTy t :: nil) :: map contifyTy G) tt) with
    | PThrow _ _ op =>
      ifVar
      (fun v =>
        OApply (First _ _) (OACons (Next _ (VarConvert contifyTy v)) (OANil _)))
      (OBind
        (Oprimop.lift _ (contifyPrimop op))
        (OApply (Next _ (First _ _)) (OACons (First _ _) (OANil _))))
      op
    | PApply _ _ _ _ func arg cont =>
      OBind
      (OLam (OCCons (OCNil
        (OApply (Next _ (Next _ (VarConvert contifyTy cont)))
          (OACons (First _ _)
            (OACons (Next _ (First _ _))
              (OANil _)))))))
      (OApply
        (Next _ (Next _ (VarConvert contifyTy func)))
        (OACons (Next _ (Next _ (VarConvert _ arg)))
          (OACons (First _ _)
            (OANil _))))
    | PBind _ _ _ op lin' =>
      OBind
      (Oprimop.lift _ (contifyPrimop op))
      (swap (contifyLinear lin'))
  end.

Logical relations


Fixpoint val_lr (t : sty) : ptyDenote t -> otyDenote (contifyTy t) -> Prop :=
  match t return (ptyDenote t -> otyDenote (contifyTy t) -> Prop) with
    | SNat => fun ns no => ns = no
    | SArrow dom ran => fun fp fo =>
      forall xp xo, val_lr dom xp xo
        -> exists thrownp,
          (forall k, fp xp k = k thrownp)
          /\ exists throwno,
            (forall k, fo (xo, (k, tt)) = k (throwno, tt))
            /\ val_lr ran thrownp throwno
  end.

Definition Subst_lr := Subst_lr contifyTy val_lr.
Hint Unfold Subst_lr.

Definition primop_lr G t (opp : pprimop G t) (opo : oprimop (map contifyTy G) (contifyTy t)) :=
  forall s s', Subst_lr s s'
    -> val_lr t (pprimopDenote opp s) (oprimopDenote opo s').

Definition linear_lr G t (linp : plinear G t) (lino : olinear (OCont (contifyTy t :: nil) :: map contifyTy G) tt) :=
  forall s s', Subst_lr s s'
    -> exists thrownp,
      (forall k, plinearDenote linp s k = k thrownp)
      /\ exists throwno,
        (forall k, olinearDenote lino (SCons _ k s') = k (throwno, tt))
        /\ val_lr t thrownp throwno.

Soundness proof


Scheme pprimop_scheme := Induction for pprimop Sort Prop
  with plinear_scheme := Induction for plinear Sort Prop.

Lemma oprimop_lift_sound : forall (G : list oty) (t : oty) (e : oprimop G t) (t' : oty),
  oprimopDenote (Oprimop.lift t' e) = fun s => oprimopDenote e (tail s).

Hint Rewrite oprimop_lift_sound swap_sound : Contify.

Ltac my_simpl := unfold linear_lr, primop_lr, withCont_bind, withCont_compose in *;
  fold ptyDenote in *; fold otyDenote in *; fold contifyTy in *;
    autorewrite with Contify; try apply ifVar_sound.

Ltac my_lr_tac := lr_tac ltac:(var_adder val_lr) stricter_inster my_simpl.

Theorem contifyLinear_sound : forall G t (e : plinear G t),
  linear_lr e (contifyLinear e).

Index
This page has been generated by coqdoc