@@ -42,8 +42,7 @@ End Private.
42
42
43
43
Notation "'var:' x := e1 'in ' e2" :=
44
44
(Lam (ident_to_string! x)%binder ((fun (x : expr) => e2%E) (Load (ident_to_string! x)%binder)) (Alloc e1%E))
45
- (at level 100, x at level 100, e1, e2 at level 200, right associativity,
46
- format "'[' 'var:' x := '[' e1 ']' 'in' '/' e2 ']'") : expr_scope.
45
+ (at level 100, x at level 100, e1, e2 at level 200, right associativity) : expr_scope.
47
46
48
47
Notation "'var:' x := e1 'in ' e2" :=
49
48
(Lam x%binder e2%V (Alloc e1%V))
@@ -78,8 +77,7 @@ Notation "'fun:' ( a ) { e }" :=
78
77
((fun a =>
79
78
e%E)
80
79
(Load (ident_to_string! a)%binder)))
81
- (at level 200, a at level 1, e at level 200,
82
- format "'[' 'fun :' ( a ) '/ ' { e } ']'").
80
+ (at level 200, a at level 1, e at level 200).
83
81
84
82
Notation "'fun :' ( a , b ) { e }" :=
85
83
(LamV (ident_to_string! a)%binder
@@ -89,8 +87,7 @@ Notation "'fun:' ( a , b ) { e }" :=
89
87
e%E)
90
88
(Load (ident_to_string! b)%binder))))
91
89
(Load (ident_to_string! a)%binder)))
92
- (at level 200, a, b at level 1, e at level 200,
93
- format "'[' 'fun :' ( a , b ) '/ ' { e } ']'").
90
+ (at level 200, a, b at level 1, e at level 200).
94
91
95
92
Notation "'fun :' ( a , b , c ) { e }" :=
96
93
(LamV (ident_to_string! a)%binder
@@ -103,8 +100,7 @@ Notation "'fun:' ( a , b , c ) { e }" :=
103
100
(Load (ident_to_string! c)%binder))))
104
101
(Load (ident_to_string! b)%binder))))
105
102
(Load (ident_to_string! a)%binder)))
106
- (at level 200, a, b, c at level 1, e at level 200,
107
- format "'[' 'fun :' ( a , b , c ) '/ ' { e } ']'").
103
+ (at level 200, a, b, c at level 1, e at level 200).
108
104
109
105
Notation "'fun :' ( a , b , c , d ) { e }" :=
110
106
(LamV (ident_to_string! a)%binder
@@ -120,8 +116,7 @@ Notation "'fun:' ( a , b , c , d ) { e }" :=
120
116
(Load (ident_to_string! c)%binder))))
121
117
(Load (ident_to_string! b)%binder))))
122
118
(Load (ident_to_string! a)%binder)))
123
- (at level 200, a, b, c, d at level 1, e at level 200,
124
- format "'[' 'fun :' ( a , b , c , d ) '/ ' { e } ']'").
119
+ (at level 200, a, b, c, d at level 1, e at level 200).
125
120
126
121
Notation "'fun :' ( a , b , c , d , e ) { e2 }" :=
127
122
(LamV (ident_to_string! a)%binder
@@ -140,8 +135,7 @@ Notation "'fun:' ( a , b , c , d , e ) { e2 }" :=
140
135
(Load (ident_to_string! c)%binder))))
141
136
(Load (ident_to_string! b)%binder))))
142
137
(Load (ident_to_string! a)%binder)))
143
- (at level 200, a, b, c, d, e at level 1, e2 at level 200,
144
- format "'[' 'fun :' ( a , b , c , d , e ) '/ ' { e2 } ']'").
138
+ (at level 200, a, b, c, d, e at level 1, e2 at level 200).
145
139
146
140
Notation "'ret:' e" := e%E (at level 20) : expr_scope.
147
141
@@ -285,39 +279,56 @@ End proofs.
285
279
286
280
(* --------- Tactics ----------- *)
287
281
282
+ (* We wan to call iSplitL using a selection pattern which includes a fresh ident,
283
+ but unfortunately the current implementation does not support this.
284
+ Thus, we duplicate the iSplitL tactic here: *)
285
+ Tactic Notation "ISplitL" constr (Hs) :=
286
+ iStartProof;
287
+ let Δ := iGetCtx in
288
+ eapply tac_sep_split with Left Hs _ _; (* (js:=Hs) *)
289
+ [tc_solve ||
290
+ let P := match goal with |- FromSep ?P _ _ => P end in
291
+ fail "iSplitL:" P "not a separating conjunction"
292
+ |pm_reduce;
293
+ lazymatch goal with
294
+ | |- False => let Hs := iMissingHypsCore Δ Hs in
295
+ fail "iSplitL: hypotheses" Hs "not found"
296
+ | _ => split; [(* subgoal 1 *) |(* subgoal 2 *) ]
297
+ end ].
298
+
288
299
Tactic Notation "wp_begin" constr (x1) :=
289
300
let phi := fresh "Φ" in
290
301
let Hphi := iFresh in
291
302
iIntros (phi); iIntros x1; iIntros [IIdent Hphi];
292
- wp_rec; wp_apply wp_wand_l; iFrame; repeat wp_lam; clear phi.
303
+ wp_rec; wp_apply wp_wand_l; ISplitL [Hphi]; first iFrame; repeat wp_lam; clear phi.
293
304
294
305
Tactic Notation "wp_begin" constr (x1) ";" ident(x2) :=
295
306
let phi := fresh "Φ" in
296
307
let Hphi := iFresh in
297
308
iIntros (phi); iIntros x1; iIntros [IIdent Hphi];
298
309
wp_alloc x2;
299
- wp_rec; wp_apply wp_wand_l; iFrame; repeat wp_lam; clear phi.
310
+ wp_rec; wp_apply wp_wand_l; ISplitL [Hphi]; first iFrame; repeat wp_lam; clear phi.
300
311
301
312
Tactic Notation "wp_begin" constr (x1) ";" ident(x2) "," ident(x3) :=
302
313
let phi := fresh "Φ" in
303
314
let Hphi := iFresh in
304
315
iIntros (phi); iIntros x1; iIntros [IIdent Hphi];
305
316
wp_alloc x3; wp_alloc x2;
306
- wp_rec; wp_apply wp_wand_l; iFrame; repeat wp_lam; clear phi.
317
+ wp_rec; wp_apply wp_wand_l; ISplitL [Hphi]; first iFrame; repeat wp_lam; clear phi.
307
318
308
319
Tactic Notation "wp_begin" constr (x1) ";" ident(x2) "," ident(x3) "," ident(x4) :=
309
320
let phi := fresh "Φ" in
310
321
let Hphi := iFresh in
311
322
iIntros (phi); iIntros x1; iIntros [IIdent Hphi];
312
323
wp_alloc x4; wp_alloc x3; wp_alloc x2;
313
- wp_rec; wp_apply wp_wand_l; iFrame; repeat wp_lam; clear phi.
324
+ wp_rec; wp_apply wp_wand_l; ISplitL [Hphi]; first iFrame; repeat wp_lam; clear phi.
314
325
315
326
Tactic Notation "wp_begin" constr (x1) ";" ident(x2) "," ident(x3) "," ident(x4) "," ident(x5) :=
316
327
let phi := fresh "Φ" in
317
328
let Hphi := iFresh in
318
329
iIntros (phi); iIntros x1; iIntros [IIdent Hphi];
319
330
wp_alloc x5; wp_alloc x4; wp_alloc x3; wp_alloc x2;
320
- wp_rec; wp_apply wp_wand_l; iFrame; repeat wp_lam; clear phi.
331
+ wp_rec; wp_apply wp_wand_l; ISplitL [Hphi]; first iFrame; repeat wp_lam; clear phi.
321
332
322
333
Tactic Notation "wp_var" ident(x) :=
323
334
wp_alloc x; wp_let.
@@ -380,8 +391,14 @@ Tactic Notation "wp_heap" :=
380
391
|| wp_load_offset || wp_store_offset
381
392
|| let x := fresh in (wp_alloc x; try done) ).
382
393
394
+ Tactic Notation "if_decide" :=
395
+ let H := fresh in case_bool_decide as H; try inversion H.
396
+
397
+ Tactic Notation "invalid_case" :=
398
+ (subst; done) || lia.
399
+
383
400
Tactic Notation "wp_type" :=
384
- iSteps; try (repeat case_bool_decide ; iSteps).
401
+ iSteps; try (repeat if_decide; try invalid_case ; iSteps).
385
402
386
403
Tactic Notation "wp_while" constr (Hinv) :=
387
404
wp_apply (wp_while_inv Hinv).
0 commit comments