|
|
|
@ -0,0 +1,140 @@
|
|
|
|
|
From stdpp Require Import gmap base relations.
|
|
|
|
|
From iris Require Import prelude.
|
|
|
|
|
From semantics.lib Require Export debruijn.
|
|
|
|
|
From semantics.ts.systemf Require Import lang notation parallel_subst types bigstep tactics.
|
|
|
|
|
From semantics.ts.systemf Require logrel binary_logrel.
|
|
|
|
|
From Equations Require Import Equations.
|
|
|
|
|
|
|
|
|
|
(** * Existential types and invariants *)
|
|
|
|
|
Implicit Types
|
|
|
|
|
(Δ : nat)
|
|
|
|
|
(Γ : typing_context)
|
|
|
|
|
(v : val)
|
|
|
|
|
(α : var)
|
|
|
|
|
(e : expr)
|
|
|
|
|
(A : type).
|
|
|
|
|
|
|
|
|
|
(** Here, we take the approach of encoding [assert],
|
|
|
|
|
instead of adding it as a primitive to the language.
|
|
|
|
|
This saves us from adding it to all of the existing proofs.
|
|
|
|
|
But clearly it has the same reduction behavior.
|
|
|
|
|
*)
|
|
|
|
|
|
|
|
|
|
Definition assert (e : expr) : expr :=
|
|
|
|
|
if: e then #LitUnit else (#0 #0).
|
|
|
|
|
Lemma assert_true : rtc contextual_step (assert #true) #().
|
|
|
|
|
Proof.
|
|
|
|
|
econstructor.
|
|
|
|
|
{ eapply base_contextual_step. constructor. }
|
|
|
|
|
constructor.
|
|
|
|
|
Qed.
|
|
|
|
|
Lemma assert_false : rtc contextual_step (assert #false) (#0 #0).
|
|
|
|
|
Proof.
|
|
|
|
|
econstructor. { eapply base_contextual_step. econstructor. }
|
|
|
|
|
constructor.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Definition Or (e1 e2 : expr) : expr :=
|
|
|
|
|
if: e1 then #true else e2.
|
|
|
|
|
Definition And (e1 e2 : expr) : expr :=
|
|
|
|
|
if: e1 then e2 else #false.
|
|
|
|
|
Notation "e1 '||' e2" := (Or e1 e2) : expr_scope.
|
|
|
|
|
Notation "e1 '&&' e2" := (And e1 e2) : expr_scope.
|
|
|
|
|
|
|
|
|
|
(** *** BIT *)
|
|
|
|
|
(* ∃ α, { bit : α, flip : α → α, get : α → bool } *)
|
|
|
|
|
Definition BIT : type := ∃: (#0 × (#0 → #0)) × (#0 → Bool).
|
|
|
|
|
|
|
|
|
|
Definition MyBit : val :=
|
|
|
|
|
pack (#0, (* bit *)
|
|
|
|
|
λ: "x", #1 - "x", (* flip *)
|
|
|
|
|
λ: "x", #0 < "x"). (* get *)
|
|
|
|
|
|
|
|
|
|
Lemma MyBit_typed n Γ :
|
|
|
|
|
TY n; Γ ⊢ MyBit : BIT.
|
|
|
|
|
Proof. eapply (typed_pack _ _ _ Int); solve_typing. Qed.
|
|
|
|
|
|
|
|
|
|
Definition MyBit_instrumented : val :=
|
|
|
|
|
pack (#0, (* bit *)
|
|
|
|
|
λ: "x", assert (("x" = #0) || ("x" = #1));; #1 - "x", (* flip *)
|
|
|
|
|
λ: "x", assert (("x" = #0) || ("x" = #1));; #0 < "x"). (* get *)
|
|
|
|
|
|
|
|
|
|
Definition MyBoolBit : val :=
|
|
|
|
|
pack (#false, (* bit *)
|
|
|
|
|
λ: "x", UnOp NegOp "x", (* flip *)
|
|
|
|
|
λ: "x", "x"). (* get *)
|
|
|
|
|
|
|
|
|
|
Lemma MyBoolBit_typed n Γ :
|
|
|
|
|
TY n; Γ ⊢ MyBoolBit : BIT.
|
|
|
|
|
Proof.
|
|
|
|
|
eapply (typed_pack _ _ _ Bool); solve_typing.
|
|
|
|
|
simpl. econstructor.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Section unary_mybit.
|
|
|
|
|
Import logrel.
|
|
|
|
|
|
|
|
|
|
Lemma MyBit_instrumented_sem_typed δ :
|
|
|
|
|
𝒱 BIT δ MyBit_instrumented.
|
|
|
|
|
Proof.
|
|
|
|
|
unfold BIT. simp type_interp.
|
|
|
|
|
eexists. split; first done.
|
|
|
|
|
pose_sem_type (λ x, x = #0 ∨ x = #1) as τ.
|
|
|
|
|
{ intros v [-> | ->]; done. }
|
|
|
|
|
exists τ.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
eexists _, _. split; first done.
|
|
|
|
|
split.
|
|
|
|
|
- simp type_interp. eexists _, _. split; first done. split.
|
|
|
|
|
+ simp type_interp. simpl. by left.
|
|
|
|
|
+ simp type_interp. eexists _, _. split; first done. split; first done.
|
|
|
|
|
intros v'. simp type_interp; simpl.
|
|
|
|
|
(* Note: this part of the proof is a bit different from the paper version, as we directly do a case split. *)
|
|
|
|
|
intros [-> | ->].
|
|
|
|
|
* exists #1. split; last simp type_interp; simpl; eauto.
|
|
|
|
|
bs_steps_det. eapply bs_if_true; bs_steps_det.
|
|
|
|
|
eapply bs_if_true; bs_steps_det.
|
|
|
|
|
* exists #0. split; last simp type_interp; simpl; eauto.
|
|
|
|
|
bs_steps_det. eapply bs_if_true; bs_steps_det.
|
|
|
|
|
eapply bs_if_false; bs_steps_det.
|
|
|
|
|
- simp type_interp. eexists _, _. split; first done. split; first done.
|
|
|
|
|
intros v'. simp type_interp; simpl. intros [-> | ->].
|
|
|
|
|
* exists #false. split; last simp type_interp; simpl; eauto.
|
|
|
|
|
bs_steps_det. eapply bs_if_true; bs_steps_det. eapply bs_if_true; bs_steps_det.
|
|
|
|
|
* exists #true. split; last simp type_interp; simpl; eauto.
|
|
|
|
|
bs_steps_det. eapply bs_if_true; bs_steps_det. eapply bs_if_false; bs_steps_det.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
End unary_mybit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Section binary_mybit.
|
|
|
|
|
Import binary_logrel.
|
|
|
|
|
|
|
|
|
|
Lemma MyBit_MyBoolBit_sem_typed δ :
|
|
|
|
|
𝒱 BIT δ MyBit MyBoolBit.
|
|
|
|
|
Proof.
|
|
|
|
|
unfold BIT. simp type_interp.
|
|
|
|
|
eexists _, _. split_and!; try done.
|
|
|
|
|
pose_sem_type (λ v w, (v = #0 ∧ w = #false) ∨ (v = #1 ∧ w = #true)) as τ.
|
|
|
|
|
{ intros v w [[-> ->] | [-> ->]]; done. }
|
|
|
|
|
exists τ.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
eexists _, _, _, _. split_and!; try done.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
eexists _, _, _, _. split_and!; try done.
|
|
|
|
|
- simp type_interp. simpl. naive_solver.
|
|
|
|
|
- simp type_interp. eexists _, _, _, _. split_and!; try done.
|
|
|
|
|
intros v w. simp type_interp. simpl.
|
|
|
|
|
intros [[-> ->]|[-> ->]]; simpl; eexists _, _; split_and!; eauto; simpl.
|
|
|
|
|
all: simp type_interp; simpl; naive_solver.
|
|
|
|
|
- simp type_interp. eexists _, _, _, _. split_and!; try done.
|
|
|
|
|
intros v w. simp type_interp. simpl.
|
|
|
|
|
intros [[-> ->]|[-> ->]]; simpl.
|
|
|
|
|
all: eexists _, _; split_and!; eauto; simpl.
|
|
|
|
|
all: simp type_interp; eauto.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
End binary_mybit.
|