338
338
let gen_select_op
339
339
~(actonly : bool )
340
340
~(mode : OpSelect.mode )
341
+ ~(forcepv : bool )
341
342
(opsc : path option )
342
343
(tvi : EcUnify.tvi )
343
344
(env : EcEnv.env )
@@ -348,15 +349,15 @@ let gen_select_op
348
349
: OpSelect. gopsel list
349
350
=
350
351
351
- let fpv me (pv , ty , ue ) =
352
+ let fpv me (pv , ty , ue ) : OpSelect.gopsel =
352
353
(`Pv (me, pv), ty, ue, (pv :> opmatch ))
353
354
354
- and fop (op , ty , ue , bd ) =
355
+ and fop (op , ty , ue , bd ) : OpSelect.gopsel =
355
356
match bd with
356
357
| None -> (`Op op, ty, ue, (`Op op :> opmatch ))
357
358
| Some bd -> (`Nt bd, ty, ue, (`Op op :> opmatch ))
358
359
359
- and flc (lc , ty , ue ) =
360
+ and flc (lc , ty , ue ) : OpSelect.gopsel =
360
361
(`Lc lc, ty, ue, (`Lc lc :> opmatch )) in
361
362
362
363
let ue_filter =
@@ -378,39 +379,52 @@ let gen_select_op
378
379
379
380
in
380
381
381
- match (if tvi = None then select_local env name else None ) with
382
- | Some (id , ty ) ->
383
- [ flc (id, ty, ue) ]
382
+ let locals () : OpSelect.gopsel list =
383
+ if Option. is_none tvi then
384
+ select_local env name
385
+ |> Option. map
386
+ (fun (id , ty ) -> flc (id, ty, ue))
387
+ |> Option. to_list
388
+ else [] in
389
+
390
+ let ops () : OpSelect.gopsel list =
391
+ let ops = EcUnify. select_op ~filter: ue_filter tvi env name ue psig in
392
+ let ops = opsc |> ofold (fun opsc -> List. mbfilter (by_scope opsc)) ops in
393
+ let ops = match List. mbfilter by_current ops with [] -> ops | ops -> ops in
394
+ let ops = match List. mbfilter by_tc ops with [] -> ops | ops -> ops in
395
+ (List. map fop ops)
396
+
397
+ and pvs () : OpSelect.gopsel list =
398
+ let me, pvs =
399
+ match EcEnv.Memory. get_active env, actonly with
400
+ | None , true -> (None , [] )
401
+ | me , _ -> ( me, select_pv env me name ue tvi psig)
402
+ in List. map (fpv me) pvs
403
+ in
384
404
385
- | None ->
386
- let ops () =
387
- let ops = EcUnify. select_op ~filter: ue_filter tvi env name ue psig in
388
- let ops = opsc |> ofold (fun opsc -> List. mbfilter (by_scope opsc)) ops in
389
- let ops = match List. mbfilter by_current ops with [] -> ops | ops -> ops in
390
- let ops = match List. mbfilter by_tc ops with [] -> ops | ops -> ops in
391
- (List. map fop ops)
392
-
393
- and pvs () =
394
- let me, pvs =
395
- match EcEnv.Memory. get_active env, actonly with
396
- | None , true -> (None , [] )
397
- | me , _ -> ( me, select_pv env me name ue tvi psig)
398
- in List. map (fpv me) pvs
399
- in
405
+ let select (filters : (unit -> OpSelect.gopsel list) list ) : OpSelect.gopsel list =
406
+ List. find_map_opt
407
+ (fun f -> match f () with [] -> None | x -> Some x)
408
+ filters
409
+ |> odfl [] in
400
410
401
- match mode with
402
- | `Expr `InOp -> ops ()
403
- | `Form -> (match pvs () with [] -> ops () | pvs -> pvs)
404
- | `Expr `InProc -> (match pvs () with [] -> ops () | pvs -> pvs)
411
+ match mode with
412
+ | `Expr `InOp -> select [locals; ops]
413
+ | `Form
414
+ | `Expr `InProc ->
415
+ if forcepv then
416
+ select [pvs; locals; ops]
417
+ else
418
+ select [locals; pvs; ops]
405
419
406
420
(* -------------------------------------------------------------------- *)
407
421
let select_exp_op env mode opsc name ue tvi psig =
408
- gen_select_op ~actonly: false ~mode: (`Expr mode)
422
+ gen_select_op ~actonly: false ~forcepv: false ~ mode: (`Expr mode)
409
423
opsc tvi env name ue psig
410
424
411
425
(* -------------------------------------------------------------------- *)
412
- let select_form_op env opsc name ue tvi psig =
413
- gen_select_op ~actonly: true ~mode: `Form
426
+ let select_form_op env ~ forcepv opsc name ue tvi psig =
427
+ gen_select_op ~actonly: true ~mode: `Form ~forcepv
414
428
opsc tvi env name ue psig
415
429
416
430
(* -------------------------------------------------------------------- *)
@@ -1745,23 +1759,36 @@ module PFS : sig
1745
1759
1746
1760
val set_memused : pfstate -> unit
1747
1761
val get_memused : pfstate -> bool
1748
- val new_memused : ('a -> 'b ) -> pfstate -> 'a -> bool * 'b
1762
+ val isforced : pfstate -> bool
1763
+ val new_memused : ('a -> 'b ) -> force :bool -> pfstate -> 'a -> bool * 'b
1749
1764
end = struct
1750
- type pfstate = { mutable pfa_memused : bool ; }
1765
+ type pfstate1 = {
1766
+ pfa_memused : bool ;
1767
+ pfa_forced : bool ;
1768
+ }
1751
1769
1752
- let create () = { pfa_memused = true ; }
1770
+ type pfstate = pfstate1 ref
1753
1771
1754
- let set_memused state =
1755
- state. pfa_memused < - true
1772
+ let create1 ~( force : bool ) : pfstate1 =
1773
+ { pfa_memused = false ; pfa_forced = force; }
1756
1774
1757
- let get_memused state =
1758
- state.pfa_memused
1775
+ let create () : pfstate =
1776
+ ref (create1 ~force: false )
1759
1777
1760
- let new_memused f state x =
1761
- let old = state.pfa_memused in
1762
- let aout = (state.pfa_memused < - false ; f x) in
1763
- let new_ = state.pfa_memused in
1764
- state.pfa_memused < - old; (new_, aout)
1778
+ let set_memused (state : pfstate ) =
1779
+ state := { ! state with pfa_memused = true }
1780
+
1781
+ let get_memused (state : pfstate ) =
1782
+ (! state).pfa_memused
1783
+
1784
+ let isforced (state : pfstate ) =
1785
+ (! state).pfa_forced
1786
+
1787
+ let new_memused (f : 'a -> 'b ) ~(force : bool ) (state : pfstate ) (x : 'a ) =
1788
+ let old = ! state in
1789
+ let aout = (state := create1 ~force ; f x) in
1790
+ let new_ = get_memused state in
1791
+ state := old; (new_, aout)
1765
1792
end
1766
1793
1767
1794
(* -------------------------------------------------------------------- *)
@@ -3026,7 +3053,10 @@ and trans_form_or_pattern env ?mv ?ps ue pf tt =
3026
3053
3027
3054
| PFident ({ pl_desc = name ; pl_loc = loc } , tvi ) ->
3028
3055
let tvi = tvi |> omap (transtvi env ue) in
3029
- let ops = select_form_op env opsc name ue tvi [] in
3056
+ let ops =
3057
+ select_form_op
3058
+ ~forcepv: (PFS. isforced state)
3059
+ env opsc name ue tvi [] in
3030
3060
begin match ops with
3031
3061
| [] ->
3032
3062
tyerror loc env (UnknownVarOrOp (name, [] ))
@@ -3045,7 +3075,7 @@ and trans_form_or_pattern env ?mv ?ps ue pf tt =
3045
3075
tyerror loc env (MultipleOpMatch (name, [] , matches))
3046
3076
end
3047
3077
3048
- | PFside (f , side ) -> begin
3078
+ | PFside (f , ( force , side ) ) -> begin
3049
3079
let (sloc, side) = (side.pl_loc, unloc side) in
3050
3080
let me =
3051
3081
match EcEnv.Memory. lookup side env with
@@ -3056,7 +3086,7 @@ and trans_form_or_pattern env ?mv ?ps ue pf tt =
3056
3086
let used, aout =
3057
3087
PFS. new_memused
3058
3088
(transf (EcEnv.Memory. set_active me env))
3059
- state f
3089
+ ~force state f
3060
3090
in
3061
3091
if not used then begin
3062
3092
let ppe = EcPrinting.PPEnv. ofenv env in
@@ -3139,11 +3169,11 @@ and trans_form_or_pattern env ?mv ?ps ue pf tt =
3139
3169
let _, f1 =
3140
3170
PFS. new_memused
3141
3171
(transf (EcEnv.Memory. set_active me1 env))
3142
- state f in
3172
+ ~force: false state f in
3143
3173
let _, f2 =
3144
3174
PFS. new_memused
3145
3175
(transf (EcEnv.Memory. set_active me2 env))
3146
- state f in
3176
+ ~force: false state f in
3147
3177
unify_or_fail env ue f.pl_loc ~expct: f1.f_ty f2.f_ty;
3148
3178
f_eq f1 f2
3149
3179
@@ -3156,7 +3186,10 @@ and trans_form_or_pattern env ?mv ?ps ue pf tt =
3156
3186
let tvi = tvi |> omap (transtvi env ue) in
3157
3187
let es = List. map (transf env) pes in
3158
3188
let esig = List. map EcFol. f_ty es in
3159
- let ops = select_form_op env opsc name ue tvi esig in
3189
+ let ops =
3190
+ select_form_op ~forcepv: (PFS. isforced state)
3191
+ env opsc name ue tvi esig in
3192
+
3160
3193
begin match ops with
3161
3194
| [] ->
3162
3195
let uidmap = UE. assubst ue in
0 commit comments