Skip to content

Commit fc94388

Browse files
authored
Merge pull request #395 from FStarLang/_nik_slprop_equiv_profiling
Profiling and revising slprop_equiv checking for fold and unfold
2 parents 5817d7f + 7f0458a commit fc94388

6 files changed

Lines changed: 63 additions & 18 deletions

File tree

lib/common/Pulse.Lib.Core.fsti

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,22 @@ than SMT. This tactic is also used by the checker when elaborating fold/unfold.
591591
let slprop_equiv_norm (_:unit) : T.Tac unit =
592592
T.mapply (`slprop_equiv_refl)
593593

594+
595+
let slprop_equiv_unfold (head_sym:string) (_:unit) : T.Tac unit =
596+
T.mapply (`slprop_equiv_trans);
597+
T.norm [hnf; zeta; delta_only [head_sym]];
598+
T.norm [hnf; iota; primops];
599+
T.mapply (`slprop_equiv_refl);
600+
T.mapply (`slprop_equiv_refl)
601+
602+
let slprop_equiv_fold (head_sym:string) (_:unit) : T.Tac unit =
603+
T.mapply (`slprop_equiv_trans);
604+
T.flip();
605+
T.norm [hnf; zeta; delta_only [head_sym]];
606+
T.norm [hnf; iota; primops];
607+
T.mapply (`slprop_equiv_refl);
608+
T.mapply (`slprop_equiv_refl)
609+
594610
let slprop_equiv_ext' (p1 p2:slprop) (_: squash (p1 == p2))
595611
: slprop_equiv p1 p2 = slprop_equiv_refl p1
596612

src/checker/Pulse.Checker.AssertWithBinders.fst

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,15 @@ let def_of_fv (g:T.env) (fv:R.fv)
142142
| R.Sg_Inductive _nm _univs params typ _ -> None
143143

144144
let unfold_head (g : env) (t:term)
145-
: T.Tac term
145+
: T.Tac (term & string)
146146
= let rg = elab_env g in
147147
match T.hua t with
148148
| Some (fv, u, args) -> (
149149
(* zeta to allow unfolding recursive definitions. Should be only once
150150
unless it appears on the head of its own definition.. which should be impossible? *)
151-
let t = T.norm_term_env rg [hnf; zeta; delta_only [T.implode_qn (T.inspect_fv fv)]] t in
152-
t
151+
let head_symbol = T.implode_qn (T.inspect_fv fv) in
152+
let t = T.norm_term_env rg [hnf; zeta; delta_only [head_symbol]] t in
153+
t, head_symbol
153154
(* Something like this would be better, but we need to instantiate
154155
the universes, and we don't have a good way to do that yet.
155156
match def_of_fv rg fv with
@@ -166,16 +167,22 @@ let unfold_head (g : env) (t:term)
166167
fail g (Some (RU.range_of_term t))
167168
(Printf.sprintf "Cannot unfold %s, the head is not an fvar" (T.term_to_string t))
168169

169-
let unfold_defs (g:env) (defs:option (list string)) (t:term)
170-
: T.Tac term
171-
= let t = unfold_head g t in
170+
let unfold_defs' (g:env) (defs:option (list string)) (t:term)
171+
: T.Tac (term & string)
172+
= let t, head_sym = unfold_head g t in
172173
let t =
173174
match defs with
174175
| None -> t
175176
| Some defs -> unfold_all g defs t
176177
in
177178
let t = T.norm_term_env (elab_env g) [hnf; iota; primops] t in
178-
t
179+
t, head_sym
180+
181+
let unfold_defs (g:env) (defs:option (list string)) (t:term)
182+
: T.Tac (term & string)
183+
= RU.profile (fun () -> unfold_defs' g defs t)
184+
(T.moduleof (fstar_env g))
185+
"Pulse.Checker.Unfold"
179186

180187
let check_unfoldable g (v:term) : T.Tac unit =
181188
match inspect_term v with
@@ -445,8 +452,8 @@ let check
445452
(| x, x_ty, pre'', g2, k_elab_trans k_frame k |)
446453

447454

448-
| UNFOLD { names; p=v }
449-
| FOLD { names; p=v } ->
455+
| UNFOLD { p=v }
456+
| FOLD { p=v } ->
450457

451458
let (| uvs, v_opened, body_opened |) =
452459
let bs = infer_binder_types g bs v in
@@ -461,14 +468,15 @@ let check
461468
add_rem_uvs (push_env g uvs) t_rem (mk_env (fstar_env g)) v_opened in
462469
push_env uvs uvs_rem, v_opened in
463470

464-
let lhs, rhs =
471+
let lhs, rhs, tac =
465472
match hint_type with
466473
| UNFOLD _ ->
467-
v_opened,
468-
unfold_defs (push_env g uvs) None v_opened
474+
let rhs, head_sym = unfold_defs (push_env g uvs) None v_opened in
475+
v_opened, rhs, Pulse.Reflection.Util.slprop_equiv_unfold_tm head_sym
469476
| FOLD { names=ns } ->
470-
unfold_defs (push_env g uvs) ns v_opened,
471-
v_opened in
477+
let lhs, head_sym = unfold_defs (push_env g uvs) ns v_opened in
478+
lhs, v_opened, Pulse.Reflection.Util.slprop_equiv_fold_tm head_sym
479+
in
472480

473481
let uvs_bs = uvs |> bindings_with_ppname |> L.rev in
474482
let uvs_closing = uvs_bs |> closing in
@@ -491,8 +499,7 @@ let check
491499
] in
492500
info_doc_env g (Some st.range) msg
493501
end;
494-
495-
let rw = mk_term (Tm_Rewrite { t1 = lhs; t2 = rhs; tac_opt = Some Pulse.Reflection.Util.slprop_equiv_norm_tm }) st.range in
502+
let rw = mk_term (Tm_Rewrite { t1 = lhs; t2 = rhs; tac_opt = Some tac }) st.range in
496503
let rw = { rw with effect_tag = as_effect_hint STT_Ghost } in
497504

498505
let st = mk_term (Tm_Bind { binder = as_binder (wr (`unit) st.range); head = rw; body }) st.range in

src/checker/Pulse.Checker.Rewrite.fst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ let check
129129
| None ->
130130
check_slprop_equiv t.range g p q
131131
| Some tac ->
132-
check_slprop_equiv_tac t.range g p q tac
132+
RU.profile (fun () -> check_slprop_equiv_tac t.range g p q tac)
133+
(T.moduleof (fstar_env g))
134+
"Pulse.Checker.Rewrite.check_slprop_equiv_tac"
133135
in
134136
let d = T_Rewrite _ p q p_typing equiv_p_q in
135137
prove_post_hint (try_frame_pre false pre_typing (match_comp_res_with_post_hint d post_hint) res_ppname) post_hint t.range

src/checker/Pulse.Reflection.Util.fst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ let seq_create_lid = ["FStar"; "Seq"; "Base"; "create"]
6262
let tot_lid = ["Prims"; "Tot"]
6363

6464
let slprop_equiv_norm_tm = R.pack_ln (R.Tv_FVar (R.pack_fv (mk_pulse_lib_core_lid "slprop_equiv_norm")))
65+
let slprop_equiv_fold_tm (s:string) =
66+
let head = R.pack_ln (R.Tv_FVar (R.pack_fv (mk_pulse_lib_core_lid "slprop_equiv_fold"))) in
67+
let s = R.pack_ln (R.Tv_Const (R.C_String s)) in
68+
let t = R.pack_ln (R.Tv_App head (s, R.Q_Explicit)) in
69+
t
70+
let slprop_equiv_unfold_tm (s:string) =
71+
let head = R.pack_ln (R.Tv_FVar (R.pack_fv (mk_pulse_lib_core_lid "slprop_equiv_unfold"))) in
72+
let s = R.pack_ln (R.Tv_Const (R.C_String s)) in
73+
let t = R.pack_ln (R.Tv_App head (s, R.Q_Explicit)) in
74+
t
6575
let match_rewrite_tac_tm = R.pack_ln (R.Tv_FVar (R.pack_fv (mk_pulse_lib_core_lid "match_rewrite_tac")))
6676

6777
(* The "plicities" *)

src/checker/Pulse.RuntimeUtils.fsti

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,15 @@ val norm_well_typed_term
8181
Ghost.erased (RT.related g t RT.R_Eq t')
8282
)
8383
val add_attribute (x:T.sigelt) (_:R.term) : (y:T.sigelt { x == y })
84-
val get_attributes (x:T.sigelt) : T.Tac (list R.term)
84+
val get_attributes (x:T.sigelt) : T.Tac (list R.term)
85+
8586
val add_noextract_qual (x:T.sigelt) : (y:T.sigelt { x == y })
8687

8788
val must_erase_for_extraction (g:env) (ty:T.term) : bool
8889

8990
val magic : #a: Type -> unit -> GTot a
9091
(* magic with a string, to at least report an error message if it is hit at runtime *)
9192
val magic_s: #a: Type -> string -> Tot a
93+
94+
val profile (f:(unit -> Tac 'b)) (module_name:name) (component_name:string)
95+
: Tac 'b

src/ml/Pulse_RuntimeUtils.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,9 @@ let must_erase_for_extraction (g:FStarC_Reflection_Types.env) (ty:FStarC_Syntax_
213213
FStarC_TypeChecker_Util.must_erase_for_extraction g ty
214214

215215
let magic_s s = failwith ("Cannot execute magic: " ^ s)
216+
217+
let profile (f: unit -> 'b utac) (module_name:string list) (component_name:string)
218+
: 'b utac
219+
= fun ps ->
220+
let name = String.concat "." module_name in
221+
FStarC_Profiling.profile (fun () -> f () ps) (Some name) component_name

0 commit comments

Comments
 (0)