1 | (**************************************************************************) |
---|
2 | (* ___ *) |
---|
3 | (* ||M|| *) |
---|
4 | (* ||A|| A project by Andrea Asperti *) |
---|
5 | (* ||T|| *) |
---|
6 | (* ||I|| Developers: *) |
---|
7 | (* ||T|| The HELM team. *) |
---|
8 | (* ||A|| http://helm.cs.unibo.it *) |
---|
9 | (* \ / *) |
---|
10 | (* \ / This file is distributed under the terms of the *) |
---|
11 | (* v GNU General Public License Version 2 *) |
---|
12 | (* *) |
---|
13 | (**************************************************************************) |
---|
14 | |
---|
15 | include "variable.ma". |
---|
16 | |
---|
17 | inductive guard_combinators : Type[0] ≝ |
---|
18 | | push_var: variable → guard_combinators |
---|
19 | | push_const : DeqNat → guard_combinators |
---|
20 | | push_plus : guard_combinators |
---|
21 | | push_minus : guard_combinators |
---|
22 | | push_eq : guard_combinators |
---|
23 | | push_not : guard_combinators. |
---|
24 | |
---|
25 | definition eq_guard_combinator : guard_combinators → guard_combinators → bool ≝ |
---|
26 | λx.match x with |
---|
27 | [ push_var v1⇒ λy.match y with [push_var v2 ⇒ eqb v1 v2 | _ ⇒ false] |
---|
28 | | push_const n1 ⇒ λy.match y with [push_const n2 ⇒ eqb n1 n2 | _ ⇒ false] |
---|
29 | | push_plus ⇒ λy.match y with [push_plus ⇒ true | _ ⇒ false ] |
---|
30 | | push_minus ⇒ λy.match y with [push_minus ⇒ true | _⇒ false ] |
---|
31 | | push_eq ⇒ λy.match y with [push_eq ⇒ true | _ ⇒ false ] |
---|
32 | | push_not ⇒ λy.match y with [push_not ⇒ true | _ ⇒ false ] |
---|
33 | ]. |
---|
34 | |
---|
35 | lemma eq_guard_combinator_elim : ∀P : bool → Prop. |
---|
36 | ∀c1,c2.(c1 = c2 → P true) → (c1 ≠ c2 → P false) → |
---|
37 | P(eq_guard_combinator c1 c2). |
---|
38 | #P * |
---|
39 | [#v1 | #n1 ] |
---|
40 | * |
---|
41 | [1,7,13,19,25,31: #v2 |2,8,14,20,26,32: #n2] |
---|
42 | normalize #H1 #H2 try @H1 try @H2 // |
---|
43 | try(% #EQ destruct) |
---|
44 | [ @(eqb_elim … v1 v2) [#EQ destruct @H1 % | * #H @H2 % #EQ destruct @H %] |
---|
45 | | @(eqb_elim … n1 n2) [#EQ destruct @H1 % | * #H @H2 % #EQ destruct @H %] |
---|
46 | ] |
---|
47 | qed. |
---|
48 | |
---|
49 | inductive stack_seq:Type[0]≝ |
---|
50 | | pop_Ass: variable → stack_seq |
---|
51 | | push : guard_combinators → stack_seq. |
---|
52 | |
---|
53 | definition eq_stack_seq : stack_seq → stack_seq → bool ≝ |
---|
54 | λx.match x with |
---|
55 | [ pop_Ass v1 ⇒ λy.match y with [pop_Ass v2 ⇒ eqb v1 v2 | _ ⇒ false ] |
---|
56 | | push c1 ⇒ λy.match y with [push c2 ⇒ eq_guard_combinator c1 c2 | _ ⇒ false] |
---|
57 | ]. |
---|
58 | |
---|
59 | lemma eq_stack_seq_elim : ∀P : bool → Prop. |
---|
60 | ∀x1,x2.(x1 = x2 → P true) → (x1 ≠ x2 → P false) → |
---|
61 | P(eq_stack_seq x1 x2). |
---|
62 | #P * [#v1 | #c1] * [1,3: #v2 |*: #c2] #H1 #H2 try(@H2 % #EQ destruct) |
---|
63 | [ normalize @(eqb_elim … v1 v2) [ #EQ destruct @H1 % | * #H @H2 % #EQ destruct @H %] |
---|
64 | | whd in match eq_stack_seq; normalize nodelta @eq_guard_combinator_elim /2/ |
---|
65 | * #H @H2 % #EQ destruct @H % |
---|
66 | ] |
---|
67 | qed. |
---|
68 | |
---|
69 | definition DeqStackSeq ≝ mk_DeqSet stack_seq eq_stack_seq ?. |
---|
70 | @hide_prf #x #y @eq_stack_seq_elim |
---|
71 | [ #EQ destruct % // | * #H % [ #EQ destruct | #EQ destruct cases(H (refl …)) ] |
---|
72 | qed. |
---|
73 | |
---|
74 | definition DeqGuardCombinator ≝ mk_DeqSet guard_combinators eq_guard_combinator ?. |
---|
75 | @hide_prf #x #y @eq_guard_combinator_elim |
---|
76 | [ #EQ destruct % // | * #H % [ #EQ destruct | #EQ destruct cases(H (refl …)) ] |
---|
77 | qed. |
---|
78 | |
---|
79 | definition stack_instr_params ≝ mk_instr_params DeqStackSeq (mk_DeqSet io_i io_i_eq io_i_eq_equality) |
---|
80 | (mk_DeqSet unit (λ_.λ_.true) ?) (DeqSet_List DeqGuardCombinator) variable (mk_DeqSet unit (λ_.λ_.true) ?). |
---|
81 | @hide_prf ** % // qed. |
---|
82 | |
---|
83 | definition stack_state_params:state_params≝ |
---|
84 | mk_state_params stack_instr_params imp_env_params flat_labels frame_store_t (*DeqEnv*). |
---|
85 | |
---|
86 | definition push : (store_type stack_state_params) → DeqNat → option (store_type stack_state_params) ≝ |
---|
87 | λs,n.match \fst s with |
---|
88 | [nil ⇒ None ? |
---|
89 | |cons x xs ⇒ return 〈〈(n::(\fst x)),\snd x〉 :: xs,\snd s〉 |
---|
90 | ]. |
---|
91 | |
---|
92 | definition pop : (store_type stack_state_params) → option (DeqNat × (store_type stack_state_params)) ≝ |
---|
93 | λs.match \fst s with |
---|
94 | [nil ⇒ None ? |
---|
95 | |cons x xs ⇒ match \fst x with |
---|
96 | [ nil ⇒ None ? |
---|
97 | | cons y ys ⇒ return 〈y,〈〈ys,\snd x〉::xs,\snd s〉〉 |
---|
98 | ] |
---|
99 | ]. |
---|
100 | |
---|
101 | definition eval_combinators : guard_combinators → (store_type stack_state_params)→ option (store_type stack_state_params)≝ |
---|
102 | λc,s.match c with |
---|
103 | [ push_var x ⇒ ! curr_env ← frame_current_env s; |
---|
104 | ! n ← read_frame curr_env (to_shift+x) O; |
---|
105 | push s n |
---|
106 | | push_const n ⇒ push s n |
---|
107 | | push_plus ⇒ ! 〈val1,st1〉 ← pop s; ! 〈val2,st2〉 ← pop st1; push st2 (val1 + val2) |
---|
108 | | push_minus ⇒ ! 〈val1,st1〉 ← pop s; ! 〈val2,st2〉 ← pop st1; push st2 (val1 - val2) |
---|
109 | | push_eq ⇒ ! 〈val1,st1〉 ← pop s; ! 〈val2,st2〉 ← pop st1; push st2 (if eqb val1 val2 then 1 else O) |
---|
110 | | push_not ⇒ ! 〈val1,st1〉 ← pop s;push st1 (1-val1) |
---|
111 | ]. |
---|
112 | |
---|
113 | |
---|
114 | definition stack_eval_seq: (seq_instr stack_state_params)→(store_type stack_state_params)→ option (store_type stack_state_params)≝ |
---|
115 | λi,s.match i with |
---|
116 | [ pop_Ass v ⇒ ! 〈val1,st1〉 ← pop s;frame_assign_var st1 (to_shift +v) val1 |
---|
117 | | push c ⇒ eval_combinators c s |
---|
118 | ]. |
---|
119 | |
---|
120 | definition stack_eval_cond_cond: |
---|
121 | (list guard_combinators) → (store_type stack_state_params)→ option (bool × (store_type stack_state_params))≝ |
---|
122 | λl,st.! fin_St ← m_fold Option … eval_combinators l st; |
---|
123 | !〈val,st2〉← pop fin_St; |
---|
124 | return 〈eqb val 1,st2〉. |
---|
125 | |
---|
126 | |
---|
127 | definition stack_eval_call:(signature stack_state_params stack_state_params)→ act_params_type stack_state_params → |
---|
128 | frame_store_t → (option frame_store_t)≝ |
---|
129 | λsgn,var,st. |
---|
130 | match sgn with |
---|
131 | [ mk_signature fun fpt rt ⇒ |
---|
132 | !〈n,st1〉 ← pop st; |
---|
133 | frame_assign_var 〈(〈(nil ?),var〉::(\fst st1)),(\snd st1)〉 fpt n |
---|
134 | ]. |
---|
135 | |
---|
136 | definition stack_return_call:frame_store_t→ (option frame_store_t)≝ |
---|
137 | λs.match (\fst s) with |
---|
138 | [nil⇒ None ? |
---|
139 | |cons hd tl⇒ let 〈env,v〉≝ hd in |
---|
140 | !〈n,st1〉 ← pop s; |
---|
141 | frame_assign_var 〈tl,\snd s〉 v n |
---|
142 | ]. |
---|
143 | |
---|
144 | |
---|
145 | |
---|
146 | definition stack_sem_state_params : sem_state_params stack_state_params ≝ mk_sem_state_params stack_state_params stack_eval_seq frame_eval_io |
---|
147 | (λ_.stack_eval_cond_cond (nil ?)) stack_eval_cond_cond stack_eval_call (λ_.stack_return_call) frame_init_store. |
---|
148 | |
---|
149 | (* Abitare tipo Instructions *) |
---|
150 | |
---|
151 | definition stack_Instructions≝Instructions stack_state_params flat_labels. |
---|
152 | |
---|
153 | definition stack_signature≝signature stack_state_params stack_state_params. |
---|
154 | |
---|
155 | |
---|
156 | definition stack_envitem≝ (env_item imp_env_params stack_instr_params flat_labels). |
---|