|
Packit |
1f8b6b |
(****************************************************************************)
|
|
Packit |
1f8b6b |
(* *)
|
|
Packit |
1f8b6b |
(* OCaml *)
|
|
Packit |
1f8b6b |
(* *)
|
|
Packit |
1f8b6b |
(* INRIA Rocquencourt *)
|
|
Packit |
1f8b6b |
(* *)
|
|
Packit |
1f8b6b |
(* Copyright 2007 Institut National de Recherche en Informatique et *)
|
|
Packit |
1f8b6b |
(* en Automatique. All rights reserved. This file is distributed under *)
|
|
Packit |
1f8b6b |
(* the terms of the GNU Library General Public License, with the special *)
|
|
Packit |
1f8b6b |
(* exception on linking described in LICENSE at the top of the Camlp4 *)
|
|
Packit |
1f8b6b |
(* source tree. *)
|
|
Packit |
1f8b6b |
(* *)
|
|
Packit |
1f8b6b |
(****************************************************************************)
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
type variable = string
|
|
Packit |
1f8b6b |
and term =
|
|
Packit |
1f8b6b |
| Var of variable
|
|
Packit |
1f8b6b |
| Lam of variable * term
|
|
Packit |
1f8b6b |
| App of term * term
|
|
Packit |
1f8b6b |
| Const of constant
|
|
Packit |
1f8b6b |
and constant =
|
|
Packit |
1f8b6b |
| CInt of int
|
|
Packit |
1f8b6b |
| CString of string
|
|
Packit |
1f8b6b |
;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
class fold = Camlp4Filters.GenerateFold.generated;;
|
|
Packit |
1f8b6b |
(* class fold = Camlp4FoldGenerator.generated;; *)
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
module VarSet = Set.Make(String);;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
(* Compute free variables with the fold class *)
|
|
Packit |
1f8b6b |
let free_variables_v1 =
|
|
Packit |
1f8b6b |
let o =
|
|
Packit |
1f8b6b |
object (self)
|
|
Packit |
1f8b6b |
inherit fold as super
|
|
Packit |
1f8b6b |
val fv = VarSet.empty
|
|
Packit |
1f8b6b |
method fv = fv
|
|
Packit |
1f8b6b |
method empty_fv = {< fv = VarSet.empty >}
|
|
Packit |
1f8b6b |
method term t =
|
|
Packit |
1f8b6b |
match t with
|
|
Packit |
1f8b6b |
| Var(v) -> {< fv = VarSet.add v fv >}
|
|
Packit |
1f8b6b |
| Lam(v, t) ->
|
|
Packit |
1f8b6b |
let fv1 = VarSet.remove v (self#empty_fv#term t)#fv in
|
|
Packit |
1f8b6b |
{< fv = VarSet.union fv fv1 >}
|
|
Packit |
1f8b6b |
| _ -> super#term t
|
|
Packit |
1f8b6b |
end
|
|
Packit |
1f8b6b |
in fun t -> VarSet.elements (o#term t)#fv
|
|
Packit |
1f8b6b |
;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
(* Let's try to abstract that a little *)
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
let fold_term f t init =
|
|
Packit |
1f8b6b |
let o =
|
|
Packit |
1f8b6b |
object (self)
|
|
Packit |
1f8b6b |
inherit fold as super
|
|
Packit |
1f8b6b |
val acc = init
|
|
Packit |
1f8b6b |
method get = acc
|
|
Packit |
1f8b6b |
method reset = {< acc = init >}
|
|
Packit |
1f8b6b |
method term t =
|
|
Packit |
1f8b6b |
{< acc = f t acc (fun t -> (self#reset#term t)#get)
|
|
Packit |
1f8b6b |
(fun t -> (super#term t)#get) >}
|
|
Packit |
1f8b6b |
end
|
|
Packit |
1f8b6b |
in
|
|
Packit |
1f8b6b |
(o#term t)#get
|
|
Packit |
1f8b6b |
;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
(* A nicer version of free_variables *)
|
|
Packit |
1f8b6b |
let free_variables_v2 t =
|
|
Packit |
1f8b6b |
VarSet.elements begin
|
|
Packit |
1f8b6b |
fold_term begin fun t fv self next ->
|
|
Packit |
1f8b6b |
match t with
|
|
Packit |
1f8b6b |
| Var(v) -> VarSet.add v fv
|
|
Packit |
1f8b6b |
| Lam(v, t) -> VarSet.union fv (VarSet.remove v (self t))
|
|
Packit |
1f8b6b |
| _ -> next t
|
|
Packit |
1f8b6b |
end t VarSet.empty
|
|
Packit |
1f8b6b |
end
|
|
Packit |
1f8b6b |
;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
let term1 =
|
|
Packit |
1f8b6b |
App(
|
|
Packit |
1f8b6b |
App(Var"x1",
|
|
Packit |
1f8b6b |
Lam("x",
|
|
Packit |
1f8b6b |
App(Var"x", App(Var"y", (Lam("y", Lam("z", (App(Var"y", App(Var"x4",Var"z")))))))))),
|
|
Packit |
1f8b6b |
Var"x3")
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
let fv1 = free_variables_v1 term1;;
|
|
Packit |
1f8b6b |
let fv2 = free_variables_v2 term1;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
(* Low cost syntax *)
|
|
Packit |
1f8b6b |
let ( ^-> ) v t = Lam(v, t)
|
|
Packit |
1f8b6b |
let ( @ ) t1 t2 = App(t1, t2)
|
|
Packit |
1f8b6b |
let ( ! ) s = Var s
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
let term2 =
|
|
Packit |
1f8b6b |
!"x1" @
|
|
Packit |
1f8b6b |
("x" ^-> !"x" @ !"y" @ ("y" ^-> ("z" ^-> !"y" @ !"x4" @ !"z"))) @
|
|
Packit |
1f8b6b |
!"x3"
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
;;
|
|
Packit |
1f8b6b |
|
|
Packit |
1f8b6b |
let fv1' = free_variables_v1 term2;;
|
|
Packit |
1f8b6b |
let fv2' = free_variables_v2 term2;;
|