[Toss-devel-svn] SF.net SVN: toss:[1704] trunk/Toss
Status: Beta
Brought to you by:
lukaszkaiser
From: <luk...@us...> - 2012-05-10 22:22:16
|
Revision: 1704 http://toss.svn.sourceforge.net/toss/?rev=1704&view=rev Author: lukaszkaiser Date: 2012-05-10 22:22:09 +0000 (Thu, 10 May 2012) Log Message: ----------- Corrections to term simplification, renaming example. Modified Paths: -------------- trunk/Toss/Arena/Term.ml trunk/Toss/Arena/Term.mli trunk/Toss/Arena/TermTest.ml trunk/Toss/Client/JsHandler.ml trunk/Toss/Client/State.js trunk/Toss/Client/index.html trunk/Toss/Solver/RealQuantElim/OrderedPoly.ml trunk/Toss/Solver/RealQuantElim/OrderedPoly.mli trunk/Toss/Solver/RealQuantElim/Poly.ml trunk/Toss/Solver/RealQuantElim/Poly.mli Added Paths: ----------- trunk/Toss/Client/img/Cell-Cycle-Tyson-1991.png trunk/Toss/examples/Cell-Cycle-Tyson-1991.toss Removed Paths: ------------- trunk/Toss/Client/img/Yeast-Cell-Cycle-Tyson.png trunk/Toss/examples/Yeast-Cell-Cycle-Tyson.toss Modified: trunk/Toss/Arena/Term.ml =================================================================== --- trunk/Toss/Arena/Term.ml 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Arena/Term.ml 2012-05-10 22:22:09 UTC (rev 1704) @@ -2,6 +2,8 @@ (* ---------------------- BASIC TYPE DEFINITION ----------------------------- *) +let simp_symb = ref false + type term = | Var of string | FVar of string * string @@ -80,27 +82,58 @@ (* -------------------- SIMPLIFICATION OF CONSTANTS ------------------------- *) (* Basic simplification, reduces constant terms to floats. *) -let rec simp_const = function +let rec simp_const_only = function | Var s -> Var s | FVar (f, a) -> FVar (f, a) | Const n -> Const n | Times (p, q) -> ( - match (simp_const p, simp_const q) with + match (simp_const_only p, simp_const_only q) with | (Const n, Const m) -> Const (n *. m) - | (Const n, Times (Const m, t)) -> Times (Const (n *. m), t) | (t, s) -> Times (t, s) ) | Plus (p, q) -> ( - match (simp_const p, simp_const q) with + match (simp_const_only p, simp_const_only q) with | (Const n, Const m) -> Const (n +. m) - | (Const n, Plus (Const m, t)) -> Plus (Const (n +. m), t) | (t, s) -> Plus (t, s) ) | Div (p, q) -> - match (simp_const p, simp_const q) with + match (simp_const_only p, simp_const_only q) with | (Const n, Const m) -> Const (n /. m) | (t, s)-> Div (t, s) +let simp_const t = + let rec to_poly = function + | Var s -> Poly.Var ("V" ^ s) + | FVar (f, a) -> Poly.Var ("F" ^ f ^ "#" ^ a) + | Const n -> Poly.Const n + | Times (p, q) -> Poly.Times (to_poly p, to_poly q) + | Plus (p, q) -> Poly.Plus (to_poly p, to_poly q) + | Div _ -> raise Not_found in + let rec from_ord = function + | OrderedPoly.Const _ -> failwith "num after non-num translation" + | OrderedPoly.FConst num -> Const (num) + | OrderedPoly.Poly (v, coefs) -> + let w = if v.[0]= 'V' then Var (String.sub v 1 ((String.length v)-1)) else + let i, l = String.index v '#', String.length v in + FVar (String.sub v 1 (i-1), String.sub v (i+1) (l-i-1)) in + let res = List.fold_left (fun acc (a, j) -> + if j = 0 then Plus (acc, from_ord a) else + match from_ord a with + | Const n when n = 1. -> Plus (acc, pow w j) + | ordt -> Plus (acc, Times (ordt, pow w j)) + ) (Const 0.) coefs in + LOG 1 "res %s" (str res); + let rec del_zero = function + | Plus (Const n, t) when n = 0. -> t + | Plus (t, s) -> Plus (del_zero t, s) + | t -> t in + del_zero res in + match simp_const_only t with + | Const n -> Const n + | t -> if not !simp_symb then t else + try let p = to_poly t in + from_ord (Poly.make_ordered ~use_num:false [] p) + with Not_found -> t (* Convert a term to float, fail on non-constant term. *) let term_val t = match simp_const t with Modified: trunk/Toss/Arena/Term.mli =================================================================== --- trunk/Toss/Arena/Term.mli 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Arena/Term.mli 2012-05-10 22:22:09 UTC (rev 1704) @@ -16,6 +16,9 @@ (** {2 Basic functions.} *) +(** Whether to simplify symbolically or not. Set to false by default. + It is nice for symbolic stuff, but slows down numerics. *) +val simp_symb : bool ref (** Print a term as a string. *) val str : term -> string Modified: trunk/Toss/Arena/TermTest.ml =================================================================== --- trunk/Toss/Arena/TermTest.ml 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Arena/TermTest.ml 2012-05-10 22:22:09 UTC (rev 1704) @@ -74,6 +74,39 @@ assert_equal ~printer:(fun x->x) "0.005" (String.sub (str (List.hd ( rk4_step "t" (Const 0.) (Const 0.1) eqs [Const 0.]))) 0 5); + ); + "rk4 eq" >:: + (fun () -> + (* Runge-Kutta symbolically with 2 free parameters. *) + let tyson = eqs_of_string + (" :y(e1)' = 0.015 + -200. * :y(e1) * :y(e4); " ^ + ":y(e2)' = -0.6 * :y(e2) + k6 * :y(e5); " ^ + ":y(e3)' = -100. * :y(e3) + k6 * :y(e5) + 100. * :y(e4); " ^ + ":y(e4)' = -100.*:y(e4) + 100.*:y(e3) + -200.*:y(e1) * :y(e4); " ^ + ":y(e5)' = -k6 * :y(e5) + 0.018 * :y(e6) + " ^ + " k4 * :y(e6) * :y(e5) * :y(e5); " ^ + ":y(e6)' = -0.018 * :y(e6) + 200. * :y(e1) * :y(e4) + " ^ + " -k4 * :y(e6) * :y(e5) * :y(e5)") in + let init = [Const 0.; Const 0.; Const 1.; Const 0.; Const 0.; Const 0.] in + Term.simp_symb := true; + let res = rk4_step "t" (Const 0.) (Const 0.005) tyson init in + Term.simp_symb := false; + let val_str vs = String.concat ", " (List.map str vs) in + assert_equal ~printer:(fun x->x) + ("6.6076722582e-05, 3.515625e-13 * k6, 3.515625e-13 * k6 + " ^ + "0.687499267591, 0.312491809132, -3.515625e-13 * k6 + " ^ + "6.08239621818e-28 * k4 + 2.02139802246e-10, " ^ + "-6.08239621818e-28 * k4 + 8.9230752782e-06") (val_str res); + + (* Generate RK4 equations symbolically for [eq], step [n]. *) + (*let generate_rksymb eq n t0 tstep = + let init m = Array.to_list (Array.mapi (fun i _ -> + Term.Var (Printf.sprintf "v%iat%i" i m)) (Array.of_list eq)) in + let res = rk4_step "t" (Const t0) (Const tstep) eq (init n) in + String.concat "\n" (List.map2 (fun t v -> + (Term.str t) ^ " = " ^ (Term.str v) ^ "\n") (init (n+1)) res) in + assert_equal ~printer:(fun x->x) "ok" (generate_rksymb tyson 0 0. 0.005); + *) ); ] Modified: trunk/Toss/Client/JsHandler.ml =================================================================== --- trunk/Toss/Client/JsHandler.ml 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Client/JsHandler.ml 2012-05-10 22:22:09 UTC (rev 1704) @@ -69,8 +69,8 @@ ("Hnefatafl", AuxIO.input_file "examples/Hnefatafl.toss"); ("Rewriting-Example", AuxIO.input_file "examples/Rewriting-Example.toss"); ("Bounce", AuxIO.input_file "examples/Bounce.toss"); - ("Yeast-Cell-Cycle-Tyson", - AuxIO.input_file "examples/Yeast-Cell-Cycle-Tyson.toss"); + ("Cell-Cycle-Tyson-1991", + AuxIO.input_file "examples/Cell-Cycle-Tyson-1991.toss"); ] let gSel_games = ref [compile_game_data "Tic-Tac-Toe" Modified: trunk/Toss/Client/State.js =================================================================== --- trunk/Toss/Client/State.js 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Client/State.js 2012-05-10 22:22:09 UTC (rev 1704) @@ -56,7 +56,7 @@ function State (game, info_obj, mirror) { // We create an SVG box with margins depending on the game. this.game = game; - this.mirror = mirror || (game == "Yeast-Cell-Cycle-Tyson"); + this.mirror = mirror || (game == "Cell-Cycle-Tyson-1991"); var create_svg_box = function (margx, margy, parent_id) { var svg_e = document.getElementById("svg"); @@ -198,7 +198,7 @@ function square_elements_game (game) { return (game !== "Connect4" && game !== "Bounce" && - game !== "Yeast-Cell-Cycle-Tyson" && + game !== "Cell-Cycle-Tyson-1991" && game !== "Rewriting-Example") } Copied: trunk/Toss/Client/img/Cell-Cycle-Tyson-1991.png (from rev 1703, trunk/Toss/Client/img/Yeast-Cell-Cycle-Tyson.png) =================================================================== (Binary files differ) Deleted: trunk/Toss/Client/img/Yeast-Cell-Cycle-Tyson.png =================================================================== (Binary files differ) Modified: trunk/Toss/Client/index.html =================================================================== --- trunk/Toss/Client/index.html 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Client/index.html 2012-05-10 22:22:09 UTC (rev 1704) @@ -172,11 +172,11 @@ </button> </div> <div class="game-picdiv3"> -<button onclick="new_play_click ('Yeast-Cell-Cycle-Tyson')" class="game-picbt"> - <img class="game-picimg" src="img/Yeast-Cell-Cycle-Tyson.png" - alt="Yeast-Cell-Cycle-Tyson" /> - <span id="pdescYeast-Cell-Cycle-Tyson" class="game-picspan"> - <span class="game-pictxt">Yeast-Cell-Cycle-Tyson</span> +<button onclick="new_play_click ('Cell-Cycle-Tyson-1991')" class="game-picbt"> + <img class="game-picimg" src="img/Cell-Cycle-Tyson-1991.png" + alt="Cell-Cycle-Tyson-1991" /> + <span id="pdescCell-Cycle-Tyson-1991" class="game-picspan"> + <span class="game-pictxt">Cell-Cycle-Tyson-1991</span> </span> </button> </div> @@ -462,8 +462,8 @@ <p><b>Bounce</b> is the basic example we use to illustrate how continuous dynamics and invariants work with structure rewriting.</p> </div> - <div class="game-desc" id="Yeast-Cell-Cycle-Tyson-desc"> - <p><b>Yeast Cell Cycle</b> model by <b>Tyson</b> (1991), + <div class="game-desc" id="Cell-Cycle-Tyson-1991-desc"> + <p>Yeast <b>Cell Cycle</b> model by <b>Tyson (1991)</b>, <a href="http://www.cellerator.org/notebooks/Tyson6.html">described here</a>, is a model of the cell cycle based on the interactions between cdc2 and cyclin. We use it as an example of non-linear Modified: trunk/Toss/Solver/RealQuantElim/OrderedPoly.ml =================================================================== --- trunk/Toss/Solver/RealQuantElim/OrderedPoly.ml 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Solver/RealQuantElim/OrderedPoly.ml 2012-05-10 22:22:09 UTC (rev 1704) @@ -12,7 +12,10 @@ Poly (z, [(Poly(y, [(Poly (x, [(Const 1, 1)]), 0)]), 2); (Poly(y, [(Poly (x, [(Const 2, 0)]), 0)]), 0)]) *) -type polynomial = Const of num | Poly of string * (polynomial * int) list +type polynomial = + | FConst of float + | Const of num + | Poly of string * (polynomial * int) list type t = polynomial (* to be compatible with OrderedType signature *) @@ -26,7 +29,8 @@ (* Print the given ordered polynomial as a string. *) let rec str = function - Const n -> string_of_num n + | FConst n -> string_of_float n + | Const n -> string_of_num n | Poly (v, clist) -> let estr (p, d) = if d = 0 then "(" ^ (str p) ^ ")" else if d = 1 then @@ -41,7 +45,8 @@ (* Check if the given ordered polynomial is equal to zero. *) let rec is_zero = function - Const n -> (sign_num n) = 0 + | FConst n -> n = 0. + | Const n -> (sign_num n) = 0 | Poly (_, []) -> true | Poly (_, [(c, n)]) -> n = 0 && is_zero c | _ -> false @@ -50,11 +55,14 @@ do not assume that both arguments are over the same set of variables. *) let rec rcompare p1 p2 = match (p1, p2) with - (Const n, Const m) -> - let c = sign_num ((abs_num n) -/ (abs_num m)) in - if c <> 0 then c else sign_num (n -/ m) + | (FConst n, FConst m) -> if n > m then 1 else if m > n then -1 else 0 + | (Const n, Const m) -> + let c = sign_num ((abs_num n) -/ (abs_num m)) in + if c <> 0 then c else sign_num (n -/ m) | (Const _, _) -> -1 | (_, Const _) -> 1 + | (FConst _, _) -> -1 + | (_, FConst _) -> 1 | (Poly (v, [(c, d)]), Poly (w, [])) -> if d = 0 && is_zero c then 0 else 1 | (Poly (w, []), Poly (v, [(c, d)])) -> if d = 0 && is_zero c then 0 else -1 | (Poly (_, _::_), Poly (_, [])) -> 1 @@ -62,19 +70,19 @@ | (Poly (_, []), Poly (_, [])) -> 0 | (Poly (v, _), Poly (w, _)) when v <> w -> String.compare v w | (Poly (v, (c1, d1)::r1), Poly (w, (c2, d2)::r2)) -> - if d1 <> d2 then d1 - d2 else - let c = rcompare c1 c2 in - if c <> 0 then c else rcompare (Poly (v, r1)) (Poly (w, r2)) + if d1 <> d2 then d1 - d2 else + let c = rcompare c1 c2 in + if c <> 0 then c else rcompare (Poly (v, r1)) (Poly (w, r2)) let rec deg_sum acc = function - Const _ -> acc + | Const _ | FConst _ -> acc | Poly (v, lst) -> - let deg_sumi acc (p, i) = deg_sum (i + acc) p in - List.fold_left deg_sumi acc lst + let deg_sumi acc (p, i) = deg_sum (i + acc) p in + List.fold_left deg_sumi acc lst let compare p q = let d = (deg_sum 0 p) - (deg_sum 0 q) in - if d <> 0 then d else rcompare p q + if d <> 0 then d else rcompare p q (* Check if two polynomials are equal. *) let equal p1 p2 = (compare p1 p2 = 0) @@ -85,78 +93,80 @@ (* Helper function to extract main variable from an ordered polynomial. *) let var = function - Const _ -> raise Unmatched_variables + | Const _ | FConst _ -> raise Unmatched_variables | Poly (v, _) -> v (* Lower the number of variables of a polynomial - remove the highest. *) let lower = function - Poly (v, [(q, d)]) when d = 0 -> q + | Poly (v, [(q, d)]) when d = 0 -> q | _ -> failwith "cannot lower non-constant or zero polynomial" (* Check if the given ordered polynomial has constant value. *) let rec constant_value = function - Const n -> Some n + | FConst n -> failwith "constant value for FConst; TODO move from Poly.ml" + | Const n -> Some n | Poly (_, []) -> Some (num_of_int 0) | Poly (_, (c, d) :: rest) when d = 0 -> constant_value c | _ -> None (* Degree of the given polynomial in its highest variable. *) let deg = function - Poly (_, (_, d) :: _) -> d + | Poly (_, (_, d) :: _) -> d | _ -> 0 (* Leading coefficient of the given polynomial, represented as ordered polynomial, multiplied by main variable raised to [n]-th power. *) let leading_coeff n = function - Poly (v, (c, _) :: _) -> Poly (v, [(c, n)]) + | Poly (v, (c, _) :: _) -> Poly (v, [(c, n)]) | Poly (v, []) -> Poly (v, []) | Const n -> Const n + | FConst n -> FConst n (* Degree 0 coefficient of the given polynomial, if it exists and is non-0. *) let rec const_coeff = function - Poly (v, [(q, d)]) as p when d = 0 && not (is_zero q) -> Some p + | Poly (v, [(q, d)]) as p when d = 0 && not (is_zero q) -> Some p | Poly (v, _ :: rs) -> const_coeff (Poly (v, rs)) | _ -> None (* Omit leading coefficient in the given polynomial. *) let omit_leading = function - Poly (v, _ :: rest) -> Poly (v, rest) + | Poly (v, _ :: rest) -> Poly (v, rest) | x -> x (* Calculate n * p for a given polynomial p. *) let rec multiple n = function - Const m -> Const ((num_of_int n) */ m) + | FConst m -> FConst ((float_of_int n) *. m) + | Const m -> Const ((num_of_int n) */ m) | Poly (v, l) -> - if n = 0 then Poly (v, []) else - Poly (v, List.map (fun (c, d) -> (multiple n c, d)) l) + if n = 0 then Poly (v, []) else + Poly (v, List.map (fun (c, d) -> (multiple n c, d)) l) let rec multiple_num n = function - Const m -> Const (n */ m) + | FConst m -> failwith "multiple num for FConst; TODO move from Poly.ml" + | Const m -> Const (n */ m) | Poly (v, l) -> - if sign_num n = 0 then Poly (v, []) else - Poly (v, List.map (fun (c, d) -> (multiple_num n c, d)) l) + if sign_num n = 0 then Poly (v, []) else + Poly (v, List.map (fun (c, d) -> (multiple_num n c, d)) l) (* If c1 * p = c2 * q for constants (c1,c2) <> (0,0), return them; else None. *) let rec constant_factors p0 q0 = match (p0, q0) with - (Const n, Const m) -> - if (sign_num m) <> 0 or (sign_num n) <> 0 then - Some (m, n) - else None + | (Const n, Const m) -> + if (sign_num m) <> 0 or (sign_num n) <> 0 then Some (m, n) else None | (Poly (v, []), _) -> - if is_zero q0 then None else Some (num_of_int 1, num_of_int 0) + if is_zero q0 then None else Some (num_of_int 1, num_of_int 0) | (_, Poly (v, [])) -> - if is_zero p0 then None else Some (num_of_int 0, num_of_int 1) + if is_zero p0 then None else Some (num_of_int 0, num_of_int 1) | (Poly (v, (p, d)::ps), Poly (w, (q, e)::qs)) when w = v -> ( - if d <> e then None else match constant_factors p q with - None -> None - | Some (a, b) -> - if equal (multiple_num a p0) (multiple_num b q0) then - Some (a,b) - else None - ) + if d <> e then None else match constant_factors p q with + | None -> None + | Some (a, b) -> + if equal (multiple_num a p0) (multiple_num b q0) then + Some (a,b) + else None + ) | _ -> raise Unmatched_variables @@ -165,23 +175,24 @@ (* Add two ordered polynomials [p1] and [p2] in the same variable. *) let rec add p1 p2 = match (p1, p2) with - (Const n, Const m) -> Const (n +/ m) + | (FConst n, FConst m) -> FConst (n +. m) + | (Const n, Const m) -> Const (n +/ m) | (Poly (v, l1), Poly (w, l2)) when v = w -> Poly (v, add_lists (l1, l2)) | _ -> raise Unmatched_variables and add_lists = function - ([(p, d)], []) when d = 0 && is_zero p -> [] + | ([(p, d)], []) when d = 0 && is_zero p -> [] | ([], [(p, d)]) when d = 0 && is_zero p -> [] | (l1, []) -> l1 | ([], l2) -> l2 | ((c1, d1) :: r1, (c2, d2) :: r2) -> - if d1 > d2 then - (c1, d1) :: (add_lists (r1, (c2, d2) :: r2)) - else if d2 > d1 then - (c2, d2) :: (add_lists ((c1, d1) :: r1, r2)) - else let c = add c1 c2 in - if is_zero c then add_lists (r1, r2) else - (c, d1) :: (add_lists (r1, r2)) + if d1 > d2 then + (c1, d1) :: (add_lists (r1, (c2, d2) :: r2)) + else if d2 > d1 then + (c2, d2) :: (add_lists ((c1, d1) :: r1, r2)) + else let c = add c1 c2 in + if is_zero c then add_lists (r1, r2) else + (c, d1) :: (add_lists (r1, r2)) (* Given a polynomial p, returns -p. *) let neg p = multiple (-1) p @@ -192,76 +203,78 @@ (* Multiply two polynomials [p1] and [p2] in the same variables. *) let rec mul p1 p2 = match (p1, p2) with - (Const n, Const m) -> Const (n */ m) + | (FConst n, FConst m) -> FConst (n *. m) + | (Const n, Const m) -> Const (n */ m) | (Poly (v, l1), Poly (w, l2)) when v = w -> Poly (v, mul_lists l1 l2) | _ -> raise Unmatched_variables and mul_lists l1 = function | [] -> [] | [(c2, d2)] -> - let append_coeff_mul (c1, d1) acc = - let c = mul c2 c1 in - if is_zero c then acc else (c, d1 + d2) :: acc - in - List.fold_right append_coeff_mul l1 [] + let append_coeff_mul (c1, d1) acc = + let c = mul c2 c1 in + if is_zero c then acc else (c, d1 + d2) :: acc in + List.fold_right append_coeff_mul l1 [] | c :: rest -> - add_lists ((mul_lists l1 [c]), (mul_lists l1 rest)) + add_lists ((mul_lists l1 [c]), (mul_lists l1 rest)) (* Raise [p] to n-th power. *) let rec pow p n = if n < 1 then failwith "we only support powers > 0" else if n = 1 then p else - let q = pow p (n / 2) in + let q = pow p (n / 2) in if n mod 2 = 0 then mul q q else mul p (mul q q) (* Given [u] and [p] return, if possible, q and r with [u] = q*[p] + r. *) (* Based on code from Jean-Christophe Filliatre, cf. Knuth volume 2, 4.6.1. *) let rec div ?(allow_frac=false) p q = - match (p, q) with - (Const n, Const m) -> - if allow_frac then Const (n // m) else - if sign_num (mod_num n m) = 0 then Const (n // m) else - raise Not_found - | (Poly (v, _), Poly (w, _)) -> - if v <> w then raise Unmatched_variables else - let (l, r) = div_rest ~allow_frac:allow_frac p q in - if is_zero r then l else raise Not_found - | _ -> raise Unmatched_variables + match (p, q) with + | (Const n, Const m) -> + if allow_frac then Const (n // m) else + if sign_num (mod_num n m) = 0 then Const (n // m) else + raise Not_found + | (Poly (v, _), Poly (w, _)) -> + if v <> w then raise Unmatched_variables else + let (l, r) = div_rest ~allow_frac:allow_frac p q in + if is_zero r then l else raise Not_found + | _ -> raise Unmatched_variables and div_rest ?(allow_frac=false) u = function - Poly (_, []) -> raise Not_found + | Poly (_, []) -> raise Not_found + | FConst _ -> failwith "div_rest: FConst arg" | Const n -> ( - match u with - Const m -> - if allow_frac then (Const (n // m), Const (num_of_int 0)) else - let r = mod_num n m in (Const ((n -/ r) // m), Const r) - | Poly (_, _) -> raise Unmatched_variables - ) + match u with + | FConst _ -> failwith "div_rest: FConst u" + | Const m -> + if allow_frac then (Const (n // m), Const (num_of_int 0)) else + let r = mod_num n m in (Const ((n -/ r) // m), Const r) + | Poly (_, _) -> raise Unmatched_variables + ) | Poly (v, (p, d) :: ps) -> - let rec loop k = function - u when k < 0 -> (Poly (v, []), u) - | Poly (w, _) when w <> v -> raise Unmatched_variables - | Poly (_, (q, i) :: qs) when i = d + k -> - let qk = div ~allow_frac:allow_frac q p in - let mqkxk = Poly (v, [(neg qk, k)]) in - let added = add (Poly (v, qs)) (mul mqkxk (Poly (v, ps))) in - let (q, r) = loop (k - 1) added in ( - match q with - Poly (_, ql) -> (Poly (v, (qk, k) :: ql), r) - | _ -> failwith "error by division" - ) - | u -> loop (k - 1) u - in - loop (deg u - d) u + let rec loop k = function + | u when k < 0 -> (Poly (v, []), u) + | Poly (w, _) when w <> v -> raise Unmatched_variables + | Poly (_, (q, i) :: qs) when i = d + k -> + let qk = div ~allow_frac:allow_frac q p in + let mqkxk = Poly (v, [(neg qk, k)]) in + let added = add (Poly (v, qs)) (mul mqkxk (Poly (v, ps))) in + let (q, r) = loop (k - 1) added in ( + match q with + | Poly (_, ql) -> (Poly (v, (qk, k) :: ql), r) + | _ -> failwith "error by division" + ) + | u -> loop (k - 1) u in + loop (deg u - d) u (* -------------------------- DIFFERENTIATION ------------------------------- *) let rec diff = function - Const n -> Const (num_of_int 0) + | FConst _ -> FConst (0.) + | Const _ -> Const (num_of_int 0) | Poly (v, l) -> Poly (v, diff_list l) and diff_list = function - [] -> [] + | [] -> [] | (c, d) :: r -> if d > 0 then (multiple d c, d-1) :: (diff_list r) else [] @@ -277,21 +290,20 @@ *) let modified_remainder p1 q = match q with - Const _ -> raise Unmatched_variables + | Const _ | FConst _ -> raise Unmatched_variables | Poly (v, _) when var p1 <> v -> raise Unmatched_variables | Poly (v, _) -> - let (m, b, q') = (deg q, leading_coeff 0 q, omit_leading q) in - if m > deg p1 then failwith "Modified reminder: wrong degree." else - let rec mr p = - let (n, a) = (deg p, leading_coeff 0 p) in - if n < m then p - else if n = m then - sub (mul b p) (mul a q) - else - let bp = mul b (omit_leading p) in - let d = sub bp (mul (leading_coeff (n-m) p) q') in - if n - 1 = deg d then mr d else - let bpow = pow b (n - 1 - (deg d)) in - mr (mul bpow d) - in - mr p1 + let (m, b, q') = (deg q, leading_coeff 0 q, omit_leading q) in + if m > deg p1 then failwith "Modified reminder: wrong degree." else + let rec mr p = + let (n, a) = (deg p, leading_coeff 0 p) in + if n < m then p + else if n = m then + sub (mul b p) (mul a q) + else + let bp = mul b (omit_leading p) in + let d = sub bp (mul (leading_coeff (n-m) p) q') in + if n - 1 = deg d then mr d else + let bpow = pow b (n - 1 - (deg d)) in + mr (mul bpow d) in + mr p1 Modified: trunk/Toss/Solver/RealQuantElim/OrderedPoly.mli =================================================================== --- trunk/Toss/Solver/RealQuantElim/OrderedPoly.mli 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Solver/RealQuantElim/OrderedPoly.mli 2012-05-10 22:22:09 UTC (rev 1704) @@ -3,7 +3,10 @@ (** {2 Basic Type Definitions} *) -type polynomial = Const of Numbers.num | Poly of string * (polynomial*int) list +type polynomial = + | FConst of float + | Const of Numbers.num + | Poly of string * (polynomial * int) list type t = polynomial (** to be compatible with OrderedType signature *) Modified: trunk/Toss/Solver/RealQuantElim/Poly.ml =================================================================== --- trunk/Toss/Solver/RealQuantElim/Poly.ml 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Solver/RealQuantElim/Poly.ml 2012-05-10 22:22:09 UTC (rev 1704) @@ -3,7 +3,7 @@ (* ---------------------- BASIC TYPE DEFINITION ----------------------------- *) type polynomial = - Var of string + | Var of string | Const of float | Times of polynomial * polynomial | Plus of polynomial * polynomial @@ -13,16 +13,18 @@ (* Print a polynomial as a string. *) let rec str = function - Var s -> s + | Var s -> s | Const n -> string_of_float n - | Times (Const n, q) -> if n = 1. then str q else poly_pair_str "*" (Const n) q + | Times (Const n, q) -> + if n = 1. then str q else poly_pair_str "*" (Const n) q | Times (p, q) -> poly_pair_str "*" p q - | Plus (p, Const n) -> if n = 0. then str p else poly_pair_str " + " p (Const n) + | Plus (p, Const n) -> + if n = 0. then str p else poly_pair_str " + " p (Const n) | Plus (p, q) -> poly_pair_str " + " p q and poly_pair_str sep p q = let brack s = if String.length s < 2 then s else "(" ^ s ^ ")" in - (brack (str p)) ^ sep ^ (brack (str q)) + (brack (str p)) ^ sep ^ (brack (str q)) (* ------------------ HELPER POWER FUNCTION USED IN PARSER ------------------ *) @@ -33,27 +35,28 @@ (* Basic simplification, reduces constant polynomials to integers. *) let rec simp_const = function - Var s -> Var s + | Var s -> Var s | Const n -> Const n | Times (p, q) -> ( match (simp_const p, simp_const q) with - (Const n, Const m) -> Const (n *. m) + | (Const n, Const m) -> Const (n *. m) | _ -> Times (p, q) - ) + ) | Plus (p, q) -> - match (simp_const p, simp_const q) with - (Const n, Const m) -> Const (n +. m) - | _ -> Plus (p, q) + match (simp_const p, simp_const q) with + | (Const n, Const m) -> Const (n +. m) + | _ -> Plus (p, q) (* ----------------- CONVERTION TO UNORDERED POLYNOMIALS -------------------- *) let rec make_unordered = function + | OrderedPoly.FConst n -> Const (n) | OrderedPoly.Const n -> Const (Numbers.float_of_num n) | OrderedPoly.Poly (v, lst) -> make_unordered_list v lst and make_unordered_list v = function - [] -> Const 0. + | [] -> Const 0. | [(p, d)] when d = 0 -> make_unordered p | [(p, d)] -> Times (make_unordered p, pow (Var v) d) | (p, d) :: ls -> @@ -82,7 +85,7 @@ (* List variables in the given polynomial. *) let rec vars = function - Var s -> [s] + | Var s -> [s] | Const _ -> [] | Times (p, q) -> combine (vars p) (vars q) | Plus (p, q) -> combine (vars p) (vars q) @@ -91,51 +94,52 @@ let vars_list pl = List.fold_left (fun vs p -> combine vs (vars p)) [] pl (* Make an ordered polynomial from a constant [n] in given ordered variables. *) -let rec make_ordered_const n = function - [] -> OrderedPoly.Const (num_of_float n) - | v :: vs -> OrderedPoly.Poly (v, [(make_ordered_const n vs, 0)]) +let rec make_ordered_const use_num n = function + | [] -> if use_num then OrderedPoly.Const (num_of_float n) else + OrderedPoly.FConst (n) + | v :: vs -> OrderedPoly.Poly (v, [(make_ordered_const use_num n vs, 0)]) (* Make an ordered polynomial from a variable [v] in given ordered variables. *) -let rec make_ordered_var v = function - [] -> failwith "given variable not found among all variables" - | w :: ws when v = w -> OrderedPoly.Poly (v, [(make_ordered_const 1. ws, 1)]) - | w :: ws -> OrderedPoly.Poly (w, [(make_ordered_var v ws, 0)]) +let rec make_ordered_var use_num v = function + | [] -> failwith "given variable not found among all variables" + | w :: ws when v = w -> + OrderedPoly.Poly (v, [(make_ordered_const use_num 1. ws, 1)]) + | w :: ws -> OrderedPoly.Poly (w, [(make_ordered_var use_num v ws, 0)]) (* Make an ordered polynomial in given ordered variables [vars]. *) -let rec make_ordered_poly vars = function - Const n -> make_ordered_const n vars - | Var v -> make_ordered_var v vars - | Times (p, q) -> - OrderedPoly.mul (make_ordered_poly vars p) (make_ordered_poly vars q) - | Plus (p, q) -> - OrderedPoly.add (make_ordered_poly vars p) (make_ordered_poly vars q) +let rec make_ordered_poly use_num vars = function + | Const n -> make_ordered_const use_num n vars + | Var v -> make_ordered_var use_num v vars + | Times (p, q) -> OrderedPoly.mul + (make_ordered_poly use_num vars p) (make_ordered_poly use_num vars q) + | Plus (p, q) -> OrderedPoly.add + (make_ordered_poly use_num vars p) (make_ordered_poly use_num vars q) (* Order on strings respecting priority given in [prio_list]. This means that if x appears in [prio_list] before y then x < y. Strings not appearing in [prio_list] at all are considered smaller than any string that appears. *) let compare prio_list x y = let rec cmp = function - [] -> String.compare x y + | [] -> String.compare x y | v :: vs when v = x -> if List.mem y vs then -1 else 1 | v :: vs when v = y -> if List.mem x vs then 1 else -1 - | v :: vs -> cmp vs - in - if x = y then 0 else cmp prio_list + | v :: vs -> cmp vs in + if x = y then 0 else cmp prio_list (* Make an ordered polynomial from [p] with [prio_list] order on variables. *) -let make_ordered prio_list p = +let make_ordered ?(use_num=true) prio_list p = let inc_cmp x y = (-1) * (compare prio_list x y) in let ord_vars = List.sort inc_cmp (vars p) in - make_ordered_poly ord_vars p + make_ordered_poly use_num ord_vars p (* Make ordered polynomials from [ps] with [prio_list] order on variables. *) let make_ordered_list prio_list ps = let vars = vars_list ps in let ord_vars = List.sort (fun x y -> (-1) * (compare prio_list x y)) vars in - List.rev_map (make_ordered_poly ord_vars) ps + List.rev_map (make_ordered_poly true ord_vars) ps (* Make ordered polynomials from first components of [ps], [prio_list] order. *) let make_ordered_pair_list prio_list ps = let vars = List.fold_left (fun vs (p, _) -> combine vs (vars p)) [] ps in let ord_vars = List.sort (fun x y -> (-1) * (compare prio_list x y)) vars in - List.rev_map (fun (p, x) -> (make_ordered_poly ord_vars p, x)) ps + List.rev_map (fun (p, x) -> (make_ordered_poly true ord_vars p, x)) ps Modified: trunk/Toss/Solver/RealQuantElim/Poly.mli =================================================================== --- trunk/Toss/Solver/RealQuantElim/Poly.mli 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/Solver/RealQuantElim/Poly.mli 2012-05-10 22:22:09 UTC (rev 1704) @@ -43,7 +43,8 @@ (** Make an ordered polynomial from [p] with [prio_list] order on variables,i.e. if x appears in [prio_list] before y then x < y. Strings not appearing in [prio_list] at all are considered smaller than any string that appears.*) -val make_ordered : string list -> polynomial -> OrderedPoly.polynomial +val make_ordered : ?use_num: bool -> + string list -> polynomial -> OrderedPoly.polynomial (** Make ordered polynomials from [ps] with [prio_list] order on variables. *) val make_ordered_list : string list -> polynomial list -> Copied: trunk/Toss/examples/Cell-Cycle-Tyson-1991.toss (from rev 1703, trunk/Toss/examples/Yeast-Cell-Cycle-Tyson.toss) =================================================================== --- trunk/Toss/examples/Cell-Cycle-Tyson-1991.toss (rev 0) +++ trunk/Toss/examples/Cell-Cycle-Tyson-1991.toss 2012-05-10 22:22:09 UTC (rev 1704) @@ -0,0 +1,75 @@ +PLAYERS 1, 2 + +RULE k1: + [ e1 | Cyc(e1) | ] -> [ e1 | Cyc(e1) | ] + dynamics + :y(e1)' = k1 + +RULE k3: + [ e1, e2, e3 | Cyc(e1); Cdc2P1(e2); Cdc2CycP1P2(e3) | ] -> + [ e1, e2, e3 | Cyc(e1); Cdc2P1(e2); Cdc2CycP1P2(e3) | ] + dynamics + :y(e1)' = -k3 * :y(e1) * :y(e2); + :y(e2)' = -k3 * :y(e1) * :y(e2); + :y(e3)' = k3 * :y(e1) * :y(e2) + +RULE k4p: + [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] -> + [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] + dynamics + :y(e1)' = -k4p * :y(e1); + :y(e2)' = k4p * :y(e1) + +RULE k4: + [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] -> + [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] + dynamics + :y(e1)' = -k4 * :y(e1) * :y(e2) * :y(e2); + :y(e2)' = k4 * :y(e1) * :y(e2) * :y(e2) + +RULE k6: + [ e1, e2, e3 | Cdc2CycP1(e1); CycP1(e2); Cdc2(e3) | ] -> + [ e1, e2, e3 | Cdc2CycP1(e1); CycP1(e2); Cdc2(e3) | ] + dynamics + :y(e1)' = -k6 * :y(e1); + :y(e2)' = k6 * :y(e1); + :y(e3)' = k6 * :y(e1) + +RULE k7: + [ e1 | CycP1(e1) | ] -> [ e1 | CycP1(e1) | ] + dynamics + :y(e1)' = -k7 * :y(e1) + +RULE k8: + [ e1, e2 | Cdc2(e1); Cdc2P1(e2) | ] -> [ e1, e2 | Cdc2(e1); Cdc2P1(e2) | ] + dynamics + :y(e1)' = -k8 * :y(e1); + :y(e2)' = k8 * :y(e1) + +RULE k9: + [ e1, e2 | Cdc2P1(e1); Cdc2(e2) | ] -> [ e1, e2 | Cdc2P1(e1); Cdc2(e2) | ] + dynamics + :y(e1)' = -k9 * :y(e1); + :y(e2)' = k9 * :y(e1) + +RULE Move: + [ e1 | Cyc(e1) | ] -> [ e1 | Cyc(e1) | ] + +LOC 0 { + PLAYER 1 { PAYOFF 0. MOVES [Move, + t : 9. -- 9., + k1 : 0.015 -- 0.015, + k3 : 200. -- 200., + k4p: 0.018 -- 0.018, + k4 : 180. -- 180., + k6 : 1. -- 1., + k7 : 0.6 -- 0.6, + k8 : 100. -- 100., + k9 : 100. -- 100. -> 0] } + PLAYER 2 { PAYOFF 0. } + UNIVERSAL { k1, k3, k4p, k4, k6, k7, k8, k9 } +} +START [ e1, e2, e3, e4, e5, e6 | Cyc(e1); CycP1(e2); Cdc2(e3); Cdc2P1(e4); + Cdc2CycP1(e5); Cdc2CycP1P2(e6) | + x { e1->1, e2->2, e3->3, e4->4, e5->5, e6->6 }; + y { e1->0, e2->0, e3->1, e4->0, e5->0, e6->0 } ] Deleted: trunk/Toss/examples/Yeast-Cell-Cycle-Tyson.toss =================================================================== --- trunk/Toss/examples/Yeast-Cell-Cycle-Tyson.toss 2012-05-09 19:41:58 UTC (rev 1703) +++ trunk/Toss/examples/Yeast-Cell-Cycle-Tyson.toss 2012-05-10 22:22:09 UTC (rev 1704) @@ -1,75 +0,0 @@ -PLAYERS 1, 2 - -RULE k1: - [ e1 | Cyc(e1) | ] -> [ e1 | Cyc(e1) | ] - dynamics - :y(e1)' = k1 - -RULE k3: - [ e1, e2, e3 | Cyc(e1); Cdc2P1(e2); Cdc2CycP1P2(e3) | ] -> - [ e1, e2, e3 | Cyc(e1); Cdc2P1(e2); Cdc2CycP1P2(e3) | ] - dynamics - :y(e1)' = -k3 * :y(e1) * :y(e2); - :y(e2)' = -k3 * :y(e1) * :y(e2); - :y(e3)' = k3 * :y(e1) * :y(e2) - -RULE k4p: - [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] -> - [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] - dynamics - :y(e1)' = -k4p * :y(e1); - :y(e2)' = k4p * :y(e1) - -RULE k4: - [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] -> - [ e1, e2 | Cdc2CycP1P2(e1); Cdc2CycP1(e2) | ] - dynamics - :y(e1)' = -k4 * :y(e1) * :y(e2) * :y(e2); - :y(e2)' = k4 * :y(e1) * :y(e2) * :y(e2) - -RULE k6: - [ e1, e2, e3 | Cdc2CycP1(e1); CycP1(e2); Cdc2(e3) | ] -> - [ e1, e2, e3 | Cdc2CycP1(e1); CycP1(e2); Cdc2(e3) | ] - dynamics - :y(e1)' = -k6 * :y(e1); - :y(e2)' = k6 * :y(e1); - :y(e3)' = k6 * :y(e1) - -RULE k7: - [ e1 | CycP1(e1) | ] -> [ e1 | CycP1(e1) | ] - dynamics - :y(e1)' = -k7 * :y(e1) - -RULE k8: - [ e1, e2 | Cdc2(e1); Cdc2P1(e2) | ] -> [ e1, e2 | Cdc2(e1); Cdc2P1(e2) | ] - dynamics - :y(e1)' = -k8 * :y(e1); - :y(e2)' = k8 * :y(e1) - -RULE k9: - [ e1, e2 | Cdc2P1(e1); Cdc2(e2) | ] -> [ e1, e2 | Cdc2P1(e1); Cdc2(e2) | ] - dynamics - :y(e1)' = -k9 * :y(e1); - :y(e2)' = k9 * :y(e1) - -RULE Move: - [ e1 | Cyc(e1) | ] -> [ e1 | Cyc(e1) | ] - -LOC 0 { - PLAYER 1 { PAYOFF 0. MOVES [Move, - t : 9. -- 9., - k1 : 0.015 -- 0.015, - k3 : 200. -- 200., - k4p: 0.018 -- 0.018, - k4 : 180. -- 180., - k6 : 1. -- 1., - k7 : 0.6 -- 0.6, - k8 : 100. -- 100., - k9 : 100. -- 100. -> 0] } - PLAYER 2 { PAYOFF 0. } - UNIVERSAL { k1, k3, k4p, k4, k6, k7, k8, k9 } -} -START [ e1, e2, e3, e4, e5, e6 | Cyc(e1); CycP1(e2); Cdc2(e3); Cdc2P1(e4); - Cdc2CycP1(e5); Cdc2CycP1P2(e6) | - x { e1->1, e2->2, e3->3, e4->4, e5->5, e6->6 }; - y { e1->0, e2->0, e3->1, e4->0, e5->0, e6->0 } ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |