-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathExample2.agda
123 lines (112 loc) · 5.47 KB
/
Example2.agda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module ExamplePrograms.Demo.Example2 where
open import Data.Unit
open import Data.List
open import Data.Bool renaming (Bool to 𝔹)
open import Data.Product using (_×_; ∃-syntax; proj₁; proj₂) renaming (_,_ to ⟨_,_⟩)
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
open import Common.Utils
open import Common.Types
open import Common.BlameLabels
open import Surface.SurfaceLang
open import CC.CCStatics renaming (Term to CCTerm;
`_ to var; $_of_ to const_of_; ƛ⟦_⟧_˙_of_ to lam⟦_⟧_˙_of_; !_ to *_)
open import CC.Compile
open import CC.Reduction
open import CC.MultiStep
open import CC.BigStep
open import Memory.Heap CCTerm Value
open import ExamplePrograms.Demo.Common
{- Input is `true` in N₁ and `false` in N₂ -}
N₁ N₂ : Term
N₁ =
`let ref⟦ low ⟧ ($ true of low) at pos 0 `in
`let if ($ true of high) ∶ ` Bool of ⋆ at pos 1
then (` 0) := $ false of low at pos 2
else (` 0) := $ true of low at pos 3
at pos 4 `in
(publish · (! (` 1)) at pos 5)
N₂ =
`let ref⟦ low ⟧ ($ true of low) at pos 0 `in
`let if ($ false of high) ∶ ` Bool of ⋆ at pos 1
then (` 0) := $ false of low at pos 2
else (` 0) := $ true of low at pos 3
at pos 4 `in
(publish · (! (` 1)) at pos 5)
⊢N₁ : [] ; l low ⊢ᴳ N₁ ⦂ ` Unit of l low
⊢N₁ =
⊢let (⊢ref ⊢const ≲-refl ≾-refl)
(⊢let (⊢if (⊢ann ⊢const (≲-ty ≾-⋆r ≲-ι))
(⊢assign (⊢var refl) ⊢const ≲-refl ≾-refl ≾-⋆l)
(⊢assign (⊢var refl) ⊢const ≲-refl ≾-refl ≾-⋆l)
refl)
(⊢app ⊢publish (⊢deref (⊢var refl)) ≲-refl ≾-refl ≾-refl))
⊢N₂ : [] ; l low ⊢ᴳ N₂ ⦂ ` Unit of l low
⊢N₂ =
⊢let (⊢ref ⊢const ≲-refl ≾-refl)
(⊢let (⊢if (⊢ann ⊢const (≲-ty ≾-⋆r ≲-ι))
(⊢assign (⊢var refl) ⊢const ≲-refl ≾-refl ≾-⋆l)
(⊢assign (⊢var refl) ⊢const ≲-refl ≾-refl ≾-⋆l)
refl)
(⊢app ⊢publish (⊢deref (⊢var refl)) ≲-refl ≾-refl ≾-refl))
𝒞N₁ = compile N₁ ⊢N₁
𝒞N₂ = compile N₂ ⊢N₂
⊢𝒞N₁ = compile-preserve N₁ ⊢N₁
⊢𝒞N₂ = compile-preserve N₂ ⊢N₂
_ :
𝒞N₁ ≡
let c₁ = cast (` Bool of l high) (` Bool of ⋆) (pos 1) (~-ty ~⋆ ~-ι) in
(`let (ref⟦ low ⟧ (const true of low))
(`let (if (const true of high ⟨ c₁ ⟩) _ (var 0 :=? (const false of low)) (var 0 :=? (const true of low)))
(compile {[]} publish ⊢publish · (* var 1))))
_ = refl
{- Both N₁ and N₂ evaluate to `nsu-error` -}
_ : ∃[ μ ] ( 𝒞N₁ ∣ ∅ ∣ low —↠ error nsu-error ∣ μ )
_ = ⟨ _ , R* ⟩
where
R* =
𝒞N₁ ∣ ∅ ∣ low
—→⟨ ξ {F = let□ _} ref-static ⟩
_ ∣ ∅ ∣ low
—→⟨ ξ {F = let□ _} (ref V-const refl) ⟩
_ ∣ ⟨ [ ⟨ 0 , (const true of low) & V-const ⟩ ] , [] ⟩ ∣ low
—→⟨ β-let V-addr ⟩
_ ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (if-cast-true (I-base-inj _)) ⟩
let a = addr a⟦ low ⟧ 0 of low in
let c = cast (` Unit of l high) (` Unit of ⋆) (pos 1) (~-ty ~⋆ ~-ι) in
`let (prot high (cast-pc ⋆ (a :=? (const false of low))) ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ {F = □⟨ _ ⟩} (prot-ctx (ξ {F = cast-pc ⋆ □} (assign?-fail (λ ()) {- high ⋠ low -})))) ⟩
`let (prot high (cast-pc ⋆ (error nsu-error)) ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ {F = □⟨ _ ⟩} (prot-ctx (ξ-err {F = cast-pc ⋆ □}))) ⟩
`let (prot high (error nsu-error) ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ {F = □⟨ _ ⟩} prot-err) ⟩
`let (error nsu-error ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ-err {F = □⟨ _ ⟩}) ⟩
`let (error nsu-error) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ-err {F = let□ _} ⟩
error nsu-error ∣ _ ∣ low ∎
_ : ∃[ μ ] ( 𝒞N₂ ∣ ∅ ∣ low —↠ error nsu-error ∣ μ )
_ = ⟨ _ , R* ⟩
where
R* =
𝒞N₂ ∣ ∅ ∣ low
—→⟨ ξ {F = let□ _} ref-static ⟩
_ ∣ ∅ ∣ low
—→⟨ ξ {F = let□ _} (ref V-const refl) ⟩
_ ∣ ⟨ [ ⟨ 0 , (const true of low) & V-const ⟩ ] , [] ⟩ ∣ low
—→⟨ β-let V-addr ⟩
_ ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (if-cast-false (I-base-inj _)) ⟩
let a = addr a⟦ low ⟧ 0 of low in
let c = cast (` Unit of l high) (` Unit of ⋆) (pos 1) (~-ty ~⋆ ~-ι) in
`let (prot high (cast-pc ⋆ (a :=? (const true of low))) ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ {F = □⟨ _ ⟩} (prot-ctx (ξ {F = cast-pc ⋆ □} (assign?-fail (λ ()) {- high ⋠ low -})))) ⟩
`let (prot high (cast-pc ⋆ (error nsu-error)) ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ {F = □⟨ _ ⟩} (prot-ctx (ξ-err {F = cast-pc ⋆ □}))) ⟩
`let (prot high (error nsu-error) ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ {F = □⟨ _ ⟩} prot-err) ⟩
`let (error nsu-error ⟨ c ⟩) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ {F = let□ _} (ξ-err {F = □⟨ _ ⟩}) ⟩
`let (error nsu-error) (_ · (* a)) ∣ _ ∣ low
—→⟨ ξ-err {F = let□ _} ⟩
error nsu-error ∣ _ ∣ low ∎