1 | |
---|
2 | include "utilities/extralib.ma". |
---|
3 | include "common/IOMonad.ma". |
---|
4 | include "common/Integers.ma". |
---|
5 | include "common/Events.ma". |
---|
6 | include "common/Mem.ma". |
---|
7 | |
---|
8 | record execstep (outty:Type[0]) (inty:outty → Type[0]) : Type[1] ≝ |
---|
9 | { genv : Type[0] |
---|
10 | ; state : Type[0] |
---|
11 | ; is_final : state → option int |
---|
12 | ; mem_of_state : state → mem |
---|
13 | ; step : genv → state → IO outty inty (trace×state) |
---|
14 | }. |
---|
15 | |
---|
16 | let rec repeat (n:nat) (outty:Type[0]) (inty:outty → Type[0]) (exec:execstep outty inty) |
---|
17 | (g:genv ?? exec) (s:state ?? exec) |
---|
18 | : IO outty inty (trace × (state ?? exec)) ≝ |
---|
19 | match n with |
---|
20 | [ O ⇒ Value ??? 〈E0, s〉 |
---|
21 | | S n' ⇒ ! 〈t1,s1〉 ← step ?? exec g s; |
---|
22 | repeat n' ?? exec g s1 |
---|
23 | ]. |
---|
24 | |
---|
25 | (* A (possibly non-terminating) execution. *) |
---|
26 | coinductive execution (state:Type[0]) (output:Type[0]) (input:output → Type[0]) : Type[0] ≝ |
---|
27 | | e_stop : trace → int → mem → execution state output input |
---|
28 | | e_step : trace → state → execution state output input → execution state output input |
---|
29 | | e_wrong : execution state output input |
---|
30 | | e_interact : ∀o:output. (input o → execution state output input) → execution state output input. |
---|
31 | |
---|
32 | (* This definition is slightly awkward because of the need to provide resumptions. |
---|
33 | It records the last trace/state passed in, then recursively processes the next |
---|
34 | state. *) |
---|
35 | |
---|
36 | let corec exec_inf_aux (output:Type[0]) (input:output → Type[0]) |
---|
37 | (exec:execstep output input) (ge:genv ?? exec) |
---|
38 | (s:IO output input (trace×(state ?? exec))) |
---|
39 | : execution ??? ≝ |
---|
40 | match s with |
---|
41 | [ Wrong ⇒ e_wrong ??? |
---|
42 | | Value v ⇒ match v with [ pair t s' ⇒ |
---|
43 | match is_final ?? exec s' with |
---|
44 | [ Some r ⇒ e_stop ??? t r (mem_of_state ?? exec s') |
---|
45 | | None ⇒ e_step ??? t s' (exec_inf_aux ??? ge (step ?? exec ge s')) ] ] |
---|
46 | | Interact out k' ⇒ e_interact ??? out (λv. exec_inf_aux ??? ge (k' v)) |
---|
47 | ]. |
---|
48 | |
---|
49 | lemma execution_cases: ∀o,i,s.∀e:execution s o i. |
---|
50 | e = match e with [ e_stop tr r m ⇒ e_stop ??? tr r m |
---|
51 | | e_step tr s e ⇒ e_step ??? tr s e |
---|
52 | | e_wrong ⇒ e_wrong ??? | e_interact o k ⇒ e_interact ??? o k ]. |
---|
53 | #o #i #s #e cases e; //; qed. |
---|
54 | |
---|
55 | axiom exec_inf_aux_unfold: ∀o,i,exec,ge,s. exec_inf_aux o i exec ge s = |
---|
56 | match s with |
---|
57 | [ Wrong ⇒ e_wrong ??? |
---|
58 | | Value v ⇒ match v with [ pair t s' ⇒ |
---|
59 | match is_final ?? exec s' with |
---|
60 | [ Some r ⇒ e_stop ??? t r (mem_of_state ?? exec s') |
---|
61 | | None ⇒ e_step ??? t s' (exec_inf_aux ??? ge (step ?? exec ge s')) ] ] |
---|
62 | | Interact out k' ⇒ e_interact ??? out (λv. exec_inf_aux ??? ge (k' v)) |
---|
63 | ]. |
---|
64 | (* |
---|
65 | #exec #ge #s >(execution_cases ? (exec_inf_aux …)) cases s |
---|
66 | [ #o #k |
---|
67 | | #x cases x #tr #s' (* XXX Can't unfold exec_inf_aux here *) |
---|
68 | | ] |
---|
69 | whd in ⊢ (??%%); //; |
---|
70 | qed. |
---|
71 | *) |
---|
72 | |
---|
73 | record fullexec (outty:Type[0]) (inty:outty → Type[0]) : Type[1] ≝ |
---|
74 | { es1 :> execstep outty inty |
---|
75 | ; program : Type[0] |
---|
76 | ; make_initial_state : program → res (genv ?? es1 × (state ?? es1)) |
---|
77 | }. |
---|
78 | |
---|
79 | definition exec_inf : ∀o,i.∀fx:fullexec o i. ∀p:program ?? fx. execution (state ?? fx) o i ≝ |
---|
80 | λo,i,fx,p. |
---|
81 | match make_initial_state ?? fx p with |
---|
82 | [ OK gs ⇒ exec_inf_aux ?? fx (\fst gs) (Value … 〈E0,\snd gs〉) |
---|
83 | | _ ⇒ e_wrong ??? |
---|
84 | ]. |
---|
85 | |
---|
86 | |
---|
87 | record execstep' (outty:Type[0]) (inty:outty → Type[0]) : Type[1] ≝ |
---|
88 | { es0 :> execstep outty inty |
---|
89 | ; initial : state ?? es0 → Prop |
---|
90 | }. |
---|
91 | |
---|
92 | |
---|
93 | alias symbol "and" (instance 2) = "logical and". |
---|
94 | record related_semantics : Type[1] ≝ |
---|
95 | { output : Type[0] |
---|
96 | ; input : output → Type[0] |
---|
97 | ; sem1 : execstep' output input |
---|
98 | ; sem2 : execstep' output input |
---|
99 | ; ge1 : genv ?? sem1 |
---|
100 | ; ge2 : genv ?? sem2 |
---|
101 | ; match_states : state ?? sem1 → state ?? sem2 → Prop |
---|
102 | ; match_initial_states : ∀st1. (initial ?? sem1) st1 → ∃st2. (initial ?? sem2) st2 ∧ match_states st1 st2 |
---|
103 | ; match_final_states : ∀st1,st2,r. match_states st1 st2 → (is_final ?? sem1) st1 = Some ? r → (is_final ?? sem2) st2 = Some ? r |
---|
104 | }. |
---|
105 | |
---|
106 | |
---|
107 | |
---|
108 | record simulation : Type[1] ≝ |
---|
109 | { sems :> related_semantics |
---|
110 | ; sim : ∀st1,st2,t,st1'. |
---|
111 | P_io' ?? (trace × (state ?? (sem1 sems))) (λr. r = 〈t,st1'〉) (step ?? (sem1 sems) (ge1 sems) st1) → |
---|
112 | match_states sems st1 st2 → |
---|
113 | ∃st2':(state ?? (sem2 sems)).(∃n:nat.P_io' ?? (trace × (state ?? (sem2 sems))) (λr. r = 〈t,st2'〉) (repeat n ?? (sem2 sems) (ge2 sems) st2)) ∧ |
---|
114 | match_states sems st1' st2' |
---|
115 | }. |
---|