-
Notifications
You must be signed in to change notification settings - Fork 0
/
var.ml
146 lines (114 loc) · 3.74 KB
/
var.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
module type CONFIG = sig
val fbase: string
val bbase: string
end
module type S = sig
(** free variables *)
type free
(** bound variables *)
type bound
(** equality test *)
val equal: free -> free -> bool
(** comparison *)
val compare: free -> free -> int
(** creation of a free variable from a base name *)
val make: string -> free
(** for pretty printing purposes only, gets the base name *)
val to_string: free -> string
(** creation of free variables from a base name, from a free variable,
or from nothing *)
val sfresh: string -> free
val ffresh: free -> free
val bfresh: bound -> free
val fresh: unit -> free
(** unsafe functions *)
val bzero: free -> bound
val bone: free -> bound
val bzerob: bound -> bound
val boneb: bound -> bound
val bzero_default: bound
val bone_default: bound
val bsucc: bound -> bound
val bequal: bound -> bound -> bool
val bequal_bzero: bound -> bool
(** comparison *)
val bcompare: bound -> bound -> int
val bmax: bound -> bound -> bound
val bto_string: bound -> string
module BSet: Set.S with type elt = bound
module BMap: Map.S with type key = bound
module Set : Set.S with type elt = free
module Map : Map.S with type key = free
module Best : sig
type t
val empty: t
val get: t -> bound -> free
val remember_get: t -> bound -> t * free
end
end
module Make (Default: sig val fbase: string val bbase: string end) : S = struct
type free = string * int
type bound = int * free
(* We record the representation of the free var for pretty
printing purpose. The comparisions will be all made against
the first component only. *)
let equal (x,n) (y,m) = MyString.equal x y && MyInt.equal n m
let compare (s1, i1) (s2, i2) =
let n_s = String.compare s1 s2 in
if n_s = 0 then compare i1 i2 else n_s
let make s = (s,0)
let to_string (s,n) = if n = 0 then s else (s ^ "/" ^ (string_of_int n))
module H = Hashtbl.Make(MyString)
let h = H.create 256
let sfresh s =
let n = try H.find h s with Not_found -> 0 in
H.replace h s (n+1) ;
(s, n+1)
let ffresh (s,_) = sfresh s
let fresh () = sfresh Default.fbase
let bfresh (_, free) = ffresh free
let bzero free = (0, free)
let bone free = (1, free)
let bzerob (_, free) = (0, free)
let boneb (_, free) = (1, free)
let bzero_default = (0, (Default.bbase, 0))
let bone_default = (1, (Default.bbase, 0))
let bsucc (i, f) = (i + 1, f)
let bequal: bound -> bound -> bool = fun x y -> (fst x) = (fst y)
let bequal_bzero (i, _) = i = 0
let bcompare : bound -> bound -> int = fun b1 b2 ->
MyInt.compare (fst b1) (fst b2)
let bmax: bound -> bound -> bound = fun x y ->
if (fst x) <= (fst y) (* we keep the name of the first argument *)
then (fst y, snd x)
else (fst x, snd x)
let bto_string (n, f) = to_string (fst f, if n = 0 then 0 else n-1)
module SMap = Map.Make(MyString)
module Bound = struct
type t = bound
let compare = bcompare
end
module BSet = Set.Make(Bound)
module BMap = Map.Make(Bound)
module Free = struct
type t = free
let compare = compare
end
module Set = Set.Make(Free)
module Map = Map.Make(Free)
module Best = struct
type t = int SMap.t * free BMap.t
let empty = (SMap.empty, BMap.empty)
let get_smap sm s = try SMap.find s sm with Not_found -> -1
let upgrade_smap sm s =
let n = get_smap sm s in
(SMap.add s (n+1) sm, n+1)
let get_bmap m (b: bound) : free = try BMap.find b m with Not_found -> snd b
let get (_, m) b = get_bmap m b
let remember_get (sm, bm) ((_, (s, _)) as b) =
let (sm', n) = upgrade_smap sm s in
let f = (s, n) in (* the free var *)
let bm' = BMap.add b f bm in
((sm', bm'), f)
end
end