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
(* ========================================================================= *)
(* Simple congruence closure. *)
(* *)
(* Copyright (c) 2003, John Harrison. (See "LICENSE.txt" for details.) *)
(* ========================================================================= *)
(* ------------------------------------------------------------------------- *)
(* Test whether subterms are congruent under an equivalence. *)
(* ------------------------------------------------------------------------- *)
let congruent eqv =
function (Fn(f,a1),Fn(g,a2)) ->
f = g &
forall2 (fun s t -> canonize eqv s = canonize eqv t) a1 a2
| _ -> false;;
(* ------------------------------------------------------------------------- *)
(* Merging of terms, with congruence closure. *)
(* ------------------------------------------------------------------------- *)
let rec emerge (s,t) (eqv,pfn) =
let s' = canonize eqv s and t' = canonize eqv t in
if s' = t' then (eqv,pfn) else
let sp = tryapplyl pfn s' and tp = tryapplyl pfn t' in
let eqv' = equate (s,t) eqv in
let st' = canonize eqv' s' in
let pfn' = (st' |-> union sp tp) pfn in
itlist (fun (u,v) (eqv,pfn) ->
if congruent eqv (u,v) then emerge (u,v) (eqv,pfn)
else eqv,pfn)
(allpairs (fun u v -> (u,v)) sp tp) (eqv',pfn');;
(* ------------------------------------------------------------------------- *)
(* Useful auxiliary functions. *)
(* ------------------------------------------------------------------------- *)
let rec subterms tm acc =
match tm with
Var x -> tm::acc
| Fn(f,args) -> tm::(itlist subterms args acc);;
let successors = function (Fn(f,args)) -> setify args | _ -> [];;
(* ------------------------------------------------------------------------- *)
(* Satisfiability of conjunction of ground equations and inequations. *)
(* ------------------------------------------------------------------------- *)
let ccsatisfiable fms =
let pos,neg = partition positive fms in
let eqps = map dest_eq pos and eqns = map (dest_eq ** negate) neg in
let lrs = map fst eqps @ map snd eqps @ map fst eqns @ map snd eqns in
let tms = setify (itlist subterms lrs []) in
let pfn = itlist
(fun x -> itlist (fun y f -> (y |-> insert x (tryapplyl f y)) f)
(successors x)) tms undefined in
let eqv,_ = itlist emerge eqps (unequal,pfn) in
forall (fun (l,r) -> canonize eqv l <> canonize eqv r) eqns;;
(* ------------------------------------------------------------------------- *)
(* Convert uninterpreted predicates into functions. *)
(* ------------------------------------------------------------------------- *)
let atomize fm =
let preds = predicates fm and funs = functions fm in
let n = Int 1 +/ itlist (max_varindex "P" ** fst) funs (Int 0) in
let preds' = map (fun i -> "P_"^string_of_num i)
(n---(n+/Int(length preds))) in
let alist = zip preds (butlast preds') and tr = Fn(last preds',[]) in
let equalize(R(p,args) as at) =
if p = "=" & length args = 2 then Atom at else
Atom(R("=",[Fn(assoc (p,length args) alist,args); tr])) in
onatoms equalize fm;;
(* ------------------------------------------------------------------------- *)
(* Validity checking a universal formula (this theory is trivially convex). *)
(* ------------------------------------------------------------------------- *)
let ccvalid fm =
let fms = simpdnf(askolemize(Not(generalize(atomize fm)))) in
not (exists ccsatisfiable fms);;
(* ------------------------------------------------------------------------- *)
(* Example. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
let fm =
< f(c) = c \/ f(g(c)) = g(f(c))>> in
ccvalid fm;;
let fm = < f(c) = c>> in
ccvalid fm;;
let fm =
< f(c) = c>> in
ccvalid fm;;
let fm =
< ~Q(f(c)))
==> P(f(c)) \/ Q(c)>> in
ccvalid fm;;
END_INTERACTIVE;;