open StdLabels (** Make a module lazy *) module Make (S : Sym.SYM_EXPR) = struct type 'a repr = 'a S.repr Lazy.t type 'a obs = 'a S.obs Lazy.t type 'a path_repr = 'a S.path_repr let empty : unit -> 'a repr = fun () -> lazy (S.empty ()) let expr : 'a repr -> 'a repr = fun expr -> Lazy.map (fun expr -> S.expr expr) expr let literal : string -> 'a repr = fun l -> lazy (S.literal l) let integer : string -> 'a repr = fun i -> lazy (S.integer i) let path : 'b path_repr -> 'b -> 'a repr = fun repr path -> lazy (S.path repr path) let concat : 'a repr list -> 'a repr = fun exprs -> lazy (let exprs' = List.map ~f:Lazy.force exprs in S.concat exprs') let window : 'a repr T.window -> 'a repr list -> 'a repr list -> 'a repr = fun w group sort -> lazy (let w' = T.map_window ~f:Lazy.force w and group' = List.map ~f:Lazy.force group and sort' = List.map ~f:Lazy.force sort in S.window w' group' sort') let nvl : 'a repr list -> 'a repr = fun exprs -> lazy (let exprs' = List.map ~f:Lazy.force exprs in S.nvl exprs') let join : string -> 'a repr list -> 'a repr = fun sep exprs -> lazy (let exprs' = List.map ~f:Lazy.force exprs in S.join sep exprs') let boperator : T.binary_operator -> 'a repr -> 'a repr -> 'a repr = fun op e1 e2 -> lazy (let e1' = Lazy.force e1 and e2' = Lazy.force e2 in S.boperator op e1' e2') let gequality : T.binary_operator -> 'a repr -> 'a repr list -> 'a repr = fun op e exprs -> lazy (let e' = Lazy.force e and exprs' = List.map ~f:Lazy.force exprs in S.gequality op e' exprs') let funct : string -> 'a repr list -> 'a repr = fun name exprs -> lazy (let exprs' = List.map ~f:Lazy.force exprs in S.funct name exprs') let function' : T.funct -> 'a repr list -> 'a repr = fun f exprs -> lazy (let exprs' = List.map ~f:Lazy.force exprs in S.function' f exprs') let observe : 'a repr -> 'a obs = fun v -> Lazy.map S.observe v end