Skip to content

Commit a333999

Browse files
committed
Fixing bug in elim* when a bound is given.
When a bound is given to elim*, do not try to destruct internal existentials.
1 parent 2459465 commit a333999

File tree

6 files changed

+104
-77
lines changed

6 files changed

+104
-77
lines changed

src/ecCoreFol.ml

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ let hoarecmp_opp cmp =
147147
| FHeq -> FHeq
148148
| FHge -> FHle
149149

150+
(* -------------------------------------------------------------------- *)
151+
let string_of_quant = function
152+
| Lforall -> "forall"
153+
| Lexists -> "exists"
154+
| Llambda -> "fun"
155+
150156
(* -------------------------------------------------------------------- *)
151157
let mk_form = EcAst.mk_form
152158
let f_node { f_node = form } = form
@@ -601,41 +607,63 @@ exception DestrError of string
601607
let destr_error e = raise (DestrError e)
602608

603609
(* -------------------------------------------------------------------- *)
604-
let destr_forall1 f =
605-
match f.f_node with
606-
| Fquant(Lforall,(x,t)::bd,p) -> x,t,f_forall bd p
607-
| _ -> destr_error "forall"
608-
609-
let destr_forall f =
610+
let decompose_binder ?(bound : int option) ~(quantif : quantif) (f : form) =
610611
match f.f_node with
611-
| Fquant(Lforall,bd,p) -> bd, p
612-
| _ -> destr_error "forall"
613-
614-
let decompose_forall f =
615-
match f.f_node with
616-
| Fquant(Lforall,bd,p) -> bd, p
617-
| _ -> [], f
612+
| Fquant (q, bds, f) when q = quantif -> begin
613+
match bound with
614+
| None ->
615+
bds, f
616+
| Some bound ->
617+
let bound = min bound (List.length bds) in
618+
let bd1, bd2 = List.takedrop bound bds in
619+
(bd1, f_quant quantif bd2 f)
620+
end
618621

619-
let destr_lambda f =
620-
match f.f_node with
621-
| Fquant(Llambda,bd,p) -> bd, p
622-
| _ -> destr_error "lambda"
622+
| _ ->
623+
([], f)
623624

624-
let decompose_lambda f =
625-
match f.f_node with
626-
| Fquant(Llambda,bd,p) -> bd, p
627-
| _ -> [], f
625+
let decompose_forall ?(bound : int option) (f : form) =
626+
decompose_binder ?bound ~quantif:Lforall f
628627

629-
let destr_exists1 f =
630-
match f.f_node with
631-
| Fquant(Lexists,(x,t)::bd,p) -> x,t,f_exists bd p
632-
| _ -> destr_error "exists"
628+
let decompose_exists ?(bound : int option) (f : form) =
629+
decompose_binder ?bound ~quantif:Lexists f
633630

634-
let destr_exists f =
635-
match f.f_node with
636-
| Fquant(Lexists,bd,p) -> bd, p
637-
| _ -> destr_error "exists"
631+
let decompose_lambda ?(bound : int option) (f : form) =
632+
decompose_binder ?bound ~quantif:Llambda f
633+
634+
(* -------------------------------------------------------------------- *)
635+
let destr_binder ?(bound : int option) ~quantif:quantif (f : form) =
636+
let bds, f = decompose_binder ?bound ~quantif f in
637+
638+
if 0 < Option.value ~default:1 bound && List.is_empty bds then
639+
destr_error (string_of_quant quantif);
640+
bds, f
641+
642+
let destr_forall ?(bound : int option) (f : form) =
643+
destr_binder ?bound ~quantif:Lforall f
644+
645+
let destr_exists ?(bound : int option) (f : form) =
646+
destr_binder ?bound ~quantif:Lexists f
647+
648+
let destr_lambda ?(bound : int option) (f : form) =
649+
destr_binder ?bound ~quantif:Llambda f
638650

651+
(* -------------------------------------------------------------------- *)
652+
let destr_binder1 ~quantif:quantif (f : form) =
653+
let (x, t), f =
654+
fst_map as_seq1 (destr_binder ~bound:1 ~quantif f)
655+
in (x, t, f)
656+
657+
let destr_forall1 (f : form) =
658+
destr_binder1 ~quantif:Lforall f
659+
660+
let destr_exists1 (f : form) =
661+
destr_binder1 ~quantif:Lexists f
662+
663+
let destr_lambda1 (f : form) =
664+
destr_binder1 ~quantif:Llambda f
665+
666+
(* -------------------------------------------------------------------- *)
639667
let destr_let f =
640668
match f.f_node with
641669
| Flet(lp, e1,e2) -> lp,e1,e2

src/ecCoreFol.mli

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ val f_xadd_simpl : form -> form -> form
224224
val f_xmul_simpl : form -> form -> form
225225
val f_xmuli_simpl : form -> form -> form
226226

227+
(* -------------------------------------------------------------------- *)
228+
val string_of_quant : quantif -> string
229+
227230
(* -------------------------------------------------------------------- *)
228231
exception DestrError of string
229232

@@ -236,6 +239,21 @@ val destr_app2 : name:string -> (path -> bool) -> form -> form * form
236239
val destr_app1_eq : name:string -> path -> form -> form
237240
val destr_app2_eq : name:string -> path -> form -> form * form
238241

242+
val decompose_binder : ?bound:int -> quantif:quantif -> form -> bindings * form
243+
val decompose_forall : ?bound:int -> form -> bindings * form
244+
val decompose_exists : ?bound:int -> form -> bindings * form
245+
val decompose_lambda : ?bound:int -> form -> bindings * form
246+
247+
val destr_binder : ?bound:int -> quantif:quantif -> form -> bindings * form
248+
val destr_forall : ?bound:int -> form -> bindings * form
249+
val destr_exists : ?bound:int -> form -> bindings * form
250+
val destr_lambda : ?bound:int -> form -> bindings * form
251+
252+
val destr_binder1 : quantif:quantif -> form -> ident * gty * form
253+
val destr_forall1 : form -> ident * gty * form
254+
val destr_exists1 : form -> ident * gty * form
255+
val destr_lambda1 : form -> ident * gty * form
256+
239257
val destr_op : form -> EcPath.path * ty list
240258
val destr_local : form -> EcIdent.t
241259
val destr_pvar : form -> prog_var * memory
@@ -256,14 +274,6 @@ val destr_eq : form -> form * form
256274
val destr_eq_or_iff : form -> form * form
257275
val destr_let : form -> lpattern * form * form
258276
val destr_let1 : form -> EcIdent.t * ty * form * form
259-
val destr_forall1 : form -> EcIdent.t * gty * form
260-
val destr_forall : form -> bindings * form
261-
val decompose_forall: form -> bindings * form
262-
val decompose_lambda: form -> bindings * form
263-
val destr_lambda : form -> bindings * form
264-
265-
val destr_exists1 : form -> EcIdent.t * gty * form
266-
val destr_exists : form -> bindings * form
267277
val destr_equivF : form -> equivF
268278
val destr_equivS : form -> equivS
269279
val destr_eagerF : form -> eagerF

src/ecFol.ml

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -984,44 +984,48 @@ let f_dlet_simpl tya tyb d f =
984984
* - p1 => E x p2 -> [x] (p1 => p2)
985985
* - E x p1 => p2 -> [] (E x p1 => p2)
986986
*)
987-
let destr_exists_prenex f =
988-
let rec prenex_exists bds p =
989-
match sform_of_form p with
990-
| SFand (`Sym, (f1, f2)) ->
991-
let (bds, f2) = prenex_exists bds f2 in
992-
let (bds, f1) = prenex_exists bds f1 in
987+
let destr_exists_prenex ?(bound : int option) (f : form) =
988+
let rec prenex_exists ~bound bds p =
989+
match bound, sform_of_form p with
990+
| Some bound, _ when bound <= 0 ->
991+
(bds, p)
992+
993+
| None, SFand (`Sym, (f1, f2)) ->
994+
let (bds, f2) = prenex_exists ~bound:None bds f2 in
995+
let (bds, f1) = prenex_exists ~bound:None bds f1 in
993996
(bds, f_and f1 f2)
994997

995-
| SFor (`Sym, (f1, f2)) ->
996-
let (bds, f2) = prenex_exists bds f2 in
997-
let (bds, f1) = prenex_exists bds f1 in
998+
| None, SFor (`Sym, (f1, f2)) ->
999+
let (bds, f2) = prenex_exists ~bound:None bds f2 in
1000+
let (bds, f1) = prenex_exists ~bound:None bds f1 in
9981001
(bds, f_or f1 f2)
9991002

1000-
| SFimp (f1, f2) ->
1001-
let (bds, f2) = prenex_exists bds f2 in
1003+
| None, SFimp (f1, f2) ->
1004+
let (bds, f2) = prenex_exists ~bound:None bds f2 in
10021005
(bds, f_imp f1 f2)
10031006

1004-
| SFquant (Lexists, bd, lazy p) ->
1005-
let bd, p =
1007+
| None, SFif (f, f1, f2) ->
1008+
let (bds, f2) = prenex_exists ~bound:None bds f2 in
1009+
let (bds, f1) = prenex_exists ~bound:None bds f1 in
1010+
(bds, f_if f f1 f2)
1011+
1012+
| bound, SFquant (Lexists, bd, lazy p) ->
1013+
let bound = Option.map (fun x -> x - 1) bound in
1014+
let bd, p =
10061015
let s = Fsubst.f_subst_init ~freshen:true () in
10071016
let s, bd = Fsubst.add_binding s bd in
10081017
bd, Fsubst.f_subst s p in
10091018
let bds = bd::bds in
1010-
prenex_exists bds p
1011-
1012-
| SFif (f, f1, f2) ->
1013-
let (bds, f2) = prenex_exists bds f2 in
1014-
let (bds, f1) = prenex_exists bds f1 in
1015-
(bds, f_if f f1 f2)
1019+
prenex_exists ~bound bds p
10161020

1017-
| SFop (op, [f1; f2]) when is_interp_ehoare_form_op op ->
1018-
let (bds, f1) = prenex_exists bds f1 in
1021+
| bound, SFop (op, [f1; f2]) when is_interp_ehoare_form_op op ->
1022+
let (bds, f1) = prenex_exists ~bound bds f1 in
10191023
(bds, f_interp_ehoare_form f1 f2)
10201024

10211025
| _ -> (bds, p)
10221026
in
10231027
(* Make it fail as with destr_exists *)
1024-
match prenex_exists [] f with
1028+
match prenex_exists ~bound [] f with
10251029
| [] , _ -> destr_error "exists"
10261030
| bds, f -> (List.rev bds, f)
10271031

src/ecFol.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ val f_real_div_simpl : form -> form -> form
149149
val f_real_inv_simpl : form -> form
150150

151151
(* -------------------------------------------------------------------- *)
152-
val destr_exists_prenex : form -> bindings * form
152+
val destr_exists_prenex : ?bound:int -> form -> bindings * form
153153
val destr_ands : deep:bool -> form -> form list
154154

155155
(* -------------------------------------------------------------------- *)

src/ecPrinting.ml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,12 +1268,6 @@ let pp_locbinds ppe ?fv vs =
12681268

12691269
pp_locbinds_blocks ppe ?fv (merge vs)
12701270

1271-
(* -------------------------------------------------------------------- *)
1272-
let string_of_quant = function
1273-
| Lforall -> "forall"
1274-
| Lexists -> "exists"
1275-
| Llambda -> "fun"
1276-
12771271
(* -------------------------------------------------------------------- *)
12781272
let string_of_hcmp = function
12791273
| FHle -> "<="

src/phl/ecPhlExists.ml

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,11 @@ let get_to_gens fs =
2424
List.map do_id fs
2525

2626
(* -------------------------------------------------------------------- *)
27-
let t_hr_exists_elim_r ?bound tc =
27+
let t_hr_exists_elim_r ?(bound : int option) (tc : tcenv1) =
2828
let pre = tc1_get_pre tc in
2929
let bd, pre =
30-
try destr_exists_prenex pre
30+
try destr_exists_prenex ?bound pre
3131
with DestrError _ -> [], pre in
32-
let bd, pre =
33-
bound
34-
|> omap (fun bound ->
35-
let bound = min bound (List.length bd) in
36-
let bd1, bd2 = List.takedrop bound bd in
37-
38-
(bd1, f_exists bd2 pre))
39-
|? (bd, pre) in
40-
4132
let concl = f_forall bd (set_pre ~pre (FApi.tc1_goal tc)) in
4233
FApi.xmutate1 tc `HlExists [concl]
4334

0 commit comments

Comments
 (0)