-
Notifications
You must be signed in to change notification settings - Fork 6
/
env.ml
55 lines (48 loc) · 1.48 KB
/
env.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
open Gtree
let mk_env (m, t) = [(m, t)]
let empty_env = ([] : ((string * gtree) list))
(* given env and value t, find the _first_ binding m->t in env and return m
* there may be other bindings in env such that m'->t
*)
let rev_lookup env t =
let rec loop env = match env with
| [] -> None
| (m,t') :: env when t = t' -> Some m
| _ :: env -> loop env
in
loop env
(* replace subterms of t that are bound in env with the binding metavariable
so subterm becomes m if m->subterm is in env
assumes that if m1->st & m2->st then m1 = m2
i.e. each metavariable denote DIFFERENT subterms
so that one can uniquely perform the rev_lookup
*)
let rec rev_sub env t =
match rev_lookup env t with
| Some m -> mkA("meta", m)
| None -> (match view t with
| C(ty, ts) -> mkC(ty,
List.rev (List.fold_left
(fun acc_ts t -> rev_sub env t :: acc_ts)
[] ts)
)
| _ -> t)
(* replace metavars in t with their corresponding binding in env (if any)
*)
let rec sub env t =
if env = [] then t
else
let rec loop t' = match view t' with
| C (ct, ts) ->
mkC(ct, List.rev (
List.fold_left (fun b a -> (loop a) :: b) [] ts
))
| A ("meta", mvar) -> (try
List.assoc mvar env with Not_found ->
mkA ("meta", mvar)
)
| _ -> t'
in
loop t
let rev_assoc a l =
fst(List.find (function (m,b) -> b = a) l)