ocaml/camlp4/test/fixtures/lambda_free.ml

69 lines
2.0 KiB
OCaml

open Format;
module S = Set.Make String;
type term =
[ Lambda of string and term
| Atom of string
| App of term and term
| Opt of term and option term and term
];
value free_vars =
let rec fv t env free =
match t with
[ Lambda x t -> fv t (S.add x env) free
| Atom x -> if S.mem x env then free else S.add x free
| App t1 t2 -> fv t1 env (fv t2 env free)
| Opt _ _ _ -> assert False ]
in fun t -> fv t S.empty S.empty;
value print_set f s = do {
fprintf f "@[<2>{ ";
S.iter (fprintf f "%s@ ") s;
fprintf f "}@]";
};
value t1 = Lambda "x" (App (Lambda "y" (App (Atom "y") (Atom "x"))) (Lambda "x" (Atom "x")));
value t2 = Lambda "x" (App (Lambda "y" (App (Atom "y") (Atom "x"))) (Lambda "z" (Atom "z")));
value t3 = Lambda "x" (App (Lambda "y" (App (Atom "y") (Atom "x"))) (Lambda "x" (Atom "z")));
value t4 = Lambda "a" (App (Lambda "y" (App (Atom "y") (Atom "x"))) (Lambda "x" (Atom "z")));
printf "t1: %a@." print_set (free_vars t1);
printf "t2: %a@." print_set (free_vars t2);
printf "t3: %a@." print_set (free_vars t3);
printf "t4: %a@." print_set (free_vars t4);
class fold ['accu] init =
object (o : 'self_type)
value accu : 'accu = init;
method accu = accu;
method term t =
match t with
[ Lambda x t -> (o#string x)#term t
| Atom x -> o#string x
| App t1 t2 -> (o#term t1)#term t2
| Opt t1 ot t2 -> ((o#term t1)#option (fun o -> o#term) ot)#term t2 ];
method string : string -> 'self_type = fun _ -> o;
method option : ! 'a. ('self_type -> 'a -> 'self_type) -> option 'a -> 'self_type =
fun f opt ->
match opt with
[ None -> o
| Some x -> f o x ];
end;
class fold_atoms ['accu] f init =
object (o : 'self_type)
inherit fold ['accu] init as super;
method term t =
match t with
[ Atom x -> {< accu = f x accu >}
| _ -> super#term t ];
end;
value t5 = Opt (Atom "a") (Some (Atom "b")) (Atom "c");
value atoms = ((new fold_atoms S.add S.empty)#term t5)#accu;
printf "atoms: %a@." print_set atoms;