Skip to content

Commit f056bc0

Browse files
Gustavo2622strub
authored andcommitted
Rigid unification option for hint solve/exact + print hint
1 parent 2c4a5e1 commit f056bc0

16 files changed

+215
-126
lines changed

src/ecCommands.ml

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
open EcUtils
33
open EcLocation
44
open EcParsetree
5+
open EcMaps
56

67
module Sid = EcIdent.Sid
78
module Mx = EcPath.Mx
@@ -298,46 +299,6 @@ let process_print_ax (scope : EcScope.scope) =
298299
let env = EcScope.env scope in
299300
let ax = EcEnv.Ax.all ~check:(fun _ ax -> EcDecl.is_axiom ax.ax_kind) env in
300301

301-
let module Trie : sig
302-
type ('a, 'b) t
303-
304-
val empty : ('a, 'b) t
305-
val add : 'a list -> 'b -> ('a, 'b) t -> ('a, 'b) t
306-
val iter : ('a list -> 'b list -> unit) -> ('a, 'b) t -> unit
307-
end = struct
308-
module Map = BatMap
309-
310-
type ('a, 'b) t =
311-
{ children : ('a, ('a, 'b) t) Map.t
312-
; value : 'b list }
313-
314-
let empty : ('a, 'b) t =
315-
{ value = []; children = Map.empty; }
316-
317-
let add (path : 'a list) (value : 'b) (t : ('a, 'b) t) =
318-
let rec doit (path : 'a list) (t : ('a, 'b) t) =
319-
match path with
320-
| [] ->
321-
{ t with value = value :: t.value }
322-
| v :: path ->
323-
let children =
324-
t.children |> Map.update_stdlib v (fun children ->
325-
let subtrie = Option.value ~default:empty children in
326-
Some (doit path subtrie)
327-
)
328-
in { t with children }
329-
in doit path t
330-
331-
let iter (f : 'a list -> 'b list -> unit) (t : ('a, 'b) t) =
332-
let rec doit (prefix : 'a list) (t : ('a, 'b) t) =
333-
if not (List.is_empty t.value) then
334-
f prefix t.value;
335-
Map.iter (fun k v -> doit (k :: prefix) v) t.children
336-
in
337-
338-
doit [] t
339-
end in
340-
341302
let ax =
342303
List.fold_left (fun axs ((p, _) as ax) ->
343304
Trie.add (EcPath.tolist (oget (EcPath.prefix p))) ax axs
@@ -354,7 +315,6 @@ let process_print_ax (scope : EcScope.scope) =
354315
| name :: prefix -> (List.rev prefix, name) in
355316

356317
let thpath = EcPath.fromqsymbol thpath in
357-
358318
let ppe = EcPrinting.PPEnv.enter_theory ppe0 thpath in
359319

360320
Format.fprintf fmt
@@ -367,6 +327,41 @@ let process_print_ax (scope : EcScope.scope) =
367327

368328
EcScope.notify scope `Warning "%s" (Buffer.contents buffer)
369329

330+
(* -------------------------------------------------------------------- *)
331+
let process_print_hint (scope : EcScope.scope) =
332+
let env = EcScope.env scope in
333+
let ax = EcEnv.Auto.all env in
334+
let ax = List.map (fun (ir, p) -> (p, (EcEnv.Ax.by_path p env, ir))) ax in
335+
let ax =
336+
List.fold_left (fun axs ((p, _) as ax) ->
337+
Trie.add (EcPath.tolist (oget (EcPath.prefix p))) ax axs
338+
) Trie.empty ax in
339+
340+
let ppe0 = EcPrinting.PPEnv.ofenv env in
341+
let buffer = Buffer.create 0 in
342+
let fmt = Format.formatter_of_buffer buffer in
343+
344+
Trie.iter (fun prefix axs ->
345+
let thpath =
346+
match prefix with
347+
| [] -> assert false
348+
| name :: prefix -> (List.rev prefix, name) in
349+
350+
let thpath = EcPath.fromqsymbol thpath in
351+
352+
let ppe = EcPrinting.PPEnv.enter_theory ppe0 thpath in
353+
354+
Format.fprintf fmt
355+
"@.========== %a ==========@.@." (EcPrinting.pp_thname ppe0) thpath;
356+
357+
List.iter (fun (p, (ax, ir)) ->
358+
Format.fprintf fmt "%a%s@." (EcPrinting.pp_axiom ppe) (p, ax)
359+
(if ir then " (irreducible)" else " (reducible)")
360+
) axs
361+
) ax;
362+
363+
EcScope.notify scope `Warning "%s" (Buffer.contents buffer)
364+
370365
(* -------------------------------------------------------------------- *)
371366
exception Pragma of [`Reset | `Restart]
372367

@@ -735,6 +730,7 @@ and process (ld : Loader.loader) (scope : EcScope.scope) g =
735730
| GsctClose name -> `Fct (fun scope -> process_sct_close scope name)
736731
| Gprint p -> `Fct (fun scope -> process_print scope p; scope)
737732
| Gpaxiom -> `Fct (fun scope -> process_print_ax scope; scope)
733+
| Gphint -> `Fct (fun scope -> process_print_hint scope; scope)
738734
| Gsearch qs -> `Fct (fun scope -> process_search scope qs; scope)
739735
| Glocate x -> `Fct (fun scope -> process_locate scope x; scope)
740736
| Gtactics t -> `Fct (fun scope -> process_tactics scope t)

src/ecEnv.ml

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ type preenv = {
181181
env_tci : ((ty_params * ty) * tcinstance) list;
182182
env_tc : TC.graph;
183183
env_rwbase : Sp.t Mip.t;
184-
env_atbase : (path list Mint.t) Msym.t;
184+
env_atbase : (bool * path) list Mint.t Msym.t; (* maybe rename to atbases? *)
185185
env_redbase : mredinfo;
186186
env_ntbase : ntbase Mop.t;
187187
env_modlcs : Sid.t; (* declared modules *)
@@ -221,6 +221,7 @@ and env_notation = ty_params * EcDecl.notation
221221

222222
and ntbase = (path * env_notation) list
223223

224+
224225
(* -------------------------------------------------------------------- *)
225226
type env = preenv
226227

@@ -1502,39 +1503,39 @@ end
15021503
module Auto = struct
15031504
let dname : symbol = ""
15041505
1505-
let updatedb ~level ?base (ps : path list) (db : (path list Mint.t) Msym.t) =
1506+
let updatedb ~level ?base (ps : (bool * path) list) (db : (bool * path) list Mint.t Msym.t) =
15061507
let nbase = (odfl dname base) in
1507-
let ps' = Msym.find_def Mint.empty nbase db in
1508-
let ps' =
1508+
let base = Msym.find_def Mint.empty nbase db in
1509+
let levels =
15091510
let doit x = Some (ofold (fun x ps -> ps @ x) ps x) in
1510-
Mint.change doit level ps' in
1511-
Msym.add nbase ps' db
1511+
Mint.change doit level base in
1512+
Msym.add nbase levels db
15121513
1513-
let add ?(import = import0) ~level ?base (ps : path list) lc (env : env) =
1514+
let add ?(import = import0) ~level ?base (axioms : (bool * path) list) locality (env : env) =
15141515
let env =
15151516
if import.im_immediate then
15161517
{ env with
1517-
env_atbase = updatedb ?base ~level ps env.env_atbase; }
1518+
env_atbase = updatedb ?base ~level axioms env.env_atbase; }
15181519
else env
15191520
in
15201521
{ env with env_item = mkitem import
1521-
(Th_auto (level, base, ps, lc)) :: env.env_item; }
1522+
(Th_auto {level; base; axioms; locality}) :: env.env_item; }
15221523
1523-
let add1 ?import ~level ?base (p : path) lc (env : env) =
1524+
let add1 ?import ~level ?base (p : (bool * path)) lc (env : env) =
15241525
add ?import ?base ~level [p] lc env
15251526
15261527
let get_core ?base (env : env) =
15271528
Msym.find_def Mint.empty (odfl dname base) env.env_atbase
15281529
1529-
let flatten_db (db : path list Mint.t) =
1530+
let flatten_db (db : (bool * path) list Mint.t) =
15301531
Mint.fold_left (fun ps _ ps' -> ps @ ps') [] db
15311532
15321533
let get ?base (env : env) =
15331534
flatten_db (get_core ?base env)
15341535
1535-
let getall (bases : symbol list) (env : env) =
1536+
let getall (bases : symbol list) (env : env) : (bool * path) list =
15361537
let dbs = List.map (fun base -> get_core ~base env) bases in
1537-
let dbs =
1538+
let dbs =
15381539
List.fold_left (fun db mi ->
15391540
Mint.union (fun _ sp1 sp2 -> Some (sp1 @ sp2)) db mi)
15401541
Mint.empty dbs
@@ -1543,6 +1544,9 @@ module Auto = struct
15431544
let getx (base : symbol) (env : env) =
15441545
let db = Msym.find_def Mint.empty base env.env_atbase in
15451546
Mint.bindings db
1547+
1548+
let all (env : env) : (bool * path) list =
1549+
Msym.values env.env_atbase |> List.map flatten_db |> List.flatten
15461550
end
15471551
15481552
(* -------------------------------------------------------------------- *)
@@ -2932,8 +2936,8 @@ module Theory = struct
29322936
(* ------------------------------------------------------------------ *)
29332937
let bind_at_th =
29342938
let for1 _path db = function
2935-
| Th_auto (level, base, ps, _) ->
2936-
Some (Auto.updatedb ?base ~level ps db)
2939+
| Th_auto {level; base; axioms; _} ->
2940+
Some (Auto.updatedb ?base ~level axioms db)
29372941
| _ -> None
29382942
29392943
in bind_base_th for1
@@ -3106,9 +3110,9 @@ module Theory = struct
31063110
let ps = List.filter ((not) |- inclear |- oget |- EcPath.prefix) ps in
31073111
if List.is_empty ps then None else Some (Th_addrw (p, ps,lc))
31083112
3109-
| Th_auto (lvl, base, ps, lc) ->
3110-
let ps = List.filter ((not) |- inclear |- oget |- EcPath.prefix) ps in
3111-
if List.is_empty ps then None else Some (Th_auto (lvl, base, ps, lc))
3113+
| Th_auto ({axioms} as auto_rl) ->
3114+
let axioms = List.filter (fun (_b, p) -> ((not) |- inclear |- oget |- EcPath.prefix) p) axioms in
3115+
if List.is_empty axioms then None else Some (Th_auto {auto_rl with axioms})
31123116
31133117
| (Th_export (p, _)) as item ->
31143118
if Sp.mem p cleared then None else Some item

src/ecEnv.mli

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,12 @@ end
413413
(* -------------------------------------------------------------------- *)
414414
module Auto : sig
415415
val dname : symbol
416-
val add1 : ?import:import -> level:int -> ?base:symbol -> path -> is_local -> env -> env
417-
val add : ?import:import -> level:int -> ?base:symbol -> path list -> is_local -> env -> env
418-
val get : ?base:symbol -> env -> path list
419-
val getall : symbol list -> env -> path list
420-
val getx : symbol -> env -> (int * path list) list
416+
val add1 : ?import:import -> level:int -> ?base:symbol -> (bool * path) -> is_local -> env -> env
417+
val add : ?import:import -> level:int -> ?base:symbol -> (bool * path) list -> is_local -> env -> env
418+
val get : ?base:symbol -> env -> (bool * path) list
419+
val getall : symbol list -> env -> (bool * path) list
420+
val getx : symbol -> env -> (int * (bool * path) list) list
421+
val all : env -> (bool * path) list
421422
end
422423

423424
(* -------------------------------------------------------------------- *)

src/ecLexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@
183183
"local" , LOCAL ; (* KW: global *)
184184
"declare" , DECLARE ; (* KW: global *)
185185
"hint" , HINT ; (* KW: global *)
186+
"irreducible" , IRREDUCIBLE; (* KW: global *)
186187
"module" , MODULE ; (* KW: global *)
187188
"of" , OF ; (* KW: global *)
188189
"const" , CONST ; (* KW: global *)

src/ecLowGoal.ml

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ module Apply = struct
726726

727727
exception NoInstance of (bool * reason * PT.pt_env * (form * form))
728728

729-
let t_apply_bwd_r ?(mode = fmdelta) ?(canview = true) pt (tc : tcenv1) =
729+
let t_apply_bwd_r ?(ri = EcReduction.full_compat) ?(mode = fmdelta) ?(canview = true) pt (tc : tcenv1) =
730730
let ((hyps, concl), pterr) = (FApi.tc1_flat tc, PT.copy pt.ptev_env) in
731731

732732
let noinstance ?(dpe = false) reason =
@@ -736,7 +736,7 @@ module Apply = struct
736736
match istop && PT.can_concretize pt.PT.ptev_env with
737737
| true ->
738738
let ax = PT.concretize_form pt.PT.ptev_env pt.PT.ptev_ax in
739-
if EcReduction.is_conv ~ri:EcReduction.full_compat hyps ax concl
739+
if EcReduction.is_conv ~ri hyps ax concl
740740
then pt
741741
else instantiate canview false pt
742742

@@ -747,7 +747,7 @@ module Apply = struct
747747
noinstance `IncompleteInference;
748748
pt
749749
with EcMatching.MatchFailure ->
750-
match TTC.destruct_product hyps pt.PT.ptev_ax with
750+
match TTC.destruct_product ~reduce:(mode.fm_conv) hyps pt.PT.ptev_ax with
751751
| Some _ ->
752752
(* FIXME: add internal marker *)
753753
instantiate canview false (PT.apply_pterm_to_hole pt)
@@ -800,15 +800,15 @@ module Apply = struct
800800

801801
t_apply pt tc
802802

803-
let t_apply_bwd ?mode ?canview pt (tc : tcenv1) =
803+
let t_apply_bwd ?(ri : EcReduction.reduction_info option) ?mode ?canview pt (tc : tcenv1) =
804804
let hyps = FApi.tc1_hyps tc in
805805
let pt, ax = LowApply.check `Elim pt (`Hyps (hyps, !!tc)) in
806806
let ptenv = ptenv_of_penv hyps !!tc in
807807
let pt = { ptev_env = ptenv; ptev_pt = pt; ptev_ax = ax; } in
808-
t_apply_bwd_r ?mode ?canview pt tc
808+
t_apply_bwd_r ?ri ?mode ?canview pt tc
809809

810-
let t_apply_bwd_hi ?(dpe = true) ?mode ?canview pt (tc : tcenv1) =
811-
try t_apply_bwd ?mode ?canview pt tc
810+
let t_apply_bwd_hi ?(ri : EcReduction.reduction_info option) ?(dpe = true) ?mode ?canview pt (tc : tcenv1) =
811+
try t_apply_bwd ?ri ?mode ?canview pt tc
812812
with (NoInstance (_, r, pt, f)) ->
813813
tc_error_exn !!tc (NoInstance (dpe, r, pt, f))
814814
end
@@ -2506,22 +2506,26 @@ let t_coq
25062506
let t_solve ?(canfail = true) ?(bases = [EcEnv.Auto.dname]) ?(mode = fmdelta) ?(depth = 1) (tc : tcenv1) =
25072507
let bases = EcEnv.Auto.getall bases (FApi.tc1_env tc) in
25082508

2509-
let t_apply1 p tc =
25102509

2510+
let t_apply1 ((ir, p): bool * path) tc =
2511+
let ri = if ir then EcReduction.no_red else EcReduction.full_compat in
2512+
let mode = if ir then fmsearch else mode in
25112513
let pt = PT.pt_of_uglobal !!tc (FApi.tc1_hyps tc) p in
25122514
try
2513-
Apply.t_apply_bwd_r ~mode ~canview:false pt tc
2514-
with Apply.NoInstance _ -> t_fail tc in
2515+
Apply.t_apply_bwd_r ~ri ~mode ~canview:false pt tc
2516+
with Apply.NoInstance _ ->
2517+
t_fail tc
2518+
in
25152519

2516-
let rec t_apply ctn p tc =
2520+
let rec t_apply ctn ip tc =
25172521
if ctn > depth
25182522
then t_fail tc
2519-
else (t_apply1 p @! t_trivial @! t_solve (ctn + 1) bases) tc
2523+
else (t_apply1 ip @! t_trivial @! t_solve (ctn + 1) bases) tc
25202524

25212525
and t_solve ctn bases tc =
25222526
match bases with
25232527
| [] -> t_abort tc
2524-
| p::bases -> (FApi.t_or (t_apply ctn p) (t_solve ctn bases)) tc in
2528+
| ip::bases -> (FApi.t_or (t_apply ctn ip) (t_solve ctn bases)) tc in
25252529

25262530
let t = t_solve 0 bases in
25272531
let t = if canfail then FApi.t_try t else t in

src/ecLowGoal.mli

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,13 @@ module Apply : sig
134134
exception NoInstance of (bool * reason * pt_env * (form * form))
135135

136136
val t_apply_bwd_r :
137-
?mode:fmoptions -> ?canview:bool -> pt_ev -> FApi.backward
137+
?ri:EcReduction.reduction_info -> ?mode:fmoptions -> ?canview:bool -> pt_ev -> FApi.backward
138138

139139
val t_apply_bwd :
140-
?mode:fmoptions -> ?canview:bool -> proofterm -> FApi.backward
140+
?ri:EcReduction.reduction_info -> ?mode:fmoptions -> ?canview:bool -> proofterm -> FApi.backward
141141

142142
val t_apply_bwd_hi:
143-
?dpe:bool -> ?mode:fmoptions -> ?canview:bool
144-
-> proofterm -> FApi.backward
143+
?ri:EcReduction.reduction_info -> ?dpe:bool -> ?mode:fmoptions -> ?canview:bool -> proofterm -> FApi.backward
145144
end
146145

147146
(* -------------------------------------------------------------------- *)

src/ecMaps.ml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,44 @@ module Hdint = EHashtbl.Make(DInt)
148148
(* --------------------------------------------------------------------*)
149149
module Mstr = Map.Make(String)
150150
module Sstr = Set.MakeOfMap(Mstr)
151+
152+
(* --------------------------------------------------------------------*)
153+
module Trie : sig
154+
type ('a, 'b) t
155+
156+
val empty : ('a, 'b) t
157+
val add : 'a list -> 'b -> ('a, 'b) t -> ('a, 'b) t
158+
val iter : ('a list -> 'b list -> unit) -> ('a, 'b) t -> unit
159+
end = struct
160+
module Map = BatMap
161+
162+
type ('a, 'b) t =
163+
{ children : ('a, ('a, 'b) t) Map.t
164+
; value : 'b list }
165+
166+
let empty : ('a, 'b) t =
167+
{ value = []; children = Map.empty; }
168+
169+
let add (path : 'a list) (value : 'b) (t : ('a, 'b) t) =
170+
let rec doit (path : 'a list) (t : ('a, 'b) t) =
171+
match path with
172+
| [] ->
173+
{ t with value = value :: t.value }
174+
| v :: path ->
175+
let children =
176+
t.children |> Map.update_stdlib v (fun children ->
177+
let subtrie = Option.value ~default:empty children in
178+
Some (doit path subtrie)
179+
)
180+
in { t with children }
181+
in doit path t
182+
183+
let iter (f : 'a list -> 'b list -> unit) (t : ('a, 'b) t) =
184+
let rec doit (prefix : 'a list) (t : ('a, 'b) t) =
185+
if not (List.is_empty t.value) then
186+
f prefix t.value;
187+
Map.iter (fun k v -> doit (k :: prefix) v) t.children
188+
in
189+
190+
doit [] t
191+
end

0 commit comments

Comments
 (0)