@@ -82,85 +82,144 @@ let t_equivS_trans = FApi.t_low3 "equiv-trans" Low.t_equivS_trans_r
8282let t_equivF_trans = FApi. t_low3 " equiv-trans" Low. t_equivF_trans_r
8383
8484(* -------------------------------------------------------------------- *)
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
8687 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
96162
97163(* -------------------------------------------------------------------- *)
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
99166 let es = tc1_as_equivS tc in
100167 let mt = snd (match s with `Left -> es.es_ml | `Right -> es.es_mr) in
168+
101169 (* 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
104196
105197(* -------------------------------------------------------------------- *)
106198let 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
108201 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
109210 t_equivF_trans f (p1, q1) (p2, q2) tc
110211
111212(* -------------------------------------------------------------------- *)
112213let 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
116216 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
144217 | 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