[Toss-devel-svn] SF.net SVN: toss:[1197] trunk/Toss
Status: Beta
Brought to you by:
lukaszkaiser
|
From: <luk...@us...> - 2010-11-27 20:55:30
|
Revision: 1197
http://toss.svn.sourceforge.net/toss/?rev=1197&view=rev
Author: lukaszkaiser
Date: 2010-11-27 20:55:24 +0000 (Sat, 27 Nov 2010)
Log Message:
-----------
First-order transitive closure and subst_vars debugging.
Modified Paths:
--------------
trunk/Toss/Formula/Aux.ml
trunk/Toss/Formula/Aux.mli
trunk/Toss/Formula/Formula.ml
trunk/Toss/Formula/FormulaOps.ml
trunk/Toss/Formula/FormulaOps.mli
trunk/Toss/Formula/FormulaOpsTest.ml
trunk/Toss/Formula/FormulaParser.mly
trunk/Toss/Solver/SolverTest.ml
Modified: trunk/Toss/Formula/Aux.ml
===================================================================
--- trunk/Toss/Formula/Aux.ml 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/Aux.ml 2010-11-27 20:55:24 UTC (rev 1197)
@@ -11,8 +11,10 @@
let strings_of_list nvs =
add_strings nvs Strings.empty
+let is_digit c =
+ (c = '0') || (c = '1') || (c = '2') || (c = '3') || (c = '4') ||
+ (c = '5') || (c = '6') || (c = '7') || (c = '8') || (c = '9')
-
(* {2 Helper functions on lists and other functions lacking from the
standard library.} *)
let concat_map f l =
Modified: trunk/Toss/Formula/Aux.mli
===================================================================
--- trunk/Toss/Formula/Aux.mli 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/Aux.mli 2010-11-27 20:55:24 UTC (rev 1197)
@@ -7,6 +7,8 @@
val add_strings : string list -> Strings.t -> Strings.t
val strings_of_list : string list -> Strings.t
+val is_digit : char -> bool
+
(** {2 Helper functions on lists and other functions lacking from the
standard library.} *)
Modified: trunk/Toss/Formula/Formula.ml
===================================================================
--- trunk/Toss/Formula/Formula.ml 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/Formula.ml 2010-11-27 20:55:24 UTC (rev 1197)
@@ -12,15 +12,14 @@
type mso_var = [ `MSO of string ];;
type real_var = [ `Real of string ];;
-let is_digit c =
- (c = '0') || (c = '1') || (c = '2') || (c = '3') || (c = '4') ||
- (c = '5') || (c = '6') || (c = '7') || (c = '8') || (c = '9')
-
(* We recognize if the variable is FO (x, y) or MSO (X, Y) or Real (r1, r2). *)
let var_of_string s : var =
- if String.length s = 0 then failwith "empty strings not allowed as vars"
- else if s.[0] = ':' then `Real s
- else if ((Char.uppercase s.[0]) = s.[0]) && (not (is_digit s.[0])) then `MSO s
+ if String.length s = 0 then
+ failwith "empty strings not allowed as vars"
+ else if s.[0] = ':' then
+ `Real s
+ else if ((Char.uppercase s.[0]) = s.[0]) && (not (Aux.is_digit s.[0])) then
+ `MSO s
else `FO s
let fo_var_of_string s : fo_var =
Modified: trunk/Toss/Formula/FormulaOps.ml
===================================================================
--- trunk/Toss/Formula/FormulaOps.ml 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/FormulaOps.ml 2010-11-27 20:55:24 UTC (rev 1197)
@@ -205,13 +205,21 @@
let new_vs = List.filter (fun x -> not (in_vs x)) subst in
if new_vs = [] then Sum(vs, phi, r) else Sum(vs, subst_vars new_vs phi, r)
+(* Helper function: strip digits from string end except if it starts with one. *)
+let rec strip_digits s =
+ if Aux.is_digit s.[0] then s else
+ let len = String.length s in
+ if Aux.is_digit s.[len-1] then
+ strip_digits (String.sub s 0 (len-1))
+ else s
+
(* Find a substitution for [v] which avoids [avs]. *)
let subst_name_avoiding avoidv var =
- let (avs, v) = (List.rev_map var_str avoidv, var_str var) in
+ let (avs, v) = (List.rev_map var_str avoidv, strip_digits (var_str var)) in
let rec asubst i =
let vi = v ^ (string_of_int i) in
- if not (List.mem vi avs) then (v, vi) else asubst (i+1) in
- if List.mem v avs then asubst 0 else (v, v)
+ if not (List.mem vi avs) then (var_str var, vi) else asubst (i+1) in
+ if List.mem v avs then asubst 0 else (var_str var, v)
(** Rename quantified variables avoiding the ones from [avs],
and the above-quantified ones. Does not go into real_expr. *)
@@ -225,7 +233,7 @@
if avoidv = [] then Ex (vs, rename_quant_avoiding (avs @ vs) phi) else
let subst = List.map (subst_name_avoiding avs) avoidv in
let nvs = okv @ (List.map var_of_string (snd (List.split subst))) in
- Ex (nvs, rename_quant_avoiding (avs @ nvs) (subst_vars subst phi))
+ Ex (nvs, subst_vars subst (rename_quant_avoiding (avs @ nvs) phi))
| All (vs, phi) ->
let (avoidv, okv) = List.partition (fun v -> List.mem v avs) vs in
if avoidv = [] then All (vs, rename_quant_avoiding (avs @ vs) phi) else
@@ -233,7 +241,16 @@
let nvs = okv @ (List.map var_of_string (snd (List.split subst))) in
All (nvs, rename_quant_avoiding (avs @ nvs) (subst_vars subst phi))
+(* Apply substitution [subst] to all free variables in the given formula
+ checking for and preventing name clashes with quantified variables. *)
+let subst_vars_check subst phi =
+ let nvars = List.map (fun (_, nv) -> var_of_string nv) subst in
+ let avoidvars = List.rev_append (free_vars phi) nvars in
+ subst_vars subst (rename_quant_avoiding avoidvars phi)
+let subst_vars_nocheck subst phi = subst_vars subst phi
+
+
(* --------------------------- TRANSITIVE CLOSURE --------------------------- *)
(* We construct transitive closure of phi(x, y, z) over x, y as
@@ -245,14 +262,23 @@
let (_, ny) = subst_name_avoiding fv yv in
let (nxv, nyv) = (fo_var_of_string nx, fo_var_of_string ny) in
let frX = mso_var_of_string(snd(subst_name_avoiding fv(var_of_string "X"))) in
- let nphi = subst_vars [(x, nx); (y, ny)] phi in
+ let nphi = subst_vars_check [(x, nx); (y, ny)] phi in
let impphi = Or [Not (And [In (nxv, frX); nphi]); In (nyv, frX)] in
let inphi = And [In (xv, frX); All (([nxv; nyv] :> var list), impphi)] in
All ([(frX :> var)], Or [Not inphi; In (yv, frX)])
+(* First-order [k]-step refl. transitive closure of [phi] over [x] and [y]. *)
+let rec make_fo_tc k x y phi =
+ let (xv, yv) = (fo_var_of_string x, fo_var_of_string y) in
+ if k = 0 then Eq (xv, yv) else if k = 1 then Or [Eq (xv, yv); phi] else
+ let (fv, k1, k2) = (free_vars phi, k / 2, k - (k / 2)) in
+ let (_, t) = subst_name_avoiding fv (var_of_string "t") in
+ let (phi1, phi2) = (make_fo_tc k1 x y phi, make_fo_tc k2 x y phi) in
+ let (phi1s, phi2s) =
+ (subst_vars_check [(y,t)] phi1, subst_vars_check [(x,t)] phi2) in
+ Ex ([var_of_string t], And [phi1s; phi2s])
-
(* --------- SUBSTITUTE DEFINED RELATIONS ------------ *)
(* Substitute in relations defined in [defs] by their definitions. *)
Modified: trunk/Toss/Formula/FormulaOps.mli
===================================================================
--- trunk/Toss/Formula/FormulaOps.mli 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/FormulaOps.mli 2010-11-27 20:55:24 UTC (rev 1197)
@@ -35,7 +35,12 @@
(* Apply substitution [subst] to all free variables in the given
formula. Preserves order of subformulas. *)
val subst_vars : (string * string) list -> formula -> formula
+val subst_vars_nocheck : (string * string) list -> formula -> formula
+(* Apply substitution [subst] to all free variables in the given formula
+ checking for and preventing name clashes with quantified variables. *)
+val subst_vars_check : (string * string) list -> formula -> formula
+
(** Rename quantified variables avoiding the ones from [avs] list,
and the above-quantified ones. Does not go into real_expr. *)
val rename_quant_avoiding : var list -> formula -> formula
@@ -55,8 +60,12 @@
(* ------------------------ Transitive Closure ---------------------------- *)
+(* Transitive closure of phi(x, y, z) over x and y, an MSO formula. *)
val make_tc : string -> string -> formula -> formula
+(* First-order [k]-step refl. transitive closure of [phi] over [x] and [y]. *)
+val make_fo_tc : int -> string -> string -> formula -> formula
+
(* -------------------------- Simplification ------------------------------ *)
(* Recursively simplify a formula *)
Modified: trunk/Toss/Formula/FormulaOpsTest.ml
===================================================================
--- trunk/Toss/Formula/FormulaOpsTest.ml 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/FormulaOpsTest.ml 2010-11-27 20:55:24 UTC (rev 1197)
@@ -15,7 +15,7 @@
let id x = x ;;
-let tests = "Formula" >::: [
+let tests = "FormulaOps" >::: [
"nnf and parsing" >::
(fun () ->
let nnf_eq phi1 phi2 = formula_eq id phi2 FormulaOps.nnf phi1 in
@@ -259,6 +259,17 @@
"R (y, x)" "S(y, x) and ex x0 (S(x, x0))";
);
+ "rename quantified variables" >::
+ (fun () ->
+ let rq_eq vs phi1 phi2 =
+ let avs = List.map Formula.var_of_string vs in
+ formula_eq id phi2 (FormulaOps.rename_quant_avoiding avs) phi1 in
+ rq_eq ["x"] "ex x R(x, y)" "ex x0 R(x0, y)";
+ rq_eq ["x"] "ex y R(x, y)" "ex y R(x, y)";
+ rq_eq ["t"] "ex t ( (x = t or R(x, t)) and ex t0 ( t=t0 or R(t, t0) ))"
+ "ex t0 ( (x = t0 or R(x, t0)) and ex t1 ((t0 = t1 or R(t0, t1)) ))";
+ );
+
"transitive closure creation" >::
(fun () ->
let tc_eq x y phi1 phi2 =
@@ -268,6 +279,18 @@
tc_eq "x" "y" "R(x, y) and x in X" "all X0 (x in X0 and (all x0,y0
(x0 in X0 and (R(x0,y0) and x0 in X) -> y0 in X0)) -> y in X0)";
);
+
+ "first-order transitive closure creation" >::
+ (fun () ->
+ let tc_eq k x y phi1 phi2 =
+ formula_eq id phi2 (FormulaOps.make_fo_tc k x y) phi1 in
+ tc_eq 2 "x" "y" "R(x, y)" "ex t((x=t or R(x,t)) and (t=y or R(t,y)))";
+ tc_eq 3 "x" "y" "R(x, y, t)" "ex t0 ( (x = t0 or R(x, t0, t)) and
+ ex t1 ( (t0 = t1 or R(t0, t1, t)) and (t1 = y or R(t1, y, t)) ) )";
+ tc_eq 5 "x" "y" "R(x, y)" "ex t ( ex t0 ( ((x = t0) or R(x, t0)) and
+ ((t0 = t) or R(t0, t)) ) and ex t0( ((t = t0) or R(t, t0)) and ex t1 (
+ (t0 = t1 or R(t0, t1)) and (t1 = y or R(t1, y)) )))";
+ );
] ;;
let a =
Modified: trunk/Toss/Formula/FormulaParser.mly
===================================================================
--- trunk/Toss/Formula/FormulaParser.mly 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Formula/FormulaParser.mly 2010-11-27 20:55:24 UTC (rev 1197)
@@ -77,6 +77,7 @@
| EX var_list formula_expr { Ex ($2, $3) }
| ALL var_list formula_expr { All ($2, $3) }
| TC ID COMMA ID formula_expr { FormulaOps.make_tc $2 $4 $5 }
+ | TC INT ID COMMA ID formula_expr { FormulaOps.make_fo_tc $2 $3 $5 $6 }
| OPEN formula_expr CLOSE { $2 }
| formula_expr AND formula_expr { And [$1; $3] }
| formula_expr OR formula_expr { Or [$1; $3] }
Modified: trunk/Toss/Solver/SolverTest.ml
===================================================================
--- trunk/Toss/Solver/SolverTest.ml 2010-11-27 14:29:19 UTC (rev 1196)
+++ trunk/Toss/Solver/SolverTest.ml 2010-11-27 20:55:24 UTC (rev 1197)
@@ -26,19 +26,19 @@
let f = register_formula solver phi in
res := AssignmentSet.str (evaluate solver f struc);
);
- assert_equal ~printer:(fun x -> x) !res aset_s
+ assert_equal ~printer:(fun x -> x) aset_s !res
;;
let eval_real_eq var_s struc_s expr_s aset_s =
let (struc, expr) = (struc_of_string struc_s, real_expr_of_string expr_s) in
assert_equal ~printer:(fun x -> x)
- (AssignmentSet.str (evaluate_real var_s expr struc)) aset_s
+ aset_s (AssignmentSet.str (evaluate_real var_s expr struc))
;;
let real_val_eq struc_s expr_s x =
let (struc, expr) = (struc_of_string struc_s, real_expr_of_string expr_s) in
assert_equal ~printer:(fun x -> string_of_float x)
- (get_real_val (new_solver ()) AssignmentSet.Any expr struc) x
+ x (get_real_val (new_solver ()) AssignmentSet.Any expr struc)
;;
@@ -112,16 +112,25 @@
"eval: mso with quantifiers" >::
(fun () ->
- let reach_f = "tc x, y R(x, y)" in
- eval_eq "[ | R { (a, b); (a, c) } | ]" reach_f
+ eval_eq "[ | R { (a, b); (a, c) } | ]" "tc x, y R(x, y)"
"{ y->1{ x->1 } , y->2{ x->1, x->2 } , y->3{ x->1, x->3 } }";
- eval_eq "[ | R { (a, b); (b, c) } | ]" reach_f
- "{ y->1{ x->1 } , y->2{ x->1, x->2 } , y->3 }";
+ eval_eq "[ | R { (a, b); (b, c) } | ]" "tc x, y R(x, y)"
+ "{ y->1{ x->1 } , y->2{ x->1, x->2 } , y->3 }";
eval_eq "[ | R { (a,b); (b,c); (c,d); (d,e); (e,f); (f,g); (g,h) } | ]"
- ("x != y and not R(x, y) and " ^ reach_f)
+ "x != y and not R(x, y) and tc x, y R(x, y)"
("{ y->3{ x->1 } , y->4{ x->1, x->2 } , y->5{ x->1, x->2, x->3 } ," ^
" y->6{ x->1, x->2, x->3, x->4 } , y->7{ x->1, x->2, x->3, x->4," ^
" x->5 } , y->8{ x->1, x->2, x->3, x->4, x->5, x->6 } }");
+ eval_eq "[ | R { (a,b); (b,c); (c,d); (d,e); (e,f); (f,g); (g,h) } | ]"
+ "x != y and not R(x, y) and tc 4 x, y R(x, y)"
+ ("{ y->3{ x->1 } , y->4{ x->1, x->2 } , y->5{ x->1, x->2, x->3 } ," ^
+ " y->6{ x->2, x->3, x->4 } , y->7{ x->3, x->4," ^
+ " x->5 } , y->8{ x->4, x->5, x->6 } }");
+ eval_eq "[ | R { (a,b); (b,c); (c,d); (d,e); (e,f); (f,g); (g,h) } | ]"
+ "x != y and not R(x, y) and tc 7 x, y R(x, y)"
+ ("{ y->3{ x->1 } , y->4{ x->1, x->2 } , y->5{ x->1, x->2, x->3 } ," ^
+ " y->6{ x->1, x->2, x->3, x->4 } , y->7{ x->1, x->2, x->3, x->4," ^
+ " x->5 } , y->8{ x->1, x->2, x->3, x->4, x->5, x->6 } }");
);
"eval: with real values" >::
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|