Skip to content

Commit 30bfa95

Browse files
committed
New tactic: "proc change"
This tactic allows to change an expression in a statement by some other expression. When applied, the user has to prove that the two expressions are equal (generalizing over all the program variables) This tactic applies to any program logic. The syntax is: proc change <side?> <codepos> : <form> This tactic is in the TCB. Test plan: - unit test (tests/prochange.ec)
1 parent 4ccf645 commit 30bfa95

File tree

6 files changed

+68
-0
lines changed

6 files changed

+68
-0
lines changed

src/ecHiTacticals.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ and process1_phl (_ : ttenv) (t : phltactic located) (tc : tcenv1) =
227227
| Pauto -> EcPhlAuto.t_auto ~conv:`Conv
228228
| Plossless -> EcPhlHiAuto.t_lossless
229229
| Prepl_stmt infos -> EcPhlTrans.process_equiv_trans infos
230+
| Pprocchange (s, p, f) -> EcPhlRewrite.process_change s p f
230231
in
231232

232233
try tx tc

src/ecParser.mly

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,6 +3233,9 @@ phltactic:
32333233
| LOSSLESS
32343234
{ Plossless }
32353235

3236+
| PROC CHANGE side=side? pos=codepos COLON f=sform
3237+
{ Pprocchange (side, pos, f) }
3238+
32363239
bdhoare_split:
32373240
| b1=sform b2=sform b3=sform?
32383241
{ BDH_split_bop (b1,b2,b3) }

src/ecParsetree.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ type phltactic =
749749
| Prw_equiv of rw_eqv_info
750750
| Psymmetry
751751
| Pbdhoare_split of bdh_split
752+
| Pprocchange of side option * codepos * pformula
752753

753754
(* Eager *)
754755
| Peager_seq of (eager_info * codepos1 pair * pformula)

src/phl/ecPhlRewrite.ml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
(* -------------------------------------------------------------------- *)
2+
open EcParsetree
3+
open EcAst
4+
open EcCoreGoal
5+
open EcModules
6+
open EcFol
7+
8+
(* -------------------------------------------------------------------- *)
9+
let process_change
10+
(side : side option)
11+
(pos : codepos)
12+
(form : pformula)
13+
(tc : tcenv1)
14+
=
15+
let concl = FApi.tc1_goal tc in
16+
17+
let change i =
18+
let (e, mk) =
19+
match i.i_node with
20+
| Sasgn (lv, e) -> (e, (fun e -> i_asgn (lv, e)))
21+
| Srnd (lv, e) -> (e, (fun e -> i_rnd (lv, e)))
22+
| _ -> assert false in
23+
24+
let m, e' = EcProofTyping.tc1_process_Xhl_form ?side tc e.e_ty form in
25+
let mid = EcMemory.memory m in
26+
let e' = expr_of_form mid e' in
27+
28+
let f = form_of_expr mid e in
29+
let f' = form_of_expr mid e' in
30+
31+
([f_forall_mems [m] (f_eq f f')], [mk e'])
32+
in
33+
34+
let kinds = [`Hoare `Stmt; `EHoare `Stmt; `PHoare `Stmt; `Equiv `Stmt] in
35+
36+
if not (EcLowPhlGoal.is_program_logic concl kinds) then
37+
assert false;
38+
39+
let s = EcLowPhlGoal.tc1_get_stmt side tc in
40+
let goals, s = EcMatching.Zipper.map pos change s in
41+
let concl = EcLowPhlGoal.hl_set_stmt side concl s in
42+
43+
FApi.xmutate1 tc `ProcChange (goals @ [concl])

src/phl/ecPhlRewrite.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(* -------------------------------------------------------------------- *)
2+
open EcParsetree
3+
open EcCoreGoal.FApi
4+
5+
(* -------------------------------------------------------------------- *)
6+
val process_change : side option -> codepos -> pformula -> backward

tests/procchange.ec

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require import AllCore.
2+
3+
module M = {
4+
proc f(x : int) = {
5+
x <- x + 0;
6+
}
7+
}.
8+
9+
lemma L : equiv[M.f ~ M.f : true ==> true].
10+
proof.
11+
proc.
12+
proc change {1} 1 : x.
13+
- smt().
14+
abort.

0 commit comments

Comments
 (0)