@@ -82,85 +82,144 @@ let t_equivS_trans = FApi.t_low3 "equiv-trans" Low.t_equivS_trans_r
82
82
let t_equivF_trans = FApi. t_low3 " equiv-trans" Low. t_equivF_trans_r
83
83
84
84
(* -------------------------------------------------------------------- *)
85
- let process_replace_stmt s p c p1 q1 p2 q2 tc =
85
+ let t_equivS_trans_eq side s tc =
86
+ let env = FApi. tc1_env tc in
86
87
let es = tc1_as_equivS tc in
87
- let ct = match s with `Left -> es.es_sl | `Right -> es.es_sr in
88
- let mt = snd (match s with `Left -> es.es_ml | `Right -> es.es_mr) in
89
- (* Translation of the stmt *)
90
- let regexpstmt = trans_block p in
91
- let map = match RegexpStmt. search regexpstmt ct.s_node with
92
- | None -> Mstr. empty
93
- | Some m -> m in
94
- let c = TTC. tc1_process_prhl_stmt tc s ~map c in
95
- t_equivS_trans (mt, c) (p1, q1) (p2, q2) tc
88
+ let c, m = match side with `Left -> es.es_sl, es.es_ml | `Right -> es.es_sr, es.es_mr in
89
+
90
+ let mem_pre = EcFol. split_sided (EcMemory. memory m) es.es_pr in
91
+ let fv_pr = EcPV.PV. fv env (EcMemory. memory m) es.es_pr in
92
+ let fv_po = EcPV.PV. fv env (fst m) es.es_po in
93
+ let fv_r = EcPV. s_read env c in
94
+ let mk_eqs fv =
95
+ let vfv, gfv = EcPV.PV. elements fv in
96
+ let veq = List. map (fun (x ,ty ) -> f_eq (f_pvar x ty mleft) (f_pvar x ty mright)) vfv in
97
+ let geq = List. map (fun mp -> f_eqglob mp mleft mp mright) gfv in
98
+ f_ands (veq @ geq) in
99
+ let pre = mk_eqs (EcPV.PV. union (EcPV.PV. union fv_pr fv_po) fv_r) in
100
+ let pre = f_and pre (odfl f_true mem_pre) in
101
+ let post = mk_eqs fv_po in
102
+ let c1, c2 =
103
+ if side = `Left then (pre, post), (es.es_pr, es.es_po)
104
+ else (es.es_pr, es.es_po), (pre, post)
105
+ in
106
+
107
+ let exists_subtac (tc : tcenv1 ) =
108
+ (* Ideally these are guaranteed fresh *)
109
+ let pl = EcIdent. create " &p__1" in
110
+ let pr = EcIdent. create " &p__2" in
111
+ let h = EcIdent. create " __" in
112
+ let tc = EcLowGoal. t_intros_i_1 [pl; pr; h] tc in
113
+ let goal = FApi. tc1_goal tc in
114
+
115
+ let p = match side with | `Left -> pl | `Right -> pr in
116
+ let b = match side with | `Left -> true | `Right -> false in
117
+
118
+ let handle_exists () =
119
+ (* Pairing up the correct variables for the exists intro *)
120
+ let vs, fm = EcFol. destr_exists goal in
121
+ let eqs_pre, _ =
122
+ let l, r = EcFol. destr_and fm in
123
+ if b then l, r else r, l
124
+ in
125
+ let eqs, _ = destr_and eqs_pre in
126
+ let eqs = destr_ands ~deep: false eqs in
127
+ let doit eq =
128
+ let l, r = EcFol. destr_eq eq in
129
+ let l, r = if b then r, l else l, r in
130
+ let v = EcFol. destr_local l in
131
+ v, r
132
+ in
133
+ let eqs = List. map doit eqs in
134
+ let exvs =
135
+ List. map
136
+ (fun (id , _ ) ->
137
+ let v = List. assoc id eqs in
138
+ Fsubst. f_subst_mem (EcMemory. memory m) p v)
139
+ vs
140
+ in
141
+
142
+ FApi. as_tcenv1 (EcLowGoal. t_exists_intro_s (List. map paformula exvs) tc)
143
+ in
144
+
145
+ let tc =
146
+ if EcFol. is_exists goal then
147
+ handle_exists ()
148
+ else
149
+ tc
150
+ in
151
+
152
+ FApi. t_seq
153
+ (EcLowGoal. t_generalize_hyp ?clear:(Some `Yes ) h)
154
+ EcHiGoal. process_done
155
+ tc
156
+ in
157
+
158
+ FApi. t_seqsub
159
+ (t_equivS_trans (EcMemory. memtype m, s) c1 c2)
160
+ [exists_subtac; EcHiGoal. process_done; EcLowGoal. t_id; EcLowGoal. t_id]
161
+ tc
96
162
97
163
(* -------------------------------------------------------------------- *)
98
- let process_trans_stmt s c p1 q1 p2 q2 tc =
164
+ let process_trans_stmt tf s ?pat c tc =
165
+ let hyps = FApi. tc1_hyps tc in
99
166
let es = tc1_as_equivS tc in
100
167
let mt = snd (match s with `Left -> es.es_ml | `Right -> es.es_mr) in
168
+
101
169
(* Translation of the stmt *)
102
- let c = TTC. tc1_process_prhl_stmt tc s c in
103
- t_equivS_trans (mt,c) (p1, q1) (p2, q2) tc
170
+ let map =
171
+ match pat with
172
+ | None -> Mstr. empty
173
+ | Some p -> begin
174
+ let regexpstmt = trans_block p in
175
+ let ct = match s with `Left -> es.es_sl | `Right -> es.es_sr in
176
+ match RegexpStmt. search regexpstmt ct.s_node with
177
+ | None -> Mstr. empty
178
+ | Some m -> m
179
+ end
180
+ in
181
+ let c = TTC. tc1_process_prhl_stmt tc s ~map c in
182
+
183
+ match tf with
184
+ | TFeq ->
185
+ t_equivS_trans_eq s c tc
186
+ | TFform (p1 , q1 , p2 , q2 ) ->
187
+ let p1, q1 =
188
+ let hyps = LDecl. push_all [es.es_ml; (mright, mt)] hyps in
189
+ TTC. pf_process_form !! tc hyps tbool p1, TTC. pf_process_form !! tc hyps tbool q1
190
+ in
191
+ let p2, q2 =
192
+ let hyps = LDecl. push_all [(mleft, mt); es.es_mr] hyps in
193
+ TTC. pf_process_form !! tc hyps tbool p2, TTC. pf_process_form !! tc hyps tbool q2
194
+ in
195
+ t_equivS_trans (mt, c) (p1, q1) (p2, q2) tc
104
196
105
197
(* -------------------------------------------------------------------- *)
106
198
let process_trans_fun f p1 q1 p2 q2 tc =
107
- let env = FApi. tc1_env tc in
199
+ let env, hyps, _ = FApi. tc1_eflat tc in
200
+ let ef = tc1_as_equivF tc in
108
201
let f = EcTyping. trans_gamepath env f in
202
+ let (_, prmt), (_, pomt) = Fun. hoareF_memenv f env in
203
+ let (prml, prmr), (poml, pomr) = Fun. equivF_memenv ef.ef_fl ef.ef_fr env in
204
+ let process ml mr fo =
205
+ TTC. pf_process_form !! tc (LDecl. push_all [ml; mr] hyps) tbool fo in
206
+ let p1 = process prml (mright, prmt) p1 in
207
+ let q1 = process poml (mright, pomt) q1 in
208
+ let p2 = process (mleft,prmt) prmr p2 in
209
+ let q2 = process (mleft,pomt) pomr q2 in
109
210
t_equivF_trans f (p1, q1) (p2, q2) tc
110
211
111
212
(* -------------------------------------------------------------------- *)
112
213
let process_equiv_trans (tk , tf ) tc =
113
- let env, hyps, _ = FApi. tc1_eflat tc in
114
-
115
- let (p1, q1, p2, q2) =
214
+ match tk with
215
+ | TKfun f -> begin
116
216
match tf with
117
- | TFform (p1 , q1 , p2 , q2 ) ->
118
- begin match tk with
119
- | TKfun f ->
120
- let ef = tc1_as_equivF tc in
121
- let f = EcTyping. trans_gamepath env f in
122
- let (_, prmt), (_, pomt) = Fun. hoareF_memenv f env in
123
- let (prml, prmr), (poml, pomr) = Fun. equivF_memenv ef.ef_fl ef.ef_fr env in
124
- let process ml mr fo =
125
- TTC. pf_process_form !! tc (LDecl. push_all [ml; mr] hyps) tbool fo in
126
- let p1 = process prml (mright, prmt) p1 in
127
- let q1 = process poml (mright, pomt) q1 in
128
- let p2 = process (mleft,prmt) prmr p2 in
129
- let q2 = process (mleft,pomt) pomr q2 in
130
- (p1,q1,p2,q2)
131
- | TKstmt (s , _ ) | TKparsedStmt (s , _ , _ ) ->
132
- let es = tc1_as_equivS tc in
133
- let mt = snd (match s with `Left -> es.es_ml | `Right -> es.es_mr) in
134
- let p1, q1 =
135
- let hyps = LDecl. push_all [es.es_ml; (mright, mt)] hyps in
136
- TTC. pf_process_form !! tc hyps tbool p1,
137
- TTC. pf_process_form !! tc hyps tbool q1 in
138
- let p2, q2 =
139
- let hyps = LDecl. push_all [(mleft, mt); es.es_mr] hyps in
140
- TTC. pf_process_form !! tc hyps tbool p2,
141
- TTC. pf_process_form !! tc hyps tbool q2 in
142
- (p1,q1,p2,q2)
143
- end
144
217
| TFeq ->
145
- let side =
146
- match tk with
147
- | TKfun _ -> tc_error !! tc " transitivity * does not work on functions"
148
- | TKstmt (s ,_ ) -> s
149
- | TKparsedStmt (s ,_ ,_ ) -> s in
150
- let es = tc1_as_equivS tc in
151
- let c,m = match side with `Left -> es.es_sl, es.es_ml | `Right -> es.es_sr, es.es_mr in
152
- let fv = EcPV.PV. fv env (fst m) es.es_po in
153
- let fvr = EcPV. s_read env c in
154
- let mk_eqs fv =
155
- let vfv, gfv = EcPV.PV. elements fv in
156
- let veq = List. map (fun (x ,ty ) -> f_eq (f_pvar x ty mleft) (f_pvar x ty mright)) vfv in
157
- let geq = List. map (fun mp -> f_eqglob mp mleft mp mright) gfv in
158
- f_ands (veq @ geq) in
159
- let pre = mk_eqs (EcPV.PV. union fvr fv) in
160
- let post = mk_eqs fv in
161
- if side = `Left then (pre, post, es.es_pr, es.es_po)
162
- else (es.es_pr, es.es_po, pre, post) in
163
- match tk with
164
- | TKfun f -> process_trans_fun f p1 q1 p2 q2 tc
165
- | TKstmt (s , c ) -> process_trans_stmt s c p1 q1 p2 q2 tc
166
- | TKparsedStmt (s , p , c ) -> process_replace_stmt s p c p1 q1 p2 q2 tc
218
+ tc_error !! tc " transitivity * does not work on functions"
219
+ | TFform (p1 , q1 , p2 , q2 ) ->
220
+ process_trans_fun f p1 q1 p2 q2 tc
221
+ end
222
+ | TKstmt (side , stmt ) ->
223
+ process_trans_stmt tf side stmt tc
224
+ | TKparsedStmt (side , pat , stmt ) ->
225
+ process_trans_stmt tf side ~pat: pat stmt tc
0 commit comments