@@ -268,6 +268,30 @@ let abstract_pvs
268268 ids, pvs, pvs_as_inv, subst
269269
270270(* -------------------------------------------------------------------- *)
271+ (* Forward ecall on Hoare goals (ecall ->>).
272+ *
273+ * Given a goal hoare[c; s : P ==> Q] where c is a call lv <@ f(e)
274+ * and a contract hoare[f : Pf ==> Qf], this tactic:
275+ *
276+ * 1. Computes seqf from the contract postcondition Qf:
277+ * - If lv is present: seqf = Qf[res / lv]
278+ * - If lv is absent: seqf = Qf with conjuncts mentioning res removed
279+ *
280+ * 2. Auto-frames precondition conjuncts independent of the call's
281+ * writes (lv ∪ writes(f)):
282+ * frame = /\{ Pi | Pi in toplevel-conjuncts(P),
283+ * reads(Pi) # (writes(lv) ∪ writes(f)) }
284+ *
285+ * 3. Produces two subgoals:
286+ * {v
287+ * (a) P => Pf[arg / e] (contract precondition holds)
288+ * (b) hoare[s : seqf /\ frame ==> Q] (continuation)
289+ * v}
290+ *
291+ * When the contract has universally-quantified parameters instantiated
292+ * with program variables, these are abstracted into local variables and
293+ * re-generalized in both subgoals.
294+ *)
271295let t_ecall_hoare_fwd ((cttpt , ctt ) : (proofterm * form )) (tc : tcenv1 ) =
272296 let hyps = FApi. tc1_hyps tc in
273297 let env = EcEnv.LDecl. toenv hyps in
@@ -352,6 +376,26 @@ let t_ecall_hoare_fwd ((cttpt, ctt) : (proofterm * form)) (tc : tcenv1) =
352376 tc
353377
354378(* -------------------------------------------------------------------- *)
379+ (* Backward ecall on Hoare goals (ecall without ->>).
380+ *
381+ * Given a goal hoare[s; c : P ==> Q] where c is a call lv <@ f(e)
382+ * and a contract hoare[f : Pf ==> Qf], this tactic:
383+ *
384+ * 1. Computes the weakest precondition of the call w.r.t. Q using
385+ * compute_hoare_call_post, yielding an intermediate assertion R.
386+ *
387+ * 2. Produces three subgoals:
388+ * {v
389+ * (a) hoare[s : P ==> R] (prefix establishes R)
390+ * (b) hoare[f : Pf ==> Qf] (contract holds)
391+ * (c) <closed by auto> (call WP matches R)
392+ * v}
393+ *
394+ * When the contract has universally-quantified parameters instantiated
395+ * with program variables, these are abstracted into local variables and
396+ * re-generalized in the subgoals. Subgoals (b) and (c) are closed
397+ * automatically, leaving only (a) for the user.
398+ *)
355399let t_ecall_hoare_bwd ((cttpt , _ ) : proofterm * form ) (tc : tcenv1 ) =
356400 let hyps = FApi. tc1_hyps tc in
357401 let env = EcEnv.LDecl. toenv hyps in
0 commit comments