aneris.aneris_lang.adequacy
From iris.algebra Require Import auth.
From iris.proofmode Require Import tactics.
From iris.program_logic Require Export weakestpre adequacy.
From aneris.aneris_lang Require Export lang resources state_interp network.
Set Default Proof Using "Type".
Import Network.
Theorem adequacy `{anerisPreG Σ} IPs A s e ip σ φ :
(∀ `{anerisG Σ}, ⊢ |={⊤}=> ∃ (f : socket_address → socket_interp Σ),
fixed A -∗ ([∗ set] a ∈ A, a ⤇ (f a)) -∗
([∗ set] i ∈ IPs, free_ip i) -∗ is_node ip -∗
WP (mkExpr ip e) @ s; ⊤ {{v, ⌜φ v⌝ }}) →
ip ∉ IPs →
dom (gset ip_address) (state_ports_in_use σ) = IPs →
(∀ ip, ip ∈ IPs → state_ports_in_use σ !! ip = Some ∅) →
(∀ a, a ∈ A → ip_of_address a ∈ IPs) →
state_heaps σ = {[ip:=∅]} →
state_sockets σ = {[ip:=∅]} →
state_ms σ = ∅ →
adequate s (mkExpr ip e) σ (λ v _, φ v).
Proof.
intros Hwp Hipdom Hpiiu Hip Hfixdom Hste Hsce Hmse.
eapply (wp_adequacy _ _); iIntros (??) "/=".
iMod node_gnames_auth_init as (γmp) "Hmp".
iMod saved_si_init as (γsi) "[Hsi Hsi']".
iMod (fixed_init A) as (γsif) "#Hsif".
iMod (free_ips_init IPs) as (γips) "[HIPsCtx HIPs]".
iMod free_ports_auth_init as (γpiu) "HPiu".
set (dg :=
{|
aneris_node_gnames_name := γmp;
aneris_si_name := γsi;
aneris_fixed_name := γsif;
aneris_freeips_name := γips;
aneris_freeports_name := γpiu;
|}).
iMod (Hwp dg) as (f) "Hwp".
iMod (saved_si_update A with "[$Hsi $Hsi']") as (M HMfs) "[HM #Hsa]".
assert (dom (gset _) M = A) as Hdmsi.
{ apply elem_of_equiv_L => ?.
split; intros ?%elem_of_elements;
apply elem_of_elements; [by rewrite -HMfs|].
by rewrite HMfs. }
iAssert ([∗ set] s ∈ A, s ⤇ f s)%I as "#Hsa'".
{ rewrite -Hdmsi -!big_sepM_dom.
iApply (big_sepM_mono with "[$Hsa]"); simpl; auto.
iIntros (? ? Hx) "[? ?]"; iExists _; iFrame. }
iMod (node_ctx_init ∅ ∅) as (γn) "[Hh Hs]".
iMod (node_gnames_alloc γn _ ip with "[$]") as "[Hmp #Hγn]"; [done|].
iAssert (is_node ip) as "Hn".
{ iExists _. eauto. }
iModIntro.
iExists (λ σ _, aneris_state_interp σ), (λ _, True)%I.
iSplitR "Hwp HIPs"; last first.
{ iApply ("Hwp" with "Hsif Hsa' HIPs Hn"). }
by iApply (@aneris_state_interp_init _ dg
with "Hmp Hγn Hh Hs Hsif HM Hsa' HIPsCtx HPiu").
Qed.
Definition safe e σ := @adequate aneris_lang NotStuck e σ (λ _ _, True).
Theorem adequacy_safe `{anerisPreG Σ} IPs A e ip σ :
(∀ `{anerisG Σ}, ⊢ |={⊤}=> ∃ (f : socket_address → socket_interp Σ),
fixed A -∗ ([∗ set] a ∈ A, a ⤇ (f a)) -∗
([∗ set] i ∈ IPs, free_ip i) -∗ is_node ip -∗
WP (mkExpr ip e) {{v, True }}) →
ip ∉ IPs →
dom (gset ip_address) (state_ports_in_use σ) = IPs →
(∀ ip, ip ∈ IPs → state_ports_in_use σ !! ip = Some ∅) →
(∀ a, a ∈ A → ip_of_address a ∈ IPs) →
state_heaps σ = {[ip:=∅]} →
state_sockets σ = {[ip:=∅]} →
state_ms σ = ∅ →
safe (mkExpr ip e) σ.
Proof. apply adequacy. Qed.
Theorem adequacy_hoare `{anerisPreG Σ} IPs A e σ φ ip :
(∀ `{anerisG Σ}, ⊢ ∃ (f : socket_address → socket_interp Σ),
{{{ fixed A ∗ ([∗ set] a ∈ A, a ⤇ (f a)) ∗ ([∗ set] ip ∈ IPs, free_ip ip) ∗ is_node ip }}}
(mkExpr ip e)
{{{ v, RET v; ⌜φ v⌝ }}}) →
ip ∉ IPs →
dom (gset ip_address) (state_ports_in_use σ) = IPs →
(∀ i, i ∈ IPs → state_ports_in_use σ !! i = Some ∅) →
(∀ a, a ∈ A → ip_of_address a ∈ IPs) →
state_heaps σ = {[ip:=∅]} →
state_sockets σ = {[ip:=∅]} →
state_ms σ = ∅ →
adequate NotStuck (mkExpr ip e) σ (λ v _, φ v).
Proof.
intros Hwp ???????.
eapply adequacy; [|done..].
intros ?. iModIntro.
iDestruct Hwp as (f) "#Hwp".
iExists f. iIntros "????".
iApply ("Hwp" with "[$]"); auto.
Qed.
From iris.proofmode Require Import tactics.
From iris.program_logic Require Export weakestpre adequacy.
From aneris.aneris_lang Require Export lang resources state_interp network.
Set Default Proof Using "Type".
Import Network.
Theorem adequacy `{anerisPreG Σ} IPs A s e ip σ φ :
(∀ `{anerisG Σ}, ⊢ |={⊤}=> ∃ (f : socket_address → socket_interp Σ),
fixed A -∗ ([∗ set] a ∈ A, a ⤇ (f a)) -∗
([∗ set] i ∈ IPs, free_ip i) -∗ is_node ip -∗
WP (mkExpr ip e) @ s; ⊤ {{v, ⌜φ v⌝ }}) →
ip ∉ IPs →
dom (gset ip_address) (state_ports_in_use σ) = IPs →
(∀ ip, ip ∈ IPs → state_ports_in_use σ !! ip = Some ∅) →
(∀ a, a ∈ A → ip_of_address a ∈ IPs) →
state_heaps σ = {[ip:=∅]} →
state_sockets σ = {[ip:=∅]} →
state_ms σ = ∅ →
adequate s (mkExpr ip e) σ (λ v _, φ v).
Proof.
intros Hwp Hipdom Hpiiu Hip Hfixdom Hste Hsce Hmse.
eapply (wp_adequacy _ _); iIntros (??) "/=".
iMod node_gnames_auth_init as (γmp) "Hmp".
iMod saved_si_init as (γsi) "[Hsi Hsi']".
iMod (fixed_init A) as (γsif) "#Hsif".
iMod (free_ips_init IPs) as (γips) "[HIPsCtx HIPs]".
iMod free_ports_auth_init as (γpiu) "HPiu".
set (dg :=
{|
aneris_node_gnames_name := γmp;
aneris_si_name := γsi;
aneris_fixed_name := γsif;
aneris_freeips_name := γips;
aneris_freeports_name := γpiu;
|}).
iMod (Hwp dg) as (f) "Hwp".
iMod (saved_si_update A with "[$Hsi $Hsi']") as (M HMfs) "[HM #Hsa]".
assert (dom (gset _) M = A) as Hdmsi.
{ apply elem_of_equiv_L => ?.
split; intros ?%elem_of_elements;
apply elem_of_elements; [by rewrite -HMfs|].
by rewrite HMfs. }
iAssert ([∗ set] s ∈ A, s ⤇ f s)%I as "#Hsa'".
{ rewrite -Hdmsi -!big_sepM_dom.
iApply (big_sepM_mono with "[$Hsa]"); simpl; auto.
iIntros (? ? Hx) "[? ?]"; iExists _; iFrame. }
iMod (node_ctx_init ∅ ∅) as (γn) "[Hh Hs]".
iMod (node_gnames_alloc γn _ ip with "[$]") as "[Hmp #Hγn]"; [done|].
iAssert (is_node ip) as "Hn".
{ iExists _. eauto. }
iModIntro.
iExists (λ σ _, aneris_state_interp σ), (λ _, True)%I.
iSplitR "Hwp HIPs"; last first.
{ iApply ("Hwp" with "Hsif Hsa' HIPs Hn"). }
by iApply (@aneris_state_interp_init _ dg
with "Hmp Hγn Hh Hs Hsif HM Hsa' HIPsCtx HPiu").
Qed.
Definition safe e σ := @adequate aneris_lang NotStuck e σ (λ _ _, True).
Theorem adequacy_safe `{anerisPreG Σ} IPs A e ip σ :
(∀ `{anerisG Σ}, ⊢ |={⊤}=> ∃ (f : socket_address → socket_interp Σ),
fixed A -∗ ([∗ set] a ∈ A, a ⤇ (f a)) -∗
([∗ set] i ∈ IPs, free_ip i) -∗ is_node ip -∗
WP (mkExpr ip e) {{v, True }}) →
ip ∉ IPs →
dom (gset ip_address) (state_ports_in_use σ) = IPs →
(∀ ip, ip ∈ IPs → state_ports_in_use σ !! ip = Some ∅) →
(∀ a, a ∈ A → ip_of_address a ∈ IPs) →
state_heaps σ = {[ip:=∅]} →
state_sockets σ = {[ip:=∅]} →
state_ms σ = ∅ →
safe (mkExpr ip e) σ.
Proof. apply adequacy. Qed.
Theorem adequacy_hoare `{anerisPreG Σ} IPs A e σ φ ip :
(∀ `{anerisG Σ}, ⊢ ∃ (f : socket_address → socket_interp Σ),
{{{ fixed A ∗ ([∗ set] a ∈ A, a ⤇ (f a)) ∗ ([∗ set] ip ∈ IPs, free_ip ip) ∗ is_node ip }}}
(mkExpr ip e)
{{{ v, RET v; ⌜φ v⌝ }}}) →
ip ∉ IPs →
dom (gset ip_address) (state_ports_in_use σ) = IPs →
(∀ i, i ∈ IPs → state_ports_in_use σ !! i = Some ∅) →
(∀ a, a ∈ A → ip_of_address a ∈ IPs) →
state_heaps σ = {[ip:=∅]} →
state_sockets σ = {[ip:=∅]} →
state_ms σ = ∅ →
adequate NotStuck (mkExpr ip e) σ (λ v _, φ v).
Proof.
intros Hwp ???????.
eapply adequacy; [|done..].
intros ?. iModIntro.
iDestruct Hwp as (f) "#Hwp".
iExists f. iIntros "????".
iApply ("Hwp" with "[$]"); auto.
Qed.