You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
semantics-2023/theories/type_systems/systemf/existential_invariants.v

141 lines
4.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.