Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
(* ========================================================================= *)
(* Unification for first order terms. *)
(* *)
(* Copyright (c) 2003, John Harrison. (See "LICENSE.txt" for details.) *)
(* ========================================================================= *)
let rec istriv env x t =
match t with
Var y -> y = x or defined env y & istriv env x (apply env y)
| Fn(f,args) -> exists (istriv env x) args & failwith "cyclic";;
(* ------------------------------------------------------------------------- *)
(* Main unification procedure *)
(* ------------------------------------------------------------------------- *)
let rec unify env eqs =
match eqs with
[] -> env
| (Fn(f,fargs),Fn(g,gargs))::oth ->
if f = g & length fargs = length gargs
then unify env (zip fargs gargs @ oth)
else failwith "impossible unification"
| (Var x,t)::oth ->
if defined env x then unify env ((apply env x,t)::oth)
else unify (if istriv env x t then env else (x|->t) env) oth
| (t,Var x)::oth -> unify env ((Var x,t)::oth);;
(* ------------------------------------------------------------------------- *)
(* Unification reaching a final solved form (often this isn't needed). *)
(* ------------------------------------------------------------------------- *)
let solve =
let rec solve (env,fs) =
if exists (fun (x,t) -> mem x (fvt t)) fs
then failwith "solve: cyclic" else
let env' =
itlist (fun (x,t) -> x |-> termsubst env t) fs undefined in
let fs' = funset env' in
if fs = fs' then env else solve (env',fs') in
fun env -> solve(env,funset env);;
let fullunify eqs = solve (unify undefined eqs);;
(* ------------------------------------------------------------------------- *)
(* Examples. *)
(* ------------------------------------------------------------------------- *)
let unify_and_apply eqs =
let i = fullunify eqs in
let apply (t1,t2) = termsubst i t1,termsubst i t2 in
map apply eqs;;
START_INTERACTIVE;;
unify_and_apply [<<|f(x,g(y))|>>,<<|f(f(z),w)|>>];;
unify_and_apply [<<|f(x,y)|>>,<<|f(y,x)|>>];;
unify_and_apply [<<|x_0|>>,<<|f(x_1,x_1)|>>;
<<|x_1|>>,<<|f(x_2,x_2)|>>;
<<|x_2|>>,<<|f(x_3,x_3)|>>];;
END_INTERACTIVE;;