aboutsummaryrefslogtreecommitdiffstats
From mininix Require Export nix.operational_props.
From stdpp Require Import options.

Definition wp (μ : mode) (e : expr) (Φ : expr → Prop) : Prop :=
  ∃ e', e -{μ}->* e' ∧ final μ e' ∧ Φ e'.

Lemma Lit_wp μ Φ bl :
  base_lit_ok bl →
  Φ (ELit bl) →
  wp μ (ELit bl) Φ.
Proof. exists (ELit bl). by repeat constructor. Qed.

Lemma Abs_wp μ Φ x e :
  Φ (EAbs x e) →
  wp μ (EAbs x e) Φ.
Proof. exists (EAbs x e). by repeat constructor. Qed.

Lemma AbsMatch_wp μ Φ ms strict e :
  Φ (EAbsMatch ms strict e) →
  wp μ (EAbsMatch ms strict e) Φ.
Proof. exists (EAbsMatch ms strict e). by repeat constructor. Qed.

Lemma LetAttr_no_recs_wp μ Φ k αs e :
  no_recs αs →
  wp μ (subst ((k,.) ∘ attr_expr <$> αs) e) Φ →
  wp μ (ELetAttr k (EAttr αs) e) Φ.
Proof.
  intros Hαs (e' & Hsteps & ? & HΦ). exists e'. split; [|done].
  etrans; [|apply Hsteps]. apply rtc_once. by constructor.
Qed.

Lemma BinOp_wp μ Φ op e1 e2 :
  wp SHALLOW e1 (λ e1', ∃ Φop,
    sem_bin_op op e1' Φop ∧ 
    wp SHALLOW e2 (λ e2', ∃ e', Φop e2' e' ∧ wp μ e' Φ)) →
  wp μ (EBinOp op e1 e2) Φ.
Proof.
  intros (e1' & Hsteps1 & ? & Φop & Hop1 & e2' & Hsteps2 & ?
          & e' & Hop2 & e'' & Hsteps & ? & HΦ).
  exists e''. split; [|done].
  etrans; [by apply SBinOpL_rtc|].
  etrans; [by eapply SBinOpR_rtc|].
  eapply rtc_l; [by econstructor|]. done.
Qed.

Lemma Id_wp μ Φ x k e :
  wp μ e Φ →
  wp μ (EId x (Some (k,e))) Φ.
Proof.
  intros (e' & Hsteps & ? & HΦ). exists e'. split; [|done].
  etrans; [|apply Hsteps]. apply rtc_once. constructor.
Qed.

Lemma App_wp μ Φ e1 e2 :
  wp SHALLOW e1 (λ e1', wp μ (EApp e1' e2) Φ) ↔
  wp μ (EApp e1 e2) Φ.
Proof.
  split.
  - intros (e1' & Hsteps1 & ? & e' & Hsteps2 & ? & HΦ).
    exists e'; split; [|done]. etrans; [|apply Hsteps2].
    by apply SAppL_rtc.
  - intros (e' & Hsteps & Hfinal & HΦ).
    cut (∃ e1', e1 -{SHALLOW}->* e1' ∧ final SHALLOW e1' ∧ EApp e1' e2 -{μ}->* e').
    { intros (e1'&?&?&?). exists e1'. split_and!; [done..|]. by exists e'. }
    clear Φ HΦ. apply rtc_nsteps in Hsteps as [n Hsteps].
    revert e1 Hsteps. induction n as [|n IH]; intros e1 Hsteps.
    { inv Hsteps. inv Hfinal. }
    inv Hsteps. inv H0.
    + eexists; split_and!; [done|by constructor|].
      eapply rtc_l; [by constructor|by eapply rtc_nsteps_2].
    + eexists; split_and!; [done|by constructor|].
      eapply rtc_l; [by constructor|by eapply rtc_nsteps_2].
    + eexists; split_and!; [done|by constructor|].
      eapply rtc_l; [by constructor|by eapply rtc_nsteps_2].
    + inv H2.
      * apply IH in H1 as (e'' & Hsteps & ? & ?).
        exists e''; split; [|done]. by eapply rtc_l.
      * eexists; split_and!; [done|by constructor|].
        eapply rtc_l; [by eapply SAppR|]. by eapply rtc_nsteps_2.
Qed.

Lemma Attr_wp_shallow Φ αs :
  Φ (EAttr (AttrN ∘ from_attr (subst (indirects αs)) id <$> αs)) →
  wp SHALLOW (EAttr αs) Φ.
Proof.
  eexists (EAttr (AttrN ∘ _ <$> αs)); split_and!; [ |by constructor|done].
  destruct (decide (no_recs αs)); [|apply rtc_once; by constructor].
  apply reflexive_eq; f_equal. apply map_eq=> x. rewrite lookup_fmap.
  destruct (αs !! x) as [[? e]|] eqn:?; f_equal/=.
  by assert (τ = NONREC) as -> by eauto using no_recs_lookup.
Qed.

Lemma β_wp μ Φ x e1 e2 :
  wp μ (subst {[x:=(ABS, e2)]} e1) Φ →
  wp μ (EApp (EAbs x e1) e2) Φ.
Proof.
  intros (e' & Hsteps & ? & ?). exists e'. split; [|done].
  eapply rtc_l; [|done]. by constructor.
Qed.

Lemma βMatch_wp μ Φ ms strict e1 αs βs :
  no_recs αs →
  matches (attr_expr <$> αs) ms strict βs →
  wp μ (subst (indirects βs) e1) Φ →
  wp μ (EApp (EAbsMatch ms strict e1) (EAttr αs)) Φ.
Proof.
  intros ?? (e' & Hsteps & ? & ?). exists e'. split; [|done].
  eapply rtc_l; [|done]. by constructor.
Qed.

Lemma Functor_wp μ Φ αs e1 e2 :
  no_recs αs →
  αs !! "__functor" = Some (AttrN e1) →
  wp μ (EApp (EApp e1 (EAttr αs)) e2) Φ →
  wp μ (EApp (EAttr αs) e2) Φ.
Proof.
  intros ?? (e' & Hsteps & ? & ?). exists e'. split; [|done].
  eapply rtc_l; [|done]. by constructor.
Qed.

Lemma If_wp μ Φ e1 e2 e3 :
  wp SHALLOW e1 (λ e1', ∃ b : bool,
    e1' = ELit (LitBool b) ∧ wp μ (if b then e2 else e3) Φ) →
  wp μ (EIf e1 e2 e3) Φ.
Proof.
  intros (e1' & Hsteps & ? & b & -> & e' & Hsteps' & ? & HΦ).
  exists e'; split; [|done]. etrans; [by apply SIf_rtc|].
  eapply rtc_l; [|done]. destruct b; constructor.
Qed.

Lemma wp_mono μ e Φ Ψ :
  wp μ e Φ →
  (∀ e', Φ e' → Ψ e') →
  wp μ e Ψ.
Proof. intros (e' & ? & ? & ?) ?. exists e'. naive_solver. Qed.

Lemma union_kinded_abs {A} mkv (v2 : A) :
  union_kinded (pair WITH <$> mkv) (Some (ABS, v2)) = Some (ABS, v2).
Proof. by destruct mkv. Qed.

Lemma union_kinded_with {A} (v : A) mkv2 :
  union_kinded (Some (WITH, v)) (pair WITH <$> mkv2) = Some (WITH, v).
Proof. by destruct mkv2. Qed.