@@ -339,6 +339,144 @@ 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
+
344
+ module Truc = struct
345
+ exception CannotTranslate
346
+
347
+ let form_of_expr env mother mh =
348
+ let map = ref (Mid. add mother (EcPV.PVMap. create env) Mid. empty) in
349
+
350
+ let rec aux fp =
351
+ match fp.f_node with
352
+ | Fint z -> e_int z
353
+ | Flocal x -> e_local x fp.f_ty
354
+
355
+ | Fop (p , tys ) -> e_op p tys fp.f_ty
356
+ | Fapp (f , fs ) -> e_app (aux f) (List. map aux fs) fp.f_ty
357
+ | Ftuple fs -> e_tuple (List. map aux fs)
358
+ | Fproj (f , i ) -> e_proj (aux f) i fp.f_ty
359
+
360
+ | Fif (c , f1 , f2 ) ->
361
+ e_if (aux c) (aux f1) (aux f2)
362
+
363
+ | Fmatch (c , bs , ty ) ->
364
+ e_match (aux c) (List. map aux bs) ty
365
+
366
+ | Flet (lp , f1 , f2 ) ->
367
+ e_let lp (aux f1) (aux f2)
368
+
369
+ | Fquant (kd , bds , f ) ->
370
+ e_quantif (auxkd kd) (List. map auxbd bds) (aux f)
371
+
372
+ | Fpvar (pv , m ) ->
373
+ if EcIdent. id_equal m mh then
374
+ e_var pv fp.f_ty
375
+ else
376
+ let bds = odfl (EcPV.PVMap. create env) (Mid. find_opt m ! map) in
377
+ let idx =
378
+ match EcPV.PVMap. find pv bds with
379
+ | None ->
380
+ let pfx = EcIdent. name m in
381
+ let pfx = String. sub pfx 1 (String. length pfx - 1 ) in
382
+ let x = symbol_of_pv pv in
383
+ let x = EcIdent. create (x ^ " _" ^ pfx) in
384
+ let bds = EcPV.PVMap. add pv (x, fp.f_ty) bds in
385
+ map := Mid. add m bds ! map; x
386
+ | Some (x , _ ) -> x
387
+
388
+ in e_local idx fp.f_ty
389
+
390
+ | Fglob _
391
+ | FhoareF _ | FhoareS _
392
+ | FeHoareF _ | FeHoareS _
393
+ | FbdHoareF _ | FbdHoareS _
394
+ | FequivF _ | FequivS _
395
+ | FeagerF _ | Fpr _ -> raise CannotTranslate
396
+
397
+ and auxkd (kd : quantif ) : equantif =
398
+ match kd with
399
+ | Lforall -> `EForall
400
+ | Lexists -> `EExists
401
+ | Llambda -> `ELambda
402
+
403
+ and auxbd ((x , bd ) : binding ) =
404
+ match bd with
405
+ | GTty ty -> (x, ty)
406
+ | _ -> raise CannotTranslate
407
+
408
+ in fun f -> let e = aux f in (e, ! map)
409
+ end
410
+
411
+ let t_equiv_ll_while_disj_r side inv tc =
412
+ let env = FApi. tc1_env tc in
413
+ let es = tc1_as_equivS tc in
414
+ let s, m_side, m_other =
415
+ match side with
416
+ | `Left -> es.es_sl, es.es_ml, es.es_mr
417
+ | `Right -> es.es_sr, es.es_mr, es.es_ml in
418
+ let (e, c), s = tc1_last_while tc s in
419
+ let e = form_of_expr (EcMemory. memory m_side) e in
420
+
421
+ let ll =
422
+ let evs = tc1_as_equivS tc in
423
+
424
+ let xhyps =
425
+ let mtypes = Mid. of_list [evs.es_ml; evs.es_mr] in
426
+
427
+ fun m fp ->
428
+ let fp =
429
+ Mid. fold (fun mh pvs fp ->
430
+ let mty = Mid. find_opt mh mtypes in
431
+ let fp =
432
+ EcPV.Mnpv. fold (fun pv (x , ty ) fp ->
433
+ f_let1 x (f_pvar pv ty mh) fp)
434
+ (EcPV.PVMap. raw pvs) fp
435
+ in f_forall_mems [mh, oget mty] fp)
436
+ m fp
437
+ in fp
438
+ in
439
+
440
+ let ml = EcMemory. memory evs.es_ml in
441
+ let subst = Fsubst. f_bind_mem Fsubst. f_subst_id ml mhr in
442
+ let inv = Fsubst. f_subst subst inv in
443
+ let e, m = Truc. form_of_expr env (EcMemory. memory evs.es_mr) ml e in
444
+ let c = s_while (e, c) in
445
+ xhyps m
446
+ (f_bdHoareS (mhr, EcMemory. memtype evs.es_ml) inv c f_true FHeq f_r1)
447
+ in
448
+
449
+ (* 1. The body preserves the invariant and the loop is lossless. *)
450
+
451
+ let m_other' = (EcIdent. create " &m" , EcMemory. memtype m_other) in
452
+
453
+ let smem = Fsubst. f_subst_id in
454
+ let smem = Fsubst. f_bind_mem smem (EcMemory. memory m_side ) mhr in
455
+ let smem = Fsubst. f_bind_mem smem (EcMemory. memory m_other) (EcMemory. memory m_other') in
456
+
457
+ let b_pre = f_and_simpl inv e in
458
+ let b_pre = Fsubst. f_subst smem b_pre in
459
+ let b_post = inv in
460
+ let b_post = Fsubst. f_subst smem b_post in
461
+ let b_concl = f_bdHoareS (mhr, EcMemory. memtype m_side) b_pre c b_post FHeq f_r1 in
462
+ let b_concl = b_concl in
463
+ let b_concl = f_forall_mems [m_other'] b_concl in
464
+
465
+ (* 2. WP of the while *)
466
+ let post = f_imps_simpl [f_not_simpl e; inv] es.es_po in
467
+ let term_condition = f_imps_simpl [inv] (f_not_simpl e) in
468
+ let post = f_and term_condition post in
469
+ let modi = s_write env c in
470
+ let post = generalize_mod env (EcMemory. memory m_side) modi post in
471
+ let post = f_and_simpl inv post in
472
+ let concl =
473
+ match side with
474
+ | `Left -> f_equivS_r { es with es_sl = s; es_po= post; }
475
+ | `Right -> f_equivS_r { es with es_sr = s; es_po= post; }
476
+ in
477
+
478
+ FApi. xmutate1 tc `While [b_concl; ll; concl]
479
+
342
480
(* -------------------------------------------------------------------- *)
343
481
let t_equiv_while_r inv tc =
344
482
let env = FApi. tc1_env tc in
@@ -374,6 +512,7 @@ let t_bdhoare_while_rev_geq = FApi.t_low4 "bdhoare-while" t_bdhoare_while_rev_ge
374
512
let t_bdhoare_while_rev = FApi. t_low1 " bdhoare-while" t_bdhoare_while_rev_r
375
513
let t_equiv_while = FApi. t_low1 " equiv-while" t_equiv_while_r
376
514
let t_equiv_while_disj = FApi. t_low3 " equiv-while" t_equiv_while_disj_r
515
+ let t_equiv_ll_while_dish = FApi. t_low2 " equiv-while" t_equiv_ll_while_disj_r
377
516
378
517
(* -------------------------------------------------------------------- *)
379
518
let process_while side winfos tc =
@@ -400,7 +539,6 @@ let process_while side winfos tc =
400
539
| Some vrnt , None ->
401
540
let _, phi = TTC. tc1_process_Xhl_formula tc phi in
402
541
let _, vrnt = TTC. tc1_process_Xhl_form tc tint vrnt in
403
-
404
542
t_bdhoare_while phi vrnt tc
405
543
406
544
| Some vrnt , Some (`Bd (k , eps )) ->
@@ -410,7 +548,6 @@ let process_while side winfos tc =
410
548
let _, eps = TTC. tc1_process_Xhl_form tc treal eps in
411
549
412
550
t_bdhoare_while_rev_geq phi vrnt k eps tc
413
-
414
551
| None , None ->
415
552
let _, phi = TTC. tc1_process_Xhl_formula tc phi in
416
553
t_bdhoare_while_rev phi tc
@@ -430,6 +567,11 @@ let process_while side winfos tc =
430
567
(TTC. tc1_process_prhl_formula tc phi)
431
568
tc
432
569
570
+ | Some side , None ->
571
+ t_equiv_ll_while_dish side
572
+ (TTC. tc1_process_prhl_formula tc phi)
573
+ tc
574
+
433
575
| _ -> tc_error !! tc " invalid arguments"
434
576
end
435
577
0 commit comments