Summary: Variables are represented as a subtype of terms. The implementation of the operations on variables is largely independent of this. This diff generalizes the implementation over the concrete representation, and moves it to a separate module. Reviewed By: ngorogiannis Differential Revision: D23660290 fbshipit-source-id: 90d8c3ca4master
parent
a7c85e2262
commit
e4426acb8a
@ -0,0 +1,57 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
|
||||
open Var_intf
|
||||
|
||||
(** Variables, parameterized over their representation *)
|
||||
module Make (T : REPR) = struct
|
||||
include T
|
||||
|
||||
type strength = t -> [`Universal | `Existential | `Anonymous] option
|
||||
|
||||
let ppx strength ppf v =
|
||||
let id = id v in
|
||||
let name = name v in
|
||||
match id with
|
||||
| -1 -> Trace.pp_styled `Bold "%@%s" ppf name
|
||||
| 0 -> Trace.pp_styled `Bold "%%%s" ppf name
|
||||
| _ -> (
|
||||
match strength v with
|
||||
| None -> Format.fprintf ppf "%%%s_%d" name id
|
||||
| Some `Universal -> Trace.pp_styled `Bold "%%%s_%d" ppf name id
|
||||
| Some `Existential -> Trace.pp_styled `Cyan "%%%s_%d" ppf name id
|
||||
| Some `Anonymous -> Trace.pp_styled `Cyan "_" ppf )
|
||||
|
||||
let pp = ppx (fun _ -> None)
|
||||
|
||||
module Map = struct
|
||||
include NS.Map.Make (T)
|
||||
include Provide_of_sexp (T)
|
||||
end
|
||||
|
||||
module Set = struct
|
||||
let pp_t = pp
|
||||
|
||||
include NS.Set.Make (T)
|
||||
include Provide_of_sexp (T)
|
||||
|
||||
let ppx strength vs = pp (ppx strength) vs
|
||||
let pp vs = pp pp_t vs
|
||||
|
||||
let pp_xs fs xs =
|
||||
if not (is_empty xs) then
|
||||
Format.fprintf fs "@<2>∃ @[%a@] .@;<1 2>" pp xs
|
||||
end
|
||||
|
||||
let fresh name ~wrt =
|
||||
let max = match Set.max_elt wrt with None -> 0 | Some max -> id max in
|
||||
let x' = make ~id:(max + 1) ~name in
|
||||
(x', Set.add wrt x')
|
||||
|
||||
let program ~name ~global = make ~id:(if global then -1 else 0) ~name
|
||||
let identified ~name ~id = make ~id ~name
|
||||
end
|
@ -0,0 +1,11 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
|
||||
open Var_intf
|
||||
|
||||
(** Variables, parameterized over their representation *)
|
||||
module Make (R : REPR) : VAR with type t = R.t
|
@ -0,0 +1,50 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
|
||||
module type REPR = sig
|
||||
type t [@@deriving compare, equal, sexp]
|
||||
|
||||
val make : id:int -> name:string -> t
|
||||
val id : t -> int
|
||||
val name : t -> string
|
||||
end
|
||||
|
||||
module type VAR = sig
|
||||
type t [@@deriving compare, equal, sexp]
|
||||
type strength = t -> [`Universal | `Existential | `Anonymous] option
|
||||
|
||||
val ppx : strength -> t pp
|
||||
val pp : t pp
|
||||
|
||||
module Map : sig
|
||||
include NS.Map.S with type key := t
|
||||
|
||||
val t_of_sexp : (Sexp.t -> 'a) -> Sexp.t -> 'a t
|
||||
end
|
||||
|
||||
module Set : sig
|
||||
include NS.Set.S with type elt := t
|
||||
|
||||
val sexp_of_t : t -> Sexp.t
|
||||
val t_of_sexp : Sexp.t -> t
|
||||
val ppx : strength -> t pp
|
||||
val pp : t pp
|
||||
val pp_xs : t pp
|
||||
end
|
||||
|
||||
val id : t -> int
|
||||
val name : t -> string
|
||||
val program : name:string -> global:bool -> t
|
||||
val fresh : string -> wrt:Set.t -> t * Set.t
|
||||
|
||||
val identified : name:string -> id:int -> t
|
||||
(** Variable with the given [id]. Variables are compared by [id] alone,
|
||||
[name] is used only for printing. The only way to ensure [identified]
|
||||
variables do not clash with [fresh] variables is to pass the
|
||||
[identified] variables to [fresh] in [wrt]:
|
||||
[Var.fresh name ~wrt:(Var.Set.of_ (Var.identified ~name ~id))]. *)
|
||||
end
|
Loading…
Reference in new issue