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
(* ========================================================================= *) (* Basic stuff for first order logic. *) (* *) (* Copyright (c) 2003, John Harrison. (See "LICENSE.txt" for details.) *) (* ========================================================================= *) (* ------------------------------------------------------------------------- *) (* Terms. *) (* ------------------------------------------------------------------------- *) type term = Var of string | Fn of string * term list;; (* ------------------------------------------------------------------------- *) (* Example. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; Fn("sqrt",[Fn("-",[Fn("1",[]); Fn("cos",[Fn("power",[Fn("+",[Var "x"; Var "y"]); Fn("2",[])])])])]);; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Abbreviation for FOL formula. *) (* ------------------------------------------------------------------------- *) type fol = R of string * term list;; (* ------------------------------------------------------------------------- *) (* Trivial example of "x + y < z". *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; Atom(R("<",[Fn("+",[Var "x"; Var "y"]); Var "z"]));; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Parsing of terms. *) (* ------------------------------------------------------------------------- *) let is_const s = forall numeric (explode s) or s = "nil";; let rec parse_atomic_term vs inp = match inp with [] -> failwith "term expected" | "("::rest -> parse_bracketed (parse_term vs) ")" rest | f::"("::")"::rest -> Fn(f,[]),rest | f::"("::rest -> papply (fun args -> Fn(f,args)) (parse_bracketed (parse_list "," (parse_term vs)) ")" rest) | a::rest -> (if is_const a & not(mem a vs) then Fn(a,[]) else Var a),rest and parse_term vs inp = parse_right_infix "::" (fun (e1,e2) -> Fn("::",[e1;e2])) (parse_right_infix "+" (fun (e1,e2) -> Fn("+",[e1;e2])) (parse_left_infix "-" (fun (e1,e2) -> Fn("-",[e1;e2])) (parse_right_infix "*" (fun (e1,e2) -> Fn("*",[e1;e2])) (parse_left_infix "^" (fun (e1,e2) -> Fn("^",[e1;e2])) (parse_atomic_term vs))))) inp;; let parset = make_parser (parse_term []);; (* ------------------------------------------------------------------------- *) (* Parsing of formulas. *) (* ------------------------------------------------------------------------- *) let parse_atom vs inp = try let tm,rest = parse_term vs inp in if exists (nextin rest) ["="; "<"; "<="; ">"; ">="] then papply (fun tm' -> Atom(R(hd rest,[tm;tm']))) (parse_term vs (tl rest)) else failwith "" with Failure _ -> match inp with | p::"("::")"::rest -> Atom(R(p,[])),rest | p::"("::rest -> papply (fun args -> Atom(R(p,args))) (parse_bracketed (parse_list "," (parse_term vs)) ")" rest) | p::rest when p <> "(" -> Atom(R(p,[])),rest | _ -> failwith "parse_atom";; let parse = make_parser (parse_formula parse_atom []);; (* ------------------------------------------------------------------------- *) (* Set up parsing of quotations. *) (* ------------------------------------------------------------------------- *) let default_parser = parse;; let secondary_parser = parset;; (* ------------------------------------------------------------------------- *) (* Example. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; <<(forall x. x < 2 ==> 2 * x <= 3) \/ false>>;; <<|2 * x|>>;; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Printing of terms. *) (* ------------------------------------------------------------------------- *) let rec print_term prec fm = match fm with Var x -> print_string x | Fn("^",[tm1;tm2]) -> print_infix_term true prec 22 "^" tm1 tm2 | Fn("*",[tm1;tm2]) -> print_infix_term false prec 20 "*" tm1 tm2 | Fn("-",[tm1;tm2]) -> print_infix_term true prec 18 "-" tm1 tm2 | Fn("+",[tm1;tm2]) -> print_infix_term false prec 16 "+" tm1 tm2 | Fn("::",[tm1;tm2]) -> print_infix_term false prec 14 "::" tm1 tm2 | Fn(f,args) -> print_fargs f args and print_fargs f args = print_string f; if args = [] then () else (print_string "("; open_box 0; print_term 0 (hd args); print_break 0 0; do_list (fun t -> print_string ","; print_break 0 0; print_term 0 t) (tl args); close_box(); print_string ")") and print_infix_term isleft oldprec newprec sym p q = if oldprec > newprec then (print_string "("; open_box 0) else (); print_term (if isleft then newprec else newprec+1) p; print_string(" "^sym); print_space(); print_term (if isleft then newprec+1 else newprec) q; if oldprec > newprec then (close_box(); print_string ")") else ();; let printert fm = open_box 0; print_term 0 fm; close_box();; START_INTERACTIVE;; #install_printer printert;; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Printing of formulas. *) (* ------------------------------------------------------------------------- *) let print_atom prec (R(p,args)) = if mem p ["="; "<"; "<="; ">"; ">="] & length args = 2 then print_infix_term false 12 12 p (el 0 args) (el 1 args) else print_fargs p args;; let printer = formula_printer print_atom;; START_INTERACTIVE;; #install_printer printer;; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Examples in the main text. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; <>;; <<~(forall x. P(x)) <=> exists y. ~P(y)>>;; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Model-theoretic notions, but here restricted to finite interpretations. *) (* ------------------------------------------------------------------------- *) type ('a)interpretation = Interp of ('a)list * (string -> ('a)list -> 'a) * (string -> ('a)list -> bool);; let domain(Interp(d,funs,preds)) = d and func(Interp(d,funs,preds)) = funs and predicate(Interp(d,funs,preds)) = preds;; (* ------------------------------------------------------------------------- *) (* Semantics. *) (* ------------------------------------------------------------------------- *) let rec termval md v tm = match tm with Var(x) -> apply v x | Fn(f,args) -> func(md) f (map (termval md v) args);; let rec holds md v fm = match fm with False -> false | True -> true | Atom(R(r,args)) -> predicate(md) r (map (termval md v) args) | Not(p) -> not(holds md v p) | And(p,q) -> (holds md v p) & (holds md v q) | Or(p,q) -> (holds md v p) or (holds md v q) | Imp(p,q) -> not(holds md v p) or (holds md v q) | Iff(p,q) -> (holds md v p = holds md v q) | Forall(x,p) -> forall (fun a -> holds md ((x |-> a) v) p) (domain md) | Exists(x,p) -> exists (fun a -> holds md ((x |-> a) v) p) (domain md);; (* ------------------------------------------------------------------------- *) (* Examples of particular interpretations. *) (* ------------------------------------------------------------------------- *) let bool_interp = let fns f args = match (f,args) with ("0",[]) -> false | ("1",[]) -> true | ("+",[x;y]) -> not(x = y) | ("*",[x;y]) -> x & y | _ -> failwith "uninterpreted function" and prs p args = match (p,args) with ("=",[x;y]) -> x = y | _ -> failwith "uninterpreted predicate" in Interp([false; true],fns,prs);; let mod_interp n = let fns f args = match (f,args) with ("0",[]) -> 0 | ("1",[]) -> 1 mod n | ("+",[x;y]) -> (x + y) mod n | ("*",[x;y]) -> (x * y) mod n | _ -> failwith "uninterpreted function" and prs p args = match (p,args) with ("=",[x;y]) -> x = y | _ -> failwith "uninterpreted predicate" in Interp(0 -- (n - 1),fns,prs);; START_INTERACTIVE;; let fm1 = <>;; holds bool_interp undefined fm1;; holds (mod_interp 2) undefined fm1;; holds (mod_interp 3) undefined fm1;; let fm2 = < exists y. x * y = 1>>;; holds bool_interp undefined fm2;; holds (mod_interp 2) undefined fm2;; holds (mod_interp 3) undefined fm2;; holds (mod_interp 4) undefined fm2;; holds (mod_interp 31) undefined fm2;; holds (mod_interp 33) undefined fm2;; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* Free variables in terms and formulas. *) (* ------------------------------------------------------------------------- *) let rec fvt tm = match tm with Var x -> [x] | Fn(f,args) -> itlist (union ** fvt) args [];; let rec fv fm = match fm with False -> [] | True -> [] | Atom(R(p,args)) -> itlist (union ** fvt) args [] | Not(p) -> fv p | And(p,q) -> union (fv p) (fv q) | Or(p,q) -> union (fv p) (fv q) | Imp(p,q) -> union (fv p) (fv q) | Iff(p,q) -> union (fv p) (fv q) | Forall(x,p) -> subtract (fv p) [x] | Exists(x,p) -> subtract (fv p) [x];; (* ------------------------------------------------------------------------- *) (* Substitution within terms. *) (* ------------------------------------------------------------------------- *) let instantiate vlist tlist = itlist2 (fun x t -> x |-> t) vlist tlist undefined;; let rec termsubst sfn tm = match tm with Var x -> tryapplyd sfn x tm | Fn(f,args) -> Fn(f,map (termsubst sfn) args);; (* ------------------------------------------------------------------------- *) (* Incorrect substitution in formulas, and example showing why it's wrong. *) (* ------------------------------------------------------------------------- *) let rec formsubst subfn fm = (* WRONG! *) match fm with False -> False | True -> True | Atom(R(p,args)) -> Atom(R(p,map (termsubst subfn) args)) | Not(p) -> Not(formsubst subfn p) | And(p,q) -> And(formsubst subfn p,formsubst subfn q) | Or(p,q) -> Or(formsubst subfn p,formsubst subfn q) | Imp(p,q) -> Imp(formsubst subfn p,formsubst subfn q) | Iff(p,q) -> Iff(formsubst subfn p,formsubst subfn q) | Forall(x,p) -> Forall(x,formsubst (undefine x subfn) p) | Exists(x,p) -> Exists(x,formsubst (undefine x subfn) p);; formsubst ("y" := Var "x") <>;; (* ------------------------------------------------------------------------- *) (* Variant function and examples. *) (* ------------------------------------------------------------------------- *) let rec variant x vars = if mem x vars then variant (x^"'") vars else x;; START_INTERACTIVE;; variant "x" ["y"; "z"];; variant "x" ["x"; "y"];; variant "x" ["x"; "x'"];; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* The correct version. *) (* ------------------------------------------------------------------------- *) let rec formsubst subfn fm = match fm with False -> False | True -> True | Atom(R(p,args)) -> Atom(R(p,map (termsubst subfn) args)) | Not(p) -> Not(formsubst subfn p) | And(p,q) -> And(formsubst subfn p,formsubst subfn q) | Or(p,q) -> Or(formsubst subfn p,formsubst subfn q) | Imp(p,q) -> Imp(formsubst subfn p,formsubst subfn q) | Iff(p,q) -> Iff(formsubst subfn p,formsubst subfn q) | Forall(x,p) -> formsubstq subfn (fun (x,p) -> Forall(x,p)) (x,p) | Exists(x,p) -> formsubstq subfn (fun (x,p) -> Exists(x,p)) (x,p) and formsubstq subfn quant (x,p) = let subfn' = undefine x subfn in let x' = if exists (fun y -> mem x (fvt(tryapplyd subfn' y (Var y)))) (subtract (fv p) [x]) then variant x (fv(formsubst subfn' p)) else x in quant(x',formsubst ((x |-> Var x') subfn) p);; (* ------------------------------------------------------------------------- *) (* Examples. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; formsubst ("y" := Var "x") <>;; formsubst ("y" := Var "x") < x = x'>>;; END_INTERACTIVE;;