@@ -17,8 +17,22 @@ module Elpi_AUX = struct
1717 let s, l, _ = Utils. map_acc f s l in
1818 s, l
1919
20+ let loc_of_pos = function
21+ | None -> Ast.Loc. initial " (elpi)"
22+ | Some x ->
23+ let { Pos. fname; start_line; start_col; _ } = Lazy. force x in
24+ {
25+ Ast.Loc. source_name = Extra.Option. get " (.)" fname;
26+ source_start = 0 ;
27+ source_stop = 0 ;
28+ line = start_line;
29+ line_starts_at = start_col;
30+ }
31+
2032end
2133
34+ (* * Terms.sym is exposed to Elpi as an opaque data type (no syntax like int or
35+ string). APIs are provided to manipulate symbols, eg get their type *)
2236let sym : Terms.sym Conversion.t = OpaqueData. declare {
2337 OpaqueData. name = " symbol" ;
2438 doc = " A symbol" ;
@@ -29,23 +43,32 @@ let sym : Terms.sym Conversion.t = OpaqueData.declare {
2943 constants = [] ;
3044}
3145
46+ (* * Waiting for a ppx to do all the work for us, we code by hand the
47+ conversion of Terms.term *)
48+
49+ (* Allocate Elpi symbols for the term constructors (type and kind are Elpi
50+ keywords, hence typ and kin) *)
3251let typec = RawData.Constants. declare_global_symbol " typ"
3352let kindc = RawData.Constants. declare_global_symbol " kin"
3453let symbc = RawData.Constants. declare_global_symbol " symb"
3554let prodc = RawData.Constants. declare_global_symbol " prod"
3655let abstc = RawData.Constants. declare_global_symbol " abst"
3756let applc = RawData.Constants. declare_global_symbol " appl"
3857
58+ (* A two way map linking Elpi's unification variable and Terms.meta.
59+ An instance of this map is part of the Elpi state (threaded by many
60+ APIs) *)
3961module M = struct
4062 type t = Terms .meta
4163 let compare m1 m2 = Stdlib. compare m1.Terms. meta_key m2.Terms. meta_key
4264 let pp = Print. pp_meta
4365 let show m = Format. asprintf " %a" pp m
4466end
4567module MM = FlexibleData. Map (M )
46-
4768let metamap : MM.t State.component = MM. uvmap
4869
70+ (* Terms.term -> Data.term, we use Ctxt.ctxt to carry a link between
71+ Bindlib's var to Elpi's De Duijn levels *)
4972let embed_term : Terms.term Conversion.embedding = fun ~depth st t ->
5073 let open RawData in
5174 let open Terms in
@@ -93,6 +116,8 @@ let embed_term : Terms.term Conversion.embedding = fun ~depth st t ->
93116 let st, t = aux ~depth [] st t in
94117 st, t, List. rev ! gls
95118
119+ (* Data.term -> Terms.term. We use and IntMap to link Elpi's De Bruijn
120+ levels to Bindlib's var *)
96121let readback_term_box : Terms.term Bindlib.box Conversion.readback =
97122fun ~depth st t ->
98123 let open RawData in
@@ -152,6 +177,7 @@ let readback_term ~depth st t =
152177 let st, t, gls = readback_term_box ~depth st t in
153178 st, Bindlib. unbox t, gls
154179
180+ (* * Terms.term has a HOAS *)
155181let term : Terms.term Conversion.t = {
156182 Conversion. ty = Conversion. TyName " term" ;
157183 pp = Print. pp_term;
@@ -168,6 +194,8 @@ type prod term -> (term -> term) -> term.
168194 embed = embed_term ;
169195}
170196
197+ (* * Assignments to Elpi's unification variables are a spine of lambdas
198+ followed by an actual term. We read them back as a Bindlib.mbinder *)
171199let readback_mbinder st t =
172200 let open RawData in
173201 let rec aux ~depth nvars t =
@@ -181,8 +209,6 @@ let readback_mbinder st t =
181209 st, unbox (bind_mvar vs t)
182210 in
183211 aux ~depth: 0 0 t
184-
185-
186212let readback_assignments st =
187213 let mmap = State. get metamap st in
188214 MM. fold (fun meta _flex body st ->
@@ -198,6 +224,7 @@ let readback_assignments st =
198224 st
199225 ) mmap st
200226
227+ (* * APIs (data types and predicates) exposed to Elpi *)
201228let lambdapi_builtin_declarations : BuiltIn.declaration list =
202229 let open BuiltIn in
203230 let open BuiltInPredicate in
@@ -232,51 +259,44 @@ let lambdapi_builtin_declarations : BuiltIn.declaration list =
232259let lambdapi_builtins =
233260 BuiltIn. declare ~file_name: " lambdap.elpi" lambdapi_builtin_declarations
234261
235- let elpi = ref None
236-
237262let document () =
238263 BuiltIn. document_file ~header: " % automatically generated" lambdapi_builtins
239264
265+ (* * The runtime of Elpi (we need only one I guess) *)
266+ let elpi = ref None
267+
240268let init () =
241269 let e, _ = Setup. init ~builtins: [lambdapi_builtins] ~basedir: " ." [] in
242270 elpi := Some e ;
243271 document ()
244272
245- let loc_of_pos = function
246- | None -> Ast.Loc. initial " (elpi)"
247- | Some x ->
248- let { Pos. fname; start_line; start_col; _ } = Lazy. force x in
249- {
250- Ast.Loc. source_name = Extra.Option. get " (.)" fname;
251- source_start = 0 ;
252- source_stop = 0 ;
253- line = start_line;
254- line_starts_at = start_col;
255- }
256-
273+ (* * Given an Elpi file, a predicate name and a Terms.term argument we
274+ run Elpi and print the term before/after the execution *)
257275let run : Sig_state.t -> string -> string -> Syntax.p_term -> unit =
258276fun ss file predicate arg ->
259277 let pos = arg.Pos. pos in
278+ let loc = Elpi_AUX. loc_of_pos pos in
260279 let arg = Scope. scope_term Public ss Env. empty arg in
261280 let elpi = match ! elpi with None -> assert false | Some x -> x in
281+
262282 let ast = Parse. program ~elpi [file] in
263283 let prog =
264284 Elpi.API.Compile. program
265285 ~flags: Elpi.API.Compile. default_flags ~elpi [ast] in
266- let loc = loc_of_pos pos in
267- let arguments = Query. (D (term,arg,N )) in
268- let query = Query. (compile prog loc (Query { predicate; arguments })) in
286+ let query =
287+ let open Query in
288+ compile prog loc (Query { predicate; arguments = D (term,arg,N ) }) in
289+
269290 if not (Elpi.API.Compile. static_check
270291 ~checker: (Elpi.Builtin. default_checker () ) query) then
271- Console. fatal pos " elpi: type error" ;
272- let exe = Elpi.API.Compile. optimize query in
273- Format. printf " \n elpi: before: %a\n " Print. pp_term arg;
274- match Execute. once exe with
292+ Console. fatal pos " elpi: type error in %s " file ;
293+
294+ Console. out 1 " \n elpi: before: %a\n " Print. pp_term arg;
295+ match Execute. once ( Elpi.API.Compile. optimize query) with
275296 | Execute. Success { Data. state; pp_ctx; constraints; _ } ->
276297 let _ = readback_assignments state in
277- Format. printf " \n elpi: after: %a\n "
278- Print. pp_term arg;
279- Format. printf " elpi: constraints: %a\n "
298+ Console. out 1 " \n elpi: after: %a\n " Print. pp_term arg;
299+ Console. out 1 " elpi: constraints: %a\n "
280300 Pp. (constraints pp_ctx) constraints
281301 | Failure -> Console. fatal_no_pos " elpi: failure"
282302 | NoMoreSteps -> assert false
0 commit comments