Skip to content

Commit b84e164

Browse files
committed
fix query type
1 parent e0efada commit b84e164

17 files changed

+546
-423
lines changed

src/.ppcache/API.ml

Lines changed: 113 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(*09dd92d029bc5129509dbb9e46c435ff8be4de41 *src/API.ml --cookie elpi_trace="false"*)
1+
(*332b22a78600ccb50a6a5a1271c10ce168f491b0 *src/API.ml --cookie elpi_trace="false"*)
22
#1 "src/API.ml"
33
module type Runtime = module type of Runtime_trace_off
44
let r = ref ((module Runtime_trace_off) : (module Runtime))
@@ -204,10 +204,103 @@ module Conversion =
204204
fun s -> fun x -> t.readback ~depth ((new ctx) h#raw) c s x)
205205
}
206206
end
207+
module OpaqueData =
208+
struct
209+
include Util.CData
210+
include ED.C
211+
type name = string
212+
type doc = string
213+
type 'a declaration =
214+
{
215+
name: name ;
216+
cname: name ;
217+
doc: doc ;
218+
pp: Format.formatter -> 'a -> unit ;
219+
compare: 'a -> 'a -> int ;
220+
hash: 'a -> int ;
221+
hconsed: bool ;
222+
constants: (name * 'a) list }
223+
type 'a cdata_with_constants =
224+
('a cdata * name * (string * 'a) ED.Constants.Map.t * doc)
225+
let rest ({ cin; name = c }, name, constants_map, doc) =
226+
((Conversion.TyName name), (fun fmt -> fun x -> pp fmt (cin x)),
227+
(fun fmt ->
228+
fun () ->
229+
let module R = (val !r) in
230+
let open R in
231+
if doc <> ""
232+
then
233+
(ED.BuiltInPredicate.pp_comment fmt ("% " ^ doc);
234+
Format.fprintf fmt "@\n");
235+
Format.fprintf fmt
236+
"@[<hov 2>typeabbrev %s (ctype \"%s\").@]@\n@\n" name c;
237+
ED.Constants.Map.iter
238+
(fun _ ->
239+
fun (c, _) ->
240+
Format.fprintf fmt "@[<hov 2>type %s %s.@]@\n" c name)
241+
constants_map))
242+
let embed ({ cin;_}, _, _, _) =
243+
();
244+
(fun ~depth:_ ->
245+
fun _ ->
246+
fun _ ->
247+
fun state -> fun x -> (state, (ED.Term.CData (cin x)), []))
248+
let readback ({ isc; cout;_}, name, constants_map, _) =
249+
();
250+
(fun ~depth ->
251+
fun _ ->
252+
fun _ ->
253+
fun state ->
254+
fun t ->
255+
let module R = (val !r) in
256+
let open R in
257+
match R.deref_head ~depth t with
258+
| ED.Term.CData c when isc c -> (state, (cout c), [])
259+
| ED.Term.Const i as t when i < 0 ->
260+
(try
261+
(state,
262+
(snd @@ (ED.Constants.Map.find i constants_map)),
263+
[])
264+
with
265+
| Not_found ->
266+
raise
267+
(Conversion.TypeErr
268+
((Conversion.TyName name), depth, t)))
269+
| t ->
270+
raise
271+
(Conversion.TypeErr
272+
((Conversion.TyName name), depth, t)))
273+
let declare { name; cname; doc; pp; compare; hash; hconsed; constants } =
274+
let cdata =
275+
declare
276+
{
277+
data_compare = compare;
278+
data_pp = pp;
279+
data_hash = hash;
280+
data_name = cname;
281+
data_hconsed = hconsed
282+
} in
283+
(cdata, name,
284+
(List.fold_right
285+
(fun (n, v) ->
286+
ED.Constants.Map.add
287+
(ED.Global_symbols.declare_global_symbol n) (n, v)) constants
288+
ED.Constants.Map.empty), doc)
289+
let build_conversion x =
290+
let (ty, pp, pp_doc) = rest x in
291+
{
292+
Conversion.ty = ty;
293+
pp;
294+
pp_doc;
295+
embed = (embed x);
296+
readback = (readback x)
297+
}
298+
end
207299
module RawOpaqueData =
208300
struct
209301
include Util.CData
210302
include ED.C
303+
let cdata (c, _, _, _) = c
211304
let { cin = of_char; isc = is_char; cout = to_char } as char =
212305
declare
213306
{
@@ -244,88 +337,6 @@ module RawOpaqueData =
244337
data_hconsed = false
245338
}
246339
let of_in_stream x = ED.mkCData (of_in_stream x)
247-
type name = string
248-
type doc = string
249-
type 'a declaration =
250-
{
251-
name: name ;
252-
doc: doc ;
253-
pp: Format.formatter -> 'a -> unit ;
254-
compare: 'a -> 'a -> int ;
255-
hash: 'a -> int ;
256-
hconsed: bool ;
257-
constants: (name * 'a) list }
258-
let conversion_of_cdata ~name ?(doc= "") ~constants_map
259-
{ cin; isc; cout; name = c } =
260-
let ty = Conversion.TyName name in
261-
let embed ~depth:_ _ _ state x = (state, (ED.Term.CData (cin x)), []) in
262-
let readback ~depth _ _ state t =
263-
let module R = (val !r) in
264-
let open R in
265-
match R.deref_head ~depth t with
266-
| ED.Term.CData c when isc c -> (state, (cout c), [])
267-
| ED.Term.Const i as t when i < 0 ->
268-
(try
269-
(state, (snd @@ (ED.Constants.Map.find i constants_map)),
270-
[])
271-
with
272-
| Not_found -> raise (Conversion.TypeErr (ty, depth, t)))
273-
| t -> raise (Conversion.TypeErr (ty, depth, t)) in
274-
let pp_doc fmt () =
275-
let module R = (val !r) in
276-
let open R in
277-
if doc <> ""
278-
then
279-
(ED.BuiltInPredicate.pp_comment fmt ("% " ^ doc);
280-
Format.fprintf fmt "@\n");
281-
Format.fprintf fmt
282-
"@[<hov 2>typeabbrev %s (ctype \"%s\").@]@\n@\n" name c;
283-
ED.Constants.Map.iter
284-
(fun _ ->
285-
fun (c, _) ->
286-
Format.fprintf fmt "@[<hov 2>type %s %s.@]@\n" c name)
287-
constants_map in
288-
{
289-
Conversion.embed = embed;
290-
readback;
291-
ty;
292-
pp_doc;
293-
pp = (fun fmt -> fun x -> pp fmt (cin x))
294-
}
295-
let declare { name; doc; pp; compare; hash; hconsed; constants } =
296-
let cdata =
297-
declare
298-
{
299-
data_compare = compare;
300-
data_pp = pp;
301-
data_hash = hash;
302-
data_name = name;
303-
data_hconsed = hconsed
304-
} in
305-
(cdata,
306-
(List.fold_right
307-
(fun (n, v) ->
308-
ED.Constants.Map.add
309-
(ED.Global_symbols.declare_global_symbol n) (n, v)) constants
310-
ED.Constants.Map.empty), doc)
311-
let declare_cdata (cd, constants_map, doc) =
312-
conversion_of_cdata ~name:(cd.Util.CData.name) ~doc ~constants_map cd
313-
end
314-
module OpaqueData =
315-
struct
316-
type name = string
317-
type doc = string
318-
type 'a declaration = 'a RawOpaqueData.declaration =
319-
{
320-
name: name ;
321-
doc: doc ;
322-
pp: Format.formatter -> 'a -> unit ;
323-
compare: 'a -> 'a -> int ;
324-
hash: 'a -> int ;
325-
hconsed: bool ;
326-
constants: (name * 'a) list }
327-
let declare x =
328-
(x |> RawOpaqueData.declare) |> RawOpaqueData.declare_cdata
329340
end
330341
module Elpi =
331342
struct
@@ -1181,20 +1192,25 @@ module BuiltInPredicate =
11811192
module Query =
11821193
struct
11831194
type name = string
1184-
type 'f arguments = 'f ED.Query.arguments =
1185-
| N: unit arguments
1186-
| D: ('a, Conversion.ctx) Conversion.t * 'a * 'x arguments -> 'x
1187-
arguments
1188-
| Q: ('a, Conversion.ctx) Conversion.t * name * 'x arguments -> ('a *
1189-
'x) arguments
1190-
type 'x t =
1191-
| Query of {
1192-
predicate: name ;
1193-
arguments: 'x arguments }
1194-
let compile (state, p) loc (Query { predicate; arguments }) =
1195+
type ('f, 'c) arguments = ('f, 'c) ED.Query.arguments =
1196+
| N: (unit, 'c) arguments
1197+
| D: ('a, #Conversion.ctx as 'c) Conversion.t * 'a * ('x, 'c) arguments
1198+
-> ('x, 'c) arguments
1199+
| Q: ('a, #Conversion.ctx as 'c) Conversion.t * name * ('x, 'c)
1200+
arguments -> (('a * 'x), 'c) arguments
1201+
type _ t =
1202+
| Query: ('a, 'x, 'c) query_contents * ('a, 'k, Conversion.ctx)
1203+
Conversion.context * (Data.state -> #Conversion.ctx as 'c) -> 'x t
1204+
and ('a, 'x, 'c) query_contents =
1205+
{
1206+
context: 'a list ;
1207+
predicate: string ;
1208+
arguments: ('x, 'c) arguments }
1209+
let compile (state, p) loc (Query
1210+
({ predicate; arguments; context }, cc, obj)) =
11951211
let (state, predicate) =
11961212
Compiler.Symbols.allocate_global_symbol_str state predicate in
1197-
let q = ED.Query.Query { predicate; arguments } in
1213+
let q = ED.Query.Query ({ predicate; arguments; context }, cc, obj) in
11981214
Compiler.query_of_data state p loc q
11991215
end
12001216
module State =
@@ -1210,6 +1226,8 @@ module RawQuery =
12101226
struct
12111227
let mk_Arg = Compiler.mk_Arg
12121228
let is_Arg = Compiler.is_Arg
1229+
type 'a query_readback =
1230+
Data.term Data.StrMap.t -> Data.constraints -> State.t -> 'a
12131231
let compile (state, p) f = Compiler.query_of_term state p f
12141232
end
12151233
module Quotation =

src/.ppcache/API.mli

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(*262f7f42585df543898448e5ff436973e6f64995 *src/API.mli --cookie elpi_trace="false"*)
1+
(*1a1a1714a91ce24bd6b8d55bb21f552675762a09 *src/API.mli --cookie elpi_trace="false"*)
22
#1 "src/API.mli"
33
[@@@ocaml.text " This module is the API for clients of the Elpi library. "]
44
[@@@ocaml.text
@@ -215,14 +215,23 @@ sig
215215
type 'a declaration =
216216
{
217217
name: name ;
218+
cname: name ;
218219
doc: doc ;
219220
pp: Format.formatter -> 'a -> unit ;
220221
compare: 'a -> 'a -> int ;
221222
hash: 'a -> int ;
222223
hconsed: bool ;
223224
constants: (name * 'a) list }[@@ocaml.doc
224225
" The [eq] function is used by unification. Limitation: unification of\n * two cdata cannot alter the constraint store. This can be lifted in the\n * future if there is user request.\n *\n * If the hconsed is true, then the [readback] function is\n * automatically hashcons the data using the [eq] and [hash] functions.\n "]
225-
val declare : 'a declaration -> ('a, 'c) Conversion.t
226+
type 'a cdata_with_constants
227+
val declare : 'a declaration -> 'a cdata_with_constants
228+
val build_conversion : 'a cdata_with_constants -> ('a, 'c) Conversion.t
229+
val embed : 'a cdata_with_constants -> ('a, 'c) Conversion.embedding
230+
val readback : 'a cdata_with_constants -> ('a, 'c) Conversion.readback
231+
val rest :
232+
'a cdata_with_constants ->
233+
(Conversion.ty_ast * (Format.formatter -> 'a -> unit) *
234+
(Format.formatter -> unit -> unit))
226235
end[@@ocaml.doc
227236
" Declare data from the host application that is opaque (no syntax), like\n int but not like list or pair "]
228237
module AlgebraicData :
@@ -350,16 +359,20 @@ end[@@ocaml.doc
350359
module Query :
351360
sig
352361
type name = string
353-
type _ arguments =
354-
| N: unit arguments
355-
| D: ('a, Conversion.ctx) Conversion.t * 'a * 'x arguments -> 'x
356-
arguments
357-
| Q: ('a, Conversion.ctx) Conversion.t * name * 'x arguments -> ('a * 'x)
358-
arguments
359-
type 'x t =
360-
| Query of {
361-
predicate: name ;
362-
arguments: 'x arguments }
362+
type (_, _) arguments =
363+
| N: (unit, 'c) arguments
364+
| D: ('a, #Conversion.ctx as 'c) Conversion.t * 'a * ('x, 'c) arguments
365+
-> ('x, 'c) arguments
366+
| Q: ('a, #Conversion.ctx as 'c) Conversion.t * name * ('x, 'c) arguments
367+
-> (('a * 'x), 'c) arguments
368+
type _ t =
369+
| Query: ('a, 'x, 'c) query_contents * ('a, 'k, Conversion.ctx)
370+
Conversion.context * (Data.state -> #Conversion.ctx as 'c) -> 'x t
371+
and ('a, 'x, 'c) query_contents =
372+
{
373+
context: 'a list ;
374+
predicate: string ;
375+
arguments: ('x, 'c) arguments }
363376
val compile : Compile.program -> Ast.Loc.t -> 'a t -> 'a Compile.query
364377
end[@@ocaml.doc
365378
" Commodity module to build a simple query\n and extract the output from the solution found by Elpi.\n\n Example: \"foo data Output\" where [data] has type [t] ([a] is [t Conversion.t])\n and [Output] has type [v] ([b] is a [v Conversion.t]) can be described as:\n{[\n\n let q : (v * unit) t = Query {\n predicate = \"foo\";\n arguments = D(a, data,\n Q(b, \"Output\",\n N))\n }\n\n ]}\n\n Then [compile q] can be used to obtain the compiled query such that the\n resulting solution has a fied output of type [(v * unit)]. Example:\n{[\n\n Query.compile q |> Compile.link |> Execute.once |> function\n | Execute.Success { output } -> output\n | _ -> ...\n\n ]} "]
@@ -503,30 +516,15 @@ sig
503516
end
504517
module RawOpaqueData :
505518
sig
506-
type name = string
507-
type doc = string
508519
type t
509-
type 'a declaration = 'a OpaqueData.declaration =
510-
{
511-
name: name ;
512-
doc: doc ;
513-
pp: Format.formatter -> 'a -> unit ;
514-
compare: 'a -> 'a -> int ;
515-
hash: 'a -> int ;
516-
hconsed: bool ;
517-
constants: (name * 'a) list }[@@ocaml.doc
518-
" If the data_hconsed is true, then the [cin] function below will\n automatically hashcons the data using the [eq] and [hash] functions. "]
519520
type 'a cdata = private
520521
{
521522
cin: 'a -> t ;
522523
isc: t -> bool ;
523524
cout: t -> 'a ;
524-
name: string }
525-
val declare :
526-
'a declaration -> ('a cdata * (name * 'a) Data.Constants.Map.t * string)
527-
val declare_cdata :
528-
('a cdata * (name * 'a) Data.Constants.Map.t * string) ->
529-
('a, 'c) Conversion.t
525+
name: string }[@@ocaml.doc
526+
" If the data_hconsed is true, then the [cin] function below will\n automatically hashcons the data using the [eq] and [hash] functions. "]
527+
val cdata : 'a OpaqueData.cdata_with_constants -> 'a cdata
530528
val pp : Format.formatter -> t -> unit
531529
val show : t -> string
532530
val equal : t -> t -> bool
@@ -622,13 +620,16 @@ sig
622620
Data.state ->
623621
name:string -> args:Data.term list -> (Data.state * Data.term)
624622
val is_Arg : Data.state -> Data.term -> bool
623+
type 'a query_readback =
624+
Data.term Data.StrMap.t -> Data.constraints -> State.t -> 'a
625625
val compile :
626626
Compile.program ->
627627
(depth:int ->
628628
Data.hyps ->
629629
Data.constraints ->
630-
Data.state -> (Data.state * (Ast.Loc.t * Data.term)))
631-
-> unit Compile.query
630+
Data.state ->
631+
(Data.state * (Ast.Loc.t * Data.term) * 'a query_readback))
632+
-> 'a Compile.query
632633
end[@@ocaml.doc
633634
" This module lets one generate a query by providing a RawData.term directly "]
634635
module Quotation :

0 commit comments

Comments
 (0)