@@ -339,6 +339,147 @@ let t_equiv_while_disj_r side vrnt inv tc =
339
339
340
340
FApi. xmutate1 tc `While [b_concl; concl]
341
341
342
+ (* -------------------------------------------------------------------- *)
343
+ module LossLess = struct
344
+ exception CannotTranslate
345
+
346
+ let form_of_expr env mother mh =
347
+ let map = ref (Mid. add mother (EcPV.PVMap. create env) Mid. empty) in
348
+
349
+ let rec aux fp =
350
+ match fp.f_node with
351
+ | Fint z -> e_int z
352
+ | Flocal x -> e_local x fp.f_ty
353
+
354
+ | Fop (p , tys ) -> e_op p tys fp.f_ty
355
+ | Fapp (f , fs ) -> e_app (aux f) (List. map aux fs) fp.f_ty
356
+ | Ftuple fs -> e_tuple (List. map aux fs)
357
+ | Fproj (f , i ) -> e_proj (aux f) i fp.f_ty
358
+
359
+ | Fif (c , f1 , f2 ) ->
360
+ e_if (aux c) (aux f1) (aux f2)
361
+
362
+ | Fmatch (c , bs , ty ) ->
363
+ e_match (aux c) (List. map aux bs) ty
364
+
365
+ | Flet (lp , f1 , f2 ) ->
366
+ e_let lp (aux f1) (aux f2)
367
+
368
+ | Fquant (kd , bds , f ) ->
369
+ e_quantif (auxkd kd) (List. map auxbd bds) (aux f)
370
+
371
+ | Fpvar (pv , m ) ->
372
+ if EcIdent. id_equal m mh then
373
+ e_var pv fp.f_ty
374
+ else
375
+ let bds = odfl (EcPV.PVMap. create env) (Mid. find_opt m ! map) in
376
+ let idx =
377
+ match EcPV.PVMap. find pv bds with
378
+ | None ->
379
+ let pfx = EcIdent. name m in
380
+ let pfx = String. sub pfx 1 (String. length pfx - 1 ) in
381
+ let x = symbol_of_pv pv in
382
+ let x = EcIdent. create (x ^ " _" ^ pfx) in
383
+ let bds = EcPV.PVMap. add pv (x, fp.f_ty) bds in
384
+ map := Mid. add m bds ! map; x
385
+ | Some (x , _ ) -> x
386
+
387
+ in e_local idx fp.f_ty
388
+
389
+ | Fglob _
390
+ | FhoareF _ | FhoareS _
391
+ | FeHoareF _ | FeHoareS _
392
+ | FbdHoareF _ | FbdHoareS _
393
+ | FequivF _ | FequivS _
394
+ | FeagerF _ | Fpr _ -> raise CannotTranslate
395
+
396
+ and auxkd (kd : quantif ) : equantif =
397
+ match kd with
398
+ | Lforall -> `EForall
399
+ | Lexists -> `EExists
400
+ | Llambda -> `ELambda
401
+
402
+ and auxbd ((x , bd ) : binding ) =
403
+ match bd with
404
+ | GTty ty -> (x, ty)
405
+ | _ -> raise CannotTranslate
406
+
407
+ in fun f -> let e = aux f in (e, ! map)
408
+
409
+ let xhyps evs =
410
+ let mtypes = Mid. of_list [evs.es_ml; evs.es_mr] in
411
+
412
+ fun m fp ->
413
+ let fp =
414
+ Mid. fold (fun mh pvs fp ->
415
+ let mty = Mid. find_opt mh mtypes in
416
+ let fp =
417
+ EcPV.Mnpv. fold (fun pv (x , ty ) fp ->
418
+ f_let1 x (f_pvar pv ty mh) fp)
419
+ (EcPV.PVMap. raw pvs) fp
420
+ in f_forall_mems [mh, oget mty] fp)
421
+ m fp
422
+ and cnt =
423
+ Mid. fold
424
+ (fun _ pvs i -> i + 1 + EcPV.Mnpv. cardinal (EcPV.PVMap. raw pvs))
425
+ m 0
426
+ in (cnt, fp)
427
+ end
428
+
429
+ (* -------------------------------------------------------------------- *)
430
+ let t_equiv_ll_while_disj_r side inv tc =
431
+ let env = FApi. tc1_env tc in
432
+ let es = tc1_as_equivS tc in
433
+ let s, m_side, m_other =
434
+ match side with
435
+ | `Left -> es.es_sl, es.es_ml, es.es_mr
436
+ | `Right -> es.es_sr, es.es_mr, es.es_ml in
437
+ let (e, c), s = tc1_last_while tc s in
438
+ let e = form_of_expr (EcMemory. memory m_side) e in
439
+
440
+ let (_,ll) =
441
+ try
442
+ let evs = tc1_as_equivS tc in
443
+ let ml = EcMemory. memory evs.es_ml in
444
+ let subst = Fsubst. f_bind_mem Fsubst. f_subst_id ml mhr in
445
+ let inv = Fsubst. f_subst subst inv in
446
+ let e, m = LossLess. form_of_expr env (EcMemory. memory evs.es_mr) ml e in
447
+ let c = s_while (e, c) in
448
+ LossLess. xhyps evs m
449
+ (f_bdHoareS (mhr, EcMemory. memtype evs.es_ml) inv c f_true FHeq f_r1)
450
+ with LossLess. CannotTranslate ->
451
+ tc_error !! tc
452
+ " while linking predicates cannot be converted to expressions" in
453
+
454
+ (* 1. The body preserves the invariant and the loop is lossless. *)
455
+
456
+ let m_other' = (EcIdent. create " &m" , EcMemory. memtype m_other) in
457
+
458
+ let smem = Fsubst. f_subst_id in
459
+ let smem = Fsubst. f_bind_mem smem (EcMemory. memory m_side ) mhr in
460
+ let smem = Fsubst. f_bind_mem smem (EcMemory. memory m_other) (EcMemory. memory m_other') in
461
+
462
+ let b_pre = f_and_simpl inv e in
463
+ let b_pre = Fsubst. f_subst smem b_pre in
464
+ let b_post = inv in
465
+ let b_post = Fsubst. f_subst smem b_post in
466
+ let b_concl = f_bdHoareS (mhr, EcMemory. memtype m_side) b_pre c b_post FHeq f_r1 in
467
+ let b_concl = b_concl in
468
+ let b_concl = f_forall_mems [m_other'] b_concl in
469
+
470
+ (* 2. WP of the while *)
471
+ let post = f_imps_simpl [f_not_simpl e; inv] es.es_po in
472
+ let modi = s_write env c in
473
+ let post = generalize_mod env (EcMemory. memory m_side) modi post in
474
+ let post = f_and_simpl inv post in
475
+ let concl =
476
+ match side with
477
+ | `Left -> f_equivS_r { es with es_sl = s; es_po= post; }
478
+ | `Right -> f_equivS_r { es with es_sr = s; es_po= post; }
479
+ in
480
+
481
+ FApi. xmutate1 tc `While [b_concl; ll; concl]
482
+
342
483
(* -------------------------------------------------------------------- *)
343
484
let t_equiv_while_r inv tc =
344
485
let env = FApi. tc1_env tc in
@@ -374,6 +515,7 @@ let t_bdhoare_while_rev_geq = FApi.t_low4 "bdhoare-while" t_bdhoare_while_rev_ge
374
515
let t_bdhoare_while_rev = FApi. t_low1 " bdhoare-while" t_bdhoare_while_rev_r
375
516
let t_equiv_while = FApi. t_low1 " equiv-while" t_equiv_while_r
376
517
let t_equiv_while_disj = FApi. t_low3 " equiv-while" t_equiv_while_disj_r
518
+ let t_equiv_ll_while_disj = FApi. t_low2 " equiv-while" t_equiv_ll_while_disj_r
377
519
378
520
(* -------------------------------------------------------------------- *)
379
521
let process_while side winfos tc =
@@ -400,7 +542,6 @@ let process_while side winfos tc =
400
542
| Some vrnt , None ->
401
543
let _, phi = TTC. tc1_process_Xhl_formula tc phi in
402
544
let _, vrnt = TTC. tc1_process_Xhl_form tc tint vrnt in
403
-
404
545
t_bdhoare_while phi vrnt tc
405
546
406
547
| Some vrnt , Some (`Bd (k , eps )) ->
@@ -410,7 +551,6 @@ let process_while side winfos tc =
410
551
let _, eps = TTC. tc1_process_Xhl_form tc treal eps in
411
552
412
553
t_bdhoare_while_rev_geq phi vrnt k eps tc
413
-
414
554
| None , None ->
415
555
let _, phi = TTC. tc1_process_Xhl_formula tc phi in
416
556
t_bdhoare_while_rev phi tc
@@ -430,79 +570,16 @@ let process_while side winfos tc =
430
570
(TTC. tc1_process_prhl_formula tc phi)
431
571
tc
432
572
573
+ | Some side , None ->
574
+ t_equiv_ll_while_disj side
575
+ (TTC. tc1_process_prhl_formula tc phi)
576
+ tc
577
+
433
578
| _ -> tc_error !! tc " invalid arguments"
434
579
end
435
580
436
581
| _ -> tc_error !! tc " expecting a hoare[...]/equiv[...]"
437
582
438
- (* -------------------------------------------------------------------- *)
439
- module ASyncWhile = struct
440
- exception CannotTranslate
441
-
442
- let form_of_expr env mother mh =
443
- let map = ref (Mid. add mother (EcPV.PVMap. create env) Mid. empty) in
444
-
445
- let rec aux fp =
446
- match fp.f_node with
447
- | Fint z -> e_int z
448
- | Flocal x -> e_local x fp.f_ty
449
-
450
- | Fop (p , tys ) -> e_op p tys fp.f_ty
451
- | Fapp (f , fs ) -> e_app (aux f) (List. map aux fs) fp.f_ty
452
- | Ftuple fs -> e_tuple (List. map aux fs)
453
- | Fproj (f , i ) -> e_proj (aux f) i fp.f_ty
454
-
455
- | Fif (c , f1 , f2 ) ->
456
- e_if (aux c) (aux f1) (aux f2)
457
-
458
- | Fmatch (c , bs , ty ) ->
459
- e_match (aux c) (List. map aux bs) ty
460
-
461
- | Flet (lp , f1 , f2 ) ->
462
- e_let lp (aux f1) (aux f2)
463
-
464
- | Fquant (kd , bds , f ) ->
465
- e_quantif (auxkd kd) (List. map auxbd bds) (aux f)
466
-
467
- | Fpvar (pv , m ) ->
468
- if EcIdent. id_equal m mh then
469
- e_var pv fp.f_ty
470
- else
471
- let bds = odfl (EcPV.PVMap. create env) (Mid. find_opt m ! map) in
472
- let idx =
473
- match EcPV.PVMap. find pv bds with
474
- | None ->
475
- let pfx = EcIdent. name m in
476
- let pfx = String. sub pfx 1 (String. length pfx - 1 ) in
477
- let x = symbol_of_pv pv in
478
- let x = EcIdent. create (x ^ " _" ^ pfx) in
479
- let bds = EcPV.PVMap. add pv (x, fp.f_ty) bds in
480
- map := Mid. add m bds ! map; x
481
- | Some (x , _ ) -> x
482
-
483
- in e_local idx fp.f_ty
484
-
485
- | Fglob _
486
- | FhoareF _ | FhoareS _
487
- | FeHoareF _ | FeHoareS _
488
- | FbdHoareF _ | FbdHoareS _
489
- | FequivF _ | FequivS _
490
- | FeagerF _ | Fpr _ -> raise CannotTranslate
491
-
492
- and auxkd (kd : quantif ) : equantif =
493
- match kd with
494
- | Lforall -> `EForall
495
- | Lexists -> `EExists
496
- | Llambda -> `ELambda
497
-
498
- and auxbd ((x , bd ) : binding ) =
499
- match bd with
500
- | GTty ty -> (x, ty)
501
- | _ -> raise CannotTranslate
502
-
503
- in fun f -> let e = aux f in (e, ! map)
504
- end
505
-
506
583
(* -------------------------------------------------------------------- *)
507
584
let process_async_while (winfos : EP.async_while_info ) tc =
508
585
let e_and e1 e2 =
@@ -587,52 +664,31 @@ let process_async_while (winfos : EP.async_while_info) tc =
587
664
in (hr1, hr2)
588
665
in
589
666
590
- let xhyps =
591
- let mtypes = Mid. of_list [evs.es_ml; evs.es_mr] in
592
-
593
- fun m fp ->
594
- let fp =
595
- Mid. fold (fun mh pvs fp ->
596
- let mty = Mid. find_opt mh mtypes in
597
- let fp =
598
- EcPV.Mnpv. fold (fun pv (x , ty ) fp ->
599
- f_let1 x (f_pvar pv ty mh) fp)
600
- (EcPV.PVMap. raw pvs) fp
601
- in f_forall_mems [mh, oget mty] fp)
602
- m fp
603
- and cnt =
604
- Mid. fold
605
- (fun _ pvs i -> i + 1 + EcPV.Mnpv. cardinal (EcPV.PVMap. raw pvs))
606
- m 0
607
- in (cnt, fp)
608
- in
609
-
610
667
let (c1, ll1), (c2, ll2) =
611
668
try
612
669
let ll1 =
613
670
let subst = Fsubst. f_bind_mem Fsubst. f_subst_id ml mhr in
614
671
let inv = Fsubst. f_subst subst inv in
615
672
let test = f_ands [fe1; f_not p0; p1] in
616
- let test, m = ASyncWhile . form_of_expr env (EcMemory. memory evs.es_mr) ml test in
673
+ let test, m = LossLess . form_of_expr env (EcMemory. memory evs.es_mr) ml test in
617
674
let c = s_while (test, cl) in
618
- xhyps m
675
+ LossLess. xhyps evs m
619
676
(f_bdHoareS (mhr, EcMemory. memtype evs.es_ml) inv c f_true FHeq f_r1)
620
677
621
678
and ll2 =
622
679
let subst = Fsubst. f_bind_mem Fsubst. f_subst_id mr mhr in
623
680
let inv = Fsubst. f_subst subst inv in
624
681
let test = f_ands [fe1; f_not p0; f_not p1] in
625
- let test, m = ASyncWhile . form_of_expr env (EcMemory. memory evs.es_ml) mr test in
682
+ let test, m = LossLess . form_of_expr env (EcMemory. memory evs.es_ml) mr test in
626
683
let c = s_while (test, cr) in
627
- xhyps m
684
+ LossLess. xhyps evs m
628
685
(f_bdHoareS (mhr, EcMemory. memtype evs.es_mr) inv c f_true FHeq f_r1)
629
686
630
687
in (ll1, ll2)
631
688
632
- with ASyncWhile .CannotTranslate ->
689
+ with LossLess .CannotTranslate ->
633
690
tc_error !! tc
634
- " async-while linking predicates cannot be converted to expressions"
635
- in
691
+ " async-while linking predicates cannot be converted to expressions" in
636
692
637
693
let concl =
638
694
let post = f_imps [f_not fe1; f_not fe2; inv] evs.es_po in
0 commit comments