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