Thread: [Toss-devel-svn] SF.net SVN: toss:[1723] trunk/Toss (Page 14)
Status: Beta
Brought to you by:
lukaszkaiser
|
From: <luk...@us...> - 2012-06-09 20:09:15
|
Revision: 1723
http://toss.svn.sourceforge.net/toss/?rev=1723&view=rev
Author: lukaszkaiser
Date: 2012-06-09 20:09:07 +0000 (Sat, 09 Jun 2012)
Log Message:
-----------
Work on the Parsing game and other small improvements.
Modified Paths:
--------------
trunk/Toss/Arena/Arena.ml
trunk/Toss/Arena/Arena.mli
trunk/Toss/Arena/ArenaParser.mly
trunk/Toss/Arena/ArenaTest.ml
trunk/Toss/Client/State.js
trunk/Toss/Client/Style.css
trunk/Toss/Client/eval.html
trunk/Toss/Client/img/Forces.png
trunk/Toss/Client/img/Parsing.png
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/Structure.ml
trunk/Toss/Solver/Structure.mli
trunk/Toss/examples/Forces.toss
trunk/Toss/examples/Parsing.toss
trunk/Toss/www/index.xml
Modified: trunk/Toss/Arena/Arena.ml
===================================================================
--- trunk/Toss/Arena/Arena.ml 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Arena/Arena.ml 2012-06-09 20:09:07 UTC (rev 1723)
@@ -267,6 +267,15 @@
let add_def_rels struc rels = List.fold_left add_def_rel_single struc rels
+let add_def_fun_single struc (f, v, def_re) =
+ let elems = Structure.elements struc in
+ let asg e = AssignmentSet.FO (v, [(e, AssignmentSet.Any)]) in
+ let fval e = Solver.M.get_real_val ~asg:(asg e) def_re struc in
+ List.fold_left (fun s e-> Structure.change_fun_int s f e (fval e)) struc elems
+
+let add_def_funs struc funs = List.fold_left add_def_fun_single struc funs
+
+
(* The order of following entries matters: [DefPlayers] adds more
players, with consecutive numbers starting from first available;
later [StartStruc], [CurrentStruc], [StateTime] and [StateLoc] entries
Modified: trunk/Toss/Arena/Arena.mli
===================================================================
--- trunk/Toss/Arena/Arena.mli 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Arena/Arena.mli 2012-06-09 20:09:07 UTC (rev 1723)
@@ -70,7 +70,10 @@
val add_def_rels : Structure.structure ->
(string * string list * Formula.formula) list -> Structure.structure
+val add_def_funs : Structure.structure ->
+ (string * string * Formula.real_expr) list -> Structure.structure
+
(** Print a label as a string. *)
val label_str : label -> string
val move_str : (label * int) -> string
Modified: trunk/Toss/Arena/ArenaParser.mly
===================================================================
--- trunk/Toss/Arena/ArenaParser.mly 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Arena/ArenaParser.mly 2012-06-09 20:09:07 UTC (rev 1723)
@@ -94,6 +94,10 @@
| rel = ID args = delimited (OPEN, separated_list (COMMA, ID), CLOSE)
EQ body = formula_expr_err { (rel, args, body) }
+fun_def_simple:
+ | COLON f = ID OPEN v = ID CLOSE EQ body = real_expr
+ { (f, v, body) }
+
game_move_timed:
| OPENSQ r = id_int t = FLOAT RARR l = INT EMB
emb = separated_list (COMMA, separated_pair (ID, COLON, id_int)) CLOSESQ
@@ -138,11 +142,19 @@
| START model = struct_expr WITH
defs = separated_list (SEMICOLON, rel_def_simple)
{ StartStruc (Arena.add_def_rels model defs) }
+ | START model = struct_expr WITH
+ defs = separated_list (SEMICOLON, rel_def_simple) WITH
+ funs = separated_list (SEMICOLON, fun_def_simple)
+ { StartStruc (Arena.add_def_funs (Arena.add_def_rels model defs) funs) }
| CURRENT model = struct_expr
{ CurrentStruc model }
| CURRENT model = struct_expr WITH
defs = separated_list (SEMICOLON, rel_def_simple)
{ CurrentStruc (Arena.add_def_rels model defs) }
+ | CURRENT model = struct_expr WITH
+ defs = separated_list (SEMICOLON, rel_def_simple) WITH
+ funs = separated_list (SEMICOLON, fun_def_simple)
+ { StartStruc (Arena.add_def_funs (Arena.add_def_rels model defs) funs) }
| MOVES moves = separated_list (SEMICOLON, game_move_timed)
{ History (moves) }
| TIME_MOD t = FLOAT
Modified: trunk/Toss/Arena/ArenaTest.ml
===================================================================
--- trunk/Toss/Arena/ArenaTest.ml 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Arena/ArenaTest.ml 2012-06-09 20:09:07 UTC (rev 1723)
@@ -17,7 +17,9 @@
"structure with rels parsing" >::
(fun () ->
let test p s res = assert_equal ~printer:(fun x -> x) res (rel_str p s) in
- test "P" "START [ 1 - 5 | | - ] with P(a) = :nbr(a) = 2" "P (e2)";
+ test "P" "START [ 1 - 5 | | - ] with P(a) = :nbr(a)= 2" "P (e2)";
+ test "P" "START [ 1 - 5 | | - ] with P(a) = :nbr(a)= 2 with :y(a) = 10*&a"
+ "P (e2)";
test "P" ("START [ 1 - 10 | | - ] with P(z) = &z > 1 and " ^
"all x, y (&x * &y = &z -> (&x = 1 or &y = 1))")
"P {e2; e3; e5; e7}";
Modified: trunk/Toss/Client/State.js
===================================================================
--- trunk/Toss/Client/State.js 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Client/State.js 2012-06-09 20:09:07 UTC (rev 1723)
@@ -196,10 +196,14 @@
}
function square_elements_game (game) {
- return (game !== "Connect4" &&
- game !== "Bounce" &&
- game !== "Cell-Cycle-Tyson-1991" &&
- game !== "Rewriting-Example")
+ return (game === "Breakthrough" ||
+ game === "Checkers" ||
+ game === "Chess" ||
+ game === "Entanglement" ||
+ game === "Gomoku" ||
+ game === "Pawn-Whopping" ||
+ game === "Tic-Tac-Toe" ||
+ game === "Hnefatafl")
}
// Draw the model.
@@ -261,8 +265,8 @@
}
// Main draw_model function.
- var sqrt = Math.round (Math.sqrt (this.elems.length));
- if (sqrt * sqrt == this.elems.length) { // perhaps a grid
+ var sqrt = Math.round (Math.sqrt (this.elems.length)); // perhaps a grid
+ if (sqrt * sqrt == this.elems.length && (sqrt > 4 || game=="Tic-Tac-Toe")) {
SHAPES.elem_size_x = SVG_WIDTH / (2.0 * (sqrt-1));
SHAPES.elem_size_y = SVG_HEIGHT / (2.0 * (sqrt-1));
} else {
Modified: trunk/Toss/Client/Style.css
===================================================================
--- trunk/Toss/Client/Style.css 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Client/Style.css 2012-06-09 20:09:07 UTC (rev 1723)
@@ -1055,17 +1055,17 @@
stroke-width: 5px;
}
-.model-pred-Cyc {
+.model-pred-Cyc, .model-pred-Pone {
stroke: #260314;
stroke-width: 3px;
fill: #e5effa;
}
-.model-pred-CycP1 {
+.model-pred-CycP1, .model-pred-Tnbr {
stroke: #260314;
stroke-width: 3px;
fill: #a5afaa;
}
-.model-pred-Cdc2 {
+.model-pred-Cdc2, .model-pred-Pnil {
stroke: #260314;
stroke-width: 3px;
fill: #93a605;
@@ -1075,7 +1075,7 @@
stroke-width: 3px;
fill: #3e5916;
}
-.model-pred-Cdc2CycP1 {
+.model-pred-Cdc2CycP1, .model-pred-Tlist {
stroke: #260314;
stroke-width: 3px;
fill: #f28705;
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Client/eval.html 2012-06-09 20:09:07 UTC (rev 1723)
@@ -94,7 +94,8 @@
<textarea id="structure" rows="3" cols="40">
[ 1 - 5 | | - ] with
-E(x, y) = &x = &y + 1</textarea>
+E(x, y) = &x = &y + 1
+with :y(a) = -10 * &a</textarea>
<button onclick="eval()">Eval and Draw</button>
Modified: trunk/Toss/Client/img/Forces.png
===================================================================
(Binary files differ)
Modified: trunk/Toss/Client/img/Parsing.png
===================================================================
(Binary files differ)
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Solver/Solver.ml 2012-06-09 20:09:07 UTC (rev 1723)
@@ -526,13 +526,13 @@
| re ->
update_cache struc;
try
- let (res, _) = Hashtbl.find !re_cache_results re in
+ let (res, _) = Hashtbl.find !re_cache_results (re, asg) in
LOG 2 "found in re cache: %s" (Formula.real_str re);
res
with Not_found ->
LOG 1 "Get real val %s" (real_str re);
let re_val = get_real_val solver asg re struc in
- Hashtbl.add !re_cache_results re (re_val, re_rels re);
+ Hashtbl.add !re_cache_results (re, asg) (re_val, re_rels re);
re_val
(* Evaluate i-th formula on j-th structure. *)
Modified: trunk/Toss/Solver/Structure.ml
===================================================================
--- trunk/Toss/Solver/Structure.ml 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Solver/Structure.ml 2012-06-09 20:09:07 UTC (rev 1723)
@@ -349,11 +349,12 @@
List.fold_left (fun s a -> add_fun s fn a) struc assgns
(* Change function [fn] assignment for element [e] to [x] in [struc]. *)
-let change_fun struc fn elem x =
- let assgs, e = StringMap.find fn struc.functions, elem_nbr struc elem in
+let change_fun_int struc fn e x =
+ let assgs = StringMap.find fn struc.functions in
let new_functions = StringMap.add fn (IntMap.add e x assgs) struc.functions in
{ struc with functions = new_functions }
+let change_fun struc fn elem x = change_fun_int struc fn (elem_nbr struc elem) x
(* ------------ GLOBAL FUNCTIONS TO CREATE STRUCTURES FROM LISTS ------------ *)
Modified: trunk/Toss/Solver/Structure.mli
===================================================================
--- trunk/Toss/Solver/Structure.mli 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/Solver/Structure.mli 2012-06-09 20:09:07 UTC (rev 1723)
@@ -229,6 +229,7 @@
(** Change function [fn] assignment for element [e] to [x] in [struc]. *)
val change_fun : structure -> string -> string -> float -> structure
+val change_fun_int : structure -> string -> int -> float -> structure
(** {2 Global function to create structures from lists} *)
Modified: trunk/Toss/examples/Forces.toss
===================================================================
--- trunk/Toss/examples/Forces.toss 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/examples/Forces.toss 2012-06-09 20:09:07 UTC (rev 1723)
@@ -42,7 +42,7 @@
LOC 0 {
PLAYER 1 { PAYOFF 0. MOVES [Move,
- :t : 3. -- 3.,
+ :t : 5. -- 5.,
:k : 0.1 -- 0.1,
:f : 0.1 -- 0.1,
:ke : 200. -- 200. -> 0] }
@@ -50,6 +50,6 @@
UNIVERSAL { Coulomb, Hooke, Friction }
}
-START [ e5 | Start(e1); E { (e1, e2); (e1, e3); (e1, e4) } |
- vx { e1->0, e2->0, e3->0, e4->0, e5->0 }; vy { e1->0, e2->0, e3->0, e4->0,e5->0 };
- x { e1->0., e2->10., e3->10., e4->10, e5->0. }; y { e1->0., e2->9, e3->0, e4->-9, e5->0 } ]
+START [ | Start(e1); E { (e1, e2); (e1, e3); (e1, e4) } |
+ vx { e1->0, e2->0, e3->0, e4->0 }; vy { e1->0, e2->0, e3->0, e4->0 };
+ x { e1->0., e2->10., e3->10., e4->10 }; y { e1->0., e2->9, e3->0, e4->-9 } ]
Modified: trunk/Toss/examples/Parsing.toss
===================================================================
--- trunk/Toss/examples/Parsing.toss 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/examples/Parsing.toss 2012-06-09 20:09:07 UTC (rev 1723)
@@ -1,16 +1,35 @@
PLAYERS 1, 2
RULE NilList:
- [e1 | Pnil(e1) | ] -> [a1, a2 | Pnil (a1); Tp (a1, a2); Tlist (a2) | ]
+ [e1 | Pnil(e1) | ] -> [a1, a2 | Pnil (a1); E (a1, a2); Tlist (a2) | ]
emb Pnil with [a1 <- e1] update
:x(a1) = :x(e1);
:x(a2) = :x(e1);
:y(a1) = :y(e1);
- :y(a2) = :y(e1) + 1.
+ :y(a2) = :y(e1) - 1
+RULE OneNbr:
+ [e1 | Pone(e1) | ] -> [a1, a2 | Pone (a1); E (a1, a2); Tnbr (a2) | ]
+ emb Pone with [a1 <- e1] update
+ :x(a1) = :x(e1);
+ :x(a2) = :x(e1);
+ :y(a1) = :y(e1);
+ :y(a2) = :y(e1) - 1
+
+RULE NbrList:
+ [e1, e2 | Tnbr(e1); Tlist(e2) | ] ->
+ [a1, a2, a3 | Tnbr (a1); Tlist (a2); Tlist (a3); E (a1, a3); E (a2, a3) | ]
+ emb Pone with [a1 <- e1, a2 <- e2] update
+ :x(a1) = :x(e1);
+ :x(a2) = :x(e2);
+ :x(a3) = :x(e1) + :x(e2) / 2;
+ :y(a1) = :y(e1);
+ :y(a2) = :y(e2);
+ :y(a3) = ((:y(e2) + :y(e2)) / 2) - 1
+
LOC 0 {
- PLAYER 1 { PAYOFF 0. MOVES [NilList -> 0] }
+ PLAYER 1 { PAYOFF 0. MOVES [NilList -> 0]; [NbrList -> 0]; [OneNbr -> 0] }
PLAYER 2 { PAYOFF 0. }
}
-START [ | Tp:2 {}; Tlist:1 {}; Pone (one); Ptrue (t); Pnil (nil);
+START [ | E:2 {}; Tlist:1 {}; Tnbr:1 {}; Pone (one); Pone (t); Pnil (nil);
S { (one, t); (t, nil) } | - ]
Modified: trunk/Toss/www/index.xml
===================================================================
--- trunk/Toss/www/index.xml 2012-06-07 21:55:42 UTC (rev 1722)
+++ trunk/Toss/www/index.xml 2012-06-09 20:09:07 UTC (rev 1723)
@@ -35,18 +35,22 @@
<section title="News">
<itemize>
+ <newsitem date="07/06/12">
+ Switching to a new ODE solver which uses the Cash-Karp method</newsitem>
+ <newsitem date="02/06/12">
+ Starting work on an interface for structures and formula evaluation</newsitem>
<newsitem date="27/05/12">
First structures defined using the term rewriting system syntax</newsitem>
<newsitem date="24/05/12">
Code for Term functions cleaned up and made JS compatible</newsitem>
- <newsitem date="13/05/12">
- Toss release 0.8 with full JS compatibility with dynamics</newsitem>
- <newsitem date="04/05/12">
- Dynamics debugged and animations now work in the JS interface</newsitem>
- <newsitem date="04/05/12">
- Old rewriting example works with the JS interface</newsitem>
- <newsitem date="25/04/12">
- Work on positioning with the JS interface</newsitem>
+ <oldnewsitem date="13/05/12">
+ Toss release 0.8 with full JS compatibility with dynamics</oldnewsitem>
+ <oldnewsitem date="04/05/12">
+ Dynamics debugged and animations now work in the JS interface</oldnewsitem>
+ <oldnewsitem date="04/05/12">
+ Old rewriting example works with the JS interface</oldnewsitem>
+ <oldnewsitem date="25/04/12">
+ Work on positioning with the JS interface</oldnewsitem>
<oldnewsitem date="30/03/12">
Adding Hnefatafl to example Toss games</oldnewsitem>
<oldnewsitem date="21/03/12">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <luk...@us...> - 2012-06-15 15:23:40
|
Revision: 1724
http://toss.svn.sourceforge.net/toss/?rev=1724&view=rev
Author: lukaszkaiser
Date: 2012-06-15 15:23:31 +0000 (Fri, 15 Jun 2012)
Log Message:
-----------
Allowing non-PNF QBFs and adding a separate SO evaluation function.
Modified Paths:
--------------
trunk/Toss/Client/State.js
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/Formula/BoolFormula.mli
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/SolverTest.ml
Modified: trunk/Toss/Client/State.js
===================================================================
--- trunk/Toss/Client/State.js 2012-06-09 20:09:07 UTC (rev 1723)
+++ trunk/Toss/Client/State.js 2012-06-15 15:23:31 UTC (rev 1724)
@@ -227,7 +227,7 @@
document.getElementById("svg").appendChild(r);
} else {
var circ = SHAPES.circle (
- elem.x, elem.y, 30,
+ elem.x, elem.y, SHAPES.circle_size,
[["id", "elem_" + elem.id], ["class", elem_class(elem.id)],
["onclick", "handle_elem_click('" + elem.id + "')"]]);
document.getElementById("svg").appendChild(circ);
@@ -269,9 +269,13 @@
if (sqrt * sqrt == this.elems.length && (sqrt > 4 || game=="Tic-Tac-Toe")) {
SHAPES.elem_size_x = SVG_WIDTH / (2.0 * (sqrt-1));
SHAPES.elem_size_y = SVG_HEIGHT / (2.0 * (sqrt-1));
+ } else if (this.elems.length < 30) {
+ SHAPES.elem_size_x = SVG_WIDTH / 20;
+ SHAPES.elem_size_y = SVG_HEIGHT / 20;
} else {
SHAPES.elem_size_x = SVG_WIDTH / 20;
- SHAPES.elem_size_y = SVG_HEIGHT / 20;
+ SHAPES.elem_size_y = SVG_WIDTH / 20;
+ SHAPES.circle_size = 300 / this.elems.length;
}
draw_background (game);
for (var i = 0; i < this.elems.length; i++) {
@@ -305,6 +309,7 @@
function Shapes () {
this.elem_size_x = 25; // suggested size of elements
this.elem_size_y = 25; // suggested size of elements
+ this.circle_size = 30;
var DEFpawn = '<g transform="translate(-22.5,-22.5)"> \
<path \
Modified: trunk/Toss/Formula/BoolFormula.ml
===================================================================
--- trunk/Toss/Formula/BoolFormula.ml 2012-06-09 20:09:07 UTC (rev 1723)
+++ trunk/Toss/Formula/BoolFormula.ml 2012-06-15 15:23:31 UTC (rev 1724)
@@ -892,13 +892,21 @@
(* Type for quantified Boolean formulas. *)
type qbf =
- | QFree of bool_formula
+ | QVar of int
+ | QNot of qbf
+ | QAnd of qbf list
+ | QOr of qbf list
| QEx of int list * qbf
| QAll of int list * qbf
(* Print a QBF formula. *)
let rec qbf_str = function
- | QFree phi -> str phi
+ | QVar v -> var_str v
+ | QNot phi -> "(not " ^ (qbf_str phi) ^ ")"
+ | QAnd [] -> "true"
+ | QOr [] -> "false"
+ | QAnd (qbflist) -> qbf_list_str " and " qbflist
+ | QOr (qbflist) -> qbf_list_str " or " qbflist
| QEx (vars, phi) ->
"(ex " ^ (String.concat ", " (List.map string_of_int vars)) ^
" " ^ qbf_str phi ^ ")"
@@ -906,7 +914,12 @@
"(ex " ^ (String.concat ", " (List.map string_of_int vars)) ^
" " ^ qbf_str phi ^ ")"
+and qbf_list_str sep = function
+ | [] -> "[]"
+ | [phi] -> qbf_str phi
+ | lst -> "(" ^ (String.concat sep (List.map qbf_str lst)) ^ ")"
+
(* Read a qdimacs description of a QBF from [in_ch]. *)
let read_qdimacs in_str =
let in_ch = ref in_str in
@@ -970,8 +983,7 @@
for i = 1 to (no_cl-1) do
cls := (read_clause (sinput_line ())) :: !cls
done;
- QFree (
- BAnd (List.map (fun lits -> BOr (List.map lit_of_int lits)) !cls))
+ QAnd (List.map (fun lits -> QOr (List.map (fun v -> QVar v) lits)) !cls)
) in
read_phi () in
@@ -980,7 +992,10 @@
(* Eliminating quantifiers from QBF formulas. *)
let rec elim_quant_rec = function
- | QFree (phi) -> phi
+ | QVar (v) -> BVar (v)
+ | QNot (f) -> BNot (elim_quant_rec f)
+ | QAnd (l) -> BAnd (List.map elim_quant_rec l)
+ | QOr (l) -> BOr (List.map elim_quant_rec l)
| QEx (vars, qphi) ->
Hashtbl.clear has_vars_mem;
let inside, len = elim_quant_rec qphi, List.length vars in
Modified: trunk/Toss/Formula/BoolFormula.mli
===================================================================
--- trunk/Toss/Formula/BoolFormula.mli 2012-06-09 20:09:07 UTC (rev 1723)
+++ trunk/Toss/Formula/BoolFormula.mli 2012-06-15 15:23:31 UTC (rev 1724)
@@ -5,7 +5,7 @@
(** This type describes formulas of relational logic with equality.
We allow only simple boolean junctors, other are resolved during parsing. *)
type bool_formula =
- BVar of int
+ | BVar of int
| BNot of bool_formula
| BAnd of bool_formula list
| BOr of bool_formula list
@@ -80,7 +80,10 @@
(** Type for quantified Boolean formulas. *)
type qbf =
- | QFree of bool_formula
+ | QVar of int
+ | QNot of qbf
+ | QAnd of qbf list
+ | QOr of qbf list
| QEx of int list * qbf
| QAll of int list * qbf
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-06-09 20:09:07 UTC (rev 1723)
+++ trunk/Toss/Solver/Solver.ml 2012-06-15 15:23:31 UTC (rev 1724)
@@ -393,6 +393,9 @@
Hashtbl.clear !re_cache_results;
List.iter (fun (p, r) -> Hashtbl.add !re_cache_results p r) !ok_re
+(* Evaluation with second-order variables. *)
+let eval_so struc phi =
+ Empty
(* Eval with very basic caching. *)
let eval_m struc phi =
@@ -405,12 +408,21 @@
res
with Not_found ->
LOG 1 "Eval_m %s" (str phi);
- let els = Assignments.set_to_set_list (Structure.elems struc) in
- check_timeout "Solver.eval_m.not_found";
- let asg = eval [] struc els Any phi in
- incr eval_counter;
- Hashtbl.add !cache_results phi (asg, phi_rels phi);
- asg
+ let vars = FormulaSubst.all_vars phi in
+ if List.exists (fun v -> Formula.is_so v) vars then (
+ check_timeout "Solver.eval_m.not_found_so";
+ let asg = eval_so struc phi in
+ incr eval_counter;
+ Hashtbl.add !cache_results phi (asg, phi_rels phi);
+ asg
+ ) else (
+ let els = Assignments.set_to_set_list (Structure.elems struc) in
+ check_timeout "Solver.eval_m.not_found_noso";
+ let asg = eval [] struc els Any phi in
+ incr eval_counter;
+ Hashtbl.add !cache_results phi (asg, phi_rels phi);
+ asg
+ )
)
(* Evaluate real expressions. Result is represented as assignments with
Modified: trunk/Toss/Solver/SolverTest.ml
===================================================================
--- trunk/Toss/Solver/SolverTest.ml 2012-06-09 20:09:07 UTC (rev 1723)
+++ trunk/Toss/Solver/SolverTest.ml 2012-06-15 15:23:31 UTC (rev 1724)
@@ -165,6 +165,13 @@
"{ z->1, z->2, z->3 }";
);
+ "eval: second-order" >::
+ (fun () ->
+ eval_eq "[ a, b | T { a } | ]"
+ "ex |R all x, y (|R (x, y) <-> (T(x) and not T(y)))"
+ "T";
+ );
+
"eval: game heuristic tests" >::
(fun () ->
let heur_phi = "(((R(v, w) and R(w, x) and R(x, y) and R(y, z)) or
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <luk...@us...> - 2012-06-16 17:01:27
|
Revision: 1726
http://toss.svn.sourceforge.net/toss/?rev=1726&view=rev
Author: lukaszkaiser
Date: 2012-06-16 17:01:17 +0000 (Sat, 16 Jun 2012)
Log Message:
-----------
Merging TermType and Term, rest of old Term are now in Coding.
Modified Paths:
--------------
trunk/Toss/Server/Tests.ml
trunk/Toss/Solver/Structure.ml
trunk/Toss/Term/BuiltinLang.ml
trunk/Toss/Term/BuiltinLang.mli
trunk/Toss/Term/BuiltinLangTest.ml
trunk/Toss/Term/ParseArc.ml
trunk/Toss/Term/ParseArc.mli
trunk/Toss/Term/ParseArcTest.ml
trunk/Toss/Term/Rewriting.ml
trunk/Toss/Term/RewritingTest.ml
trunk/Toss/Term/SyntaxDef.ml
trunk/Toss/Term/SyntaxDef.mli
trunk/Toss/Term/SyntaxDefTest.ml
trunk/Toss/Term/TRS.ml
trunk/Toss/Term/TRS.mli
trunk/Toss/Term/TRSTest.ml
Added Paths:
-----------
trunk/Toss/Term/Coding.ml
trunk/Toss/Term/Coding.mli
trunk/Toss/Term/CodingTest.ml
trunk/Toss/Term/Term.ml
trunk/Toss/Term/Term.mli
trunk/Toss/Term/TermTest.ml
Removed Paths:
-------------
trunk/Toss/Term/Term.ml
trunk/Toss/Term/Term.mli
trunk/Toss/Term/TermTest.ml
trunk/Toss/Term/TermType.ml
trunk/Toss/Term/TermType.mli
trunk/Toss/Term/TermTypeTest.ml
Modified: trunk/Toss/Server/Tests.ml
===================================================================
--- trunk/Toss/Server/Tests.ml 2012-06-15 21:24:23 UTC (rev 1725)
+++ trunk/Toss/Server/Tests.ml 2012-06-16 17:01:17 UTC (rev 1726)
@@ -14,10 +14,10 @@
]
let term_tests = "Term", [
- "TermTypeTest", [TermTypeTest.tests];
+ "TermTest", [TermTest.tests];
"SyntaxDefTest", [SyntaxDefTest.tests];
"BuiltinLangTest", [BuiltinLangTest.tests];
- "TermTest", [TermTest.tests];
+ "CodingTest", [CodingTest.tests];
"RewritingTest", [RewritingTest.tests];
"ParseArcTest", [ParseArcTest.tests];
"TRSTest", [TRSTest.tests; TRSTest.bigtests];
Modified: trunk/Toss/Solver/Structure.ml
===================================================================
--- trunk/Toss/Solver/Structure.ml 2012-06-15 21:24:23 UTC (rev 1725)
+++ trunk/Toss/Solver/Structure.ml 2012-06-16 17:01:17 UTC (rev 1726)
@@ -529,17 +529,17 @@
let trs_set_struc s = function
| ("addrel", te_rel, te_arglist) ->
- let rname = Term.decode_string te_rel in
- let args = Term.decode_list Term.term_to_string te_arglist in
+ let rname = Coding.decode_string te_rel in
+ let args = Coding.decode_list Coding.term_to_string te_arglist in
let (struc, args) = List.fold_left (fun (st, a) e ->
let (s1, i) = find_or_new_elem st e in (s1, i :: a)) (s, []) args in
add_rel struc rname (Array.of_list (List.rev args))
| (str, te, arg) when String.length str > 3 && String.sub str 0 3 = "fun" ->
let fname = String.sub str 3 ((String.length str) - 3) in
- let (struc, i) = find_or_new_elem s (Term.term_to_string te) in
- let v = Term.decode_bit_list arg in
+ let (struc, i) = find_or_new_elem s (Coding.term_to_string te) in
+ let v = Coding.decode_bit_list arg in
add_fun struc fname (i, float v)
- | _-> raise (Term.DECODE "Structure.trs_set_struc not a structure update set")
+ | _-> raise (Coding.DECODE "Structure.trs_set_struc not a struc update set")
let struc_from_trs str =
let (o, trs, _) = TRS.run_shell_str str in
Modified: trunk/Toss/Term/BuiltinLang.ml
===================================================================
--- trunk/Toss/Term/BuiltinLang.ml 2012-06-15 21:24:23 UTC (rev 1725)
+++ trunk/Toss/Term/BuiltinLang.ml 2012-06-16 17:01:17 UTC (rev 1726)
@@ -1,6 +1,6 @@
(* Basic Built-in TRS Language Syntax. *)
-open TermType
+open Term
open SyntaxDef
@@ -29,12 +29,12 @@
let list_sd = SDtype [Tp term_type_tp; Str "list"]
let list_name = name_of_sd list_sd
-let list_tp t = TTerm (list_name, [|t|])
-let list_tp_a = list_tp (TVar ("a", [||], 0, [||]))
+let list_tp t = Term (list_name, [||], [|t|])
+let list_tp_a = list_tp (Var ("a", [||], 0, [||]))
let list_nil_sd = SDfun ([Str "["; Str "]"], list_tp_a)
let list_nil_name = name_of_sd list_nil_sd
-let list_cons_sd = SDfun ([Tp (TVar ("a",[||],0,[||])); Str ","; Tp list_tp_a],
+let list_cons_sd = SDfun ([Tp (Var ("a",[||],0,[||])); Str ","; Tp list_tp_a],
list_tp_a)
let list_cons_name = name_of_sd list_cons_sd
@@ -147,8 +147,8 @@
let input_rewrite_rule_name = name_of_sd input_rewrite_rule_sd
let input_rewrite_rule_tp = type_of_sd input_rewrite_rule_sd
-let let_be_sd = SDfun ([Str "let"; Tp (TVar ("a_1",[||],0,[||])); Str "be";
- Tp (TVar ("a_1",[||],0,[||]))], input_rewrite_rule_tp)
+let let_be_sd = SDfun ([Str "let"; Tp (Var ("a_1",[||],0,[||])); Str "be";
+ Tp (Var ("a_1",[||],0,[||]))], input_rewrite_rule_tp)
let let_be_name = name_of_sd let_be_sd
let priority_input_rewrite_rule_sd = SDtype ([Str "priority";
@@ -159,8 +159,8 @@
type_of_sd priority_input_rewrite_rule_sd
let let_major_be_sd =
- SDfun ([Str "let"; Str "major"; Tp (TVar ("a_1",[||],0,[||])); Str "be";
- Tp (TVar ("a_1",[||],0,[||]))], priority_input_rewrite_rule_tp)
+ SDfun ([Str "let"; Str "major"; Tp (Var ("a_1",[||],0,[||])); Str "be";
+ Tp (Var ("a_1",[||],0,[||]))], priority_input_rewrite_rule_tp)
let let_major_be_name = name_of_sd let_major_be_sd
let fun_definition_sd = SDtype ([Str "fun"; Str "definition"])
@@ -185,44 +185,44 @@
let exception_cl_sd = SDtype [Tp term_type_tp; Str "exception"]
let exception_cl_name = name_of_sd exception_cl_sd
-let exception_cl_tp t = TTerm (exception_cl_name, [|t|])
+let exception_cl_tp t = Term (exception_cl_name, [||], [|t|])
let exception_sd =
- SDfun ([Str "!"; Str "!"; Tp (TVar ("a",[||],0,[||])); Str "!";Str "!";],
- exception_cl_tp (TVar ("other_than_a!",[||],0,[||])))
+ SDfun ([Str "!"; Str "!"; Tp (Var ("a",[||],0,[||])); Str "!";Str "!";],
+ exception_cl_tp (Var ("other_than_a!",[||],0,[||])))
let exception_name = name_of_sd exception_sd
let exn_ok_sd =
- SDfun ([Str "+"; Str "+"; Tp (TVar ("a",[||],0,[||])); Str "+";Str "+";],
- exception_cl_tp (TVar ("a",[||],0,[||]))) (* Here it should be a! *)
+ SDfun ([Str "+"; Str "+"; Tp (Var ("a",[||],0,[||])); Str "+";Str "+";],
+ exception_cl_tp (Var ("a",[||],0,[||]))) (* Here it should be a! *)
let exn_ok_name = name_of_sd exception_sd
(* --- Special functions recognized during Normalisation --- *)
-let brackets_sd = SDfun ([Str "("; Tp (TVar ("b",[||],0,[||])); Str ")"],
- TVar ("b",[||],0,[||]))
+let brackets_sd = SDfun ([Str "("; Tp (Var ("b",[||],0,[||])); Str ")"],
+ Var ("b",[||],0,[||]))
let brackets_name = name_of_sd brackets_sd
-let verbatim_sd = SDfun ([Str "<"; Str "|"; Tp (TVar ("b",[||],0,[||]));
- Str "|"; Str ">"], TVar ("b",[||],0,[||]))
+let verbatim_sd = SDfun ([Str "<"; Str "|"; Tp (Var ("b",[||],0,[||]));
+ Str "|"; Str ">"], Var ("b",[||],0,[||]))
let verbatim_name = name_of_sd verbatim_sd
let if_then_else_sd = SDfun ([Str "if"; Tp boolean_tp; Str "then";
- Tp (TVar ("a",[||],0,[||])); Str "else";
- Tp (TVar ("a",[||],0,[||]))], TVar ("a",[||],0,[||]))
+ Tp (Var ("a",[||],0,[||])); Str "else";
+ Tp (Var ("a",[||],0,[||]))], Var ("a",[||],0,[||]))
let if_then_else_name = name_of_sd if_then_else_sd
-let eq_bool_sd = SDfun ([Tp (TVar ("a",[||],0,[||])); Str "=";
- Tp (TVar ("a",[||],0,[||]))], boolean_tp)
+let eq_bool_sd = SDfun ([Tp (Var ("a",[||],0,[||])); Str "=";
+ Tp (Var ("a",[||],0,[||]))], boolean_tp)
let eq_bool_name = name_of_sd eq_bool_sd
(* --- Syntax Definitions for special meta-functions --- *)
-let code_as_term_sd = SDfun ([Str "code"; Tp (TVar ("a",[||],0,[||]));
+let code_as_term_sd = SDfun ([Str "code"; Tp (Var ("a",[||],0,[||]));
Str "as"; Str "term"], term_tp)
let code_as_term_name = name_of_sd code_as_term_sd
@@ -278,13 +278,13 @@
let set_command_tp = type_of_sd set_command_sd
let set_prop_sd = SDfun ([Str "set"; Tp (string_tp); Str "of";
- Tp (TVar ("a",[||],0,[||])); Str "to";
- Tp (TVar ("b",[||],0,[||]))], set_command_tp)
+ Tp (Var ("a",[||],0,[||])); Str "to";
+ Tp (Var ("b",[||],0,[||]))], set_command_tp)
let set_prop_name = name_of_sd set_prop_sd
let preprocess_sd = SDfun ([Str "#"; Str "#"; Str "#";
- Tp (TVar ("p",[||],0,[||]))], TVar ("q",[||],0,[||]))
+ Tp (Var ("p",[||],0,[||]))], Var ("q",[||],0,[||]))
let preprocess_name = name_of_sd preprocess_sd
Modified: trunk/Toss/Term/BuiltinLang.mli
===================================================================
--- trunk/Toss/Term/BuiltinLang.mli 2012-06-15 21:24:23 UTC (rev 1725)
+++ trunk/Toss/Term/BuiltinLang.mli 2012-06-16 17:01:17 UTC (rev 1726)
@@ -7,7 +7,7 @@
val bit_sd : syntax_def
val bit_name : string
-val bit_tp : TermType.term_type
+val bit_tp : Term.term
val bit_0_cons_sd : syntax_def
val bit_0_cons_name : string
val bit_1_cons_sd : syntax_def
@@ -15,18 +15,18 @@
val char_sd : syntax_def
val char_name : string
-val char_tp : TermType.term_type
+val char_tp : Term.term
val char_cons_sd : syntax_def
val char_cons_name : string
val term_type_sd : syntax_def
val term_type_name : string
-val term_type_tp : TermType.term_type
+val term_type_tp : Term.term
val list_sd : syntax_def
val list_name : string
-val list_tp : TermType.term_type -> TermType.term_type
-val list_tp_a : TermType.term_type
+val list_tp : Term.term -> Term.term
+val list_tp_a : Term.term
val list_nil_sd : syntax_def
val list_nil_name : string
val list_cons_sd : syntax_def
@@ -34,13 +34,13 @@
val string_sd : syntax_def
val string_name : string
-val string_tp : TermType.term_type
+val string_tp : Term.term
val string_cons_sd : syntax_def
val string_cons_name : string
val boolean_sd : syntax_def
val boolean_name : string
-val boolean_tp : TermType.term_type
+val boolean_tp : Term.term
val boolean_true_sd : syntax_def
val boolean_true_name : string
val boolean_false_sd : syntax_def
@@ -48,7 +48,7 @@
val ternary_truth_value_sd : syntax_def
val ternary_truth_value_name : string
-val ternary_truth_value_tp : TermType.term_type
+val ternary_truth_value_tp : Term.term
val ternary_true_sd : syntax_def
val ternary_true_name : string
val ternary_unknown_sd : syntax_def
@@ -65,21 +65,21 @@
val syntax_element_sd : syntax_def
val syntax_element_name : string
-val syntax_element_tp : TermType.term_type
+val syntax_element_tp : Term.term
val syntax_element_str_sd : syntax_def
val syntax_element_str_name : string
val syntax_element_tp_sd : syntax_def
val syntax_element_tp_name : string
val syntax_element_list_sd : syntax_def
val syntax_element_list_name : string
-val syntax_element_list_tp : TermType.term_type
+val syntax_element_list_tp : Term.term
val syntax_element_list_elem_sd : syntax_def
val syntax_element_list_elem_name : string
val syntax_element_list_cons_sd : syntax_def
val syntax_element_list_cons_name : string
val syntax_definition_sd : syntax_def
val syntax_definition_name : string
-val syntax_definition_tp : TermType.term_type
+val syntax_definition_tp : Term.term
val syntax_definition_type_sd : syntax_def
val syntax_definition_type_name : string
val syntax_definition_fun_sd : syntax_def
@@ -92,34 +92,34 @@
val term_sd : syntax_def
val term_name : string
-val term_tp : TermType.term_type
+val term_tp : Term.term
val term_var_cons_sd : syntax_def
val term_var_cons_name : string
val term_term_cons_sd : syntax_def
val term_term_cons_name : string
val rewrite_rule_sd : syntax_def
val rewrite_rule_name : string
-val rewrite_rule_tp : TermType.term_type
+val rewrite_rule_tp : Term.term
val rewrite_rule_cons_sd : syntax_def
val rewrite_rule_cons_name : string
val input_rewrite_rule_sd : syntax_def
val input_rewrite_rule_name : string
-val input_rewrite_rule_tp : TermType.term_type
+val input_rewrite_rule_tp : Term.term
val let_be_sd : syntax_def
val let_be_name : string
val priority_input_rewrite_rule_sd : syntax_def
val priority_input_rewrite_rule_name : string
-val priority_input_rewrite_rule_tp : TermType.term_type
+val priority_input_rewrite_rule_tp : Term.term
val let_major_be_sd : syntax_def
val let_major_be_name : string
val fun_definition_sd : syntax_def
val fun_definition_name : string
-val fun_definition_tp : TermType.term_type
+val fun_definition_tp : Term.term
val fun_definition_cons_sd : syntax_def
val fun_definition_cons_name : string
val type_definition_sd : syntax_def
val type_definition_name : string
-val type_definition_tp : TermType.term_type
+val type_definition_tp : Term.term
val type_of_sd_sd : syntax_def
val type_of_name : string
@@ -165,7 +165,7 @@
val outside_paths_sd : syntax_def
val outside_paths_name : string
-val outside_paths_tp : TermType.term_type
+val outside_paths_tp : Term.term
val path_library_sd : syntax_def
val path_library_name : string
@@ -175,26 +175,20 @@
val load_command_sd : syntax_def
val load_command_name : string
-val load_command_tp : TermType.term_type
+val load_command_tp : Term.term
val load_file_sd : syntax_def
val load_file_name : string
val sys_commands_sd : syntax_def
val sys_commands_name : string
-val sys_commands_tp : TermType.term_type
+val sys_commands_tp : Term.term
val close_context_sd : syntax_def
val close_context_name : string
-(*val remove_command_sd : syntax_def
-val remove_command_name : string
-val remove_command_tp : TermType.term_type
-val system_remove_sd : syntax_def
-val system_remove_name : string*)
-
val set_command_sd : syntax_def
val set_command_name : string
-val set_command_tp : TermType.term_type
+val set_command_tp : Term.term
val set_prop_sd : syntax_def
val set_prop_name : string
Modified: trunk/Toss/Term/BuiltinLangTest.ml
===================================================================
--- trunk/Toss/Term/BuiltinLangTest.ml 2012-06-15 21:24:23 UTC (rev 1725)
+++ trunk/Toss/Term/BuiltinLangTest.ml 2012-06-16 17:01:17 UTC (rev 1726)
@@ -1,12 +1,12 @@
open OUnit
-open TermType
+open Term
open BuiltinLang
let tests = "BuiltinLang" >::: [
"type names" >::
(fun () ->
let test_type_name res tp =
- assert_equal ~printer:(fun x -> x) res (TermType.type_to_string tp) in
+ assert_equal ~printer:(fun x -> x) res (Term.type_to_string tp) in
test_type_name "T\\?_list (@? a)" list_tp_a;
test_type_name "Tbit" bit_tp;
test_type_name "Tchar" char_tp;
Copied: trunk/Toss/Term/Coding.ml (from rev 1725, trunk/Toss/Term/Term.ml)
===================================================================
--- trunk/Toss/Term/Coding.ml (rev 0)
+++ trunk/Toss/Term/Coding.ml 2012-06-16 17:01:17 UTC (rev 1726)
@@ -0,0 +1,502 @@
+(* Contains the type of typed terms, functions calculating type and
+ reconstruction for a term and printing and parsing for terms. *)
+
+open Array
+open Aux
+
+open Term
+open SyntaxDef
+open BuiltinLang
+
+
+(* --- Coding basic things as Terms --- *)
+
+exception DECODE of string
+exception CODE of string
+
+let rec code_list f = function
+ | [] -> Term (list_nil_name, [||], [||])
+ | x :: xs -> Term (list_cons_name, [||], [|f (x); code_list f xs|])
+
+
+let rec decode_list f = function
+ | Term (n, _, [||]) when n = list_nil_name -> []
+ | Term (n, _, [|x; xs|]) when n = list_cons_name -> (f x):: (decode_list f xs)
+ | _ -> raise (DECODE "list")
+
+
+let decode_list_opt f l = try Some (decode_list f l) with DECODE _ -> None
+
+let rec int_to_bits = function
+ | 0 -> [0]
+ | 1 -> [1]
+ | i -> if i mod 2 = 0 then 0 :: int_to_bits (i/2) else 1 :: int_to_bits (i/2)
+
+
+let bits_to_int i =
+ let rec bits_to_int_rec start = function
+ | [] -> 0
+ | x :: xs -> x * start + bits_to_int_rec (2*start) xs in
+ bits_to_int_rec 1 i
+
+
+let code_bit = function
+ | 0 -> Term (bit_0_cons_name, [||], [||])
+ | 1 -> Term (bit_1_cons_name, [||], [||])
+ | _ -> failwith "not bit while coding bit"
+
+
+let decode_bit = function
+ | Term (n, _, [||]) when n = bit_0_cons_name -> 0
+ | Term (n, _, [||]) when n = bit_1_cons_name -> 1
+ | _ -> raise (DECODE "bit")
+
+let decode_bit_list bl = bits_to_int (decode_list decode_bit bl)
+
+let code_char c =
+ let bits = int_to_bits (Char.code c) in
+ let rec zeros i = if i <= 0 then [] else 0 :: zeros (i-1) in
+ let eight_bits = bits @ zeros (8 - List.length bits) in
+ Term (char_cons_name, [||], of_list (List.map code_bit eight_bits))
+
+let decode_char = function
+ | Term (n, _, bits) when n = char_cons_name ->
+ Char.chr (bits_to_int (to_list (map decode_bit bits)))
+ | _ -> raise (DECODE "char")
+
+let code_string s =
+ let rec char_list i = if i < 0 then [] else s.[i] :: char_list (i-1) in
+ let chars = List.rev (char_list ((String.length s) - 1)) in
+ let char_term = code_list code_char chars in
+ Term (string_cons_name, [||], [|char_term|])
+
+
+let decode_string t =
+ let rec string_of_list_i s i = function
+ | [] -> s
+ | x :: xs -> (s.[i] <- x; string_of_list_i s (i+1) xs) in
+ let string_of_list l = string_of_list_i (String.create (List.length l)) 0 l in
+ match t with
+ | Term (n, _, [|c|]) when n = string_cons_name ->
+ string_of_list (decode_list decode_char c)
+ | _ -> raise (DECODE "string")
+
+
+let decode_string_opt t = try Some (decode_string t) with DECODE _ -> None
+
+
+let code_bool = function
+ | true -> Term (boolean_true_name, [||], [||])
+ | false -> Term (boolean_false_name, [||], [||])
+
+
+let decode_bool = function
+ | Term (n, _, [||]) when n = boolean_true_name -> true
+ | Term (n, _, [||]) when n = boolean_false_name -> false
+ | _ -> raise (DECODE "bool")
+
+
+let rec code_term_type = function
+ | Var (name, [||], 0, [||])->
+ Term (term_type_var_name, [||], [|code_string name|])
+ | Var _ -> failwith "code_term_type: non-type variable"
+ | Term (name, [||], arr) when name = Term.fun_type_name ->
+ let l = Array.length arr in
+ let (args_types, return_type) = (Array.sub arr 0 (l-1), arr.(l-1)) in
+ Term (term_type_fun_name, [||], [|
+ code_list code_term_type (to_list args_types);
+ code_term_type return_type|])
+ | Term (name, [||], args) ->
+ Term (term_type_cons_name, [||], [|
+ code_string name;
+ code_list code_term_type (to_list args)|])
+ | Term _ -> failwith "code_term_type: non-type term"
+
+
+let rec decode_term_type = function
+ | Term (s, _, [|coded_name|]) when s = term_type_var_name ->
+ Var (decode_string coded_name, [||], 0, [||])
+ | Term (s, _, [|coded_1; coded_2|]) when s = term_type_fun_name ->
+ Term (Term.fun_type_name, [||], of_list (
+ (decode_list decode_term_type coded_1) @ [decode_term_type coded_2]))
+ | Term (s, _, [|coded_1; coded_2|]) when s = term_type_cons_name ->
+ Term (decode_string coded_1, [||],
+ of_list (decode_list decode_term_type coded_2))
+ | _ -> raise (DECODE "term_type")
+
+
+let decode_term_type_opt t =
+ try Some (decode_term_type t) with DECODE _ -> None
+
+
+let rec code_term = function
+ | Var (name, var_types, deg, args) ->
+ Term (term_var_cons_name, [||],
+ [|code_string name;
+ code_term_type var_types.(0);
+ code_list code_bit (int_to_bits deg);
+ code_list code_term (to_list args)|])
+ | Term (name, _, args) ->
+ Term (term_term_cons_name, [||], [|code_string name;
+ code_list code_term (to_list args)|])
+
+
+let rec code_term_incr_vars = function
+ | Var (name, var_type, deg, args) ->
+ Var (name, var_type, deg+1, map code_term_incr_vars args)
+ | Term (name, _, args) ->
+ Term (term_term_cons_name, [||], [|
+ code_string name; code_list code_term_incr_vars (to_list args)|])
+
+
+let rec decode_term = function
+ | Term (s, _, [|coded_name; coded_type; coded_deg; coded_args|])
+ when s = term_var_cons_name ->
+ Var (decode_string coded_name,
+ [|decode_term_type coded_type|],
+ bits_to_int (decode_list decode_bit coded_deg),
+ of_list (decode_list decode_term coded_args))
+ | Term (s, _, [|coded_name; coded_args|])
+ when s = term_term_cons_name ->
+ Term (decode_string coded_name, [||],
+ of_list (decode_list decode_term coded_args))
+ | _ -> raise (DECODE "term")
+
+
+let decode_term_opt t = try Some (decode_term t) with DECODE _ -> None
+
+
+type rewrite_rule = term * term
+
+
+let code_rewrite_rule (left, right) =
+ Term (rewrite_rule_cons_name, [||], [|code_term left; code_term right|])
+
+
+let decode_rewrite_rule = function
+ | Term (n, _, [|left; right|]) when n = rewrite_rule_cons_name ->
+ (decode_term left, decode_term right)
+ | _ -> raise (DECODE "rewrite rule")
+
+
+let code_input_rewrite_rule (left, right) =
+ Term (let_be_name, [||], [|left; right|])
+
+
+let decode_input_rewrite_rule = function
+ | Term (n, _, [|left; right|]) when n = let_be_name -> (left, right)
+ | _ -> raise (DECODE "input rewrite rule")
+
+
+let code_priority_input_rewrite_rule (left, right) =
+ Term (let_major_be_name, [||], [|left; right|])
+
+
+let decode_priority_input_rewrite_rule = function
+ | Term (n, [||], [|left; right|]) when n = let_major_be_name -> (left, right)
+ | _ -> raise (DECODE "priority input rewrite rule")
+
+
+type fun_definition = string * Term.term list * Term.term
+
+let code_fun_definition (name, args_types, return_type) =
+ Term (fun_definition_cons_name, [||], [|
+ code_string name;
+ code_list code_term_type args_types;
+ code_term_type return_type|])
+
+
+let decode_fun_definition = function
+ | Term (n, _, [|name; args; ret|]) when n = fun_definition_cons_name ->
+ (decode_string name, decode_list decode_term_type args,
+ decode_term_type ret)
+ | _ -> raise (DECODE "function definition")
+
+
+type type_definition = string * int
+
+let code_type_definition (name, arity) =
+ let rec var = function
+ | 0 -> []
+ | i -> Var ("a_" ^ (string_of_int i), [||], 0, [||]) :: (var (i-1)) in
+ Term (type_of_name, [||],
+ [|code_term_type (Term (name, [||], of_list (var arity)))|])
+
+
+let decode_type_definition = function
+ | Term (n, _, [|ty|]) when n = type_of_name ->
+ (match (decode_term_type ty) with
+ | Term (name, [||], args) -> (name, Array.length args)
+ | _ -> raise (DECODE "type definition 1")
+ )
+ | _ -> raise (DECODE "type definition 2")
+
+
+let code_syntax_element = function
+ | Str s -> Term (syntax_element_str_name, [||], [|code_string s|])
+ | Tp tt -> Term (syntax_element_tp_name, [||], [|code_term_type tt|])
+
+
+let decode_syntax_element = function
+ | Term (s, _, [|strt|]) when s = syntax_element_str_name ->
+ Str (decode_string strt)
+ | Term (s, _, [|tt|]) when s = syntax_element_tp_name ->
+ Tp (decode_term_type tt)
+ | _ -> raise (DECODE "syntax element")
+
+
+let rec code_syntax_element_list = function
+ | [se] -> Term (syntax_element_list_elem_name, [||],
+ [|code_syntax_element se|])
+ | se :: ses -> Term (syntax_element_list_cons_name, [||],
+ [|code_syntax_element se; code_syntax_element_list ses|])
+ | [] -> raise (CODE "syntax element list")
+
+
+let rec decode_syntax_element_list = function
+ | Term (name, _, [|coded_se|]) when name = syntax_element_list_elem_name ->
+ [decode_syntax_element coded_se]
+ | Term (name, _, [|coded_se; coded_ses|])
+ when name = syntax_element_list_cons_name ->
+ (decode_syntax_element coded_se) :: (decode_syntax_element_list coded_ses)
+ | _ -> raise (DECODE "syntax element list")
+
+
+let code_syntax_definition = function
+ | SDtype se ->
+ Term (syntax_definition_type_name, [||], [|code_syntax_element_list se|])
+ | SDfun (se, res_ty) ->
+ Term (syntax_definition_fun_name, [||],
+ [|code_syntax_element_list se; code_term_type res_ty|])
+ | SDvar (se, res_ty) ->
+ Term (syntax_definition_var_name, [||],
+ [|code_syntax_element_list se; code_term_type res_ty|])
+
+
+let decode_syntax_definition = function
+ | Term (str, _, [|t1|]) when str = syntax_definition_type_name ->
+ SDtype (decode_syntax_element_list t1)
+ | Term (str, _, [|t1; t2|]) ->
+ let se = decode_syntax_element_list t1 in
+ let res_ty = decode_term_type t2 in
+ if str = syntax_definition_fun_name then SDfun (se, res_ty) else
+ if str = syntax_definition_var_name then SDvar (se, res_ty) else
+ raise (DECODE "syntax definition 1")
+ | _ -> raise (DECODE "syntax definition 2")
+
+
+
+(* --- Term matching and substitutions --- *)
+
+let rec matches dict = function
+ | (Term (n1, _, a1), Term (n2, _, a2)) when n1=n2 && (length a1 = length a2)->
+ Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
+ | (Var (n1, _, d1, a1), Var (n2, _, d2, a2))
+ when n1 = n2 && d1 = d2 && length a1 = length a2 ->
+ Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
+ | (Var (n1, _, d1, [||]), te) ->
+ (try
+ let arg = List.assoc n1 (!dict) in
+ let coded_arg = fn_apply d1 code_term arg in
+ te = coded_arg
+ with Not_found ->
+ let decoded_te = fn_apply d1 decode_term te in
+ (dict := (n1, decoded_te) :: (!dict); true)
+ )
+ | _ -> false
+
+
+(* Application of term substitutions (only flat functional substitutes). *)
+let rec apply_s substs = function
+ | Var (n, _, d, [||]) as t ->
+ (try (fn_apply d code_term (List.assoc n substs)) with Not_found -> t)
+ | Term (n, tp, a) -> Term (n, tp, map (apply_s substs) a)
+ | Var (n, t, deg, a) ->
+ try (
+ let raw_result =
+ match (List.assoc n substs) with
+ | Term (name, [||], [||]) ->
+ Term (name, [||], map (apply_s substs) a)
+ | Var (name, ty, d, [||]) ->
+ Var (name, ty, d, map (apply_s substs) a)
+ | _ -> failwith "functional substitution of non-flat term" in
+ fn_apply deg code_term raw_result
+ )
+ with Not_found -> Var (n, t, deg, map (apply_s substs) a)
+
+
+(* --- Nice Term display based on Syntax Definitions --- *)
+
+let is_some = function Some _ -> true | None -> false
+
+let rec display_term = function
+ | te when is_some (decode_string_opt te) ->
+ "\"" ^ (decode_string te) ^ "\""
+ | te when is_some (decode_list_opt (fun x -> x) te) ->
+ let str_list = List.map display_term (decode_list (fun x -> x) te) in
+ "["^ (String.concat ", " str_list) ^ "]"
+ | Term (n, _, a) ->
+ let args = List.map display_term (Array.to_list a) in
+ display_sd (split_sdef_name n) args
+ | Var (n, _, _, a) ->
+ let args = List.map display_term (Array.to_list a) in
+ display_sd (split_sdef_name n) args
+
+
+(* --- Display terms and types as XML --- *)
+
+let rec display_type_xml = function
+ | Var (n, [||], 0, [||]) ->
+ "<type_var>" ^ (make_xml_compatible n) ^ "</type_var>"
+ | Var _ -> failwith "display_type_xml: non-type variable"
+ | Term (n, _, a) ->
+ "<type class=\"" ^ (make_xml_compatible n) ^ "\">\n" ^
+ (String.concat "\n" (List.map display_type_xml (to_list a))) ^
+ "\n</type>"
+
+let rec display_term_xml = function
+ | te when is_some (decode_string_opt te) ->
+ "<term-string>" ^ (make_xml_compatible (decode_string te)) ^
+ "</term-string>"
+ | te when is_some (decode_list_opt (fun x -> x) te) ->
+ let str_list = List.map display_term_xml (decode_list (fun x -> x) te) in
+ "<term-list>"^ (String.concat " " str_list) ^ "</term-list>"
+ | Term (n, _, a) ->
+ "<term class=\"" ^ (make_xml_compatible n) ^ "\">\n" ^
+ (String.concat "\n" (List.map display_term_xml (to_list a))) ^
+ "\n</term>"
+ | Var (n, ty, deg, a) ->
+ "<term-variable class=\"" ^ (make_xml_compatible n) ^
+ "\" deg=\"" ^ (string_of_int deg) ^ "\">" ^
+ (String.concat "" (List.map display_term_xml (to_list a))) ^
+ "<term-variable-type>"^(display_type_xml ty.(0))^"</term-variable-type>" ^
+ "</term-variable>"
+
+
+
+(* --- Term parsing and printing --- *)
+
+(* Printing terms. *)
+let rec term_to_string term =
+ let term_array_to_string ta =
+ String.concat ", " (to_list (map term_to_string ta)) in
+ match term with
+ | _ when is_some (decode_string_opt term) ->
+ let s = (match (decode_string_opt term) with Some s -> s | None -> "") in
+ "@`" ^ (Aux.normalize_spaces s) ^ "@`"
+ | _ when is_some (decode_list_opt (fun x -> x) term) ->
+ (match (decode_list_opt (fun x -> x) term) with None -> ""
+ | Some l -> "@L["^ (String.concat ", " (List.map term_to_string l))^"]")
+ | _ when is_some (decode_term_type_opt term) ->
+ (match (decode_term_type_opt term) with None -> ""
+ | Some ty -> "@Y " ^ (type_to_string ty))
+ | _ when is_some (decode_term_opt term) ->
+ (match (decode_term_opt term) with None -> ""
+ | Some te -> "@T " ^ (term_to_string te))
+ | Var (v, t, d, [||]) ->
+ "@V [" ^ v ^ " @: " ^ (type_to_string t.(0)) ^
+ " @: "^ string_of_int (d) ^ " ]"
+ | Var (v, t, d, a) ->
+ "@V [" ^ v ^ " @: " ^ (type_to_string t.(0)) ^
+ " @: "^ string_of_int (d) ^ " ] (" ^
+ (term_array_to_string a) ^ " )"
+ | Term (n, [||], [||]) -> n
+ | Term (n, [||], a) ->
+ n ^ " (" ^ (term_array_to_string a) ^ " )"
+ | Term _ -> failwith "term_to_string: stored types not supported yet"
+
+
+(* Parser for terms. *)
+let rec parse_term = function
+ | (Delim "@`") :: rest ->
+ (match parse_text_list rest with
+ | (s, (Delim "@`") :: cont) ->
+ (if s = "" then code_string "" else
+ code_string (String.sub s 0 ((String.length s) - 1))), cont
+ | _ -> failwith "parse_term: string not closed"
+ )
+ | (Delim "@L") :: (Delim "[") :: rest ->
+ (match parse_term_list rest with
+ | (l, (Delim "]") :: cont) -> (code_list (fun x -> x) l, cont)
+ | _ -> failwith "parse_term: list not closed"
+ )
+ | (Delim "@Y") :: rest ->
+ let (ty, cont) = parse_type rest in
+ (code_term_type ty, cont)
+ | (Delim "@T") :: rest ->
+ let (te, cont) = parse_term rest in
+ (code_term te, cont)
+ | (Delim "@V") :: (Delim "[") :: (Text v) :: (Delim "@:") :: rest ->
+ (match parse_type rest with
+ | (ty, (Delim "@:") :: (Text deg) :: (Delim "]") :: cont) -...
[truncated message content] |
|
From: <luk...@us...> - 2012-06-20 21:51:26
|
Revision: 1730
http://toss.svn.sourceforge.net/toss/?rev=1730&view=rev
Author: lukaszkaiser
Date: 2012-06-20 21:51:20 +0000 (Wed, 20 Jun 2012)
Log Message:
-----------
Hierarchical structures possible, used to define shapes for elements.
Modified Paths:
--------------
trunk/Toss/Client/Drawing.ml
trunk/Toss/Client/JsEval.ml
trunk/Toss/Client/eval.html
trunk/Toss/Makefile
trunk/Toss/Server/Tests.ml
trunk/Toss/Solver/Structure.ml
trunk/Toss/Solver/Structure.mli
Added Paths:
-----------
trunk/Toss/Client/Drawing.mli
trunk/Toss/Client/DrawingTest.ml
Modified: trunk/Toss/Client/Drawing.ml
===================================================================
--- trunk/Toss/Client/Drawing.ml 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Client/Drawing.ml 2012-06-20 21:51:20 UTC (rev 1730)
@@ -35,48 +35,111 @@
(* Various shapes. *)
-type shapes =
- | Circle of point * float (* circle, given middle and radius *)
- | Rectangle of point * point (* rectangle, given middle and width-height *)
+type shape =
+ | Circle of point * point (* circle, given middle and radiuses *)
| Line of point * point (* line, given from and to *)
-(* Create an arrow from x to y assuming circle of radius [rad] *)
-let arrow rad x y =
+let shape_str = function
+ | Circle (p, r) -> Printf.sprintf "circle (%F, %F) r (%F, %F)" p.x p.y r.x r.y
+ | Line (f, t) -> Printf.sprintf "line (%F, %F) -- (%F, %F)" f.x f.y t.x t.y
+
+let shapes_str l = String.concat "; " (List.map shape_str l)
+
+(* Shift a shape by [x]. *)
+let shift_shape x = function
+ | Circle (p, r) -> Circle (p +: x, r)
+ | Line (f, t) -> Line (f +: x, t +: x)
+
+let shift_shapes x l = List.map (shift_shape x) l
+
+(* Change coordinates in a shape. *)
+let change_coords_shape c1 c2 = function
+ | Circle (p, r) ->
+ let z = {x=0.; y=0.} in
+ Circle (change_coords c1 c2 p, change_coords (z, snd c1) (z, snd c2) r)
+ | Line (f, t) -> Line (change_coords c1 c2 f, change_coords c1 c2 t)
+
+let change_coords_shapes c1 c2 l = List.map (change_coords_shape c1 c2) l
+
+(* Helper function - solve a quadratic equation ax^2 + bx + c = 0. *)
+let quadratic a b c =
+ let d = b *. b -. 4. *. a *. c in
+ if d < 0. then [] else if d = 0. then [-1. *. b /. (2. *. a)] else
+ [(-1.*.b +. (sqrt d)) /. (2. *. a); (-1.*.b -. (sqrt d)) /. (2. *. a)]
+
+(* Calculate where the line [p] -- [q] crosses the shape. *)
+let crossing p q = function
+ | Circle (m, r) ->
+ let norm_coord pt = change_coords (m, r) ({x=0.;y=0.}, {x=1.;y=1.}) pt in
+ let back_coord pt = change_coords ({x=0.;y=0.}, {x=1.;y=1.}) (m, r) pt in
+ let p, q = norm_coord p, norm_coord q in
+ let d = q -: p in (* Now we just cross p--q with the unit circle. *)
+ let c =
+ if d.x = 0. && d.y = 0. then
+ if p.x *. p.x +. p.y *. p.y = 0. then [p] else []
+ else if d.x = 0. then (* x = p.x = q.x crosses unit circle *)
+ if p.x < -1. || p.x > 1. then [] else
+ if p.x = 1. || p.x = -1. then [{ x = p.x ; y = 0. }] else
+ let y = sqrt (1. -. p.x *. p.x) in
+ [{ x = p.x ; y = y }; { x = p.x ; y = -1. *. y }]
+ else ( (* y - p.y = d.y / d.x ( x - p.x ) and unit square *)
+ let d = d.y /. d.x in (* ( d (x - p.x) + p.y )^2 + x^2 = 1 *)
+ let c = p.y -. d *. p.x in (* (d x + c)^2 + x^2 - 1 = 0 *)
+ LOG 1 "p = (%F, %F), q = (%F, %F), d = %F, c = %F" p.x p.y q.x q.y d c;
+ let xs = quadratic (1. +. d*.d) (2.*.d*.c) (c*.c -. 1.) in
+ List.map (fun x -> { x = x ; y = d *. (x -. p.x) +. p.y }) xs ) in
+ List.map back_coord c
+ | Line (f, t) -> failwith "crossing not yet implemented for lines"
+
+let crossings p q l = Aux.concat_map (crossing p q) l
+
+(* Maximal distance of shape points from (0, 0). *)
+let radius_single = function
+ | Circle (p, r) -> dist p {x=0.;y=0.} +. (max r.x r.y) (* FIXME *)
+ | Line (f, t) -> max (dist f {x=0.;y=0.}) (dist t {x=0.;y=0.})
+
+let radius l = List.fold_left max 0. (List.rev_map radius_single l)
+
+(* Create an arrow from x to y given the shapes of x and y. *)
+let arrow (x, shapes_x) (y, shapes_y) =
let len = dist x y in
- if len < 0.1 then [] else
- let d = (y -: x) *! (rad /. len) in
- let q, p = x +: d, y -: d in
- let arr = p -: (d *! 0.5) in
- [ Line (q, p); Line (p, rotate p 30. arr); Line (p, rotate p (-30.) arr) ]
+ if len < 0.1 then [] else (
+ let pl, ql = crossings x y shapes_x, crossings x y shapes_y in
+ let mdist x p q =
+ let f = (dist p x) -. (dist q x) in
+ if f = 0. then 0 else if f > 0. then 1 else -1 in
+ let pl, ql = List.sort (mdist y) pl, List.sort (mdist x) ql in
+ let p = if pl = [] then x else List.hd pl in
+ let q = if ql = [] then y else List.hd ql in
+ let tip = q -: ((y -: q) *! 0.5) in
+ [ Line (p, q); Line (q, rotate q 30. tip); Line (q, rotate q (-30.) tip) ]
+ )
-
(* Structure with coordinates for drawing on canvas. *)
type structure_with_coords = {
struc : Structure.structure ;
coordC: point * point ;
coordS: point * point ;
- radius: float ;
}
let empty_struc_coords () = {
struc = Structure.empty_structure ();
coordC = {x=0.;y=0.}, {x=0.;y=0.};
coordS = {x=0.;y=0.}, {x=0.;y=0.};
- radius = 0.
}
(* Get the position of an element. *)
-let get_pos struc e = (* Canvas positions count "from up" on y, thus -1. *)
+let get_pos_pair struc e = (* Canvas positions count "from up" on y, thus -1. *)
(Structure.fun_val struc "x" e, -1. *. Structure.fun_val struc "y" e)
+let get_pos struc e = let (x, y) = get_pos_pair struc e in {x=x; y=y}
+
(* Create a structure with canvas coordinates given canvas sizes, structure.
The first four parameters are the width, height and margins of canvas,
- the third and fourth are (optional) min and max of structure coordinates. *)
+ the fifth and sixth are (optional) min and max of structure coordinates. *)
let add_coords cwidth cheight cmarginx cmarginy minp maxp struc =
let elems = Structure.elements struc in
- let rad = (* radius for elements *)
- min 45. (max 5. (450. /. float (List.length elems))) in
- let positions = List.map (get_pos struc) elems in
+ let positions = List.map (get_pos_pair struc) elems in
let minp = match minp with Some p -> p | None ->
let (posx, posy) = List.split positions in
{ x = List.fold_left min (List.hd posx) posx;
@@ -86,44 +149,70 @@
{ x = List.fold_left max (List.hd posx) posx;
y = List.fold_left max (List.hd posy) posy } in
let diffp = { x= max (maxp.x -. minp.x) 1.; y= max (maxp.y -. minp.y) 1. } in
+ let diffp = { x= max diffp.x diffp.y; y= max diffp.x diffp.y } in(*no strech*)
let coordC = ({ x= cwidth/.2. +. cmarginx; y= cheight/.2. +. cmarginy},
{ x= cwidth; y= cheight }) in
let coordS = ((maxp +: minp) /: {x = 2.; y = 2.}, diffp) in
- { struc = struc ; coordC = coordC ; coordS = coordS ; radius = rad }
+ { struc = struc ; coordC = coordC ; coordS = coordS }
+(* Read a shape encoded in a structure. *)
+let read_shapes struc =
+ LOG 1 "reading shapes %s" (Structure.str struc);
+ let circles = Structure.rel_graph "Circle" struc in
+ let radius e =
+ {x = Structure.fun_val struc "rx" e; y = Structure.fun_val struc "ry" e} in
+ let circ e = Circle (get_pos struc e, radius e) in
+ List.map (fun e -> circ e.(0)) (Structure.Tuples.elements circles)
+
+(* Draw an element of a structure with coordinates. *)
+let draw_elem st_c e =
+ let struc, coordS, coordC = st_c.struc, st_c.coordS, st_c.coordC in
+ let shapes = read_shapes (Structure.model_val struc "shape" e) in
+ change_coords_shapes coordS coordC (shift_shapes (get_pos struc e) shapes)
+
+(* Check whether the float pair (on canvas) is inside the element radius. *)
+let in_elem_radius st_c e (x, y) =
+ let struc, coordS, coordC = st_c.struc, st_c.coordS, st_c.coordC in
+ let shapes = read_shapes (Structure.model_val struc "shape" e) in
+ let p, r = get_pos struc e, radius (shapes)
+ in dist p (change_coords coordC coordS {x=x; y=y}) < r
+
(* Draw the structure with coordinates [st_c] as a sequence of shapes. *)
let draw_struc st_c =
let struc, coordS, coordC = st_c.struc, st_c.coordS, st_c.coordC in
- let positions = List.map (get_pos struc) (Structure.elements struc) in
- let circ (x,y)= Circle (change_coords coordS coordC {x=x; y=y},st_c.radius) in
- let elem_drawings = List.map circ positions in
+ let elems =
+ List.rev_map (fun e -> (e, draw_elem st_c e)) (Structure.elements struc) in
+ let elem_drawings = Aux.concat_map (fun (_, d) -> d) elems in
(* drawing relations *)
- let pos e =
- let (x,y) = get_pos struc e in
- change_coords coordS coordC {x=x; y=y} in
+ let pos e = change_coords coordS coordC (get_pos struc e) in
+ let pos_draw e = (pos e, List.assoc e elems) in
let draw_rel (rel, arity) =
if arity = 1 then
let elems = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- Aux.concat_map (fun a -> [Circle (pos a.(0), st_c.radius /. 2.)]) elems
+ Aux.concat_map (fun a -> [Circle (pos a.(0), {x=10.; y=10.})]) elems
else if arity = 2 then
let tuples = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- Aux.concat_map (fun a -> arrow st_c.radius (pos a.(0)) (pos a.(1))) tuples
+ Aux.concat_map (fun a-> arrow (pos_draw a.(0)) (pos_draw a.(1))) tuples
else [] in
elem_drawings @ (Aux.concat_map draw_rel (Structure.rel_signature struc))
(* Compile the shape to a JavaScript program drawing the shape on 'ctx'. *)
let shape_to_canvas = function
- | Circle (p, r) ->
- let s = Printf.sprintf "ctx.arc(%F,%F,%F,0,2*Math.PI,false); " p.x p.y r in
- "ctx.beginPath(); " ^ s ^ "ctx.fill(); ctx.stroke(); "
- | Rectangle (m, wh) ->
- Printf.sprintf "ctx.fillRect(%F,%F,%F,%F); " m.x m.y wh.x wh.y
+ | Circle (p, r) ->
+ if r.x = r.y then
+ let s = Printf.sprintf "ctx.arc(%F,%F,%F,0,2*Math.PI,false); " p.x p.y r.x
+ in "ctx.beginPath(); "^ s^"ctx.fill(); ctx.stroke(); ctx.closePath(); "
+ else
+ let sc = Printf.sprintf "ctx.scale(%F, %F); " (r.x /.100.) (r.y /.100.) in
+ let tr = Printf.sprintf "ctx.translate(%F, %F); " p.x p.y in
+ "ctx.save(); "^ tr ^sc ^"ctx.beginPath(); ctx.arc(0,0,100,0,2*Math.PI); "^
+ "ctx.stroke(); ctx.closePath(); ctx.restore(); "
| Line (f, t) ->
let fs = Printf.sprintf "ctx.moveTo(%F,%F); " f.x f.y in
let ts = Printf.sprintf "ctx.lineTo(%F,%F); " t.x t.y in
- "ctx.beginPath(); " ^ fs ^ ts ^ "ctx.stroke(); "
+ "ctx.beginPath(); " ^ fs ^ ts ^ "ctx.stroke(); ctx.closePath(); "
let shapes_to_canvas l =
String.concat " " (List.rev (List.rev_map shape_to_canvas l))
Added: trunk/Toss/Client/Drawing.mli
===================================================================
--- trunk/Toss/Client/Drawing.mli (rev 0)
+++ trunk/Toss/Client/Drawing.mli 2012-06-20 21:51:20 UTC (rev 1730)
@@ -0,0 +1,80 @@
+(** Drawing structures, with compilation to HTML5 canvas commands. *)
+
+(** Points. *)
+type point = { x : float; y : float }
+
+(** Component-wise operations on points. *)
+val ( +: ) : point -> point -> point
+val ( -: ) : point -> point -> point
+val ( *: ) : point -> point -> point
+val ( /: ) : point -> point -> point
+
+(** Scalar operations on points. *)
+val ( +! ) : point -> float -> point
+val ( -! ) : point -> float -> point
+val ( *! ) : point -> float -> point
+val ( /! ) : point -> float -> point
+
+(** Change coordinates from one system to another (given mid-point and size). *)
+val change_coords : point * point -> point * point -> point -> point
+
+(** Distance between two points. *)
+val dist : point -> point -> float
+
+(** Rotate the point [p] around [start] by [angle]. *)
+val rotate : point -> float -> point -> point
+
+
+(** Shapes. *)
+type shape =
+ | Circle of point * point (** circle, given middle and radiuses *)
+ | Line of point * point (** line, given from and to *)
+
+(** Print shapes. *)
+val shapes_str : shape list -> string
+
+(** Shift shapes by a vector. *)
+val shift_shapes : point -> shape list -> shape list
+
+(** Change coordinates in shapes. *)
+val change_coords_shapes : point * point -> point * point ->
+ shape list -> shape list
+
+(** Calculate where the line [p] -- [q] crosses shapes. *)
+val crossings : point -> point -> shape list -> point list
+
+(** Maximal distance of shape points from (0, 0). *)
+val radius : shape list -> float
+
+(** Structure with coordinates for drawing on canvas. *)
+type structure_with_coords = {
+ struc : Structure.structure ;
+ coordC: point * point ;
+ coordS: point * point ;
+}
+
+(** Empty structure with trivial coordinates. *)
+val empty_struc_coords : unit -> structure_with_coords
+
+(** Get the position of an element in a structure as a point. *)
+val get_pos : Structure.structure -> int -> point
+
+(** Read a shape encoded in a structure. *)
+val read_shapes : Structure.structure -> shape list
+
+
+(** Create a structure with canvas coordinates given canvas sizes, structure.
+ The first four parameters are the width, height and margins of canvas,
+ the fifth and sixth are (optional) min and max of structure coordinates. *)
+val add_coords: float -> float -> float -> float -> point option -> point option
+ -> Structure.structure -> structure_with_coords
+
+(** Draw the structure with coordinates [st_c] as a sequence of shapes. *)
+val draw_struc : structure_with_coords -> shape list
+
+(** Check whether the float pair (on canvas) is inside the element radius. *)
+val in_elem_radius : structure_with_coords -> int -> float * float -> bool
+
+(** Compile the shapes to a JavaScript program drawing the shape on 'ctx'.
+ With [result] in JS do: var ctx = canvas.getContext("2d"); eval (result). *)
+val shapes_to_canvas : shape list -> string
Added: trunk/Toss/Client/DrawingTest.ml
===================================================================
--- trunk/Toss/Client/DrawingTest.ml (rev 0)
+++ trunk/Toss/Client/DrawingTest.ml 2012-06-20 21:51:20 UTC (rev 1730)
@@ -0,0 +1,29 @@
+open OUnit
+open Drawing
+
+let eq_point p q =
+ assert_equal ~printer:(fun p -> Printf.sprintf "(%F, %F)" p.x p.y) p q
+
+let eq_point_list pl ql =
+ let str p = Printf.sprintf "(%F, %F)" p.x p.y in
+ assert_equal ~printer:(fun l -> String.concat ", " (List.map str l)) pl ql
+
+let tests = "Drawing" >::: [
+ "change coords" >::
+ (fun () ->
+ let z, o = {x=0.;y=0.}, {x=1.;y=1.} in
+ eq_point o (change_coords (z, o) (z, o) o);
+ eq_point (o *! 2.) (change_coords (z, o) (z, o *! 2.) o);
+ eq_point (o *! 2.) (change_coords (z, o) (o, o) o);
+ );
+
+ "crossings" >::
+ (fun () ->
+ let z, o, hsq2 = {x=0.;y=0.}, {x=1.;y=1.}, (sqrt 2.) *. 0.5 in
+ eq_point_list [o*!hsq2; o *! (-1.*.hsq2)] (crossings z o [Circle (z, o)]);
+ eq_point_list [{x=1.;y=0.}] (crossings z {x=1.;y=0.} [Circle (o, o)]);
+ eq_point_list [{x = 2. ; y = 0.}; {x = -2. ; y = 0.}]
+ (crossings z {x=1.; y=0.} [Circle (z, o *! 2.)]);
+ );
+]
+
Modified: trunk/Toss/Client/JsEval.ml
===================================================================
--- trunk/Toss/Client/JsEval.ml 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Client/JsEval.ml 2012-06-20 21:51:20 UTC (rev 1730)
@@ -1,5 +1,6 @@
(* Evaluating formulas on structures for JS. *)
+
(* --- Boilerplate code for calling OCaml in the worker thread. --- *)
let js_object = Js.Unsafe.variable "Object"
let js_handler = jsnew js_object ()
@@ -68,11 +69,7 @@
let mousedown_handle x y =
let (x, y), struc = (Js.to_float x, Js.to_float y), !cur_st.Drawing.struc in
- let cc e = let (x, y) = Drawing.get_pos struc e in
- let p = Drawing.change_coords !cur_st.Drawing.coordS
- !cur_st.Drawing.coordC {Drawing.x = x; Drawing.y = y} in
- (p.Drawing.x, p.Drawing.y) in
- let near e = dist (cc e) (x, y) < !cur_st.Drawing.radius in
+ let near e = Drawing.in_elem_radius !cur_st e (x, y) in
let near_elems = List.filter near (Structure.elements struc) in
if near_elems = [] then () else (
moving_elem := Some (List.hd near_elems);
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Client/eval.html 2012-06-20 21:51:20 UTC (rev 1730)
@@ -121,8 +121,8 @@
document.getElementById ("relations").value =
"E(x, y) = &y = &x + 1;\n" +
"S(x, y) = x != y and tc x, y E(x, y)";
- document.getElementById ("positions").value = ":x(a) = &a; \n:y(a) = &a*&a";
- document.getElementById ("no-elems").value = "3";
+ document.getElementById ("positions").value = ":x(a) = 10*&a;\n:y(a) = &a*&a";
+ document.getElementById ("no-elems").value = "4";
eval_it ();
}
@@ -164,7 +164,7 @@
<textarea id="positions" rows="3" cols="40">
:x(a) = &a;
-:y(a) = 10 * &a * (10 - &a)
+:y(a) = &a * (10 - &a) / 10
</textarea>
<p>Elements: <input id="no-elems" type="text" size="4" value="15"></input>
Modified: trunk/Toss/Makefile
===================================================================
--- trunk/Toss/Makefile 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Makefile 2012-06-20 21:51:20 UTC (rev 1730)
@@ -144,7 +144,7 @@
PlayINC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena
LearnINC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena
GGPINC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena,Play
-ServerINC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena,Play,GGP,Learn
+ServerINC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena,Play,GGP,Learn,Client
ClientINC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena,Play,GGP,Learn,Server
.INC=MenhirLib,Term,Formula,Formula/Sat,Formula/Sat/dpll,Solver/RealQuantElim,Solver/Num,Solver,Arena,Play,GGP,Learn,Server
@@ -246,6 +246,14 @@
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -extratest Learn
+# Client tests
+ClientTests: Server/Server.native
+ cp _build/Server/Server.native TossServer
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Client
+ClientTestsVerbose: Server/Server.native
+ cp _build/Server/Server.native TossServer
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Client -v
+
# Server tests
ServerTests: Server/Server.native
cp _build/Server/Server.native TossServer
Modified: trunk/Toss/Server/Tests.ml
===================================================================
--- trunk/Toss/Server/Tests.ml 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Server/Tests.ml 2012-06-20 21:51:20 UTC (rev 1730)
@@ -68,6 +68,10 @@
"LearnGameTest", [LearnGameTest.tests; LearnGameTest.bigtests];
]
+let client_tests = "Client", [
+ "DrawingTest", [DrawingTest.tests];
+]
+
let tests_l = [
formula_tests;
term_tests;
@@ -76,6 +80,7 @@
play_tests;
ggp_tests;
learn_tests;
+ client_tests;
]
Modified: trunk/Toss/Solver/Structure.ml
===================================================================
--- trunk/Toss/Solver/Structure.ml 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Solver/Structure.ml 2012-06-20 21:51:20 UTC (rev 1730)
@@ -52,6 +52,7 @@
elements : Elems.t ;
relations : Tuples.t StringMap.t ;
functions : (float IntMap.t) StringMap.t ;
+ models : (structure IntMap.t) StringMap.t ;
incidence : (TIntMap.t) StringMap.t ;
names : int StringMap.t ;
inv_names : string IntMap.t ;
@@ -103,6 +104,7 @@
elements = Elems.empty ;
relations = StringMap.empty ;
functions = StringMap.empty ;
+ models = StringMap.empty ;
incidence = StringMap.empty ;
names = StringMap.empty ;
inv_names = IntMap.empty ;
@@ -136,8 +138,13 @@
(* Return the value of function [f] on [e] in [struc]. *)
let fun_val struc f e =
let f_vals = StringMap.find f struc.functions in
- IntMap.find e f_vals
+ IntMap.find e f_vals
+(* Return the model assigned by [f] to [e] in [struc]. *)
+let model_val struc f e =
+ let f_vals = StringMap.find f struc.models in
+ IntMap.find e f_vals
+
(* Return the list of functions. *)
let f_signature struc =
StringMap.fold (fun f _ acc -> f :: acc) struc.functions []
@@ -356,6 +363,21 @@
let change_fun struc fn elem x = change_fun_int struc fn (elem_nbr struc elem) x
+
+(* Add model assignment [e] -> [s] to function [fn] in structure [struc].
+ Assumes [e] is already an element of [struc]. *)
+let add_model struc fn (e, s) =
+ let new_models =
+ try
+ let assgns = StringMap.find fn struc.models in
+ StringMap.add fn (IntMap.add e s assgns) struc.models
+ with Not_found ->
+ StringMap.add fn (IntMap.add e s IntMap.empty) struc.models in
+ { struc with models = new_models }
+
+let add_models st fn ms = List.fold_left (fun s a -> add_model s fn a) st ms
+
+
(* ------------ GLOBAL FUNCTIONS TO CREATE STRUCTURES FROM LISTS ------------ *)
(** Map a function over an array threading an accumulator. *)
@@ -401,10 +423,18 @@
| None -> empty_structure ()
| Some s -> s in
add_from_lists struc els rels funs
-
+
+let circle_structure rx ry =
+ create_from_lists ["e"] [("Circle", None, [[|"e"|]])]
+ [("rx", [("e", rx)]); ("ry", [("e", ry)]);
+ ("x", [("e", 0.)]); ("y", [("e", 0.)])]
+
let create_from_lists_position ?struc els rels =
let s = create_from_lists ?struc els rels [] in
let elems = List.sort (fun x y -> x - y) (Elems.elements s.elements) in
+ let circ = circle_structure (cBOARD_DX /. 3.) (cBOARD_DX /. 3.) in
+ let shapes = List.map (fun e -> (e, circ)) elems in
+ let s = add_models s "shape" shapes in
let zero = List.map (fun e -> (e, 0.)) elems in
let (_, next) = List.fold_left (fun (cur, acc) e ->
(cur +. cBOARD_DX, (e, cur) :: acc)) (0., []) elems in
@@ -414,6 +444,9 @@
let create_from_lists_range start ?struc els rels =
let s = create_from_lists ?struc els rels [] in
let elems = List.sort (fun x y -> x - y) (Elems.elements s.elements) in
+ let circ = circle_structure (1. /. 3.) (1. /. 3.) in
+ let shapes = List.map (fun e -> (e, circ)) elems in
+ let s = add_models s "shape" shapes in
let zero = List.map (fun e -> (e, 0.)) elems in
let (_, nextnbr) = List.fold_left (fun (cur, acc) e ->
(cur +. 1., (e, cur) :: acc)) (start, []) elems in
@@ -1336,6 +1369,7 @@
let col_index =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" in
+ let shape = circle_structure (cBOARD_DX /. 3.) (cBOARD_DX /. 3.) in
for r = 1 to r_max do
for c = 1 to c_max do
if List.hd !fields = [] then
@@ -1361,6 +1395,7 @@
if r > 1 && elem <> -1 && board_els.(c-1).(r-2) <> -1 then
struc := add_rel !struc col [|board_els.(c-1).(r-2); elem|];
if elem <> -1 then begin
+ struc := add_model !struc "shape" (elem, shape);
struc := add_fun !struc "x"
(elem, x0 +. dx *. float_of_int (c-1));
struc := add_fun !struc "y"
Modified: trunk/Toss/Solver/Structure.mli
===================================================================
--- trunk/Toss/Solver/Structure.mli 2012-06-19 21:22:16 UTC (rev 1729)
+++ trunk/Toss/Solver/Structure.mli 2012-06-20 21:51:20 UTC (rev 1730)
@@ -98,6 +98,9 @@
(** Return the value of function [f] on [e] in [struc]. *)
val fun_val : structure -> string -> int -> float
+(** Return the model assigned by [f] to [e] in [struc]. *)
+val model_val : structure -> string -> int -> structure
+
(** Return the list of functions. *)
val f_signature : structure -> string list
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <luk...@us...> - 2012-06-22 13:48:36
|
Revision: 1731
http://toss.svn.sourceforge.net/toss/?rev=1731&view=rev
Author: lukstafi
Date: 2012-06-22 13:48:24 +0000 (Fri, 22 Jun 2012)
Log Message:
-----------
New Speagram step 1: term representation and mgu according to specification, old types kept as toplevel terms for now.
Modified Paths:
--------------
trunk/Toss/Makefile
trunk/Toss/Play/HeuristicTest.ml
trunk/Toss/Term/BuiltinLang.ml
trunk/Toss/Term/Coding.ml
trunk/Toss/Term/Coding.mli
trunk/Toss/Term/CodingTest.ml
trunk/Toss/Term/Makefile
trunk/Toss/Term/ParseArc.ml
trunk/Toss/Term/ParseArcTest.ml
trunk/Toss/Term/Rewriting.ml
trunk/Toss/Term/RewritingTest.ml
trunk/Toss/Term/SyntaxDef.ml
trunk/Toss/Term/SyntaxDefTest.ml
trunk/Toss/Term/TRS.ml
trunk/Toss/Term/TRSTest.ml
trunk/Toss/Term/Term.ml
trunk/Toss/Term/Term.mli
trunk/Toss/Term/TermTest.ml
trunk/Toss/Term/lib/core.trs
Modified: trunk/Toss/Makefile
===================================================================
--- trunk/Toss/Makefile 2012-06-20 21:51:20 UTC (rev 1730)
+++ trunk/Toss/Makefile 2012-06-22 13:48:24 UTC (rev 1731)
@@ -110,7 +110,7 @@
EXTDEPS = caml_extensions/pa_let_try.cmo caml_extensions/pa_log.cmo Formula/Resources.ml
-MKPARSED = ./TRSTest.native -l "Term/lib"
+MKPARSED = ./TRSTest.native -v -l "Term/lib"
%.trs.parsed: %.trs
make ./Term/TRSTest.native
Modified: trunk/Toss/Play/HeuristicTest.ml
===================================================================
--- trunk/Toss/Play/HeuristicTest.ml 2012-06-20 21:51:20 UTC (rev 1730)
+++ trunk/Toss/Play/HeuristicTest.ml 2012-06-22 13:48:24 UTC (rev 1731)
@@ -362,6 +362,19 @@
(Formula.real_str loc_heurs.(0).(0));
);
+ "default_heuristic_old: problem with fluent_preconds" >::
+ (fun () ->
+ let (game,state) =
+ state_of_file "./examples/Parsing.toss" in
+ let loc_heurs =
+ Heuristic.default_heuristic_old ~struc:state.Arena.struc
+ ~advr:2.0 game in
+
+ assert_eq_str
+ "0."
+ (Formula.real_str loc_heurs.(0).(0));
+ );
+
"suggest_expansion: tic-tac-toe" >::
(fun () ->
let state = struc_of_string
Modified: trunk/Toss/Term/BuiltinLang.ml
===================================================================
--- trunk/Toss/Term/BuiltinLang.ml 2012-06-20 21:51:20 UTC (rev 1730)
+++ trunk/Toss/Term/BuiltinLang.ml 2012-06-22 13:48:24 UTC (rev 1731)
@@ -29,12 +29,13 @@
let list_sd = SDtype [Tp term_type_tp; Str "list"]
let list_name = name_of_sd list_sd
-let list_tp t = Term (list_name, [||], [|t|])
-let list_tp_a = list_tp (Var ("a", [||], 0, [||]))
+let list_tp t = Term (list_name, toplevel_type, [|t|])
+let list_tp_a = list_tp (Var ("a", 0, top_type_term, [||]))
let list_nil_sd = SDfun ([Str "["; Str "]"], list_tp_a)
let list_nil_name = name_of_sd list_nil_sd
-let list_cons_sd = SDfun ([Tp (Var ("a",[||],0,[||])); Str ","; Tp list_tp_a],
+let list_cons_sd = SDfun ([Tp (Var ("a",0,top_type_term,[||]));
+ Str ","; Tp list_tp_a],
list_tp_a)
let list_cons_name = name_of_sd list_cons_sd
@@ -130,8 +131,10 @@
Tp term_type_tp; Str ":"; Tp (list_tp bit_tp);
Str "("; Tp (list_tp term_tp); Str ")"], term_tp)
let term_var_cons_name = name_of_sd term_var_cons_sd
-let term_term_cons_sd = SDfun ([Str "term"; Tp string_tp; Str "(";
- Tp (list_tp term_tp); Str ")"], term_tp)
+let term_term_cons_sd =
+ SDfun ([Str "term"; Tp string_tp; Str "(";
+ Tp (list_tp term_type_tp); Str ":"; Tp (list_tp term_tp);
+ Str ")"], term_tp)
let term_term_cons_name = name_of_sd term_term_cons_sd
let rewrite_rule_sd = SDtype ([Str "rewrite"; Str "rule"])
@@ -147,8 +150,9 @@
let input_rewrite_rule_name = name_of_sd input_rewrite_rule_sd
let input_rewrite_rule_tp = type_of_sd input_rewrite_rule_sd
-let let_be_sd = SDfun ([Str "let"; Tp (Var ("a_1",[||],0,[||])); Str "be";
- Tp (Var ("a_1",[||],0,[||]))], input_rewrite_rule_tp)
+let let_be_sd = SDfun ([Str "let"; Tp (Var ("a_1",0,top_type_term,[||]));
+ Str "be"; Tp (Var ("a_1",0,top_type_term,[||]))],
+ input_rewrite_rule_tp)
let let_be_name = name_of_sd let_be_sd
let priority_input_rewrite_rule_sd = SDtype ([Str "priority";
@@ -159,8 +163,10 @@
type_of_sd priority_input_rewrite_rule_sd
let let_major_be_sd =
- SDfun ([Str "let"; Str "major"; Tp (Var ("a_1",[||],0,[||])); Str "be";
- Tp (Var ("a_1",[||],0,[||]))], priority_input_rewrite_rule_tp)
+ SDfun ([Str "let"; Str "major";
+ Tp (Var ("a_1",0,top_type_term,[||])); Str "be";
+ Tp (Var ("a_1",0,top_type_term,[||]))],
+ priority_input_rewrite_rule_tp)
let let_major_be_name = name_of_sd let_major_be_sd
let fun_definition_sd = SDtype ([Str "fun"; Str "definition"])
@@ -185,44 +191,47 @@
let exception_cl_sd = SDtype [Tp term_type_tp; Str "exception"]
let exception_cl_name = name_of_sd exception_cl_sd
-let exception_cl_tp t = Term (exception_cl_name, [||], [|t|])
+let exception_cl_tp t = Term (exception_cl_name, toplevel_type, [|t|])
let exception_sd =
- SDfun ([Str "!"; Str "!"; Tp (Var ("a",[||],0,[||])); Str "!";Str "!";],
- exception_cl_tp (Var ("other_than_a!",[||],0,[||])))
+ SDfun ([Str "!"; Str "!"; Tp (Var ("a",0,top_type_term,[||]));
+ Str "!";Str "!";],
+ exception_cl_tp (Var ("other_than_a!",0,top_type_term,[||])))
let exception_name = name_of_sd exception_sd
let exn_ok_sd =
- SDfun ([Str "+"; Str "+"; Tp (Var ("a",[||],0,[||])); Str "+";Str "+";],
- exception_cl_tp (Var ("a",[||],0,[||]))) (* Here it should be a! *)
+ SDfun ([Str "+"; Str "+"; Tp (Var ("a",0,top_type_term,[||]));
+ Str "+";Str "+";],
+ exception_cl_tp (Var ("a",0,top_type_term,[||]))) (* Here it should be a! *)
let exn_ok_name = name_of_sd exception_sd
(* --- Special functions recognized during Normalisation --- *)
-let brackets_sd = SDfun ([Str "("; Tp (Var ("b",[||],0,[||])); Str ")"],
- Var ("b",[||],0,[||]))
+let brackets_sd = SDfun ([Str "(";
+ Tp (Var ("b",0,top_type_term,[||])); Str ")"],
+ Var ("b",0,top_type_term,[||]))
let brackets_name = name_of_sd brackets_sd
-let verbatim_sd = SDfun ([Str "<"; Str "|"; Tp (Var ("b",[||],0,[||]));
- Str "|"; Str ">"], Var ("b",[||],0,[||]))
+let verbatim_sd = SDfun ([Str "<"; Str "|"; Tp (Var ("b",0,top_type_term,[||]));
+ Str "|"; Str ">"], Var ("b",0,top_type_term,[||]))
let verbatim_name = name_of_sd verbatim_sd
let if_then_else_sd = SDfun ([Str "if"; Tp boolean_tp; Str "then";
- Tp (Var ("a",[||],0,[||])); Str "else";
- Tp (Var ("a",[||],0,[||]))], Var ("a",[||],0,[||]))
+ Tp (Var ("a",0,top_type_term,[||])); Str "else";
+ Tp (Var ("a",0,top_type_term,[||]))], Var ("a",0,top_type_term,[||]))
let if_then_else_name = name_of_sd if_then_else_sd
-let eq_bool_sd = SDfun ([Tp (Var ("a",[||],0,[||])); Str "=";
- Tp (Var ("a",[||],0,[||]))], boolean_tp)
+let eq_bool_sd = SDfun ([Tp (Var ("a",0,top_type_term,[||])); Str "=";
+ Tp (Var ("a",0,top_type_term,[||]))], boolean_tp)
let eq_bool_name = name_of_sd eq_bool_sd
(* --- Syntax Definitions for special meta-functions --- *)
-let code_as_term_sd = SDfun ([Str "code"; Tp (Var ("a",[||],0,[||]));
+let code_as_term_sd = SDfun ([Str "code"; Tp (Var ("a",0,top_type_term,[||]));
Str "as"; Str "term"], term_tp)
let code_as_term_name = name_of_sd code_as_term_sd
@@ -278,13 +287,13 @@
let set_command_tp = type_of_sd set_command_sd
let set_prop_sd = SDfun ([Str "set"; Tp (string_tp); Str "of";
- Tp (Var ("a",[||],0,[||])); Str "to";
- Tp (Var ("b",[||],0,[||]))], set_command_tp)
+ Tp (Var ("a",0,top_type_term,[||])); Str "to";
+ Tp (Var ("b",0,top_type_term,[||]))], set_command_tp)
let set_prop_name = name_of_sd set_prop_sd
let preprocess_sd = SDfun ([Str "#"; Str "#"; Str "#";
- Tp (Var ("p",[||],0,[||]))], Var ("q",[||],0,[||]))
+ Tp (Var ("p",0,top_type_term,[||]))], Var ("q",0,top_type_term,[||]))
let preprocess_name = name_of_sd preprocess_sd
Modified: trunk/Toss/Term/Coding.ml
===================================================================
--- trunk/Toss/Term/Coding.ml 2012-06-20 21:51:20 UTC (rev 1730)
+++ trunk/Toss/Term/Coding.ml 2012-06-22 13:48:24 UTC (rev 1731)
@@ -14,9 +14,9 @@
exception DECODE of string
exception CODE of string
-let rec code_list f = function
- | [] -> Term (list_nil_name, [||], [||])
- | x :: xs -> Term (list_cons_name, [||], [|f (x); code_list f xs|])
+let rec code_list tp f = function
+ | [] -> Term (list_nil_name, tp, [||])
+ | x :: xs -> Term (list_cons_name, tp, [|f (x); code_list tp f xs|])
let rec decode_list f = function
@@ -41,8 +41,8 @@
let code_bit = function
- | 0 -> Term (bit_0_cons_name, [||], [||])
- | 1 -> Term (bit_1_cons_name, [||], [||])
+ | 0 -> Term (bit_0_cons_name, [|bit_tp|], [||])
+ | 1 -> Term (bit_1_cons_name, [|bit_tp|], [||])
| _ -> failwith "not bit while coding bit"
@@ -57,7 +57,7 @@
let bits = int_to_bits (Char.code c) in
let rec zeros i = if i <= 0 then [] else 0 :: zeros (i-1) in
let eight_bits = bits @ zeros (8 - List.length bits) in
- Term (char_cons_name, [||], of_list (List.map code_bit eight_bits))
+ Term (char_cons_name, [|char_tp|], of_list (List.map code_bit eight_bits))
let decode_char = function
| Term (n, _, bits) when n = char_cons_name ->
@@ -67,8 +67,8 @@
let code_string s =
let rec char_list i = if i < 0 then [] else s.[i] :: char_list (i-1) in
let chars = List.rev (char_list ((String.length s) - 1)) in
- let char_term = code_list code_char chars in
- Term (string_cons_name, [||], [|char_term|])
+ let char_term = code_list [|list_tp char_tp|] code_char chars in
+ Term (string_cons_name, [|string_tp|], [|char_term|])
let decode_string t =
@@ -86,8 +86,8 @@
let code_bool = function
- | true -> Term (boolean_true_name, [||], [||])
- | false -> Term (boolean_false_name, [||], [||])
+ | true -> Term (boolean_true_name, [|boolean_tp|], [||])
+ | false -> Term (boolean_false_name, [|boolean_tp|], [||])
let decode_bool = function
@@ -97,30 +97,32 @@
let rec code_term_type = function
- | Var (name, [||], 0, [||])->
- Term (term_type_var_name, [||], [|code_string name|])
+ | Var (name, 0, tp, [||]) when tp = top_type_term ->
+ Term (term_type_var_name, [|term_type_tp|], [|code_string name|])
| Var _ -> failwith "code_term_type: non-type variable"
- | Term (name, [||], arr) when name = Term.fun_type_name ->
+ | Term (name, tp, arr) when name = Term.fun_type_name && tp = toplevel_type->
let l = Array.length arr in
let (args_types, return_type) = (Array.sub arr 0 (l-1), arr.(l-1)) in
- Term (term_type_fun_name, [||], [|
- code_list code_term_type (to_list args_types);
+ Term (term_type_fun_name, [|term_type_tp|], [|
+ code_list [|list_tp term_type_tp|] code_term_type (to_list args_types);
code_term_type return_type|])
- | Term (name, [||], args) ->
- Term (term_type_cons_name, [||], [|
+ | Term (name, tp, args) when tp = toplevel_type ->
+ Term (term_type_cons_name, [|term_type_tp|], [|
code_string name;
- code_list code_term_type (to_list args)|])
- | Term _ -> failwith "code_term_type: non-type term"
+ code_list [|list_tp term_type_tp|] code_term_type (to_list args)|])
+ | Term (name, _, _) when name = top_type_name -> failwith
+ "code_term_type: coding top term (the type of a type) not supported"
+ | Term (name, _, _) -> failwith
+ ("code_term_type: non-type term at symbol " ^ name)
-
let rec decode_term_type = function
| Term (s, _, [|coded_name|]) when s = term_type_var_name ->
- Var (decode_string coded_name, [||], 0, [||])
+ Var (decode_string coded_name, 0, top_type_term, [||])
| Term (s, _, [|coded_1; coded_2|]) when s = term_type_fun_name ->
- Term (Term.fun_type_name, [||], of_list (
+ Term (Term.fun_type_name, toplevel_type, of_list (
(decode_list decode_term_type coded_1) @ [decode_term_type coded_2]))
| Term (s, _, [|coded_1; coded_2|]) when s = term_type_cons_name ->
- Term (decode_string coded_1, [||],
+ Term (decode_string coded_1, toplevel_type,
of_list (decode_list decode_term_type coded_2))
| _ -> raise (DECODE "term_type")
@@ -130,35 +132,40 @@
let rec code_term = function
- | Var (name, var_types, deg, args) ->
- Term (term_var_cons_name, [||],
+ | Var (name, deg, var_type, args) ->
+ Term (term_var_cons_name, [|term_tp|],
[|code_string name;
- code_term_type var_types.(0);
- code_list code_bit (int_to_bits deg);
- code_list code_term (to_list args)|])
- | Term (name, _, args) ->
- Term (term_term_cons_name, [||], [|code_string name;
- code_list code_term (to_list args)|])
+ code_term_type var_type;
+ code_list [|list_tp bit_tp|] code_bit (int_to_bits deg);
+ code_list [|list_tp term_tp|] code_term (to_list args)|])
+ | Term (name, types, args) ->
+ Term (term_term_cons_name, [|term_tp|],
+ [|code_string name;
+ code_list [|list_tp term_type_tp|] code_term_type (to_list types);
+ code_list [|list_tp term_tp|] code_term (to_list args)|])
let rec code_term_incr_vars = function
- | Var (name, var_type, deg, args) ->
- Var (name, var_type, deg+1, map code_term_incr_vars args)
- | Term (name, _, args) ->
- Term (term_term_cons_name, [||], [|
- code_string name; code_list code_term_incr_vars (to_list args)|])
+ | Var (name, deg, var_type, args) ->
+ Var (name, deg+1, var_type, map code_term_incr_vars args)
+ | Term (name, types, args) ->
+ Term (term_term_cons_name, [|term_tp|],
+ [|code_string name;
+ code_list [|list_tp term_type_tp|] code_term_type (to_list types);
+ code_list [|list_tp term_tp|] code_term_incr_vars (to_list args)|])
let rec decode_term = function
| Term (s, _, [|coded_name; coded_type; coded_deg; coded_args|])
when s = term_var_cons_name ->
Var (decode_string coded_name,
- [|decode_term_type coded_type|],
bits_to_int (decode_list decode_bit coded_deg),
+ decode_term_type coded_type,
of_list (decode_list decode_term coded_args))
- | Term (s, _, [|coded_name; coded_args|])
+ | Term (s, _, [|coded_name; coded_types; coded_args|])
when s = term_term_cons_name ->
- Term (decode_string coded_name, [||],
+ Term (decode_string coded_name,
+ of_list (decode_list decode_term_type coded_types),
of_list (decode_list decode_term coded_args))
| _ -> raise (DECODE "term")
@@ -170,7 +177,8 @@
let code_rewrite_rule (left, right) =
- Term (rewrite_rule_cons_name, [||], [|code_term left; code_term right|])
+ Term (rewrite_rule_cons_name, [|rewrite_rule_tp|],
+ [|code_term left; code_term right|])
let decode_rewrite_rule = function
@@ -180,7 +188,7 @@
let code_input_rewrite_rule (left, right) =
- Term (let_be_name, [||], [|left; right|])
+ Term (let_be_name, [|input_rewrite_rule_tp|], [|left; right|])
let decode_input_rewrite_rule = function
@@ -189,20 +197,20 @@
let code_priority_input_rewrite_rule (left, right) =
- Term (let_major_be_name, [||], [|left; right|])
+ Term (let_major_be_name, [|priority_input_rewrite_rule_tp|], [|left; right|])
let decode_priority_input_rewrite_rule = function
- | Term (n, [||], [|left; right|]) when n = let_major_be_name -> (left, right)
+ | Term (n, _, [|left; right|]) when n = let_major_be_name -> (left, right)
| _ -> raise (DECODE "priority input rewrite rule")
type fun_definition = string * Term.term list * Term.term
let code_fun_definition (name, args_types, return_type) =
- Term (fun_definition_cons_name, [||], [|
+ Term (fun_definition_cons_name, [|fun_definition_tp|], [|
code_string name;
- code_list code_term_type args_types;
+ code_list [|list_tp term_type_tp|] code_term_type args_types;
code_term_type return_type|])
@@ -218,23 +226,23 @@
let code_type_definition (name, arity) =
let rec var = function
| 0 -> []
- | i -> Var ("a_" ^ (string_of_int i), [||], 0, [||]) :: (var (i-1)) in
- Term (type_of_name, [||],
- [|code_term_type (Term (name, [||], of_list (var arity)))|])
+ | i -> Var ("a_" ^ (string_of_int i), 0, top_type_term, [||]) :: (var (i-1)) in
+ Term (type_of_name, [|type_definition_tp|],
+ [|code_term_type (Term (name, toplevel_type, of_list (var arity)))|])
let decode_type_definition = function
| Term (n, _, [|ty|]) when n = type_of_name ->
(match (decode_term_type ty) with
- | Term (name, [||], args) -> (name, Array.length args)
+ | Term (name, _, args) -> (name, Array.length args)
| _ -> raise (DECODE "type definition 1")
)
| _ -> raise (DECODE "type definition 2")
let code_syntax_element = function
- | Str s -> Term (syntax_element_str_name, [||], [|code_string s|])
- | Tp tt -> Term (syntax_element_tp_name, [||], [|code_term_type tt|])
+ | Str s -> Term (syntax_element_str_name, [|syntax_element_tp|], [|code_string s|])
+ | Tp tt -> Term (syntax_element_tp_name, [|syntax_element_tp|], [|code_term_type tt|])
let decode_syntax_element = function
@@ -246,9 +254,9 @@
let rec code_syntax_element_list = function
- | [se] -> Term (syntax_element_list_elem_name, [||],
+ | [se] -> Term (syntax_element_list_elem_name, [|syntax_element_list_tp|],
[|code_syntax_element se|])
- | se :: ses -> Term (syntax_element_list_cons_name, [||],
+ | se :: ses -> Term (syntax_element_list_cons_name, [|syntax_element_list_tp|],
[|code_syntax_element se; code_syntax_element_list ses|])
| [] -> raise (CODE "syntax element list")
@@ -264,12 +272,12 @@
let code_syntax_definition = function
| SDtype se ->
- Term (syntax_definition_type_name, [||], [|code_syntax_element_list se|])
+ Term (syntax_definition_type_name, [|syntax_definition_tp|], [|code_syntax_element_list se|])
| SDfun (se, res_ty) ->
- Term (syntax_definition_fun_name, [||],
+ Term (syntax_definition_fun_name, [|syntax_definition_tp|],
[|code_syntax_element_list se; code_term_type res_ty|])
| SDvar (se, res_ty) ->
- Term (syntax_definition_var_name, [||],
+ Term (syntax_definition_var_name, [|syntax_definition_tp|],
[|code_syntax_element_list se; code_term_type res_ty|])
@@ -291,10 +299,10 @@
let rec matches dict = function
| (Term (n1, _, a1), Term (n2, _, a2)) when n1=n2 && (length a1 = length a2)->
Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, _, d1, a1), Var (n2, _, d2, a2))
+ | (Var (n1, d1, _, a1), Var (n2, d2, _, a2))
when n1 = n2 && d1 = d2 && length a1 = length a2 ->
Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, _, d1, [||]), te) ->
+ | (Var (n1, d1, _, [||]), te) ->
(try
let arg = List.assoc n1 (!dict) in
let coded_arg = fn_apply d1 code_term arg in
@@ -308,21 +316,22 @@
(* Application of term substitutions (only flat functional substitutes). *)
let rec apply_s substs = function
- | Var (n, _, d, [||]) as t ->
+ | Var (n, d, _, [||]) as t ->
+ (* FIXME: why we don't apply substitutions recursively, as below? *)
(try (fn_apply d code_term (List.assoc n substs)) with Not_found -> t)
- | Term (n, tp, a) -> Term (n, tp, map (apply_s substs) a)
- | Var (n, t, deg, a) ->
+ | Term (n, tp, a) -> Term (n, map (apply_s substs) tp, map (apply_s substs) a)
+ | Var (n, deg, t, a) ->
try (
let raw_result =
match (List.assoc n substs) with
- | Term (name, [||], [||]) ->
- Term (name, [||], map (apply_s substs) a)
- | Var (name, ty, d, [||]) ->
- Var (name, ty, d, map (apply_s substs) a)
+ | Term (name, tps, [||]) ->
+ Term (name, map (apply_s substs) tps, map (apply_s substs) a)
+ | Var (name, d, ty, [||]) ->
+ Var (name, d, apply_s substs ty, map (apply_s substs) a)
| _ -> failwith "functional substitution of non-flat term" in
fn_apply deg code_term raw_result
)
- with Not_found -> Var (n, t, deg, map (apply_s substs) a)
+ with Not_found -> Var (n, deg, t, map (apply_s substs) a)
(* --- Nice Term display based on Syntax Definitions --- *)
@@ -346,7 +355,7 @@
(* --- Display terms and types as XML --- *)
let rec display_type_xml = function
- | Var (n, [||], 0, [||]) ->
+ | Var (n, 0, top_type_term, [||]) ->
"<type_var>" ^ (make_xml_compatible n) ^ "</type_var>"
| Var _ -> failwith "display_type_xml: non-type variable"
| Term (n, _, a) ->
@@ -365,11 +374,11 @@
"<term class=\"" ^ (make_xml_compatible n) ^ "\">\n" ^
(String.concat "\n" (List.map display_term_xml (to_list a))) ^
"\n</term>"
- | Var (n, ty, deg, a) ->
+ | Var (n, deg, ty, a) ->
"<term-variable class=\"" ^ (make_xml_compatible n) ^
"\" deg=\"" ^ (string_of_int deg) ^ "\">" ^
(String.concat "" (List.map display_term_xml (to_list a))) ^
- "<term-variable-type>"^(display_type_xml ty.(0))^"</term-variable-type>" ^
+ "<term-variable-type>"^(display_type_xml ty)^"</term-variable-type>" ^
"</term-variable>"
@@ -380,6 +389,8 @@
let rec term_to_string term =
let term_array_to_string ta =
String.concat ", " (to_list (map term_to_string ta)) in
+ let type_array_to_string ta =
+ String.concat ", " (to_list (map type_to_string ta)) in
match term with
| _ when is_some (decode_string_opt term) ->
let s = (match (decode_string_opt term) with Some s -> s | None -> "") in
@@ -393,17 +404,17 @@
| _ when is_some (decode_term_opt term) ->
(match (decode_term_opt term) with None -> ""
| Some te -> "@T " ^ (term_to_string te))
- | Var (v, t, d, [||]) ->
- "@V [" ^ v ^ " @: " ^ (type_to_string t.(0)) ^
+ | Var (v, d, t, [||]) ->
+ "@V [" ^ v ^ " @: " ^ (type_to_string t) ^
" @: "^ string_of_int (d) ^ " ]"
- | Var (v, t, d, a) ->
- "@V [" ^ v ^ " @: " ^ (type_to_string t.(0)) ^
+ | Var (v, d, t, a) ->
+ "@V [" ^ v ^ " @: " ^ (type_to_string t) ^
" @: "^ string_of_int (d) ^ " ] (" ^
(term_array_to_string a) ^ " )"
- | Term (n, [||], [||]) -> n
- | Term (n, [||], a) ->
- n ^ " (" ^ (term_array_to_string a) ^ " )"
- | Term _ -> failwith "term_to_string: stored types not supported yet"
+ (* FIXME: we should print types!!! *)
+ | Term (n, tp, [||]) -> n ^ "[ @: " ^ type_array_to_string tp ^ "]"
+ | Term (n, tp, a) ->
+ n ^ "[ @: " ^ type_array_to_string tp ^ "] (" ^ (term_array_to_string a) ^ " )"
(* Parser for terms. *)
@@ -417,7 +428,12 @@
)
| (Delim "@L") :: (Delim "[") :: rest ->
(match parse_term_list rest with
- | (l, (Delim "]") :: cont) -> (code_list (fun x -> x) l, cont)
+ | (l, (Delim "]") :: cont) ->
+ let tp = match l with
+ | [] -> top_type_term
+ | Var (_, _, tp, _)::_ -> tp
+ | Term (_, tps, _)::_ -> tps.(0) in
+ code_list [|list_tp tp|] (fun x -> x) l, cont
| _ -> failwith "parse_term: list not closed"
)
| (Delim "@Y") :: rest ->
@@ -430,12 +446,13 @@
(match parse_type rest with
| (ty, (Delim "@:") :: (Text deg) :: (Delim "]") :: cont) ->
let (l, c) = parse_bracketed_list cont in
- (Var (v, [|ty|], int_of_string (deg), of_list l), c)
+ (Var (v, int_of_string (deg), ty, of_list l), c)
| _ -> failwith "parse_term: var not closed"
)
- | (Text n) :: rest ->
+ | (Text n) :: Delim "[" :: Delim "@:" :: rest ->
+ let types, rest = parse_type_list rest in
let (l, cont) = parse_bracketed_list rest in
- (Term (n, [||], of_list l), cont)
+ (Term (n, of_list types, of_list l), cont)
| _ -> failwith "parse_term: bad start"
and parse_text_list = function
| (Text n) :: rest ->
@@ -467,6 +484,16 @@
| (Delim ",") :: rest ->
let (l, cont) = parse_term_list rest in (l, cont)
| l -> ([], l)
+and parse_type_list l =
+ try let (te, cont) = parse_type l in
+ let (lst, c) = parse_type_list_delim cont in
+ (te :: lst, c)
+ with _ -> ([], l)
+and parse_type_list_delim = function
+ | (Delim ",") :: rest ->
+ let (l, cont) = parse_type_list rest in (l, cont)
+ | Delim "]" :: rest -> ([], rest)
+ | rest -> failwith "parse_type_list: not closed with ]"
let term_of_string s =
let (te, cont) = parse_term (split_to_list s) in
@@ -476,27 +503,29 @@
(* --- Rules for special built-in functions --- *)
let brackets_rules =
- [(Term (brackets_name, [||], [|Var ("x", [|Var("a",[||],0,[||])|],0,[||])|]),
- Var ("x", [|Var ("a",[||],0,[||])|], 0, [||]))]
+ [(Term (brackets_name, [|Var ("b",0,top_type_term,[||])|], [|Var ("x", 0, Var("a",0,top_type_term,[||]),[||])|]),
+ Var ("x", 0, Var ("a",0,top_type_term,[||]), [||]))]
let verbatim_rules =
- [(Term (verbatim_name, [||], [|Var ("x",[|Var ("a",[||],0,[||])|],0,[||])|]),
- Var ("x", [|Var ("a",[||],0,[||])|], 0, [||]))]
+ [(Term (verbatim_name, [|Var ("b",0,top_type_term,[||])|], [|Var ("x",0,Var ("a",0,top_type_term,[||]),[||])|]),
+ Var ("x", 0, Var ("a",0,top_type_term,[||]), [||]))]
let if_then_else_rules = [
- (Term (if_then_else_name, [||], [|code_bool true;
- Var ("x", [|Var ("a",[||],0,[||])|], 0, [||]);
- Var ("y", [|Var ("a",[||],0,[||])|], 0, [||])|]),
- Var ("x", [|Var ("a",[||],0,[||])|], 0, [||]));
- (Term (if_then_else_name, [||], [|code_bool false;
- Var ("x", [|Var ("a",[||],0,[||])|], 0, [||]);
- Var ("y", [|Var ("a",[||],0,[||])|], 0, [||])|]),
- Var ("y", [|Var ("a",[||],0,[||])|], 0, [||]))]
+ (Term (if_then_else_name, [|Var ("a",0,top_type_term,[||])|],
+ [|code_bool true;
+ Var ("x",0,Var ("a",0,top_type_term,[||]),[||]);
+ Var ("y",0,Var ("a",0,top_type_term,[||]),[||])|]),
+ Var ("x",0,Var ("a",0,top_type_term,[||]),[||]));
+ (Term (if_then_else_name, [|Var ("a",0,top_type_term,[||])|],
+ [|code_bool false;
+ Var ("x",0,Var ("a",0,top_type_term,[||]),[||]);
+ Var ("y",0,Var ("a",0,top_type_term,[||]),[||])|]),
+ Var ("y",0,Var ("a",0,top_type_term,[||]),[||]))]
-let varx_te = Var ("x", [|Var ("p",[||],0,[||])|], 0, [||])
-let preprocess_rules = [(Term (preprocess_name, [||], [|varx_te|]), varx_te)]
+let varx_te = Var ("x", 0, Var ("p",0,top_type_term,[||]), [||])
+let preprocess_rules = [(Term (preprocess_name, [|Var ("q",0,top_type_term,[||])|], [|varx_te|]), varx_te)]
let string_quote_rules =
- [(Term (string_quote_name, [||], [|Var ("s", [|string_tp|], 0, [||])|]),
- Var ("s", [|string_tp|], 0, [||]))]
+ [(Term (string_quote_name, [|string_tp|], [|Var ("s", 0, string_tp, [||])|]),
+ Var ("s", 0, string_tp, [||]))]
let additional_xslt_rules =
- [(Term (additional_xslt_name, [||], [||]), code_string " ")]
+ [(Term (additional_xslt_name, [|string_tp|], [||]), code_string " ")]
Modified: trunk/Toss/Term/Coding.mli
===================================================================
--- trunk/Toss/Term/Coding.mli 2012-06-20 21:51:20 UTC (rev 1730)
+++ trunk/Toss/Term/Coding.mli 2012-06-22 13:48:24 UTC (rev 1731)
@@ -9,7 +9,7 @@
(** Thrown when decoding fails. *)
exception DECODE of string
-val code_list : ('a -> term) -> 'a list -> term
+val code_list : term array -> ('a -> term) -> 'a list -> term
val decode_list : (term -> 'a) -> term -> 'a list
val decode_list_opt : (term -> 'a) -> term -> 'a list option
val int_to_bits : int -> int list
Modified: trunk/Toss/Term/CodingTest.ml
===================================================================
--- trunk/Toss/Term/CodingTest.ml 2012-06-20 21:51:20 UTC (rev 1730)
+++ trunk/Toss/Term/CodingTest.ml 2012-06-22 13:48:24 UTC (rev 1731)
@@ -2,16 +2,16 @@
open Term
open Coding
-let tests = "Term" >::: [
+let tests = "Coding" >::: [
"coding term types" >::
(fun () ->
let test_code_decode_tt tt =
let tt1 = decode_term_type (code_term_type tt) in
assert_equal ~printer:(fun x -> type_to_string x) tt tt1 in
- let tt1 = Term ("ala", [||], [||]) in
- let tt2 = Term ("bolek", [||], [|tt1; tt1|]) in
- let tt3 = Term (Term.fun_type_name, [||], [|tt1; tt2; tt1|]) in
- let tt4 = Var ("zmienna",[||],0,[||]) in
+ let tt1 = Term ("ala", toplevel_type, [||]) in
+ let tt2 = Term ("bolek", toplevel_type, [|tt1; tt1|]) in
+ let tt3 = Term (Term.fun_type_name, toplevel_type, [|tt1; tt2; tt1|]) in
+ let tt4 = Var ("zmienna",0,top_type_term,[||]) in
test_code_decode_tt tt1;
test_code_decode_tt tt2;
test_code_decode_tt tt3;
@@ -23,10 +23,11 @@
let test_code_decode_te te =
let te1 = decode_term (code_term te) in
assert_equal ~printer:(fun x -> term_to_string x) te te1 in
- let term1 = Term ("ala", [||], [||]) in
- let term2 = Term ("bolek", [||], [|term1|]) in
- let term3 = Term ("cynik", [||], [|term1; term2|]) in
- let term4 = Var ("zmienna", [|Var ("a1",[||],0,[||])|], 0, [| |]) in
+ let ty = Term ("text", toplevel_type, [||]) in
+ let term1 = Term ("ala", [|ty|], [||]) in
+ let term2 = Term ("bolek", [|ty|], [|term1|]) in
+ let term3 = Term ("cynik", [|ty|], [|term1; term2|]) in
+ let term4 = Var ("zmienna", 0, Var ("a1",0,top_type_term,[||]), [| |]) in
test_code_decode_te term1;
test_code_decode_te term2;
test_code_decode_te term3;
@@ -52,10 +53,10 @@
let sd1 = decode_syntax_definition (code_syntax_definition sd) in
assert_equal ~printer:(fun x -> "syntax definition test") sd sd1 in
let se1 = SyntaxDef.Str "napisek" in
- let se2 = SyntaxDef.Tp (Var ("eee",[||],0,[||])) in
+ let se2 = SyntaxDef.Tp (Var ("eee",0,top_type_term,[||])) in
let sd1 = SyntaxDef.SDtype [se1; se2] in
- let sd2 = SyntaxDef.SDfun ([se2; se1; se1], Term ("aaa", [||], [||])) in
- let sd3 = SyntaxDef.SDv...
[truncated message content] |
|
From: <luk...@us...> - 2012-06-25 14:30:33
|
Revision: 1733
http://toss.svn.sourceforge.net/toss/?rev=1733&view=rev
Author: lukstafi
Date: 2012-06-25 14:30:21 +0000 (Mon, 25 Jun 2012)
Log Message:
-----------
New Speagram step 2: doing inference online during parsing. For clean intermediate step, removed dealing with types from rewriting, apart from preserving them on rewritten subterms.
Modified Paths:
--------------
trunk/Toss/Formula/Aux.ml
trunk/Toss/Formula/Aux.mli
trunk/Toss/Term/BuiltinLang.ml
trunk/Toss/Term/Coding.ml
trunk/Toss/Term/Coding.mli
trunk/Toss/Term/ParseArc.ml
trunk/Toss/Term/ParseArc.mli
trunk/Toss/Term/ParseArcTest.ml
trunk/Toss/Term/Rewriting.ml
trunk/Toss/Term/SyntaxDef.ml
trunk/Toss/Term/SyntaxDef.mli
trunk/Toss/Term/TRS.ml
trunk/Toss/Term/TRS.mli
trunk/Toss/Term/TRSTest.ml
trunk/Toss/Term/Term.ml
trunk/Toss/Term/Term.mli
trunk/Toss/Term/TermTest.ml
trunk/Toss/Term/tests/short_checks.log
trunk/Toss/Term/tests/short_checks.trs
Modified: trunk/Toss/Formula/Aux.ml
===================================================================
--- trunk/Toss/Formula/Aux.ml 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Formula/Aux.ml 2012-06-25 14:30:21 UTC (rev 1733)
@@ -203,6 +203,11 @@
in
List.rev (maps_f [] l)
+let rec find_some f = function
+ | [] -> raise Not_found
+ | a::l ->
+ match f a with None -> find_some f l | Some r -> r
+
let map_reduce mapf redf red0 l =
match List.sort (fun x y -> compare (fst x) (fst y))
(List.map mapf l) with
@@ -707,6 +712,15 @@
true
with Not_found -> false
+let array_iter2 f a b =
+ let len = Array.length a in
+ if len <> Array.length b then
+ raise (Invalid_argument "Aux.array_iter2")
+ else
+ for i = 0 to len - 1 do
+ f (Array.unsafe_get a i) (Array.unsafe_get b i)
+ done
+
let array_replace array i elem =
let a = Array.copy array in a.(i) <- elem; a
Modified: trunk/Toss/Formula/Aux.mli
===================================================================
--- trunk/Toss/Formula/Aux.mli 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Formula/Aux.mli 2012-06-25 14:30:21 UTC (rev 1733)
@@ -62,6 +62,8 @@
(** Map a list filtering out some elements. *)
val map_some : ('a -> 'b option) -> 'a list -> 'b list
+(** Find the first non-None element. Raise [Not_found] if none exists. *)
+val find_some : ('a -> 'b option) -> 'a list -> 'b
(** Map elements into key-value pairs, and fold values with the same
key. Uses {!List.fold_left}, therefore reverses the order. The
@@ -288,6 +290,11 @@
arrays are of different lengths. *)
val array_for_all2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool
+(** Iterate an action over all elements of two arrays
+ pointwise. Raises [Invalid_argument "Aux.array_iter2"] if
+ arrays are of different lengths. *)
+val array_iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit
+
(** Return a copy of [array] with the [i]th element replaced by [elem]. *)
val array_replace : 'a array -> int -> 'a -> 'a array
Modified: trunk/Toss/Term/BuiltinLang.ml
===================================================================
--- trunk/Toss/Term/BuiltinLang.ml 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Term/BuiltinLang.ml 2012-06-25 14:30:21 UTC (rev 1733)
@@ -293,7 +293,7 @@
let preprocess_sd = SDfun ([Str "#"; Str "#"; Str "#";
- Tp (Var ("p",0,top_type_term,[||]))], Var ("q",0,top_type_term,[||]))
+ Tp (Var ("p",0,top_type_term,[||]))], Var ("p",0,top_type_term,[||]))
let preprocess_name = name_of_sd preprocess_sd
Modified: trunk/Toss/Term/Coding.ml
===================================================================
--- trunk/Toss/Term/Coding.ml 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Term/Coding.ml 2012-06-25 14:30:21 UTC (rev 1733)
@@ -296,13 +296,36 @@
(* --- Term matching and substitutions --- *)
+(* Including supertypes.
let rec matches dict = function
- | (Term (n1, _, a1), Term (n2, _, a2)) when n1=n2 && (length a1 = length a2)->
+ | (Term (n1, t1, a1), Term (n2, t2, a2))
+ when n1=n2 && (length t1 = length t2) && (length a1 = length a2)->
+ Aux.array_for_all2 (fun u v -> matches dict (u, v)) t1 t2 &&
Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, d1, _, a1), Var (n2, d2, _, a2))
+ | (Var (n1, d1, t1, a1), Var (n2, d2, t2, a2))
when n1 = n2 && d1 = d2 && length a1 = length a2 ->
+ matches dict (t1, t2) &&
+ Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
+ | (Var (n1, d1, t1, [||]), te) ->
+ (try
+ let arg = List.assoc n1 (!dict) in
+ let coded_arg = fn_apply d1 code_term arg in
+ te = coded_arg
+ with Not_found ->
+ let decoded_te = fn_apply d1 decode_term te in
+ (dict := (n1, decoded_te) :: (!dict); true)
+ )
+ | _ -> false
+*)
+(* Ignoring supertypes. *)
+let rec matches dict = function
+ | (Term (n1, _, a1), Term (n2, _, a2))
+ when n1=n2 && (length a1 = length a2)->
Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, d1, _, [||]), te) ->
+ | (Var (n1, d1, _, a1), Var (n2, d2, _, a2))
+ when n1 = n2 && d1 = d2 && length a1 = length a2 ->
+ Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
+ | (Var (n1, d1, t1, [||]), te) ->
(try
let arg = List.assoc n1 (!dict) in
let coded_arg = fn_apply d1 code_term arg in
@@ -313,27 +336,50 @@
)
| _ -> false
-
-(* Application of term substitutions (only flat functional substitutes). *)
+(* Application of term substitutions (only flat functional
+ substitutes). Ignoring supertypes. *)
let rec apply_s substs = function
| Var (n, d, _, [||]) as t ->
(* FIXME: why we don't apply substitutions recursively, as below? *)
(try (fn_apply d code_term (List.assoc n substs)) with Not_found -> t)
- | Term (n, tp, a) -> Term (n, map (apply_s substs) tp, map (apply_s substs) a)
+ | Term (n, tp, a) -> Term (n, tp, map (apply_s substs) a)
| Var (n, deg, t, a) ->
try (
let raw_result =
match (List.assoc n substs) with
| Term (name, tps, [||]) ->
- Term (name, map (apply_s substs) tps, map (apply_s substs) a)
+ Term (name, tps, map (apply_s substs) a)
| Var (name, d, ty, [||]) ->
- Var (name, d, apply_s substs ty, map (apply_s substs) a)
+ Var (name, d, ty, map (apply_s substs) a)
| _ -> failwith "functional substitution of non-flat term" in
fn_apply deg code_term raw_result
)
with Not_found -> Var (n, deg, t, map (apply_s substs) a)
+(* Application of term substitutions (only flat functional
+ substitutes). Including supertypes. *)
+let rec apply_st substs = function
+ | Var (n, d, t, [||]) ->
+ (* FIXME: why we don't apply substitutions recursively, as below? *)
+ (try (fn_apply d code_term (List.assoc n substs))
+ with Not_found -> Var (n, d, apply_st substs t, [||]))
+ | Term (n, tp, a) ->
+ Term (n, map (apply_st substs) tp, map (apply_st substs) a)
+ | Var (n, deg, t, a) ->
+ try (
+ let raw_result =
+ match (List.assoc n substs) with
+ | Term (name, tps, [||]) ->
+ Term (name, map (apply_st substs) tps, map (apply_st substs) a)
+ | Var (name, d, ty, [||]) ->
+ Var (name, d, apply_st substs ty, map (apply_st substs) a)
+ | _ -> failwith "functional substitution of non-flat term" in
+ fn_apply deg code_term raw_result
+ )
+ with Not_found ->
+ Var (n, deg, apply_st substs t, map (apply_st substs) a)
+
(* --- Nice Term display based on Syntax Definitions --- *)
let is_some = function Some _ -> true | None -> false
@@ -351,7 +397,21 @@
let args = List.map display_term (Array.to_list a) in
display_sd (split_sdef_name n) args
+let rec display_term_bracketed = function
+ | te when is_some (decode_string_opt te) ->
+ "\"" ^ (decode_string te) ^ "\""
+ | te when is_some (decode_list_opt (fun x -> x) te) ->
+ let str_list = List.map display_term_bracketed
+ (decode_list (fun x -> x) te) in
+ "["^ (String.concat ", " str_list) ^ "]"
+ | Term (n, _, a) ->
+ let args = List.map display_term_bracketed (Array.to_list a) in
+ display_sd_bracketed (split_sdef_name n) args
+ | Var (n, _, _, a) ->
+ let args = List.map display_term_bracketed (Array.to_list a) in
+ display_sd_bracketed (split_sdef_name n) args
+
(* --- Display terms and types as XML --- *)
let rec display_type_xml = function
@@ -405,18 +465,30 @@
(match (decode_term_opt term) with None -> ""
| Some te -> "@T " ^ (term_to_string te))
| Var (v, d, t, [||]) ->
+ (try
"@V [" ^ v ^ " @: " ^ (type_to_string t) ^
" @: "^ string_of_int (d) ^ " ]"
+ with exn -> Printf.printf "Nontype: %s\n%!"(term_to_string t);
+ raise exn)
| Var (v, d, t, a) ->
+ (try
"@V [" ^ v ^ " @: " ^ (type_to_string t) ^
" @: "^ string_of_int (d) ^ " ] (" ^
(term_array_to_string a) ^ " )"
- (* FIXME: we should print types!!! *)
- | Term (n, tp, [||]) -> n ^ "[ @: " ^ type_array_to_string tp ^ "]"
+ with exn -> Printf.printf "Nontype: %s\n%!"(term_to_string t);
+ raise exn)
+ (* FIXME: we should print types!!! *)
+ | Term (n, tp, [||]) ->
+ (try
+ n ^ "[ @: " ^ type_array_to_string tp ^ "]"
+ with exn -> Printf.printf "Nontype: %s\n%!"(term_to_string tp.(0));
+ raise exn)
| Term (n, tp, a) ->
- n ^ "[ @: " ^ type_array_to_string tp ^ "] (" ^ (term_array_to_string a) ^ " )"
+ (try
+ n ^ "[ @: " ^ type_array_to_string tp ^ "] (" ^ (term_array_to_string a) ^ " )"
+ with exn -> Printf.printf "Nontype: %s\n%!"(term_to_string tp.(0));
+ raise exn)
-
(* Parser for terms. *)
let rec parse_term = function
| (Delim "@`") :: rest ->
Modified: trunk/Toss/Term/Coding.mli
===================================================================
--- trunk/Toss/Term/Coding.mli 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Term/Coding.mli 2012-06-25 14:30:21 UTC (rev 1733)
@@ -63,12 +63,18 @@
(** {2 Term Matching} *)
val matches : (string * term) list ref -> term * term -> bool
+(** Application of term substitutions (only flat functional
+ substitutes). Ignoring supertypes. *)
val apply_s : (string * term) list -> term -> term
+(** Application of term substitutions (only flat functional
+ substitutes). Including supertypes. *)
+val apply_st : (string * term) list -> term -> term
(** {2 Term Display, printing and parsing} *)
val display_term : term -> string
+val display_term_bracketed : term -> string
val display_type_xml : term -> string
val display_term_xml : term -> string
Modified: trunk/Toss/Term/ParseArc.ml
===================================================================
--- trunk/Toss/Term/ParseArc.ml 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Term/ParseArc.ml 2012-06-25 14:30:21 UTC (rev 1733)
@@ -7,172 +7,189 @@
(* The type of elements created during parsing.
- Tokens come just from lexer and terms are created during parsing.
- Type is kept together with each term not to recalculate it too often. *)
+ Tokens come just from lexer and terms are created during parsing.
+ [term] does not have [substitution] applied. *)
type parser_elem =
| Token of string
- | Typed_term of term * term
+ | PTerm of term * substitution * int (* From [parsed_elems], [cstrn]
+ and [endpos] of {!parser_arc}. *)
(* Print a parser elem. *)
let elem_str = function
| Token s -> "Tok " ^ s
- | Typed_term (tp, te) ->
- "Te " ^ (Coding.term_to_string te) ^ " : " ^ (type_to_string tp)
+ | PTerm (te, subst, endpos) -> (* FIXME perhaps *)
+ "Te " ^ Coding.term_to_string te
-(* The type of incomplete arcs that appear during parsing;
- The last field is the position where the arc begins
- and the elements on the list are in reverse order
- and the field after the syntax definition is the
- unique name generated for this syntax def. *)
-type parser_arc = Arc of syntax_def * string * parser_elem list * int
+(* Incomplete arcs that appear during parsing. [parsed_elems] do not have
+ [cstrn] applied. *)
+type parser_arc = {
+ sd_n : string; (* The parsed definition's unique name. *)
+ sd_res : sdef_result; (* Its supertypes and whether it's
+ a variable. *)
+ rem_elems : syntax_elem list; (* Its remaining elements. *)
+ parsed_elems : parser_elem list; (* Useful elements parsed so far in
+ rev. order (all will be arguments). *)
+ spos : int; (* Start position of the arc. *)
+ endpos : int; (* The current end position of the
+ arc. FIXME: unnecessary? *)
+ cstrn : substitution; (* Constraint for the arc. *)
+}
-
(* --- Extending and closing arcs --- *)
-exception NOT_EXTENDED
-exception NOT_CLOSED
+(* This function takes a parser element and an arc and extends the arc
+ if the next free position in the arc matches the given
+ element. Maching means equality for tokens and inference constraint
+ satisfaction for terms. Throws NOT_EXTENDED if it was impossible
+ to extend the arc.
-(* Checking if a given parser element matches the given position in a syntax
- definition. Maching means equality for tokens and unification possibility
- when a typed term is put against a type. When a typed term is put against
- a constant string in syntax definition then it does not match and if a token
- is put agains a type then it matches only if its type is the string type. *)
-let matches_position elem sd i =
- let sel = syntax_elems_of_sd sd in
- let sd_elem =
- if (length sel < i) then None else Some (nth sel (i-1)) in
- match (sd_elem, elem) with
- | (None, _) -> false
- | (Some (Str s), Token t) -> s = t
- | (Some (Str s), Typed_term (_,te)) -> false
- | (Some (Tp ty), Token tk) -> ty = BuiltinLang.string_tp
- | (Some (Tp ty), Typed_term (t, _)) ->
- let (ty, t as tp) = suffix 0 ty, suffix 1 t in
- try let _ = mgu [] [tp] in true
- with UNIFY -> false
+ When a term is put against a constant string in syntax definition
+ then it does not match and if a token is put against a term then it
+ matches only if it is a string type. Parsing can be seen as
+ performing "algorithm W" style type inference.
+ Note that the remaining elements were originally generated from a
+ syntax definition by freshening the s.d.'s variables. *)
+let extend_arc elem arc =
+ match arc.rem_elems, elem with
+ | [], _ -> None
+ | Str s::rem_elems, Token t ->
+ if s = t
+ then Some {arc with rem_elems; endpos = arc.endpos + 1}
+ else None
+ | Str s::_, PTerm _ -> None
+ | Tp ty::rem_elems, Token tk ->
+ if ty = BuiltinLang.string_tp
+ then Some
+ {arc with rem_elems; endpos = arc.endpos + 1;
+ parsed_elems = elem::arc.parsed_elems}
+ else None
+ | Tp ty::rem_elems, PTerm (t, t_cstrn, t_endpos) ->
+ (* For now (first-order mgu) we assume single type. *)
+ let pty = type_of t in
+ try
+ (* Purely an optimization step. *)
+ precheck_eq ty pty;
+ (*let ty = Term.apply_sb arc.cstrn ty in
+ let pty = Term.apply_sb t_cstrn pty in
+ precheck_eq ty pty;*)
+ (* Combine the constraints so far, and extend them to cover
+ the new parsed element. *)
+ let cstrn = combine_mgu_sb t_cstrn arc.cstrn in
+ let cstrn =
+ mgu cstrn [apply_sb cstrn pty, apply_sb cstrn ty] in
+ Some
+ {arc with rem_elems; parsed_elems = elem::arc.parsed_elems;
+ endpos = t_endpos; cstrn}
+ with UNIFY -> None
-(* This function takes a parser element and an arc and extends
- the arc if the next free position in the syntax definition
- of the arc matches the given element.
- Throws NOT_EXTENDED if it was impossible to extend the arc. *)
-let extend_arc elem = function
- | Arc (sd, n, l, p) ->
- if matches_position elem sd ((length l) + 1) then
- Arc (sd, n, (elem :: l), p)
- else raise NOT_EXTENDED
-
-
(* Extends all the arcs in the given list that can be extended
and removes all other arcs. *)
let extend_arc_list elem arcs =
- let extend_elem arc = try [extend_arc elem arc] with NOT_EXTENDED -> [] in
- flatten (map extend_elem arcs)
+ Aux.map_some (extend_arc elem) arcs
-(* Divides arcs into complete and incomplete looking at the length
- of the syntax definition input list and the list of parsed elements.
- In other words the arc is complete if nothing can be added to it. *)
-let divide_arcs arcs =
- let is_complete = function
- | Arc (SDtype i, _, l, _) -> length i = length l
- | Arc (SDfun (i, _), _, l, _) -> length i = length l
- | Arc (SDvar (i, _), _, l, _) -> length i = length l in
- (filter is_complete arcs, filter (fun a -> not (is_complete a)) arcs)
+(* Divides arcs into completed and incompleted (the arc is completed if
+ nothing can be added to it). *)
+let completed_arcs arcs =
+ List.partition (fun arc -> arc.rem_elems = []) arcs
-(* Closes an arc, also when an arc is full generates a term
- from it so as the syntax definition prescribes and returns this
- element together with the starting position of the arc.
- It is checked if the generated term is well-typed and
- the type is computetd and kept in the resulting parser element.
- Type declarations are given as a list of pairs that gives
- for each term symbol the type of that symbol.
- Throws NOT_CLOSED if closing fails. *)
-let match_of_tok = function
- | (Str _, _) -> []
- | (Tp _, Token s) -> [Coding.code_string s]
- | (Tp _, Typed_term (_, te)) -> [te]
-
-let close_arc type_decls = function
- | Arc (sd, n, l, spos) when (length l = length (syntax_elems_of_sd sd)) ->
- let elems = syntax_elems_of_sd sd in
- let args = flatten (map match_of_tok (combine elems (rev l))) in
- let res_term = (match sd with
- | SDtype _ ->
+(* Closes an arc when it is completed: returns the corresponding term
+ parser element together with the starting position of the arc. *)
+let close_arc arc =
+ let match_of_tok = function
+ | Token s -> Coding.code_string s
+ | PTerm (t,_,_) -> t in (* t_cstrn is part of arc.cstrn *)
+ if arc.rem_elems <> [] then None else
+ let args = rev_map match_of_tok arc.parsed_elems in
+ let res_term = match arc.sd_res with
+ | SD_Term ty when ty = toplevel_type ->
Term (BuiltinLang.term_type_cons_name, [|BuiltinLang.term_type_tp|],
- [|Coding.code_string n;
+ [|Coding.code_string arc.sd_n;
Coding.code_list
[|BuiltinLang.list_tp BuiltinLang.term_type_tp|]
(fun x -> x) args|])
- | SDfun (_,tp) -> Term (n, [|tp|], Array.of_list args)
- | SDvar (_, _) ->
- (match sd_type sd with
- | None -> failwith "variable syntax definition w/o type"
- | Some (ty) -> Var (n, 0, ty, Array.of_list args) )
- ) in
- (try
- let typ = type_of_term type_decls res_term in
- (Typed_term (typ, res_term), spos)
- with NOT_WELL_TYPED _ ->
- raise NOT_CLOSED)
- | _ -> raise NOT_CLOSED
+ | SD_Term tp -> Term (arc.sd_n, tp, Array.of_list args)
+ | SD_Var tp -> Var (arc.sd_n, 0, tp, Array.of_list args) in
+ (* Note that [arc.cstrn] is not applied to [res_term]. *)
+ Some (PTerm (res_term, arc.cstrn, arc.endpos), arc.spos)
-(* Closes all arcs from the given list that can be closed
- and returns the elements together with starting positions. *)
-let close_arc_list type_decls arcs =
- let close_a a = try [close_arc type_decls a] with NOT_CLOSED -> [] in
- flatten (map close_a arcs)
+(* --- Parsing by adding arcs --- *)
+let fresh_suffix = ref 0
+let reset_fresh_count () = fresh_suffix := 0
+let create_arc sdef sd_n spos =
+ let freshen = List.map
+ (function Str _ as e -> e | Tp t -> Tp (suffix !fresh_suffix t)) in
+ let elems, sd_res =
+ match sdef with
+ | SDtype elems -> incr fresh_suffix;
+ freshen elems, SD_Term toplevel_type
+ | SDfun (elems, ty) -> incr fresh_suffix;
+ freshen elems, SD_Term [|suffix !fresh_suffix ty|]
+ | SDvar (elems, ty) ->
+ (* Do not freshen variable types or their argument types --
+ variables are not polymorphic! *)
+ elems, SD_Var ty in
+ {
+ sd_n; spos; sd_res;
+ rem_elems = elems;
+ parsed_elems = [];
+ endpos = spos;
+ cstrn = empty_sb;
+ }
-(* --- Parsing by adding arcs --- *)
-
-(* Parsing proceeds by going from left to right through the list
+(* TODO: clean-up the description.
+ Parsing proceeds by going from left to right through the list
of tokens and extending the incomplete arcs for each position.
We have our constant set of syntax definitions and in each step
we have a list of incomplete arcs ending in all up to this position
and the new parser elements (starting with just the next token).
We gather the secured incomplete arcs for the next position by doing this:
(1) extend all incomplete arcs (also assuming that each syntax definition
- is a new incomplete arc with empty list of parser elems) ending in
- this position with the new token,
+ is a new incomplete arc with empty list of parser elems) ending in
+ this position with the new token,
(2) secure the arcs that were extended and are still incomplete for the
- next step and close all complete arcs generating new parser elems
+ next step and close all complete arcs generating new parser elems
(3) for each new generated parser element look where its arc was
- starting and try extend all incomplete arcs ending there with
- the new element; repeat recursively until no new elements are generated.
- WARINNG: at the end we need to return also the elements. *)
-let rec extend type_decls sdefs arcs_to pos elem =
- let arcs = (map (fun (sd, n) -> Arc (sd,n,[],pos)) sdefs)@ arcs_to.(pos-1) in
- let (complete_arcs, ready_arcs) = divide_arcs (extend_arc_list elem arcs) in
- let new_els = close_arc_list type_decls complete_arcs in
- let res = map (fun (e, s) -> extend type_decls sdefs arcs_to s e) new_els in
+ starting and try extend all incomplete arcs ending there with
+ the new element; repeat recursively until no new elements are generated.
+ WARINNG: at the end we need to return also the elements. *)
+let rec extend sdefs arcs_to pos elem =
+ let arcs =
+ map (fun (n, sd) -> create_arc sd n pos) sdefs @ arcs_to.(pos-1) in
+ let compl_arcs, ready_arcs =
+ completed_arcs (extend_arc_list elem arcs) in
+ let new_els = Aux.map_some close_arc compl_arcs in
+ let res = map (fun (e, spos) -> extend sdefs arcs_to spos e) new_els in
let (res_arcs, res_elems) = List.split ((ready_arcs, new_els) :: res) in
(flatten res_arcs, flatten res_elems)
-let parse_elems type_decls sdefs elems =
+let parse_elems sdefs elems =
let len = length elems in
let arcs_to = Array.make (len + 1) [] in
let parsed_elems = Array.make (len + 1) [] in
let rec update i = if i > len then () else
- let (arcs_i,el_i) = extend type_decls sdefs arcs_to i (nth elems (i-1)) in
+ let (arcs_i,el_i) = extend sdefs arcs_to i (nth elems (i-1)) in
( arcs_to.(i) <- arcs_i; parsed_elems.(i) <- el_i; update (i+1) ) in
- ( update 1; (arcs_to, parsed_elems) )
+ update 1;
+ (arcs_to, parsed_elems)
-let parse_to_array type_decls sdefs_original strs =
+let parse_to_array sdefs_original strs =
let possible_tok = function Tp _ -> true | Str s -> mem s strs in
let possible_sd sd = for_all possible_tok (syntax_elems_of_sd sd) in
- let sdefs = filter (fun (sd, s) -> possible_sd sd) sdefs_original in
- snd (parse_elems type_decls sdefs (map (fun s -> Token s) strs))
+ let sdefs = filter (fun (n, sd) -> possible_sd sd) sdefs_original in
+ snd (parse_elems sdefs (map (fun s -> Token s) strs))
-let parse type_decls sdefs strs =
- let parsed = (parse_to_array type_decls sdefs strs).(length strs) in
- fst (List.split (filter (fun (_, start) -> start = 1) parsed))
+let parse sdefs strs =
+ let parsed = (parse_to_array sdefs strs).(length strs) in
+ map fst (filter (fun (_, start) -> start = 1) parsed)
(* --- Input splitting --- *)
@@ -244,3 +261,12 @@
let res = first_down (split_string_all split_delims_str) in
LOG 1 "%s" (String.concat " " res);
res
+
+(* --- Final parsing --- *)
+let parse_with_sdefs sdefs str =
+ let type_of_pe = function Token _ -> None
+ | PTerm (te, cstrn, _) ->
+ let result = apply_sb cstrn te in
+ Some result in
+ let elems = parse sdefs (split_input_string str) in
+ Aux.map_some type_of_pe elems
Modified: trunk/Toss/Term/ParseArc.mli
===================================================================
--- trunk/Toss/Term/ParseArc.mli 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Term/ParseArc.mli 2012-06-25 14:30:21 UTC (rev 1733)
@@ -4,34 +4,52 @@
open Term
open SyntaxDef
-(** Elements used in the parser. *)
+(** The type of elements created during parsing. Tokens come just
+ from lexer and terms are created during parsing. [term] does not
+ have [substitution] applied. *)
type parser_elem =
| Token of string
- | Typed_term of term * Term.term
+ | PTerm of term * substitution * int (** From [parsed_elems], [cstrn]
+ and [endpos] of {!parser_arc}. *)
(** Print a parser elem. *)
val elem_str : parser_elem -> string
-(** Arcs built by the parser. *)
-type parser_arc = Arc of syntax_def * string * parser_elem list * int
+(** Reset the variable suffix count. *)
+val reset_fresh_count : unit -> unit
+(** Incomplete arcs that appear during parsing. [parsed_elems] do not have
+ [cstrn] applied. *)
+type parser_arc = {
+ sd_n : string; (** The parsed definition's unique name. *)
+ sd_res : sdef_result; (** Its supertypes and whether it's
+ a variable. *)
+ rem_elems : syntax_elem list; (** Its remaining elements. *)
+ parsed_elems : parser_elem list; (** Useful elements parsed so far in
+ rev. order (all will be arguments). *)
+ spos : int; (** Start position of the arc. *)
+ endpos : int; (** The current end position of the arc. *)
+ cstrn : substitution; (** Constraint for the arc. *)
+}
+
(** {2 Parsing, done by adding arcs} *)
+val create_arc : syntax_def -> string -> int -> parser_arc
+
(** Extends all the arcs in the given list that can be extended
and removes all other arcs. *)
val extend_arc_list : parser_elem -> parser_arc list -> parser_arc list
-(** Closes all arcs from the given list that can be closed
- and returns the elements together with starting positions. *)
-val close_arc_list : (string, term) Hashtbl.t ->
- parser_arc list -> (parser_elem * int) list
+(** Closes an arc when it is completed: returns the corresponding term
+ parser element together with the starting position of the arc. *)
+val close_arc : parser_arc -> (parser_elem * int) option
+val parse_to_array :
+ (string * syntax_def) list -> string list -> (parser_elem * int) list array
-val parse_to_array : (string, term) Hashtbl.t ->
- (syntax_def * string) list -> string list -> (parser_elem * int) list array
+val parse : (string * syntax_def) list -> string list -> parser_elem list
-val parse : (string, term) Hashtbl.t -> (syntax_def * string) list ->
- string list -> parser_elem list
+val split_input_string : string -> string list
-val split_input_string : string -> string list
+val parse_with_sdefs : (string * syntax_def) list -> string -> term list
Modified: trunk/Toss/Term/ParseArcTest.ml
===================================================================
--- trunk/Toss/Term/ParseArcTest.ml 2012-06-22 13:58:16 UTC (rev 1732)
+++ trunk/Toss/Term/ParseArcTest.ml 2012-06-25 14:30:21 UTC (rev 1733)
@@ -20,25 +20,25 @@
let var_x_a_sd = SDvar ([Str "x"], Var ("a",0,top_type_term,[||])) in
let sdefs = [list_cons_sd; list_nil_sd;
boolean_true_sd; boolean_false_sd; var_x_a_sd] in
- let arcs = List.map (fun sd -> Arc (sd, (name_of_sd sd), [], 0)) sdefs in
+ let arcs = List.map (fun sd -> create_arc sd (name_of_sd sd) 0) sdefs in
let var_arc = extend_arc_list (Token "x") arcs in
- let var_closed = fst (List.hd (close_arc_list tps var_arc)) in
- elem_eq "Te @V [Vx @: @? a @: 0 ] : @? a" var_closed;
+ let var_closed = fst (Aux.find_some close_arc var_arc) in
+ elem_eq "Te @V [Vx @: @? a @: 0 ]" var_closed;
let nil_part_arcs = extend_arc_list (Token "[") arcs in
let nil_arc = extend_arc_list (Token "]") nil_part_arcs in
- let nil_closed = fst (List.hd (close_arc_list tps nil_arc)) in
- elem_eq "Te @L[] : T\\?_list (@? a._.5)" nil_closed;
+ let nil_closed = fst (Aux.find_some close_arc nil_arc) in
+ elem_eq "Te @L[]" nil_closed;
let cons_part1_arc = extend_arc_list var_closed arcs in
let cons_part2_arc = extend_arc_list (Token ",") cons_part1_arc in
let cons_arc = extend_arc_list nil_closed cons_part2_arc in
- let cons_closed = fst (List.hd (close_arc_list tps cons_arc)) in
- elem_eq "Te @L[@V [Vx @: @? a @: 0 ]] : T\\?_list (@? a._.6)" cons_closed;
+ let cons_closed = fst (Aux.find_some close_arc cons_arc) in
+ elem_eq "Te @L[@V [Vx @: @? a @: 0 ]]" cons_closed;
let cons_bad_arc = extend_arc_list var_closed cons_part2_arc in
- let cons_bad_closed = close_arc_list tps cons_bad_arc in
+ let cons_bad_closed = Aux.map_some close_arc cons_bad_arc in
assert_equal ~printer:(fun x -> "empty list test") [] cons_bad_closed;
);
@@ -56,16 +56,17 @@
let var_x_a_sd = SDvar ([Str "x"], Var ("...
[truncated message content] |
|
From: <luk...@us...> - 2012-06-25 18:03:59
|
Revision: 1734
http://toss.svn.sourceforge.net/toss/?rev=1734&view=rev
Author: lukaszkaiser
Date: 2012-06-25 18:03:52 +0000 (Mon, 25 Jun 2012)
Log Message:
-----------
Test corrections and unicode for formulas.
Modified Paths:
--------------
trunk/Toss/Arena/Arena.ml
trunk/Toss/Arena/ContinuousRule.ml
trunk/Toss/Arena/DiscreteRule.ml
trunk/Toss/Client/eval.html
trunk/Toss/Formula/Formula.ml
trunk/Toss/Formula/Formula.mli
trunk/Toss/Formula/FormulaParser.mly
trunk/Toss/Formula/FormulaSubstTest.ml
trunk/Toss/Formula/FormulaTest.ml
trunk/Toss/Formula/Lexer.mll
trunk/Toss/Formula/Tokens.mly
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/StructureTest.ml
trunk/Toss/Term/Rewriting.ml
trunk/Toss/Term/RewritingTest.ml
trunk/Toss/Term/tests/sasha_basic.log
trunk/Toss/Term/tests/sasha_basic.trs
Modified: trunk/Toss/Arena/Arena.ml
===================================================================
--- trunk/Toss/Arena/Arena.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Arena/Arena.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -105,7 +105,7 @@
Format.fprintf f "@ @[<0>PLAYER@ %s@ {@ %a}@]@," (Aux.rev_assoc pnames player)
(fun f (payoff, moves) ->
Format.fprintf f "@[<1>PAYOFF@ @[<1>%a@]@]@ "
- (Formula.fprint_real(* _nobra 0 *)) payoff;
+ (Formula.fprint_real ~unicode:false (* _nobra 0 *)) payoff;
if moves <> [] then
Format.fprintf f "@[<1>MOVES@ %a@]@ "
(Aux.fprint_sep_list ";" (fun f ({
@@ -185,11 +185,11 @@
if !equational_def_style then
Format.fprintf ppf "@[<1>REL@ %s@,(@[<1>%a@])@ =@ @[<1>%a@]"
drel (Aux.fprint_sep_list "," Format.pp_print_string) args
- Formula.fprint body
+ (Formula.fprint ~unicode:false) body
else
Format.fprintf ppf "@[<1>REL@ %s@,(@[<1>%a@])@ {@,@[<1>%a@,@]}"
drel (Aux.fprint_sep_list "," Format.pp_print_string) args
- Formula.fprint body;
+ (Formula.fprint ~unicode:false) body;
Format.fprintf ppf "@]@ ";
) defined_rels;
Format.fprintf ppf "@[<1>PLAYERS@ %a@]@ "
@@ -268,6 +268,7 @@
let add_def_rels struc rels = List.fold_left add_def_rel_single struc rels
let add_def_fun_single struc (f, v, def_re) =
+ LOG 1 "adding fun %s def %s" f (Formula.real_str def_re);
let elems = Structure.elements struc in
let asg e = AssignmentSet.FO (v, [(e, AssignmentSet.Any)]) in
let fval e = Solver.M.get_real_val ~asg:(asg e) def_re struc in
Modified: trunk/Toss/Arena/ContinuousRule.ml
===================================================================
--- trunk/Toss/Arena/ContinuousRule.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Arena/ContinuousRule.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -246,14 +246,16 @@
(DiscreteRule.fprint_full print_compiled) r.discrete;
if has_dynamics r then
Format.fprintf f "@ @[<hv>dynamics@ %a@]"
- (Formula.fprint_eqs ~diff:true) (List.sort Pervasives.compare r.dynamics);
+ (Formula.fprint_eqs ~unicode:false ~diff:true)
+ (List.sort Pervasives.compare r.dynamics);
if has_update r then
Format.fprintf f "@ @[<hv>update@ %a@]"
- (Formula.fprint_eqs ~diff:false) (List.sort Pervasives.compare r.update);
- if r.inv <> Formula.And [] then
- Format.fprintf f "@ @[<1>inv@ %a@]" Formula.fprint r.inv;
+ (Formula.fprint_eqs ~unicode:false ~diff:false)
+ (List.sort Pervasives.compare r.update);
+ if r.inv <> Formula.And [] then
+ Format.fprintf f "@ @[<1>inv@ %a@]" (Formula.fprint ~unicode:false) r.inv;
if r.post <> Formula.And [] then
- Format.fprintf f "@ @[<1>post@ %a@]" Formula.fprint r.post;
+ Format.fprintf f "@ @[<1>post@ %a@]" (Formula.fprint ~unicode:false) r.post;
Format.fprintf f "@]"
let fprint = fprint_full false
Modified: trunk/Toss/Arena/DiscreteRule.ml
===================================================================
--- trunk/Toss/Arena/DiscreteRule.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Arena/DiscreteRule.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -1185,7 +1185,8 @@
(Aux.fprint_sep_list "," matched) r.rule_s;
Format.fprintf f "@]";
if (fst r.pre <> Formula.And [] || snd r.pre <> []) then
- Format.fprintf f "@ @[<1>pre@ %a@]" Formula.fprint (fst r.pre);
+ Format.fprintf f "@ @[<1>pre@ %a@]"
+ (Formula.fprint ~unicode:false) (fst r.pre);
if (snd r.pre <> []) then
let before_str (name, b) = if b then name else "not " ^ name in
let before_s = String.concat ", " (List.map before_str (snd r.pre)) in
@@ -1310,7 +1311,7 @@
Format.fprintf f "@]") in
Format.fprintf f "@[<1>MATCH@ %a@ "
- (Formula.fprint_prec (-1)) r.match_formula;
+ (Formula.fprint_prec false (-1)) r.match_formula;
del_part ();
if del_elems <> [] || r.del_tuples <> []
then Format.fprintf f "@ ";
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Client/eval.html 2012-06-25 18:03:52 UTC (rev 1734)
@@ -156,15 +156,15 @@
<p>Relations:</p>
-<textarea id="relations" rows="3" cols="40">
-E(x, y) = &y = &x + 1
+<textarea id="relations" rows="3" cols="60">
+E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)
</textarea>
<p>Positions:</p>
-<textarea id="positions" rows="3" cols="40">
+<textarea id="positions" rows="3" cols="60">
:x(a) = &a;
-:y(a) = &a * (10 - &a) / 10
+:y(a) = &a · (10 - &a) / 10
</textarea>
<p>Elements: <input id="no-elems" type="text" size="4" value="15"></input>
Modified: trunk/Toss/Formula/Formula.ml
===================================================================
--- trunk/Toss/Formula/Formula.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/Formula.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -86,13 +86,13 @@
type sign_op = EQZero | GZero | LZero | GEQZero | LEQZero | NEQZero
(* Print a sign_op as string. *)
-let sign_op_str = function
+let sign_op_str ?(unicode=false) = function
| EQZero -> " = 0"
| GZero -> " > 0"
| LZero -> " < 0"
- | GEQZero -> " >= 0"
- | LEQZero -> " =< 0"
- | NEQZero -> " <> 0"
+ | GEQZero -> if unicode then " ≥ 0" else " >= 0"
+ | LEQZero -> if unicode then " ≤ 0" else " =< 0"
+ | NEQZero -> if unicode then " ≠ 0" else " <> 0"
(* This type describes formulas of relational logic with equality.
@@ -165,111 +165,127 @@
let fprint_var f v = Format.pp_print_string f (var_str v)
(* Bracket-savvy encodings: 0 or, 1 and, 2 not ex all *)
-let rec fprint_prec prec f = function
+let rec fprint_prec unicode prec f = function
| Rel (s, vars) ->
Format.fprintf f "%s(%a)" s
(Aux.fprint_sep_list "," fprint_var) (Array.to_list vars)
| Eq (x, y) -> Format.fprintf f "%s = %s" (var_str x) (var_str y)
- | In (x, y) -> Format.fprintf f "%s in %s" (var_str x) (var_str y)
+ | In (x, y) ->
+ if unicode then
+ Format.fprintf f "%s ∈ %s" (var_str x) (var_str y)
+ else
+ Format.fprintf f "%s in %s" (var_str x) (var_str y)
| SO (r, vars) ->
Format.fprintf f "%a(%a)" fprint_var r
(Aux.fprint_sep_list "," fprint_var) (Array.to_list vars)
| RealExpr (p, s) ->
- Format.fprintf f "@[(%a%s)@]" (fprint_real_prec 0) p (sign_op_str s)
+ Format.fprintf f "@[(%a%s)@]" (fprint_real_prec unicode 0)
+ p (sign_op_str ~unicode s)
| Not phi ->
- let lb, rb =
- if prec > 2 then "(", ")" else "", "" in
- Format.fprintf f "@[<1>%snot@ %a%s@]" lb (fprint_prec 2) phi rb
+ let lb, rb = if prec > 2 then "(", ")" else "", "" in
+ if unicode then
+ Format.fprintf f "@[<1>%s¬@ %a%s@]" lb (fprint_prec unicode 2) phi rb
+ else
+ Format.fprintf f "@[<1>%snot@ %a%s@]" lb (fprint_prec unicode 2) phi rb
| And [] -> Format.fprintf f "true"
| Or [] -> Format.fprintf f "false"
- | And [phi] -> fprint_prec prec f phi
- | Or [phi] -> fprint_prec prec f phi
+ | And [phi] -> fprint_prec unicode prec f phi
+ | Or [phi] -> fprint_prec unicode prec f phi
| And flist ->
let lb, rb = if prec = 0 || prec > 1 then "(", ")" else "", "" in
+ let sep = if unicode then " ∧" else " and" in
Format.fprintf f "@[<1>%s%a%s@]" lb
- (Aux.fprint_sep_list " and" (fprint_prec 1)) flist rb
+ (Aux.fprint_sep_list sep (fprint_prec unicode 1)) flist rb
| Or flist ->
let lb, rb = if prec > 0 then "(", ")" else "", "" in
+ let sep = if unicode then " ∨" else " or" in
Format.fprintf f "@[<1>%s%a%s@]" lb
- (Aux.fprint_sep_list " or" (fprint_prec 0)) flist rb
+ (Aux.fprint_sep_list sep (fprint_prec unicode 0)) flist rb
| Ex (x, phi) ->
let lb, rb = if prec > 2 then "(", ")" else "", "" in
- Format.fprintf f "@[<1>%sex@ %a@ %a%s@]" lb
- (Aux.fprint_sep_list "," fprint_var) x (fprint_prec 2) phi rb
+ let quant = if unicode then "∃" else "ex" in
+ Format.fprintf f "@[<1>%s%s@ %a@ %a%s@]" lb quant
+ (Aux.fprint_sep_list "," fprint_var) x (fprint_prec unicode 2) phi rb
| All (x, phi) ->
let lb, rb = if prec > 2 then "(", ")" else "", "" in
- Format.fprintf f "@[<1>%sall@ %a@ %a%s@]" lb
- (Aux.fprint_sep_list "," fprint_var) x (fprint_prec 2) phi rb
+ let quant = if unicode then "∀" else "all" in
+ Format.fprintf f "@[<1>%s%s@ %a@ %a%s@]" lb quant
+ (Aux.fprint_sep_list "," fprint_var) x (fprint_prec unicode 2) phi rb
| Lfp (r, vs, fpphi) ->
Format.fprintf f "@[<1>lfp %a(%a) = (%a)@]" fprint_var r
(Aux.fprint_sep_list "," fprint_var) (Array.to_list vs)
- (fprint_prec prec) fpphi
+ (fprint_prec unicode prec) fpphi
| Gfp (r, vs, fpphi) ->
Format.fprintf f "@[<1>gfp %a(%a) = (%a)@]" fprint_var r
(Aux.fprint_sep_list "," fprint_var) (Array.to_list vs)
- (fprint_prec prec) fpphi
+ (fprint_prec unicode prec) fpphi
| Let (r, args, rphi, inphi) ->
Format.fprintf f "@[<1>let %s(%s) = %a in@]@ %a" r (String.concat ", " args)
- (fprint_prec prec) rphi (fprint_prec prec) inphi
+ (fprint_prec unicode prec) rphi (fprint_prec unicode prec) inphi
(* Bracket-savvy precedences: 0 +, 2 * *)
-and fprint_real_prec prec f = function
+and fprint_real_prec unicode prec f = function
| RVar s -> Format.fprintf f "%s" s
| Const fl -> Format.fprintf f "%F" fl
| Plus (r1, Times (Const fl, r2)) when fl = -1. -> (* r1 - r2 short *)
let lb, rb = if prec > 0 then "(", ")" else "", "" in
Format.fprintf f "@[<1>%s%a@ -@ %a%s@]" lb
- (fprint_real_prec 0) r1 (fprint_real_prec 1) r2 rb
+ (fprint_real_prec unicode 0) r1 (fprint_real_prec unicode 1) r2 rb
| Times (r1, r2) ->
- let lb, rb =
- if prec > 2 then "(", ")" else "", "" in
- Format.fprintf f "@[<1>%s%a@ *@ %a%s@]" lb
- (fprint_real_prec 2) r1 (fprint_real_prec 2) r2 rb
+ let lb, rb = if prec > 2 then "(", ")" else "", "" in
+ let m = if unicode then "·" else "*" in
+ Format.fprintf f "@[<1>%s%a@ %s@ %a%s@]" lb
+ (fprint_real_prec unicode 2) r1 m (fprint_real_prec unicode 2) r2 rb
| Plus (r1, r2) ->
let lb, rb = if prec > 0 then "(", ")" else "", "" in
Format.fprintf f "@[<1>%s%a@ +@ %a%s@]" lb
- (fprint_real_prec 0) r1 (fprint_real_prec 0) r2 rb
+ (fprint_real_prec unicode 0) r1 (fprint_real_prec unicode 0) r2 rb
| Pow (r1, r2) ->
let lb, rb = if prec > 2 then "(", ")" else "", "" in
Format.fprintf f "@[<1>%s%a^%a%s@]" lb
- (fprint_real_prec 4) r1 (fprint_real_prec 4) r2 rb
+ (fprint_real_prec unicode 4) r1 (fprint_real_prec unicode 4) r2 rb
| Fun (s, v) -> Format.fprintf f ":%s(%s)" s (var_str v)
- | Char phi -> Format.fprintf f "@[<1>:(@,%a@,)@]" (fprint_prec 0) phi
+ | Char phi -> Format.fprintf f "@[<1>:(@,%a@,)@]" (fprint_prec unicode 0) phi
| Sum (vl, phi, r) ->
- Format.fprintf f "@[<1>Sum@ (@,%a@ |@ %a@ :@ %a@,)@]"
- (Aux.fprint_sep_list "," fprint_var) vl (fprint_prec 0) phi
- (fprint_real_prec 0) r
+ let sum = if unicode then "∑" else "Sum" in
+ Format.fprintf f "@[<1>%s@ (@,%a@ |@ %a@ :@ %a@,)@]" sum
+ (Aux.fprint_sep_list "," fprint_var) vl (fprint_prec unicode 0) phi
+ (fprint_real_prec unicode 0) r
| RLet (v, lre, inre) ->
Format.fprintf f "@[<1>let %s = %a in %a@]" v
- (fprint_real_prec prec) lre (fprint_real_prec prec) inre
+ (fprint_real_prec unicode prec) lre (fprint_real_prec unicode prec) inre
-let fprint f phi = fprint_prec 0 f phi
-let fprint_real f phi = fprint_real_prec 0 f phi
-let sprint phi = AuxIO.sprint_of_fprint fprint phi
-let print phi = AuxIO.print_of_fprint fprint phi
-let print_real r = AuxIO.print_of_fprint fprint_real r
-let sprint_real r = AuxIO.sprint_of_fprint fprint_real r
-let str f = sprint f
-let real_str r = sprint_real r
+let fprint ?(unicode=false) f phi = fprint_prec unicode 0 f phi
+let fprint_real ?(unicode=false) f phi = fprint_real_prec unicode 0 f phi
+let sprint ?(unicode=false) phi =
+ AuxIO.sprint_of_fprint (fprint_prec unicode 0) phi
+let print ?(unicode=false) phi =
+ AuxIO.print_of_fprint (fprint_prec unicode 0) phi
+let print_real ?(unicode=false) r =
+ AuxIO.print_of_fprint (fprint_real_prec unicode 0) r
+let sprint_real ?(unicode=false) r =
+ AuxIO.sprint_of_fprint (fprint_real_prec unicode 0) r
+let str ?(unicode=false) f = sprint ~unicode f
+let real_str ?(unicode=false) r = sprint_real ~unicode r
type eq_sys = ((string * string) * real_expr) list
(* Print an equation system. *)
-let fprint_eqs ?(diff=false) ppf eqs =
+let fprint_eqs ?(unicode=false) ?(diff=false) ppf eqs =
let sing ppf ((f, a), t) =
let mid_str = if diff then "'" else "" in
Format.fprintf ppf "@[<1>:%s(%s)%s@ =@ @[<1>%a@]@]"
- f a mid_str fprint_real t in
+ f a mid_str (fprint_real ~unicode) t in
Format.fprintf ppf "@[<hv>%a@]" (Aux.fprint_sep_list ";" sing) eqs
(* Print an equation system as a string. *)
-let eq_str ?(diff=false) eqs =
+let eq_str ?(unicode=false) ?(diff=false) eqs =
let sing_str ((f, a), t) =
let mid_str = if diff then "' = " else " = " in
- let l_str = real_str (Fun (f, `FO a)) in
- let r_str = real_str t in
+ let l_str = real_str ~unicode (Fun (f, `FO a)) in
+ let r_str = real_str ~unicode t in
l_str ^ mid_str ^ r_str in
" " ^ (String.concat ";\n " (List.map sing_str eqs))
Modified: trunk/Toss/Formula/Formula.mli
===================================================================
--- trunk/Toss/Formula/Formula.mli 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/Formula.mli 2012-06-25 18:03:52 UTC (rev 1734)
@@ -42,7 +42,7 @@
type sign_op = EQZero | GZero | LZero | GEQZero | LEQZero | NEQZero
(** Print a sign_op as string. *)
-val sign_op_str : sign_op -> string
+val sign_op_str : ?unicode: bool -> sign_op -> string
(** This type describes formulas of relational logic with equality.
@@ -96,24 +96,25 @@
val var_list_str: [< var] list -> string
(** Print a formula as a string. *)
-val str : formula -> string
+val str : ?unicode: bool -> formula -> string
val mona_str : formula -> string
-val print : formula -> unit
-val sprint : formula -> string
-val fprint : Format.formatter -> formula -> unit
+val print : ?unicode: bool -> formula -> unit
+val sprint : ?unicode: bool -> formula -> string
+val fprint : ?unicode: bool -> Format.formatter -> formula -> unit
(** Print a real_expr as a string. *)
-val real_str : real_expr -> string
-val print_real : real_expr -> unit
-val sprint_real : real_expr -> string
-val fprint_real : Format.formatter -> real_expr -> unit
+val real_str : ?unicode: bool -> real_expr -> string
+val print_real : ?unicode: bool -> real_expr -> unit
+val sprint_real : ?unicode: bool -> real_expr -> string
+val fprint_real : ?unicode: bool -> Format.formatter -> real_expr -> unit
-val fprint_prec : int -> Format.formatter -> formula -> unit
-val fprint_real_prec : int -> Format.formatter -> real_expr -> unit
+val fprint_prec : bool -> int -> Format.formatter -> formula -> unit
+val fprint_real_prec : bool -> int -> Format.formatter -> real_expr -> unit
(** Print an equation system. *)
-val fprint_eqs : ?diff : bool -> Format.formatter -> eq_sys -> unit
-val eq_str : ?diff:bool -> eq_sys -> string
+val fprint_eqs : ?unicode: bool -> ?diff: bool ->
+ Format.formatter -> eq_sys -> unit
+val eq_str : ?unicode: bool -> ?diff: bool -> eq_sys -> string
(** {2 Formula syntax check} *)
Modified: trunk/Toss/Formula/FormulaParser.mly
===================================================================
--- trunk/Toss/Formula/FormulaParser.mly 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/FormulaParser.mly 2012-06-25 18:03:52 UTC (rev 1734)
@@ -62,7 +62,7 @@
{ Formula.Sum ($3, $5, $7) }
| COLON OPEN formula_expr CLOSE { Char (Formula.flatten $3) }
| OPEN real_expr CLOSE { $2 }
- | COLON LET_CMD COLON v = ID EQ def = real_expr IN_MOD re = real_expr
+ | LET_CMD COLON v = ID EQ def = real_expr IN_MOD re = real_expr
{ RLet (":" ^ v, def, re) }
real_ineq:
@@ -125,8 +125,11 @@
| formula_expr MID formula_expr { Or [$1; $3] }
| formula_expr XOR formula_expr { And [Or [$1; $3]; Not (And [$1; $3])] }
| formula_expr RARR formula_expr { Or [Not ($1); $3] }
+ | formula_expr RDARR formula_expr { Or [Not ($1); $3] }
| formula_expr LRARR formula_expr
{ Or [And [Not ($1); Not ($3)]; And [$1; $3]] }
+ | formula_expr LRDARR formula_expr
+ { Or [And [Not ($1); Not ($3)]; And [$1; $3]] }
| OPEN formula_expr CLOSE { $2 }
| LET_CMD rel = ID args = delimited (OPEN, separated_list (COMMA, ID), CLOSE)
EQ body = formula_expr IN_MOD phi = formula_expr
Modified: trunk/Toss/Formula/FormulaSubstTest.ml
===================================================================
--- trunk/Toss/Formula/FormulaSubstTest.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/FormulaSubstTest.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -110,7 +110,7 @@
"let Next(x, y) = E(x, y) and R(y) in R(a)")
"lfp R(a) = (P(a) or ex y (E(a, y) and y in R))";
exp_eq "let R(x) = P(x) in :(R(a)) > 1" ":(P(a)) > 1";
- exp_eq "(:let :x = 3 in :x) > 1" "3 > 1";
+ exp_eq "(let :x = 3 in :x) > 1" "3 > 1";
);
"fv" >::
Modified: trunk/Toss/Formula/FormulaTest.ml
===================================================================
--- trunk/Toss/Formula/FormulaTest.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/FormulaTest.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -55,6 +55,12 @@
test_pp "all y (R(x, y) or not P(y))";
test_pp "(:x - (:y + :z) < 0)";
test_pp "(:x - :y + :z < 0)";
+
+ let test_pp_unicode f_s = assert_equal ~printer:(fun x -> x) f_s
+ (str ~unicode:true (flatten (formula_of_string f_s))) in
+ test_pp_unicode "∃ y (R(x, y) ∧ P(y))";
+ test_pp_unicode "∀ y (R(x, y) ∨ ¬ P(y))";
+ test_pp_unicode "(∑ (x | P(x) : 2. · :f(x)) ≥ 0)";
);
"rk4" >::
Modified: trunk/Toss/Formula/Lexer.mll
===================================================================
--- trunk/Toss/Formula/Lexer.mll 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/Lexer.mll 2012-06-25 18:03:52 UTC (rev 1734)
@@ -152,24 +152,33 @@
| '&' { AMP }
| '|' { MID }
| "Sum" { SUM }
+ | "∑" { SUM }
| '+' { PLUS }
| '-' { MINUS }
+ | "−" { MINUS }
| '*' { TIMES }
+ | "·" { TIMES }
+ | "×" { TIMES }
| '/' { DIV }
| '^' { POW }
| '>' { GR }
| ">=" { GREQ }
+ | "≥" { GREQ }
| '<' { LT }
| "=<" { EQLT }
+ | "≤" { EQLT }
| '=' { EQ }
| "<>" { LTGR }
| "!=" { NEQ }
+ | "≠" { NEQ }
| "!" { NOT }
| "<-" { LARR }
| "<=" { LDARR }
| "->" { RARR }
| "=>" { RDARR }
+ | "⇒" { RDARR }
| "<->" { LRARR }
+ | "⇔" { LRDARR }
| "<=>" { LRDARR }
| "--" { INTERV }
| '(' { OPEN }
@@ -180,12 +189,20 @@
| ']' { CLOSESQ }
| "in" { IN_MOD }
| "and" { AND }
+ | "∧" { AND }
| "or" { OR }
+ | "∨" { OR }
| "xor" { XOR }
+ | "⊕" { XOR }
| "not" { NOT }
+ | "¬" { NOT }
| "ex" { EX }
+ | "\\E" { EX }
| "exists" { EX }
+ | "∃" { EX }
| "all" { ALL }
+ | "\\A" { ALL }
+ | "∀" { ALL }
| "tc" { TC }
| "TC" { TC }
| "with" { WITH }
Modified: trunk/Toss/Formula/Tokens.mly
===================================================================
--- trunk/Toss/Formula/Tokens.mly 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Formula/Tokens.mly 2012-06-25 18:03:52 UTC (rev 1734)
@@ -14,7 +14,7 @@
%token CURRENT UNIVERSAL RULE_SPEC STATE_SPEC CLASS LFP GFP EOF
/* List in order of increasing precedence. */
-%nonassoc LET_CMD
+%nonassoc LET_CMD IN_MOD
%nonassoc COND
%left LARR
%right RARR
@@ -26,7 +26,7 @@
%left OR
%left AND
%left COMMA
-%nonassoc EQ IN_MOD
+%nonassoc EQ
%left NOT EX ALL
%%
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Solver/Solver.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -507,6 +507,10 @@
(Array.of_list (List.map var_str all_vs)) [tp] in
acc +. (get_real_val solver tp_asg r struc) in
List.fold_left add_val 0. tps
+ | RLet _ ->
+ let e = FormulaSubst.expand_real_expr expr in
+ LOG 1 "get_real_val: expanded to: %s" (real_str e);
+ get_real_val solver asg e struc
| _ ->
check_timeout "Solver.get_real_val.other";
let rec get_rval = function
@@ -579,8 +583,8 @@
let check struc phi = check_cache (
check solver ~formula:(register_formula_s struc solver phi) struc)
- let get_real_val ?asg re struc = check_cache (
- check_cache (get_real_val_cache ?asg solver struc re))
+ let get_real_val ?asg re struc =
+ check_cache (get_real_val_cache ?asg solver struc re)
let set_timeout t = timeout := t
let clear_timeout () = timeout := (fun () -> false);
Modified: trunk/Toss/Solver/StructureTest.ml
===================================================================
--- trunk/Toss/Solver/StructureTest.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Solver/StructureTest.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -373,10 +373,7 @@
" in
let (_, st) = struc_from_trs s in
assert_equal ~printer:(fun x -> x)
- ("[F0_0\\, F1_0\\, F2, F3, F4, F5 | R {(F0_0\\, F1_0\\); (F1_0\\, F2);"^
- " (F2, F3); (F3, F4); (F4, F5)} | x {F0_0\\->0., F1_0\\->1.," ^
- " F2->2., F3->3., F4->4., F5->5.}; y {F0_0\\->0., F1_0\\->1.," ^
- " F2->2., F3->3., F4->4., F5->5.}]") (Structure.str st);
+ ("[F0_0\\[ @: Tnatural_number], F1_0\\[ @: Tnatural_number], F2[ @: Tnatural_number], F3[ @: Tnatural_number], F4[ @: Tnatural_number], F5[ @: Tnatural_number] | R {(F0_0\\[ @: Tnatural_number], F1_0\\[ @: Tnatural_number]); (F1_0\\[ @: Tnatural_number], F2[ @: Tnatural_number]); (F2[ @: Tnatural_number], F3[ @: Tnatural_number]); (F3[ @: Tnatural_number], F4[ @: Tnatural_number]); (F4[ @: Tnatural_number], F5[ @: Tnatural_number])} | x {F0_0\\[ @: Tnatural_number]->0., F1_0\\[ @: Tnatural_number]->1., F2[ @: Tnatural_number]->2., F3[ @: Tnatural_number]->3., F4[ @: Tnatural_number]->4., F5[ @: Tnatural_number]->5.}; y {F0_0\\[ @: Tnatural_number]->0., F1_0\\[ @: Tnatural_number]->1., F2[ @: Tnatural_number]->2., F3[ @: Tnatural_number]->3., F4[ @: Tnatural_number]->4., F5[ @: Tnatural_number]->5.}]") (Structure.str st);
);
"sprint simple" >::
Modified: trunk/Toss/Term/Rewriting.ml
===================================================================
--- trunk/Toss/Term/Rewriting.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Term/Rewriting.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -55,10 +55,6 @@
| (Term (n1, _, _), Term (n2, _, [||])) when (n1 = n2) ->
raise NO_MATCH (* used cons vs. functional cons *)
| (Term (n1, _, _), Term (n2, _, _)) when (n1 = n2) ->
- (*Printf.printf "check_clash_match: [1] %s(%d) %s(%d): %a -- %a\n"
- n1 (Array.length a1) n2 (Array.length a2)
- (Aux.array_fprint (fun o t->output_string o (Coding.term_to_string t))) a1
- (Aux.array_fprint (fun o t->output_string o (Coding.term_to_string t))) a2;*)
failwith "curried functions not supported (yet?)"
| (Term (n1, _, _), Term (n2, _, _)) -> (* when (n2.[0] != 'F') *)
raise NO_MATCH
@@ -80,15 +76,12 @@
raise NO_MATCH (* non-0-arg fun and functional term *)
| _ -> failwith "rewriting not this function"
-(* Merging substitutions according to variable names. FIXME: perhaps
- use [Term.combine_mgu_sb], otherwise streamline. *)
+(* Merging substitutions according to variable names.
+ FIXME: perhaps use [Term.combine_mgu_sb], otherwise streamline.
+ NOTE: we assume that the rules are left-linear (checked above). *)
let merge_substs substs =
let merged_substs = Aux.collect substs in
- let mkcm b = (* if List.length b <> 1 then failwith "cm" else *)
- snd (List.hd b) in
- let make_cm (a, b) = (false, (a, mkcm b)) in
- let (clashes, substs) = List.split (map make_cm merged_substs) in
- (exists (fun x -> x) clashes, substs)
+ (false, List.map (fun (a, b) -> (a, snd (List.hd b))) merged_substs)
(* The final function for applying a rewrite rule with clash checking and
@@ -101,7 +94,7 @@
if merge_clash then term
else
let result = Coding.apply_s merged_substs right in
- (* For now, we copy over the supertypes fro the original, as
+ (* For now, we copy over the supertypes from the original, as
the old rewriting ignores supertypes. *)
match term, result with
| Term (_, oldtys, _), Term (n, _, args) ->
@@ -179,21 +172,21 @@
else
let (steps, res) = basic_normalise rr rr_spec m rewritten in
(steps + steps_c + 1, res)
- | Term (n, t, a) when n.[0] = 'F' ->
- (let (prev_steps, prev_res) = basic_normalise_arr rr rr_spec m a in
- let nmlized = Term (n, t, prev_res) in
- let found= try Some (TermHashtbl.find m nmlized) with Not_found -> None in
- match found with Some (r) -> (prev_steps, r) | None ->
- let rewritten = rr nmlized in
- if rewritten = nmlized then (prev_steps, rewritten) else
- let (steps, res) = basic_normalise rr rr_spec m rewritten in
- let memory_size = TermHashtbl.length m in
- let threshold = (memory_size / cMEM_USE_INCREASE_FACTOR) + 1 in
- let size_addon = min (size_up_to 256 nmlized) threshold in
- if steps > threshold + size_addon then
- (TermHashtbl.add m nmlized res; (0, res))
- else (prev_steps + steps + 1, res)
- )
+ | Term (n, t, a) when n.[0] = 'F' -> (
+ let (prev_steps, prev_res) = basic_normalise_arr rr rr_spec m a in
+ let nmlized = Term (n, t, prev_res) in
+ let found= try Some (TermHashtbl.find m nmlized) with Not_found -> None in
+ match found with Some (r) -> (prev_steps, r) | None -> (
+ let rewritten = rr nmlized in
+ if rewritten = nmlized then (prev_steps, nmlized) else (
+ let (steps, res) = basic_normalise rr rr_spec m rewritten in
+ let memory_size = TermHashtbl.length m in
+ let threshold = (memory_size / cMEM_USE_INCREASE_FACTOR) + 1 in
+ let size_addon = min (size_up_to 256 nmlized) threshold in
+ if steps > threshold + size_addon then
+ (TermHashtbl.add m nmlized res; (0, res))
+ else (prev_steps + steps + 1, res)
+ )))
| Term (n, t, a) ->
let (steps, res) = basic_normalise_arr rr rr_spec m a in
(steps, Term (n, t, res))
Modified: trunk/Toss/Term/RewritingTest.ml
===================================================================
--- trunk/Toss/Term/RewritingTest.ml 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Term/RewritingTest.ml 2012-06-25 18:03:52 UTC (rev 1734)
@@ -51,7 +51,7 @@
let t3 = Term ("Fand", [|boolean_tp|], [|var_x_b; t1|]) in
test_ne rrs "Fand[ @: Tboolean] (@V [x @: Tboolean @: 0 ], Ftrue[ @: Tboolean] )" t3;
let t4 = Term (if_then_else_name, [|boolean_tp|], [|var_x_b; t1; t1|]) in
- test_ne rrs ("Fif_\?_then_\?_else_\?[ @: Tboolean] (@V [x @: Tboolean @: 0 ], Fand[ @: Tboolean] (Ftrue[ @: Tboolean], Ftrue[ @: Tboolean] ), Fand[ @: Tboolean] (Ftrue[ @: Tboolean], Ftrue[ @: Tboolean] ) )") t4;
+ test_ne rrs ("Fif_\\?_then_\\?_else_\\?[ @: Tboolean] (@V [x @: Tboolean @: 0 ], Fand[ @: Tboolean] (Ftrue[ @: Tboolean], Ftrue[ @: Tboolean] ), Fand[ @: Tboolean] (Ftrue[ @: Tboolean], Ftrue[ @: Tboolean] ) )") t4;
let t5 = Term ("Ckot", [|char_tp|], [|var_x_b; t1; t1|]) in
test_ne rrs "Ckot[ @: Tchar] (@V [x @: Tboolean @: 0 ], Ftrue[ @: Tboolean], Ftrue[ @: Tboolean] )" t5;
);
Modified: trunk/Toss/Term/tests/sasha_basic.log
===================================================================
--- trunk/Toss/Term/tests/sasha_basic.log 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Term/tests/sasha_basic.log 2012-06-25 18:03:52 UTC (rev 1734)
@@ -255,7 +255,7 @@
hanoi (0 , startPeg , goalPeg) => []
New rewrite rule defined.
-hanoi (noDiscs , startPeg , goalPeg) => hanoi (noDiscs - 1 , startPeg , remainingPeg (startPeg , goalPeg) ) + [ (startPeg , goalPeg) ] + hanoi (noDiscs - 1 , remainingPeg (startPeg , goalPeg) , goalPeg)
+hanoi (noDiscs , startPeg , goalPeg) => hanoi (noDiscs - 1 , startPeg , remainingPeg (startPeg , goalPeg) ) + ( [ (startPeg , goalPeg) ] + hanoi (noDiscs - 1 , remainingPeg (startPeg , goalPeg) , goalPeg) )
Closed context.
Modified: trunk/Toss/Term/tests/sasha_basic.trs
===================================================================
--- trunk/Toss/Term/tests/sasha_basic.trs 2012-06-25 14:30:21 UTC (rev 1733)
+++ trunk/Toss/Term/tests/sasha_basic.trs 2012-06-25 18:03:52 UTC (rev 17...
[truncated message content] |
|
From: <ab...@us...> - 2012-06-27 17:33:16
|
Revision: 1735
http://toss.svn.sourceforge.net/toss/?rev=1735&view=rev
Author: abuzaid
Date: 2012-06-27 17:33:04 +0000 (Wed, 27 Jun 2012)
Log Message:
-----------
Evaluation of SO-Formulae by reduction to SAT
Modified Paths:
--------------
trunk/Toss/Client/JsEval.ml
trunk/Toss/Client/eval.html
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/Formula/BoolFormula.mli
trunk/Toss/Formula/Formula.ml
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/Solver.mli
trunk/Toss/Solver/SolverTest.ml
Added Paths:
-----------
trunk/Toss/Formula/myTest.ml
Modified: trunk/Toss/Client/JsEval.ml
===================================================================
--- trunk/Toss/Client/JsEval.ml 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Client/JsEval.ml 2012-06-27 17:33:04 UTC (rev 1735)
@@ -43,13 +43,27 @@
(* The Formula evaluation and registration in JS. *)
let js_eval phi struc =
let (phi, struc) = (Js.to_string phi, Js.to_string struc) in
- LOG 0 "Evaluation of %s on %s" phi struc;
let (f, struc) = (formula_of_string phi, structure_of_string struc) in
Js.string (AssignmentSet.named_str struc (Solver.M.evaluate struc f))
-
+
+
+(*
+let js_eval_so phi struc =
+ let (phi, struc) = (Js.to_string phi, Js.to_string struc) in
+ let (f, struc) = (formula_of_string phi, structure_of_string struc) in
+ let qbf = (Solver.so_to_qbf struc f) in
+ let sat = (Solver.elim_quant_naiv qbf) in
+ LOG 0 "Formula: %s" (Formula.str f);
+ LOG 0 "QBF Formula: %s" (BoolFormula.qbf_str qbf);
+ LOG 0 "SAT Formula: %s" (BoolFormula.str sat);
+ Js.string (AssignmentSet.named_str struc (Solver.eval_so struc f))
+*)
+
let _ = set_handle "eval" js_eval
+
+
(* Drawing the structure. *)
let draw_struc_js struc_s =
let st = structure_of_string (Js.to_string struc_s) in
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Client/eval.html 2012-06-27 17:33:04 UTC (rev 1735)
@@ -59,6 +59,7 @@
})
}
+
function canvasCoords (event) { // From stackoverflow.com
var totalOffsetX = 0;
var totalOffsetY = 0;
@@ -128,9 +129,9 @@
function example_3col () {
document.getElementById ("formula").value =
- "ex R, G, B all x, y ( \n (x in R or x in G or x in B) and (" +
- "\n E(x,y) -> not ( (x in R and y in R) " +
- "\n or (x in G and y in G) or (x in B and y in B) ) ) )";
+ "ex |R, |G, |B all x, y ( \n ( |R(x) or |G(x) or |B(x)) and (" +
+ "\n E(x,y) -> not ( ( |R(x) and |R(y)) " +
+ "\n or (|G(x) and |G(y)) or (|B(x) and |B(y)) ) ) )";
document.getElementById ("structure").value =
"[ | E { (a, b); (b, c); (c, a) } | " +
"\n x { a -> 1, b -> 2, c -> 3 }; " +
@@ -161,7 +162,6 @@
</textarea>
<p>Positions:</p>
-
<textarea id="positions" rows="3" cols="60">
:x(a) = &a;
:y(a) = &a · (10 - &a) / 10
Modified: trunk/Toss/Formula/BoolFormula.ml
===================================================================
--- trunk/Toss/Formula/BoolFormula.ml 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Formula/BoolFormula.ml 2012-06-27 17:33:04 UTC (rev 1735)
@@ -911,7 +911,7 @@
"(ex " ^ (String.concat ", " (List.map string_of_int vars)) ^
" " ^ qbf_str phi ^ ")"
| QAll (vars, phi) ->
- "(ex " ^ (String.concat ", " (List.map string_of_int vars)) ^
+ "(all " ^ (String.concat ", " (List.map string_of_int vars)) ^
" " ^ qbf_str phi ^ ")"
and qbf_list_str sep = function
@@ -1030,3 +1030,37 @@
let res = elim_quant_rec phi in
set_simplification 2;
res
+
+(* reduce QBF to SAT *)
+let sat_of_qbf phi = let ids, free_id = Hashtbl.create 7, ref 0 in
+ let get_id x = try Hashtbl.find ids x with Not_found ->
+ (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
+ let compute_id var asgn = get_id (var, asgn) in
+ (* reduce QBF to SAT (recursive helper)*)
+ let rec sat_of_qbf_rec phi asgn = (match phi with
+ | QVar v -> (try List.assoc v asgn with Not_found -> (BVar v))
+ | QAnd l ->
+ let resl = (Aux.unique_sorted (List.filter (fun x -> x <> BAnd []) (List.map (fun x -> sat_of_qbf_rec x asgn) l))) in
+ (try List.find (fun x -> x = BOr []) resl with Not_found -> (BAnd resl))
+ | QOr l ->
+ let resl = (Aux.unique_sorted (List.filter (fun x -> x <> BOr []) (List.map (fun x -> sat_of_qbf_rec x asgn) l))) in
+ (try List.find (fun x -> x = BAnd []) resl with Not_found -> (BOr resl))
+ | QNot f ->
+ let res = (sat_of_qbf_rec f asgn) in
+ if res = BAnd [] then BOr []
+ else if res = BOr [] then BAnd []
+ else BNot res
+ | QEx (var::vl, f) -> (sat_of_qbf_rec (QEx (vl, f)) ((var, (BVar (get_id (var, asgn))))::asgn))
+ | QEx ([], f) -> (sat_of_qbf_rec f asgn)
+ | QAll (var::tl, f) ->
+ let resl =
+ (Aux.unique_sorted (List.filter
+ (fun x -> x <> BAnd [])
+ [(sat_of_qbf_rec (QAll (tl, f)) ((var, BOr [])::asgn)); (sat_of_qbf_rec (QAll (tl, f)) ((var, BAnd [])::asgn))]
+ )) in
+ (try (List.find (fun x -> x = BOr []) resl) with Not_found -> (BAnd resl))
+ | QAll ([], f) -> (sat_of_qbf_rec f asgn)
+ )
+ in
+ (sat_of_qbf_rec phi [])
+
Modified: trunk/Toss/Formula/BoolFormula.mli
===================================================================
--- trunk/Toss/Formula/BoolFormula.mli 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Formula/BoolFormula.mli 2012-06-27 17:33:04 UTC (rev 1735)
@@ -95,3 +95,6 @@
(** Eliminating quantifiers from QBF formulas. *)
val elim_quant : qbf -> bool_formula
+
+(** Reduce QBF to SAT by elimination of quantifiers. *)
+val sat_of_qbf : qbf -> bool_formula
\ No newline at end of file
Modified: trunk/Toss/Formula/Formula.ml
===================================================================
--- trunk/Toss/Formula/Formula.ml 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Formula/Formula.ml 2012-06-27 17:33:04 UTC (rev 1735)
@@ -757,3 +757,4 @@
quit2 := max 1. (min 10000. q2);
(y5, h, h *. (min 5. (sf /. e4)))
)
+
Added: trunk/Toss/Formula/myTest.ml
===================================================================
--- trunk/Toss/Formula/myTest.ml (rev 0)
+++ trunk/Toss/Formula/myTest.ml 2012-06-27 17:33:04 UTC (rev 1735)
@@ -0,0 +1,6 @@
+open Formula
+
+let formula_of_string s =
+ FormulaParser.parse_formula Lexer.lex (Lexing.from_string s)
+
+Hashtbl.iter (fun v a -> Printf.printf "%s: %d" v a) so_arities (Hashtbl.create 10) (formula_of_string "Ex |R (All x |R(x))")
\ No newline at end of file
Property changes on: trunk/Toss/Formula/myTest.ml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Solver/Solver.ml 2012-06-27 17:33:04 UTC (rev 1735)
@@ -1,11 +1,13 @@
(* Solver for checking if formulas hold on structures. *)
+open BoolFormula
open Bitvector
open AssignmentSet
open Assignments
open Structure
open Formula
+
(* CACHE *)
type cachetbl =
@@ -393,10 +395,105 @@
Hashtbl.clear !re_cache_results;
List.iter (fun (p, r) -> Hashtbl.add !re_cache_results p r) !ok_re
+
+
+let so_to_qbf struc psi =
+ let ids, free_id = Hashtbl.create 7, ref 0 in
+ let get_id x = try Hashtbl.find ids x with Not_found ->
+ (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
+ let compute_id var args asgn = get_id (var, args, asgn) in
+ (* Reduce the Evaluation Problem of SO formulae to QBF *)
+let rec so_to_qbf_rec struc psi asgn = match psi with
+ | SO (rel, args) ->
+ let v = (compute_id (var_str rel) args asgn) in
+ (QVar v, [(var_str rel, v)])
+ | Rel (rel, va) ->
+ let args = Array.map (fun x -> try List.assoc x asgn with Not_found -> 0) va in
+ if (Structure.check_rel struc rel args) then (QAnd [], []) else (QOr [], [])
+ | Eq (var1, var2) -> if (try List.assoc var1 asgn with Not_found -> 0) = (try List.assoc var1 asgn with Not_found -> 0) then (QAnd [], []) else (QOr [], [])
+ | And phil ->
+ let resl = (List.map (fun phi -> (so_to_qbf_rec struc phi asgn)) phil) in
+ let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
+ let dictl = (List.map (snd) resl) in
+ (try
+ ((List.find (fun x -> x = QOr []) qphil), [])
+ with Not_found -> (
+ QAnd (List.filter (fun x -> x <> QAnd []) qphil), List.concat dictl
+ ))
+
+ | Or phil ->
+ let resl = (List.map (fun phi -> (so_to_qbf_rec struc phi asgn)) phil) in
+ let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
+ let dictl = (List.map (snd) resl) in
+ (try ((List.find (fun x -> x = QAnd []) qphil), []) with Not_found -> (QOr (List.filter (fun x -> x <> QOr []) qphil), List.concat dictl))
+ | Not phi -> let (qphi, dict) = so_to_qbf_rec struc phi asgn in
+ (if qphi = QOr [] then
+ (QAnd [], dict)
+ else if qphi = QAnd [] then
+ (QOr [], dict)
+ else
+ (QNot qphi, dict))
+ | Ex (vl, phi) ->
+ (
+ match vl with
+ | [] -> so_to_qbf_rec struc phi asgn
+ | var::tl ->
+ if is_fo var then
+ let asgn_list = List.map (fun x -> (Formula.to_fo var, x)::asgn) (Structure.elements struc) in
+ let res = (List.map (fun x -> so_to_qbf_rec struc (Ex (tl, phi)) x) asgn_list) in
+ let (qphil, dictl) = ((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res)in
+ (try ((List.find (fun x -> x = QAnd []) qphil), []) with Not_found -> (QOr (List.filter (fun x -> x <> QOr []) qphil), List.concat dictl))
+ else if is_so var then
+ let (qbf_phi, dict_phi) = (so_to_qbf_rec struc (Ex (tl, phi)) asgn) in
+ let rel_qbf_vars = Aux.unique_sorted (Aux.assoc_all (var_str var) dict_phi) in
+ if qbf_phi = QAnd [] then (QAnd [], [])
+ else if qbf_phi = QOr [] then (QOr [], [])
+ else if (rel_qbf_vars = []) then (qbf_phi, dict_phi)
+ else (QEx (rel_qbf_vars, qbf_phi), dict_phi)
+ else (* stub *)
+ (so_to_qbf_rec struc phi asgn)
+ )
+ | All (vl, phi) ->
+ (
+ match vl with
+ | [] -> so_to_qbf_rec struc phi asgn
+ | var::tl ->
+ if is_fo var then
+ let asgn_list = List.map (fun x -> (Formula.to_fo var, x)::asgn) (Structure.elements struc) in
+ let res = (List.map (fun x -> so_to_qbf_rec struc (All (tl, phi)) x) asgn_list) in
+ let (qphil, dictl) = ((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res)in
+ (try
+ ((List.find (fun x -> x = (QOr [])) qphil), [])
+ with Not_found ->
+ (QAnd (List.filter (fun x -> x <> (QAnd [])) qphil), List.concat dictl))
+ else if is_so var then
+ let (qbf_phi, dict_phi) = so_to_qbf_rec struc (All (tl, phi)) asgn in
+ let rel_qbf_vars = Aux.unique_sorted (Aux.assoc_all (var_str var) dict_phi) in
+ if qbf_phi = QAnd [] then (QAnd [], [])
+ else if qbf_phi = QOr [] then (QOr [], [])
+ else if (rel_qbf_vars = []) then (qbf_phi, dict_phi)
+ else (QAll (rel_qbf_vars, qbf_phi), dict_phi)
+ else (* stub *)
+ (so_to_qbf_rec struc phi asgn)
+ ) in
+fst (so_to_qbf_rec struc psi [])
+
+
+
+
(* Evaluation with second-order variables. *)
-let eval_so struc phi =
- Empty
-
+let eval_so struc phi =
+ let qbf = (so_to_qbf struc phi) in
+ let bf = (BoolFormula.sat_of_qbf qbf) in
+ let cnf = (BoolFormula.convert bf) in
+ LOG 0 "QBF:";
+ LOG 0 "%s" (BoolFormula.qbf_str qbf);
+ LOG 0 "BF:";
+ LOG 0 "%s" (BoolFormula.str bf);
+ LOG 0 "CNF:";
+ LOG 0 "%s" (Sat.cnf_str cnf);
+ if (Sat.is_sat cnf) then Any else Empty
+
(* Eval with very basic caching. *)
let eval_m struc phi =
if phi = And [] then Any else (
Modified: trunk/Toss/Solver/Solver.mli
===================================================================
--- trunk/Toss/Solver/Solver.mli 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Solver/Solver.mli 2012-06-27 17:33:04 UTC (rev 1735)
@@ -2,7 +2,6 @@
(** {1 Interface} *)
-
(** Interface to the solver. *)
module M : sig
(** Check the formula on the structure. *)
@@ -31,7 +30,8 @@
val set_timeout : (unit -> bool) -> unit
(** Clear timeout function. *)
- val clear_timeout : unit -> unit
+ val clear_timeout : unit -> unit
+
end
Modified: trunk/Toss/Solver/SolverTest.ml
===================================================================
--- trunk/Toss/Solver/SolverTest.ml 2012-06-25 18:03:52 UTC (rev 1734)
+++ trunk/Toss/Solver/SolverTest.ml 2012-06-27 17:33:04 UTC (rev 1735)
@@ -34,7 +34,7 @@
let tests = "Solver" >::: [
- "eval: first-order quantifier free" >::
+ "eval: first-order quantifier free" >::
(fun () ->
eval_eq "[ | P { (a1) }; R:1 {} | ]" "P(x0)" "{ x0->1 }";
eval_eq "[ | P:1 {}; R { (a1) } | ]" "P(x0)" "{}";
@@ -165,13 +165,41 @@
"{ z->1, z->2, z->3 }";
);
- "eval: second-order" >::
+ "eval: second-order T" >::
(fun () ->
- eval_eq "[ a, b | T { a } | ]"
- "ex |R all x, y (|R (x, y) <-> (T(x) and not T(y)))"
- "T";
+ let formula = "all |Q ex |R all x, y (|R (x, y) <-> (|Q(x) and not T(y)))" in
+ let struc = "[ a, b | T { a } | ]" in
+ (
+ eval_eq struc
+ formula
+ "T";
+ )
);
-
+
+ "eval: second-order F" >::
+ (fun () ->
+ let formula = "ex |R all |Q all x (not (|R(x) and |Q(x)) and (|R(x) or |Q(x)))" in
+ let struc = "[ a, b | T { a } | ]" in
+ (
+ eval_eq struc
+ formula
+ "{}";
+ )
+ );
+(*
+ "convert: eval second-order to QBF" >::
+ (fun () ->(
+ print_endline (Formula.str (formula_of_string "ex |V all |Q ex |R all x, y (T(x) or |R (x, y))"));
+ print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "ex |R all x, y (T(x) or |R (x, y))")));
+
+ print_endline (Formula.str (formula_of_string "all |Q all x, y (T(x) or Q(y) or (x = y))"));
+ print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "all |Q all x, y (T(x) or Q(y) or (x = y))")));
+
+ print_endline (Formula.str (formula_of_string "ex x all y ((T(x) and T(y)) -> x = y)"));
+ print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "ex x all y ((T(x) and T(y)) -> x = y)")));
+ )
+ );
+*)
"eval: game heuristic tests" >::
(fun () ->
let heur_phi = "(((R(v, w) and R(w, x) and R(x, y) and R(y, z)) or
@@ -247,6 +275,7 @@
let bigtests = "SolverBig" >::: [
+(*
"eval: bigger tc tests" >::
(fun () ->
let diag_phi_mso =
@@ -413,5 +442,5 @@
eval_eq (grid 2) four_color_f "";
);*)
-
+*)
]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <luk...@us...> - 2012-06-27 23:29:15
|
Revision: 1737
http://toss.svn.sourceforge.net/toss/?rev=1737&view=rev
Author: lukaszkaiser
Date: 2012-06-27 23:29:07 +0000 (Wed, 27 Jun 2012)
Log Message:
-----------
New code cleanups and tests.
Modified Paths:
--------------
trunk/Toss/Client/eval.html
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/Formula/BoolFormula.mli
trunk/Toss/Makefile
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/Solver.mli
trunk/Toss/Solver/SolverTest.ml
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Client/eval.html 2012-06-27 23:29:07 UTC (rev 1737)
@@ -138,11 +138,25 @@
"\n y { a -> 0, b -> -1, c -> 0 } ]";
eval_it ();
}
+
+function example_heart_drawing () {
+ document.getElementById ("relations").value =
+ "E(x, y) = (&y = &x + 1 and &x != 18) ∨ (&x=37 ∧ &y=18)";
+ document.getElementById ("positions").value =
+ ":x(a) = :(&a <= 18) * (:(&a =< 10) * &a - :(&a > 10) * (&a - 20)) \n" +
+ " - let :b = &a - 18 in :(&a > 18) * (:(:b =< 10) * :b - \n " +
+ " :(:b > 10) * (:b - 20) - 2); \n\n" +
+ ":y(a) = :(&a <= 18) * (:(&a =< 10) *&a · (10 - &a) / 10 - \n " +
+ " :(&a > 10)*(&a - 10)) + let :b = &a - 18 in \n" +
+ " :(&a > 18) * (:(:b =< 10) *:b · (10 - :b) / 10 - :(:b > 10)*(:b - 10))";
+ document.getElementById ("no-elems").value = "37";
+ eval_it ();
+}
//-->
</script>
</head>
-<body onload="init_canvas ()">
+<body onload="init_canvas (); eval_it ()">
<div id="main">
<div id="top">
Modified: trunk/Toss/Formula/BoolFormula.ml
===================================================================
--- trunk/Toss/Formula/BoolFormula.ml 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Formula/BoolFormula.ml 2012-06-27 23:29:07 UTC (rev 1737)
@@ -1030,37 +1030,37 @@
let res = elim_quant_rec phi in
set_simplification 2;
res
-
-(* reduce QBF to SAT *)
-let sat_of_qbf phi = let ids, free_id = Hashtbl.create 7, ref 0 in
- let get_id x = try Hashtbl.find ids x with Not_found ->
- (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
- let compute_id var asgn = get_id (var, asgn) in
- (* reduce QBF to SAT (recursive helper)*)
- let rec sat_of_qbf_rec phi asgn = (match phi with
- | QVar v -> (try List.assoc v asgn with Not_found -> (BVar v))
- | QAnd l ->
- let resl = (Aux.unique_sorted (List.filter (fun x -> x <> BAnd []) (List.map (fun x -> sat_of_qbf_rec x asgn) l))) in
- (try List.find (fun x -> x = BOr []) resl with Not_found -> (BAnd resl))
- | QOr l ->
- let resl = (Aux.unique_sorted (List.filter (fun x -> x <> BOr []) (List.map (fun x -> sat_of_qbf_rec x asgn) l))) in
- (try List.find (fun x -> x = BAnd []) resl with Not_found -> (BOr resl))
- | QNot f ->
- let res = (sat_of_qbf_rec f asgn) in
- if res = BAnd [] then BOr []
- else if res = BOr [] then BAnd []
- else BNot res
- | QEx (var::vl, f) -> (sat_of_qbf_rec (QEx (vl, f)) ((var, (BVar (get_id (var, asgn))))::asgn))
- | QEx ([], f) -> (sat_of_qbf_rec f asgn)
- | QAll (var::tl, f) ->
- let resl =
- (Aux.unique_sorted (List.filter
- (fun x -> x <> BAnd [])
- [(sat_of_qbf_rec (QAll (tl, f)) ((var, BOr [])::asgn)); (sat_of_qbf_rec (QAll (tl, f)) ((var, BAnd [])::asgn))]
- )) in
- (try (List.find (fun x -> x = BOr []) resl) with Not_found -> (BAnd resl))
- | QAll ([], f) -> (sat_of_qbf_rec f asgn)
- )
- in
- (sat_of_qbf_rec phi [])
+(* Reduce QBF to SAT by taking all possibilities for universal variables *)
+let sat_of_qbf phi =
+ let ids, free_id = Hashtbl.create 7, ref 0 in
+ let get_id x = try Hashtbl.find ids x with Not_found ->
+ (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
+ (* reduce QBF to SAT (recursive helper)*)
+ let rec sat_of_qbf_rec phi asgn =
+ match phi with
+ | QVar v -> (try List.assoc v asgn with Not_found -> (BVar v))
+ | QAnd l ->
+ let resl = Aux.unique_sorted (List.filter (fun x -> x <> BAnd []) (
+ List.rev_map (fun x -> sat_of_qbf_rec x asgn) l)) in
+ (try List.find (fun x -> x = BOr []) resl with Not_found -> (BAnd resl))
+ | QOr l ->
+ let resl = Aux.unique_sorted (List.filter (fun x -> x <> BOr []) (
+ List.rev_map (fun x -> sat_of_qbf_rec x asgn) l)) in
+ (try List.find (fun x -> x = BAnd []) resl with Not_found -> (BOr resl))
+ | QNot f ->
+ let res = sat_of_qbf_rec f asgn in
+ if res = BAnd [] then BOr []
+ else if res = BOr [] then BAnd []
+ else BNot res
+ | QEx (var::vl, f) ->
+ sat_of_qbf_rec (QEx (vl, f)) ((var, BVar (get_id (var, asgn)))::asgn)
+ | QEx ([], f) -> (sat_of_qbf_rec f asgn)
+ | QAll (var::tl, f) ->
+ let redl = [(sat_of_qbf_rec (QAll (tl, f)) ((var, BOr [])::asgn));
+ (sat_of_qbf_rec (QAll (tl, f)) ((var, BAnd [])::asgn))] in
+ let resl = Aux.unique_sorted (List.filter (fun x->x <> BAnd []) redl) in
+ (try (List.find (fun x-> x = BOr []) resl) with Not_found-> (BAnd resl))
+ | QAll ([], f) -> (sat_of_qbf_rec f asgn)
+ in (sat_of_qbf_rec phi [])
+
Modified: trunk/Toss/Formula/BoolFormula.mli
===================================================================
--- trunk/Toss/Formula/BoolFormula.mli 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Formula/BoolFormula.mli 2012-06-27 23:29:07 UTC (rev 1737)
@@ -96,5 +96,5 @@
(** Eliminating quantifiers from QBF formulas. *)
val elim_quant : qbf -> bool_formula
-(** Reduce QBF to SAT by elimination of quantifiers. *)
-val sat_of_qbf : qbf -> bool_formula
\ No newline at end of file
+(** Reduce QBF to SAT by taking all possibilities for universal variables *)
+val sat_of_qbf : qbf -> bool_formula
Modified: trunk/Toss/Makefile
===================================================================
--- trunk/Toss/Makefile 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Makefile 2012-06-27 23:29:07 UTC (rev 1737)
@@ -186,48 +186,48 @@
# Formula tests
FormulaTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Formula
-FormulaTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Formula -v
+FormulaTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Formula -v
# Solver tests
SolverTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Solver
-SolverTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Solver -v
+SolverTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Solver -v
# Term tests
TermTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Term
-TermTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Term -v
+TermTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Term -v
# Arena tests
ArenaTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Arena
-ArenaTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Arena -v
+ArenaTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Arena -v
# Play tests
PlayTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Play
-PlayTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Play -v
+PlayTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Play -v
# GGP tests
GGPTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest GGP
-GGPTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test GGP -v
+GGPTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest GGP -v
@@ -237,8 +237,8 @@
# Learn tests
LearnTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Learn
-LearnTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Learn -v
+LearnTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Learn -v
@@ -249,16 +249,16 @@
# Client tests
ClientTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Client
-ClientTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Client -v
+ClientTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Client -v
# Server tests
ServerTests: Server/Server.native
cp _build/Server/Server.native TossServer
- OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Server
-ServerTestsVerbose: Server/Server.native
+ OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -test Server -v
+ServerTestsFull: Server/Server.native
cp _build/Server/Server.native TossServer
OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ./TossServer -fulltest Server -v
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Solver/Solver.ml 2012-06-27 23:29:07 UTC (rev 1737)
@@ -396,103 +396,96 @@
List.iter (fun (p, r) -> Hashtbl.add !re_cache_results p r) !ok_re
-
-let so_to_qbf struc psi =
- let ids, free_id = Hashtbl.create 7, ref 0 in
- let get_id x = try Hashtbl.find ids x with Not_found ->
- (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
- let compute_id var args asgn = get_id (var, args, asgn) in
- (* Reduce the Evaluation Problem of SO formulae to QBF *)
-let rec so_to_qbf_rec struc psi asgn = match psi with
- | SO (rel, args) ->
- let v = (compute_id (var_str rel) args asgn) in
- (QVar v, [(var_str rel, v)])
- | Rel (rel, va) ->
- let args = Array.map (fun x -> try List.assoc x asgn with Not_found -> 0) va in
- if (Structure.check_rel struc rel args) then (QAnd [], []) else (QOr [], [])
- | Eq (var1, var2) -> if (try List.assoc var1 asgn with Not_found -> 0) = (try List.assoc var1 asgn with Not_found -> 0) then (QAnd [], []) else (QOr [], [])
- | And phil ->
- let resl = (List.map (fun phi -> (so_to_qbf_rec struc phi asgn)) phil) in
- let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
- let dictl = (List.map (snd) resl) in
- (try
- ((List.find (fun x -> x = QOr []) qphil), [])
- with Not_found -> (
- QAnd (List.filter (fun x -> x <> QAnd []) qphil), List.concat dictl
- ))
-
- | Or phil ->
- let resl = (List.map (fun phi -> (so_to_qbf_rec struc phi asgn)) phil) in
- let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
- let dictl = (List.map (snd) resl) in
- (try ((List.find (fun x -> x = QAnd []) qphil), []) with Not_found -> (QOr (List.filter (fun x -> x <> QOr []) qphil), List.concat dictl))
- | Not phi -> let (qphi, dict) = so_to_qbf_rec struc phi asgn in
- (if qphi = QOr [] then
- (QAnd [], dict)
- else if qphi = QAnd [] then
- (QOr [], dict)
- else
- (QNot qphi, dict))
- | Ex (vl, phi) ->
- (
- match vl with
- | [] -> so_to_qbf_rec struc phi asgn
- | var::tl ->
- if is_fo var then
- let asgn_list = List.map (fun x -> (Formula.to_fo var, x)::asgn) (Structure.elements struc) in
- let res = (List.map (fun x -> so_to_qbf_rec struc (Ex (tl, phi)) x) asgn_list) in
- let (qphil, dictl) = ((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res)in
- (try ((List.find (fun x -> x = QAnd []) qphil), []) with Not_found -> (QOr (List.filter (fun x -> x <> QOr []) qphil), List.concat dictl))
- else if is_so var then
- let (qbf_phi, dict_phi) = (so_to_qbf_rec struc (Ex (tl, phi)) asgn) in
- let rel_qbf_vars = Aux.unique_sorted (Aux.assoc_all (var_str var) dict_phi) in
- if qbf_phi = QAnd [] then (QAnd [], [])
- else if qbf_phi = QOr [] then (QOr [], [])
- else if (rel_qbf_vars = []) then (qbf_phi, dict_phi)
- else (QEx (rel_qbf_vars, qbf_phi), dict_phi)
- else (* stub *)
- (so_to_qbf_rec struc phi asgn)
- )
- | All (vl, phi) ->
- (
- match vl with
- | [] -> so_to_qbf_rec struc phi asgn
- | var::tl ->
- if is_fo var then
- let asgn_list = List.map (fun x -> (Formula.to_fo var, x)::asgn) (Structure.elements struc) in
- let res = (List.map (fun x -> so_to_qbf_rec struc (All (tl, phi)) x) asgn_list) in
- let (qphil, dictl) = ((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res)in
- (try
- ((List.find (fun x -> x = (QOr [])) qphil), [])
- with Not_found ->
- (QAnd (List.filter (fun x -> x <> (QAnd [])) qphil), List.concat dictl))
- else if is_so var then
- let (qbf_phi, dict_phi) = so_to_qbf_rec struc (All (tl, phi)) asgn in
- let rel_qbf_vars = Aux.unique_sorted (Aux.assoc_all (var_str var) dict_phi) in
- if qbf_phi = QAnd [] then (QAnd [], [])
- else if qbf_phi = QOr [] then (QOr [], [])
- else if (rel_qbf_vars = []) then (qbf_phi, dict_phi)
- else (QAll (rel_qbf_vars, qbf_phi), dict_phi)
- else (* stub *)
- (so_to_qbf_rec struc phi asgn)
- ) in
-fst (so_to_qbf_rec struc psi [])
+(* Compute the QBF equivalent to the given SO formula on the given structure. *)
+let so_to_qbf struc psi =
+ let ids, free_id, elems = Hashtbl.create 7, ref 0, Structure.elements struc in
+ let get_id x = try Hashtbl.find ids x with Not_found ->
+ (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
+ let compute_id var args asgn = get_id (var, args, asgn) in
+ let assoc_or_zero asgn x = try List.assoc x asgn with Not_found -> 0 in
+ (* Reduce the Evaluation Problem of SO formulae to QBF *)
+ let rec so_to_qbf_rec asgn = function
+ | SO (rel, args) ->
+ let v = (compute_id (var_str rel) args asgn) in
+ (QVar v, [(var_str rel, v)])
+ | Rel (rel, va) ->
+ let args = Array.map (assoc_or_zero asgn) va in
+ if (Structure.check_rel struc rel args) then (QAnd [], [])
+ else (QOr [], [])
+ | Eq (var1, var2) ->
+ if assoc_or_zero asgn var1 = assoc_or_zero asgn var2 then
+ (QAnd [], [])
+ else (QOr [], [])
+ | And phil ->
+ let resl = (List.map (fun phi -> (so_to_qbf_rec asgn phi)) phil) in
+ let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
+ let dictl = (List.map snd resl) in
+ (try (List.find (fun x -> x = QOr []) qphil, [])
+ with Not_found ->
+ (QAnd (List.filter (fun x -> x <> QAnd []) qphil), List.concat dictl)
+ )
+ | Or phil ->
+ let resl = (List.map (fun phi -> (so_to_qbf_rec asgn phi)) phil) in
+ let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
+ let dictl = (List.map (snd) resl) in
+ (try ((List.find (fun x -> x = QAnd []) qphil), []) with Not_found ->
+ (QOr (List.filter (fun x -> x <> QOr []) qphil), List.concat dictl)
+ )
+ | Not phi ->
+ let (qphi, dict) = so_to_qbf_rec asgn phi in
+ if qphi = QOr [] then (QAnd [], dict)
+ else if qphi = QAnd [] then(QOr [], dict)
+ else (QNot qphi, dict)
+ | Ex ([], phi) -> so_to_qbf_rec asgn phi
+ | Ex (var::tl, phi) when is_fo var ->
+ let asgn_list = List.map (fun x -> (Formula.to_fo var, x)::asgn) elems in
+ let res = List.map (fun x -> so_to_qbf_rec x (Ex (tl, phi))) asgn_list in
+ let (qphil, dictl) =
+ ((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res) in
+ (try (List.find (fun x -> x = QAnd []) qphil, []) with Not_found ->
+ (QOr (List.filter (fun x-> x <> QOr []) qphil), List.concat dictl)
+ )
+ | Ex (var::tl, phi) when is_so var ->
+ let (qbf_phi, dict_phi) = (so_to_qbf_rec asgn (Ex (tl, phi))) in
+ let rel_qbf_vars =
+ Aux.unique_sorted (Aux.assoc_all (var_str var) dict_phi) in
+ if qbf_phi = QAnd [] then (QAnd [], [])
+ else if qbf_phi = QOr [] then (QOr [], [])
+ else if (rel_qbf_vars = []) then (qbf_phi, dict_phi)
+ else (QEx (rel_qbf_vars, qbf_phi), dict_phi)
+ | Ex (var::tl, phi) -> (*stub*) failwith "not implemented yet (so_qbf_Ex)"
+ | All ([], phi) -> so_to_qbf_rec asgn phi
+ | All (var::tl, phi) when is_fo var ->
+ let asgn_list = List.map (fun x -> (Formula.to_fo var, x)::asgn) elems in
+ let res = List.map (fun x -> so_to_qbf_rec x (All (tl, phi))) asgn_list in
+ let (qphil, dictl) =
+ ((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res) in
+ (try
+ ((List.find (fun x -> x = (QOr [])) qphil), [])
+ with Not_found ->
+ (QAnd (List.filter (fun x -> x <> (QAnd [])) qphil), List.concat dictl)
+ )
+ | All (var::tl, phi) when is_so var ->
+ let (qbf_phi, dict_phi) = so_to_qbf_rec asgn (All (tl, phi)) in
+ let rel_qbf_vars =
+ Aux.unique_sorted (Aux.assoc_all (var_str var) dict_phi) in
+ if qbf_phi = QAnd [] then (QAnd [], [])
+ else if qbf_phi = QOr [] then (QOr [], [])
+ else if (rel_qbf_vars = []) then (qbf_phi, dict_phi)
+ else (QAll (rel_qbf_vars, qbf_phi), dict_phi)
+ | All (var::tl, _) -> (*stub*) failwith "not implemented yet (so_qbf_All)"
+ | _ -> failwith "not implemented yet (so_qbf_Other)"
+ in fst (so_to_qbf_rec [] psi)
-
-
(* Evaluation with second-order variables. *)
let eval_so struc phi =
- let qbf = (so_to_qbf struc phi) in
- let bf = (BoolFormula.sat_of_qbf qbf) in
- let cnf = (BoolFormula.convert bf) in
- LOG 0 "QBF:";
- LOG 0 "%s" (BoolFormula.qbf_str qbf);
- LOG 0 "BF:";
- LOG 0 "%s" (BoolFormula.str bf);
- LOG 0 "CNF:";
- LOG 0 "%s" (Sat.cnf_str cnf);
- if (Sat.is_sat cnf) then Any else Empty
+ let qbf = so_to_qbf struc phi in
+ let bf = (* BoolFormula.sat_of_qbf qbf *) BoolFormula.elim_quant qbf in
+ let cnf = BoolFormula.convert bf in
+ LOG 1 "QBF %s BF %s CNF %s:" (BoolFormula.qbf_str qbf) (BoolFormula.str bf)
+ (Sat.cnf_str cnf);
+ if Sat.is_sat cnf then Any else Empty
(* Eval with very basic caching. *)
let eval_m struc phi =
Modified: trunk/Toss/Solver/Solver.mli
===================================================================
--- trunk/Toss/Solver/Solver.mli 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Solver/Solver.mli 2012-06-27 23:29:07 UTC (rev 1737)
@@ -38,5 +38,6 @@
(** Counter of internal formula evaluations for profiling. *)
val eval_counter : int ref
+(** Compute the QBF equivalent to the given SO formula on the given structure.*)
+val so_to_qbf : Structure.structure -> Formula.formula -> BoolFormula.qbf
-
Modified: trunk/Toss/Solver/SolverTest.ml
===================================================================
--- trunk/Toss/Solver/SolverTest.ml 2012-06-27 18:18:35 UTC (rev 1736)
+++ trunk/Toss/Solver/SolverTest.ml 2012-06-27 23:29:07 UTC (rev 1737)
@@ -15,8 +15,8 @@
let eval_eq struc_s phi_s aset_s =
let res = ref "" in
- let (struc, phi) = (struc_of_string struc_s, formula_of_string phi_s) in
- res := AssignmentSet.str (evaluate struc phi);
+ let (struc, phi) = (struc_of_string struc_s, formula_of_string phi_s) in
+ res := AssignmentSet.str (evaluate struc phi);
assert_equal ~printer:(fun x -> x) aset_s !res
@@ -165,41 +165,46 @@
"{ z->1, z->2, z->3 }";
);
- "eval: second-order T" >::
- (fun () ->
- let formula = "all |Q ex |R all x, y (|R (x, y) <-> (|Q(x) and not T(y)))" in
- let struc = "[ a, b | T { a } | ]" in
- (
- eval_eq struc
- formula
- "T";
- )
+ "convert: second-order to QBF" >::
+ (fun () ->(
+ let qbf_str_eq struc_s phi_s qbf_s =
+ let phi, struc = formula_of_string phi_s, struc_of_string struc_s in
+ LOG 1 "%s" (Formula.str phi);
+ assert_equal ~printer:(fun x -> x) qbf_s
+ (BoolFormula.qbf_str (Solver.so_to_qbf struc phi)) in
+
+ qbf_str_eq "[ a, b | T { a } | ]" "ex |R all x, y (T(x) or |R (x, y))"
+ "which result is ok?";
+
+ print_endline (Formula.str (formula_of_string "ex |V all |Q ex |R all x, y (T(x) or |R (x, y))"));
+ print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "ex |R all x, y (T(x) or |R (x, y))")));
+
+ print_endline (Formula.str (formula_of_string "all |Q all x, y (T(x) or Q(y) or (x = y))"));
+ print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "all |Q all x, y (T(x) or Q(y) or (x = y))")));
+
+ print_endline (Formula.str (formula_of_string "ex x all y ((T(x) and T(y)) -> x = y)"));
+ print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "ex x all y ((T(x) and T(y)) -> x = y)"))); )
);
-
- "eval: second-order F" >::
+
+ "eval: second-order" >::
(fun () ->
- let formula = "ex |R all |Q all x (not (|R(x) and |Q(x)) and (|R(x) or |Q(x)))" in
- let struc = "[ a, b | T { a } | ]" in
- (
- eval_eq struc
- formula
- "{}";
- )
+ let phi = "all |Q ex |R all x, y (|R (x, y) <-> (|Q(x) and not T(y)))" in
+ let struc = "[ a, b | T { a } | ]" in
+ eval_eq struc phi "T";
+
+ let formula =
+ "ex |R all |Q all x (not (|R(x) and |Q(x)) and (|R(x) or |Q(x)))" in
+ let struc = "[ a, b | T { a } | ]" in
+ eval_eq struc formula "{}";
+
+ let col3phi =
+ ("ex |R, |G, |B all x, y ( (|R(x) or |G(x) or |B(x)) and (" ^
+ " E(x,y) -> not ( (|R(x) and |R(y)) " ^
+ " or (|G(x) and |G(y)) or (|B(x) and |B(y)) ) ) )") in
+ let triangle = "[ | E { (a, b); (b, c); (c, a) } | ] " in
+ eval_eq triangle col3phi "T";
);
-(*
- "convert: eval second-order to QBF" >::
- (fun () ->(
- print_endline (Formula.str (formula_of_string "ex |V all |Q ex |R all x, y (T(x) or |R (x, y))"));
- print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "ex |R all x, y (T(x) or |R (x, y))")));
-
- print_endline (Formula.str (formula_of_string "all |Q all x, y (T(x) or Q(y) or (x = y))"));
- print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "all |Q all x, y (T(x) or Q(y) or (x = y))")));
-
- print_endline (Formula.str (formula_of_string "ex x all y ((T(x) and T(y)) -> x = y)"));
- print_endline (BoolFormula.qbf_str (Solver.so_to_qbf (struc_of_string "[ a, b | T { a } | ]") (formula_of_string "ex x all y ((T(x) and T(y)) -> x = y)")));
- )
- );
-*)
+
"eval: game heuristic tests" >::
(fun () ->
let heur_phi = "(((R(v, w) and R(w, x) and R(x, y) and R(y, z)) or
@@ -270,12 +275,10 @@
real_val_eq "[ | R { (a, a); (a, b) } | ] "
"Sum (x, y | R (x, y) : 1)" 2.;
);
-
]
let bigtests = "SolverBig" >::: [
-(*
"eval: bigger tc tests" >::
(fun () ->
let diag_phi_mso =
@@ -442,5 +445,4 @@
eval_eq (grid 2) four_color_f "";
);*)
-*)
]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <luk...@us...> - 2012-07-02 00:27:50
|
Revision: 1738
http://toss.svn.sourceforge.net/toss/?rev=1738&view=rev
Author: lukaszkaiser
Date: 2012-07-02 00:27:40 +0000 (Mon, 02 Jul 2012)
Log Message:
-----------
Interface work on the structure editor.
Modified Paths:
--------------
trunk/Toss/Client/Style.css
trunk/Toss/Client/eval.html
trunk/Toss/Formula/Lexer.mll
Modified: trunk/Toss/Client/Style.css
===================================================================
--- trunk/Toss/Client/Style.css 2012-06-27 23:29:07 UTC (rev 1737)
+++ trunk/Toss/Client/Style.css 2012-07-02 00:27:40 UTC (rev 1738)
@@ -64,7 +64,7 @@
float: right;
}
-.obt, .boldobt, .gamebt {
+.obt, .boldobt, .gamebt, .ebt {
text-align: left;
border-color: #260314;
border-radius: 4px;
@@ -76,7 +76,7 @@
font-family: Verdana, 'TeXGyreHerosRegular', sans;
}
-.obt:hover {
+.obt:hover, .ebt:hover, .boldobt:hover, .gamebt:hover {
cursor: pointer;
text-decoration: underline;
}
@@ -86,9 +86,9 @@
font-size: 1em;
}
-.boldobt:hover, .gamebt:hover {
- cursor: pointer;
- text-decoration: underline;
+.ebt {
+ /*font-weight: bold;*/
+ border-width: 2px;
}
.gamebt {
@@ -900,8 +900,8 @@
#board-left {
position: relative;
- left: 40em;
- top: -18em;
+ left: 2em;
+ top: 5em;
}
#board {
@@ -1006,8 +1006,8 @@
}
#canvas {
- width: 30em;
- height: 30em;
+ width: 28em;
+ height: 28em;
border: 2px solid #260314;
}
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-06-27 23:29:07 UTC (rev 1737)
+++ trunk/Toss/Client/eval.html 2012-07-02 00:27:40 UTC (rev 1738)
@@ -2,8 +2,8 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/xhtml+xml; charset=UTF-8" />
- <title>Toss Formula Evaluator</title>
- <meta name="Description" content="Evaluate Formulas on Structures." />
+ <title>Toss Relational Structures Explorer</title>
+ <meta name="Description" content="Explore Relational Structures." />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<link rel="icon" type="image/vnd.microsoft.icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="Style.css" media="screen" title="Default"/>
@@ -51,8 +51,10 @@
function eval_it () {
var rels = document.getElementById ("relations").value;
var pos = document.getElementById ("positions").value;
- var elems = document.getElementById ("no-elems").value;
- var struc = "[ 1 - " + elems + " | | - ] with " + rels + " with " + pos;
+ var elemsF = document.getElementById ("no-elems-start").value;
+ var elemsT = document.getElementById ("no-elems-end").value;
+ var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with " +
+ rels + " with " + pos;
ASYNCH ("draw_struc", [struc], true, function (s) {
var ctx = document.getElementById("canvas").getContext("2d");
eval (s);
@@ -60,7 +62,7 @@
}
-function canvasCoords (event) { // From stackoverflow.com
+function canvasCoords (eventPageX, eventPageY) { // From stackoverflow.com
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
@@ -74,8 +76,8 @@
}
while (currentElement = currentElement.offsetParent)
- canvasX = event.pageX - totalOffsetX;
- canvasY = event.pageY - totalOffsetY;
+ canvasX = eventPageX - totalOffsetX;
+ canvasY = eventPageY - totalOffsetY;
// Fix for variable canvas width
canvasX = Math.round( canvasX * (canvas.width / canvas.offsetWidth) );
@@ -85,48 +87,89 @@
}
function mouseup_handle (e) {
- var pos = canvasCoords (e);
+ var pos = canvasCoords (e.pageX, e.pageY);
ASYNCH ("mouseup_handle", [pos.x, pos.y], true, function (s) {
var ctx = document.getElementById("canvas").getContext("2d");
eval (s);
})
}
+function touchend_handle (e) {
+ var pos = canvasCoords (e.targetTouches[0].pageX, e.targetTouches[0].pageY);
+ ASYNCH ("mouseup_handle", [pos.x, pos.y], false, function (s) {
+ var ctx = document.getElementById("canvas").getContext("2d");
+ eval (s);
+ })
+}
+
function mousedown_handle (e) {
- var pos = canvasCoords (e);
+ var pos = canvasCoords (e.pageX, e.pageY);
ASYNCH ("mousedown_handle", [pos.x, pos.y], true, function (s) {
var ctx = document.getElementById("canvas").getContext("2d");
eval (s);
})
}
+function touchstart_handle (e) {
+ var pos = canvasCoords (e.targetTouches[0].pageX, e.targetTouches[0].pageY);
+ ASYNCH ("mousedown_handle", [pos.x, pos.y], false, function (s) {
+ var ctx = document.getElementById("canvas").getContext("2d");
+ eval (s);
+ })
+}
+
function mousemove_handle (e) {
- var pos = canvasCoords (e);
+ var pos = canvasCoords (e.pageX, e.pageY);
ASYNCH ("mousemove_handle", [pos.x, pos.y], false, function (s) {
var ctx = document.getElementById("canvas").getContext("2d");
eval (s);
})
}
+function touchmove_handle (e) {
+ e.preventDefault(); // avoid elastic page scrolling on tablets
+ var pos = canvasCoords (e.targetTouches[0].pageX, e.targetTouches[0].pageY);
+ ASYNCH ("mousemove_handle", [pos.x, pos.y], false, function (s) {
+ var ctx = document.getElementById("canvas").getContext("2d");
+ eval (s);
+ })
+}
+
+
function handle_elem_click (eid) { console.log (eid); }
function example_primes () {
+ document.getElementById ("struc-name").value = "Prime Numbers";
document.getElementById ("relations").value =
- "P(z) = &z > 1 and all x, y \n (&x * &y = &z -> (&x = 1 or &y = 1))";
+ "P(z) = &z > 1 and ∀ x, y \n (&x · &y = &z → (&x = 1 ∨ &y = 1))";
document.getElementById ("positions").value = ":x(a) = &a; \n:y(a) = 0";
- document.getElementById ("no-elems").value = "10";
+ document.getElementById ("no-elems-start").value = "1";
+ document.getElementById ("no-elems-end").value = "10";
eval_it ();
}
function example_tc () {
+ document.getElementById ("struc-name").value = "Transitive Closure";
document.getElementById ("relations").value =
"E(x, y) = &y = &x + 1;\n" +
- "S(x, y) = x != y and tc x, y E(x, y)";
- document.getElementById ("positions").value = ":x(a) = 10*&a;\n:y(a) = &a*&a";
- document.getElementById ("no-elems").value = "4";
+ "S(x, y) = x ≠ y ∧ tc x,y E(x, y)";
+ document.getElementById("positions").value=":x(a) = 5·&a;\n:y(a) = &a·&a / 2";
+ document.getElementById ("no-elems-start").value = "1";
+ document.getElementById("no-elems-end").value = "4";
eval_it ();
}
+function example_basic () {
+ document.getElementById ("struc-name").value = "Basic Example";
+ document.getElementById ("relations").value =
+ "E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)";
+ document.getElementById ("positions").value = ":x(a) = &a;\n" +
+ ":y(a) = &a · (10 - &a) / 10";
+ document.getElementById ("no-elems-start").value = "1";
+ document.getElementById ("no-elems-end").value = "15";
+ eval_it ();
+}
+
function example_3col () {
document.getElementById ("formula").value =
"ex |R, |G, |B all x, y ( \n ( |R(x) or |G(x) or |B(x)) and (" +
@@ -139,24 +182,131 @@
eval_it ();
}
-function example_heart_drawing () {
+function example_heart () {
+ document.getElementById ("struc-name").value = "Heart Drawing";
document.getElementById ("relations").value =
- "E(x, y) = (&y = &x + 1 and &x != 18) ∨ (&x=37 ∧ &y=18)";
+ "E(x, y) = (&y = &x + 1 ∧ &x ≠ 18) ∨ (&x=37 ∧ &y=18)";
document.getElementById ("positions").value =
- ":x(a) = :(&a <= 18) * (:(&a =< 10) * &a - :(&a > 10) * (&a - 20)) \n" +
- " - let :b = &a - 18 in :(&a > 18) * (:(:b =< 10) * :b - \n " +
- " :(:b > 10) * (:b - 20) - 2); \n\n" +
- ":y(a) = :(&a <= 18) * (:(&a =< 10) *&a · (10 - &a) / 10 - \n " +
- " :(&a > 10)*(&a - 10)) + let :b = &a - 18 in \n" +
- " :(&a > 18) * (:(:b =< 10) *:b · (10 - :b) / 10 - :(:b > 10)*(:b - 10))";
- document.getElementById ("no-elems").value = "37";
+ ":x(a) = :(&a ≤ 18) · (:(&a ≤ 10) · &a - :(&a > 10) · (&a - 20)) \n" +
+ " - let :b = &a - 18 in :(&a > 18) · (:(:b ≤ 10) · :b - \n " +
+ " :(:b > 10) · (:b - 20) - 2); \n\n" +
+ ":y(a) = :(&a ≤ 18) · (:(&a ≤ 10) ·&a · (10 - &a) / 10 - \n " +
+ " :(&a > 10)·(&a - 10)) + let :b = &a - 18 in \n" +
+ " :(&a > 18) · (:(:b ≤ 10) ·:b · (10 - :b) / 10 - :(:b > 10)·(:b - 10))";
+ document.getElementById ("no-elems-start").value = "1";
+ document.getElementById ("no-elems-end").value = "37";
eval_it ();
}
+
+function add_field (field, s) {
+ var e = document.getElementById(field);
+ var cursor = e.selectionStart;
+ var v1 = e.value.substring(0, cursor);
+ var v2 = e.value.substring(cursor, e.value.length);
+ e.value = v1 + s + " " + v2;
+ e.selectionStart = cursor + 2;
+}
+
+function add_elem () {
+ var e = document.getElementById ("no-elems-end").value;
+ document.getElementById ("no-elems-end").value = parseInt(e) + 1;
+ eval_it ();
+}
+
+function del_elem () {
+ var e = document.getElementById ("no-elems-end").value;
+ document.getElementById ("no-elems-end").value = parseInt(e) - 1;
+ eval_it ();
+}
+
+function save () {
+ var name = document.getElementById ("struc-name").value;
+ var elems1 = document.getElementById ("no-elems-start").value;
+ var elems2 = document.getElementById ("no-elems-end").value;
+ var rels = document.getElementById ("relations").value;
+ var pos = document.getElementById ("positions").value;
+ localStorage["TRelStrucExplEl1"+name] = elems1;
+ localStorage["TRelStrucExplEl2"+name] = elems2;
+ localStorage["TRelStrucExplRel"+name] = rels;
+ localStorage["TRelStrucExplPos"+name] = pos;
+ list_stored ();
+}
+
+function load (name) {
+ document.getElementById ("struc-name").value = name;
+ document.getElementById ("no-elems-start").value =
+ localStorage["TRelStrucExplEl1"+name];
+ document.getElementById ("no-elems-end").value =
+ localStorage["TRelStrucExplEl2"+name];
+ document.getElementById ("relations").value =
+ localStorage["TRelStrucExplRel"+name];
+ document.getElementById ("positions").value =
+ localStorage["TRelStrucExplPos"+name];
+ eval_it ();
+}
+
+function list_stored () {
+ var saved = document.getElementById("saved-strucs");
+ while (saved.childNodes.length > 0) { saved.removeChild(saved.firstChild); }
+ for (var i=0; i < localStorage.length; i++) {
+ var k = localStorage.key(i);
+ if (k.substring (0, 16) === "TRelStrucExplEl1") {
+ var n = k.substring (16, k.length);
+ var li = document.createElement('li');
+ li.innerHTML = '<button class="obt" onclick="load('+ "'"+ n +"'" +')">' +
+ n +'</button> (<button class="obt" onclick="del_saved('+ "'"+ n +
+ "'" +')" title="Delete this structure.">-</button>)';
+ saved.appendChild (li);
+ }
+ }
+}
+
+function del_saved (name) {
+ localStorage.removeItem("TRelStrucExplEl1"+name);
+ localStorage.removeItem("TRelStrucExplEl2"+name);
+ localStorage.removeItem("TRelStrucExplRel"+name);
+ localStorage.removeItem("TRelStrucExplPos"+name);
+ list_stored ();
+}
+
+function toggle_edit () {
+ var bt = document.getElementById("editbt");
+ if (bt.innerHTML == "Edit") {
+ document.getElementById('edit').style.display = 'block';
+ document.getElementById('board-left').style.left = '38em';
+ bt.innerHTML = "Hide Edit";
+ } else {
+ document.getElementById('edit').style.display = 'none';
+ document.getElementById('board-left').style.left = '2em';
+ bt.innerHTML = "Edit";
+ }
+}
+
+function toggle_view () {
+ var bt = document.getElementById("viewbt");
+ if (bt.innerHTML == "View") {
+ document.getElementById('board-left').style.display = 'block';
+ bt.innerHTML = "Hide View";
+ } else {
+ document.getElementById('board-left').style.display = 'none';
+ bt.innerHTML = "View";
+ }
+}
+
+function adjust_to_width () {
+ var e = document.getElementById ("edit");
+ var em_size =
+ document.defaultView.getComputedStyle(e,null).getPropertyValue('font-size');
+ var em_size_int = parseInt (em_size.substring (0, em_size.length - 2));
+ if (window.innerWidth > 80 * em_size_int) { // enough space for edit
+ toggle_edit ()
+ }
+}
//-->
</script>
</head>
-<body onload="init_canvas (); eval_it ()">
+<body onload="init_canvas (); list_stored (); eval_it (); adjust_to_width()">
<div id="main">
<div id="top">
@@ -165,46 +315,96 @@
<img id="leftupperlogo-img" src="img/logo.png" alt="back" />
</a>
</div>
+<span style="position: relative; left: 2em; top: 0.5em; font-size: 1.2em">
+ Relational Structures Explorer</span>
+<span id="toprighttab" style="display: block;">
+ <button class="obt" id="editbt" onclick="toggle_edit()">Edit</button>
+ <button class="obt" id="viewbt" onclick="toggle_view()">Hide View</button>
+</span>
</div>
-<div style="position: relative; top: 4em; left: 2em">
+<div id="board-left">
+<canvas id="canvas" height="1100" width="1100"
+ onmouseup="mouseup_handle(event)"
+ onmousedown="mousedown_handle(event)"
+ onmousemove="mousemove_handle(event)"
+ ontouchstart="touchstart_handle(event)"
+ ontouchend="touchend_handle(event)"
+ ontouchmove="touchmove_handle(event)">
+This text is displayed if your browser does not support HTML5 Canvas.
+</canvas>
+</div>
-<p>Relations:</p>
+<div id="edit" style="position: absolute; top: 4em; left: 2em; display: none">
-<textarea id="relations" rows="3" cols="60">
+<p>Name
+ <input id="struc-name" type="text" size="20" value="MyStructure1"
+ style="width: 10em"></input>
+ <button class="ebt" onclick="save()">Save</button>
+</p>
+
+<p>Elements
+ <input id="no-elems-start" type="text" size="2" value="1"
+ style="width: 2em"></input> —
+ <input id="no-elems-end" type="text" size="4" value="15"
+ style="width: 2em"></input>
+ <button class="ebt" onclick="add_elem()">+</button>
+ <button class="ebt" onclick="del_elem()">-</button>
+</p>
+
+<p>Relations
+ <button class="ebt" title="Conjunction. You can also write 'and' or '&'."
+ onclick="add_field('relations', '∧')">∧</button>
+ <button class="ebt" title="Disjunction. You can also write 'or' or '|'."
+ onclick="add_field('relations', '∨')">∨</button>
+ <button class="ebt" title="Negation. You can also write 'not'."
+ onclick="add_field('relations', '¬')">¬</button>
+ <button class="ebt" title="Implication. You can also write '->'."
+ onclick="add_field('relations', '→')">→</button>
+ <button title="Existential Quantifier. You can also write 'ex' or '\E'."
+ class="ebt" onclick="add_field('relations', '∃')">∃</button>
+ <button title="Universal Quantifier. You can also write 'all' or '\A'."
+ class="ebt" onclick="add_field('relations', '∀')">∀</button>
+ <button class="ebt" onclick="eval_it()">Redraw</button>
+</p>
+<textarea id="relations" rows="3" cols="70">
E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)
</textarea>
-<p>Positions:</p>
-<textarea id="positions" rows="3" cols="60">
+<p>Positions
+ <button class="ebt" onclick="add_field('positions', '+')">+</button>
+ <button class="ebt" onclick="add_field('positions', '-')">-</button>
+ <button class="ebt" onclick="add_field('positions', '·')">·</button>
+ <button class="ebt" onclick="add_field('positions', '/')">/</button>
+ <button class="ebt" onclick="add_field('positions', '^')">^</button>
+ <button class="ebt" onclick="eval_it()">Redraw</button>
+</p>
+
+<textarea id="positions" rows="3" cols="70">
:x(a) = &a;
:y(a) = &a · (10 - &a) / 10
</textarea>
-<p>Elements: <input id="no-elems" type="text" size="4" value="15"></input>
- <button onclick="eval_it()">Draw</button>
-</p>
+</div>
-<p>Examples:</p>
+<div style="position: absolute; top: 4em; right: 0.5em; text-align: left">
+<p>Your Structures</p>
+<ul id="saved-strucs" style="list-style: square; margin-left: -1.5em">
+<li>Nothing here yet</li>
+</ul>
-<button onclick="example_primes()">Primes</button>
+<p>Examples</p>
+<ul style="list-style: square; margin-left: -1.5em">
+<li><button class="obt" onclick="example_basic()">Basic Example</button></li>
+<li><button class="obt" onclick="example_primes()">Prime Numbers</button></li>
+<li><button class="obt" onclick="example_tc()">Transitive Closure</button></li>
+<li><button class="obt" onclick="example_heart()">Heart Drawing</button></li>
+</ul>
-<button onclick="example_tc()">TC</button>
-
<!-- <button onclick="example_3col()">3col</button> -->
-
</div>
-<div id="board-left">
-<canvas id="canvas" height="1100" width="1100"
- onmouseup="mouseup_handle(event)"
- onmousedown="mousedown_handle(event)"
- onmousemove="mousemove_handle(event)">
-This text is displayed if your browser does not support HTML5 Canvas.
-</canvas>
-</div>
-
<div id="bottom">
<div id="bottomright">
<a href="http://toss.sourceforge.net" id="toss-link">Contact</a>
Modified: trunk/Toss/Formula/Lexer.mll
===================================================================
--- trunk/Toss/Formula/Lexer.mll 2012-06-27 23:29:07 UTC (rev 1737)
+++ trunk/Toss/Formula/Lexer.mll 2012-07-02 00:27:40 UTC (rev 1738)
@@ -175,6 +175,7 @@
| "<-" { LARR }
| "<=" { LDARR }
| "->" { RARR }
+ | "→" { RARR }
| "=>" { RDARR }
| "⇒" { RDARR }
| "<->" { LRARR }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <luk...@us...> - 2012-07-03 23:55:28
|
Revision: 1741
http://toss.svn.sourceforge.net/toss/?rev=1741&view=rev
Author: lukaszkaiser
Date: 2012-07-03 23:55:21 +0000 (Tue, 03 Jul 2012)
Log Message:
-----------
Second-order eval debugging and interface.
Modified Paths:
--------------
trunk/Toss/Client/Drawing.ml
trunk/Toss/Client/Drawing.mli
trunk/Toss/Client/JsEval.ml
trunk/Toss/Client/eval.html
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/Formula/BoolFormula.mli
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/Solver.mli
trunk/Toss/Solver/SolverTest.ml
Modified: trunk/Toss/Client/Drawing.ml
===================================================================
--- trunk/Toss/Client/Drawing.ml 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Client/Drawing.ml 2012-07-03 23:55:21 UTC (rev 1741)
@@ -33,31 +33,42 @@
let sina, cosa = sin a, cos a in
{ x = q.x *. cosa -. q.y *. sina ; y = q.x *. sina +. q.y *. cosa } +: start
+(* Colors in RBGA format. *)
+type color = { red: int; blue: int; green: int; alpha: int }
+let defaultCFill = { red=255 ; green = 228 ; blue = 170 ; alpha = 0 }
+let defaultCStroke = { red=38 ; green = 3 ; blue = 20 ; alpha = 0 }
+let defaultCRed = {red=242 ; green=92 ; blue=5 ; alpha = 0 }
+let defaultCGreen = {red=62 ; green=89 ; blue=24 ; alpha = 0 }
+let defaultCBlue = {red=165 ; green=175 ; blue=170 ; alpha = 0 }
+
+let color_to_hex c =
+ Printf.sprintf "%s%.2x%.2x%.2x" "#" c.red c.green c.blue
+
(* Various shapes. *)
type shape =
- | Circle of point * point (* circle, given middle and radiuses *)
- | Line of point * point (* line, given from and to *)
+ | Circle of point * point * color (* circle, given middle and radiuses *)
+ | Line of point * point * color (* line, given from and to *)
let shape_str = function
- | Circle (p, r) -> Printf.sprintf "circle (%F, %F) r (%F, %F)" p.x p.y r.x r.y
- | Line (f, t) -> Printf.sprintf "line (%F, %F) -- (%F, %F)" f.x f.y t.x t.y
+ | Circle (p,r,_)-> Printf.sprintf "circle (%F, %F) r (%F, %F)" p.x p.y r.x r.y
+ | Line (f,t,_) -> Printf.sprintf "line (%F, %F) -- (%F, %F)" f.x f.y t.x t.y
let shapes_str l = String.concat "; " (List.map shape_str l)
(* Shift a shape by [x]. *)
let shift_shape x = function
- | Circle (p, r) -> Circle (p +: x, r)
- | Line (f, t) -> Line (f +: x, t +: x)
+ | Circle (p, r, c) -> Circle (p +: x, r, c)
+ | Line (f, t, c) -> Line (f +: x, t +: x, c)
let shift_shapes x l = List.map (shift_shape x) l
(* Change coordinates in a shape. *)
let change_coords_shape c1 c2 = function
- | Circle (p, r) ->
+ | Circle (p, r, c) ->
let z = {x=0.; y=0.} in
- Circle (change_coords c1 c2 p, change_coords (z, snd c1) (z, snd c2) r)
- | Line (f, t) -> Line (change_coords c1 c2 f, change_coords c1 c2 t)
+ Circle (change_coords c1 c2 p, change_coords (z, snd c1) (z, snd c2) r, c)
+ | Line (f, t, c) -> Line (change_coords c1 c2 f, change_coords c1 c2 t, c)
let change_coords_shapes c1 c2 l = List.map (change_coords_shape c1 c2) l
@@ -69,7 +80,7 @@
(* Calculate where the line [p] -- [q] crosses the shape. *)
let crossing p q = function
- | Circle (m, r) ->
+ | Circle (m, r, _) ->
let norm_coord pt = change_coords (m, r) ({x=0.;y=0.}, {x=1.;y=1.}) pt in
let back_coord pt = change_coords ({x=0.;y=0.}, {x=1.;y=1.}) (m, r) pt in
let p, q = norm_coord p, norm_coord q in
@@ -89,19 +100,19 @@
let xs = quadratic (1. +. d*.d) (2.*.d*.c) (c*.c -. 1.) in
List.map (fun x -> { x = x ; y = d *. (x -. p.x) +. p.y }) xs ) in
List.map back_coord c
- | Line (f, t) -> failwith "crossing not yet implemented for lines"
+ | Line (f, t, _) -> failwith "crossing not yet implemented for lines"
let crossings p q l = Aux.concat_map (crossing p q) l
(* Maximal distance of shape points from (0, 0). *)
let radius_single = function
- | Circle (p, r) -> dist p {x=0.;y=0.} +. (max r.x r.y) (* FIXME *)
- | Line (f, t) -> max (dist f {x=0.;y=0.}) (dist t {x=0.;y=0.})
+ | Circle (p, r, _) -> dist p {x=0.;y=0.} +. (max r.x r.y) (* FIXME *)
+ | Line (f, t, _) -> max (dist f {x=0.;y=0.}) (dist t {x=0.;y=0.})
let radius l = List.fold_left max 0. (List.rev_map radius_single l)
(* Create an arrow from x to y given the shapes of x and y. *)
-let arrow (x, shapes_x) (y, shapes_y) =
+let arrow c (x, shapes_x) (y, shapes_y) =
let len = dist x y in
if len < 0.1 then [] else (
let pl, ql = crossings x y shapes_x, crossings x y shapes_y in
@@ -112,7 +123,8 @@
let p = if pl = [] then x else List.hd pl in
let q = if ql = [] then y else List.hd ql in
let tip = q -: ((y -: q) *! 0.5) in
- [ Line (p, q); Line (q, rotate q 30. tip); Line (q, rotate q (-30.) tip) ]
+ [ Line (p, q, c); Line (q, rotate q 30. tip, c);
+ Line (q, rotate q (-30.) tip, c) ]
)
(* Structure with coordinates for drawing on canvas. *)
@@ -162,7 +174,7 @@
let circles = Structure.rel_graph "Circle" struc in
let radius e =
{x = Structure.fun_val struc "rx" e; y = Structure.fun_val struc "ry" e} in
- let circ e = Circle (get_pos struc e, radius e) in
+ let circ e = Circle (get_pos struc e, radius e, defaultCFill) in
List.map (fun e -> circ e.(0)) (Structure.Tuples.elements circles)
(* Draw an element of a structure with coordinates. *)
@@ -190,29 +202,34 @@
let draw_rel (rel, arity) =
if arity = 1 then
let elems = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- Aux.concat_map (fun a -> [Circle (pos a.(0), {x=10.; y=10.})]) elems
+ let col = match rel with | "|R" -> defaultCRed | "|G" -> defaultCGreen
+ | "|B" -> defaultCBlue | _ -> defaultCFill in
+ Aux.concat_map (fun a -> [Circle (pos a.(0), {x=10.; y=10.}, col)]) elems
else if arity = 2 then
let tuples = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- Aux.concat_map (fun a-> arrow (pos_draw a.(0)) (pos_draw a.(1))) tuples
+ Aux.concat_map (fun a ->
+ arrow defaultCStroke (pos_draw a.(0)) (pos_draw a.(1))) tuples
else [] in
elem_drawings @ (Aux.concat_map draw_rel (Structure.rel_signature struc))
(* Compile the shape to a JavaScript program drawing the shape on 'ctx'. *)
let shape_to_canvas = function
- | Circle (p, r) ->
+ | Circle (p, r, col) ->
+ let fill = "ctx.fillStyle = \""^(color_to_hex col)^"\"; ctx.fill();" in
if r.x = r.y then
let s = Printf.sprintf "ctx.arc(%F,%F,%F,0,2*Math.PI,false); " p.x p.y r.x
- in "ctx.beginPath(); "^ s^"ctx.fill(); ctx.stroke(); ctx.closePath(); "
+ in "ctx.beginPath(); "^ s ^ fill ^ " ctx.stroke(); ctx.closePath(); "
else
let sc = Printf.sprintf "ctx.scale(%F, %F); " (r.x /.100.) (r.y /.100.) in
let tr = Printf.sprintf "ctx.translate(%F, %F); " p.x p.y in
"ctx.save(); "^ tr ^sc ^"ctx.beginPath(); ctx.arc(0,0,100,0,2*Math.PI); "^
- "ctx.stroke(); ctx.closePath(); ctx.restore(); "
- | Line (f, t) ->
+ fill ^ "ctx.stroke(); ctx.closePath(); ctx.restore(); "
+ | Line (f, t, col) ->
let fs = Printf.sprintf "ctx.moveTo(%F,%F); " f.x f.y in
let ts = Printf.sprintf "ctx.lineTo(%F,%F); " t.x t.y in
- "ctx.beginPath(); " ^ fs ^ ts ^ "ctx.stroke(); ctx.closePath(); "
+ let stroke= "ctx.strokeStyle = \""^(color_to_hex col)^"\"; ctx.stroke();" in
+ "ctx.beginPath(); " ^ fs ^ ts ^ stroke ^ " ctx.closePath(); "
let shapes_to_canvas l =
String.concat " " (List.rev (List.rev_map shape_to_canvas l))
Modified: trunk/Toss/Client/Drawing.mli
===================================================================
--- trunk/Toss/Client/Drawing.mli 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Client/Drawing.mli 2012-07-03 23:55:21 UTC (rev 1741)
@@ -24,11 +24,13 @@
(** Rotate the point [p] around [start] by [angle]. *)
val rotate : point -> float -> point -> point
+(** Colors in RBGA format. *)
+type color = { red: int; blue: int; green: int; alpha: int }
(** Shapes. *)
type shape =
- | Circle of point * point (** circle, given middle and radiuses *)
- | Line of point * point (** line, given from and to *)
+ | Circle of point * point * color (** circle, given middle and radiuses *)
+ | Line of point * point * color (** line, given from and to *)
(** Print shapes. *)
val shapes_str : shape list -> string
Modified: trunk/Toss/Client/JsEval.ml
===================================================================
--- trunk/Toss/Client/JsEval.ml 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Client/JsEval.ml 2012-07-03 23:55:21 UTC (rev 1741)
@@ -40,37 +40,17 @@
| _ -> failwith "not a structure"
-(* The Formula evaluation and registration in JS. *)
-let js_eval phi struc =
- let (phi, struc) = (Js.to_string phi, Js.to_string struc) in
- let (f, struc) = (formula_of_string phi, structure_of_string struc) in
- Js.string (AssignmentSet.named_str struc (Solver.M.evaluate struc f))
-
-
-(*
-let js_eval_so phi struc =
- let (phi, struc) = (Js.to_string phi, Js.to_string struc) in
- let (f, struc) = (formula_of_string phi, structure_of_string struc) in
- let qbf = (Solver.so_to_qbf struc f) in
- let sat = (Solver.elim_quant_naiv qbf) in
- LOG 0 "Formula: %s" (Formula.str f);
- LOG 0 "QBF Formula: %s" (BoolFormula.qbf_str qbf);
- LOG 0 "SAT Formula: %s" (BoolFormula.str sat);
- Js.string (AssignmentSet.named_str struc (Solver.eval_so struc f))
-*)
-
-let _ = set_handle "eval" js_eval
-
-
-
-
(* Drawing the structure. *)
-let draw_struc_js struc_s =
- let st = structure_of_string (Js.to_string struc_s) in
+let draw_struc_js so_s struc_s =
+ let st, so = structure_of_string (Js.to_string struc_s), Js.to_string so_s in
+ let st, so_res = if Aux.strip_spaces so = "" then (st, "none") else
+ let so_phi = formula_of_string so in
+ let st, res = Solver.find_so st so_phi in
+ if res then st, "true" else st, "false" in
let st_c = Drawing.add_coords 1000. 1000. 50. 50. None None st in
cur_st := st_c;
let draw = Drawing.shapes_to_canvas (Drawing.draw_struc st_c) in
- Js.string ("clear_canvas (); " ^ draw)
+ Js.array [|Js.string ("clear_canvas (); " ^ draw) ; Js.string so_res |]
let _ = set_handle "draw_struc" draw_struc_js
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Client/eval.html 2012-07-03 23:55:21 UTC (rev 1741)
@@ -48,19 +48,33 @@
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
-function eval_it () {
+function draw_it () {
var rels = document.getElementById ("relations").value;
var pos = document.getElementById ("positions").value;
var elemsF = document.getElementById ("no-elems-start").value;
var elemsT = document.getElementById ("no-elems-end").value;
var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with " +
rels + " with " + pos;
- ASYNCH ("draw_struc", [struc], true, function (s) {
+ ASYNCH ("draw_struc", ["", struc], true, function (a) {
var ctx = document.getElementById("canvas").getContext("2d");
- eval (s);
+ eval (a[0])
})
}
+function find_draw_it () {
+ var rels = document.getElementById ("relations").value;
+ var pos = document.getElementById ("positions").value;
+ var elemsF = document.getElementById ("no-elems-start").value;
+ var elemsT = document.getElementById ("no-elems-end").value;
+ var so = document.getElementById ("second-order").value;
+ var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with " +
+ rels + " with " + pos;
+ ASYNCH ("draw_struc", [so, struc], true, function (a) {
+ var ctx = document.getElementById("canvas").getContext("2d");
+ eval (a[0]);
+ alert (a[1])
+ })
+}
function canvasCoords (eventPageX, eventPageY) { // From stackoverflow.com
var totalOffsetX = 0;
@@ -157,11 +171,11 @@
function example_primes () {
document.getElementById ("struc-name").value = "Prime Numbers";
document.getElementById ("relations").value =
- "P(z) = &z > 1 and ∀ x, y \n (&x · &y = &z → (&x = 1 ∨ &y = 1))";
+ "P(z) = &z > 1 and ∀ x,y \n (&x · &y = &z → (&x = 1 ∨ &y = 1))";
document.getElementById ("positions").value = ":x(a) = &a; \n:y(a) = 0";
document.getElementById ("no-elems-start").value = "1";
document.getElementById ("no-elems-end").value = "10";
- eval_it ();
+ draw_it ();
}
function example_tc () {
@@ -172,7 +186,7 @@
document.getElementById("positions").value=":x(a) = 5·&a;\n:y(a) = &a·&a / 2";
document.getElementById ("no-elems-start").value = "1";
document.getElementById("no-elems-end").value = "4";
- eval_it ();
+ draw_it ();
}
function example_basic () {
@@ -183,19 +197,21 @@
":y(a) = &a · (10 - &a) / 10";
document.getElementById ("no-elems-start").value = "1";
document.getElementById ("no-elems-end").value = "15";
- eval_it ();
+ draw_it ();
}
+function example_2col () {
+ document.getElementById ("second-order").value =
+ "∀ x,y ( (|R(x) ∨ |G(x)) ∧ ( E(x,y) → " +
+ "\n ¬( (|R(x) ∧ |R(y)) ∨ (|G(x) ∧ |G(y)) ) ) )";
+ find_draw_it ();
+}
+
function example_3col () {
- document.getElementById ("formula").value =
- "ex |R, |G, |B all x, y ( \n ( |R(x) or |G(x) or |B(x)) and (" +
- "\n E(x,y) -> not ( ( |R(x) and |R(y)) " +
- "\n or (|G(x) and |G(y)) or (|B(x) and |B(y)) ) ) )";
- document.getElementById ("structure").value =
- "[ | E { (a, b); (b, c); (c, a) } | " +
- "\n x { a -> 1, b -> 2, c -> 3 }; " +
- "\n y { a -> 0, b -> -1, c -> 0 } ]";
- eval_it ();
+ document.getElementById ("second-order").value =
+ "∀ x,y ( ( |R(x) ∨ |G(x) ∨ |B(x)) ∧ ( E(x,y) → " +
+ "\n ¬( (|R(x) ∧ |R(y)) ∨ (|G(x) ∧ |G(y)) ∨ (|B(x) ∧ |B(y)) ) ) )";
+ find_draw_it ();
}
function example_heart () {
@@ -211,28 +227,31 @@
" :(&a > 18) · (:(:b ≤ 10) ·:b · (10 - :b) / 10 - :(:b > 10)·(:b - 10))";
document.getElementById ("no-elems-start").value = "1";
document.getElementById ("no-elems-end").value = "37";
- eval_it ();
+ draw_it ();
}
function add_field (field, s) {
var e = document.getElementById(field);
var cursor = e.selectionStart;
+ var selEnd = e.selectionEnd;
var v1 = e.value.substring(0, cursor);
var v2 = e.value.substring(cursor, e.value.length);
e.value = v1 + s + " " + v2;
e.selectionStart = cursor + 2;
+ e.selectionEnd = selEnd + 2;
+ e.focus();
}
function add_elem () {
var e = document.getElementById ("no-elems-end").value;
document.getElementById ("no-elems-end").value = parseInt(e) + 1;
- eval_it ();
+ draw_it ();
}
function del_elem () {
var e = document.getElementById ("no-elems-end").value;
document.getElementById ("no-elems-end").value = parseInt(e) - 1;
- eval_it ();
+ draw_it ();
}
function save () {
@@ -258,7 +277,7 @@
localStorage["TRelStrucExplRel"+name];
document.getElementById ("positions").value =
localStorage["TRelStrucExplPos"+name];
- eval_it ();
+ draw_it ();
}
function list_stored () {
@@ -322,7 +341,7 @@
</script>
</head>
-<body onload="init_canvas (); list_stored (); eval_it (); adjust_to_width()">
+<body onload="init_canvas (); list_stored (); draw_it (); adjust_to_width()">
<div id="main">
<div id="top">
@@ -381,7 +400,7 @@
class="ebt" onclick="add_field('relations', '∃')">∃</button>
<button title="Universal Quantifier. You can also write 'all' or '\A'."
class="ebt" onclick="add_field('relations', '∀')">∀</button>
- <button class="ebt" onclick="eval_it()">Redraw</button>
+ <button class="ebt" onclick="draw_it()">Redraw</button>
</p>
<textarea id="relations" rows="3" cols="70">
E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)
@@ -393,7 +412,7 @@
<button class="ebt" onclick="add_field('positions', '·')">·</button>
<button class="ebt" onclick="add_field('positions', '/')">/</button>
<button class="ebt" onclick="add_field('positions', '^')">^</button>
- <button class="ebt" onclick="eval_it()">Redraw</button>
+ <button class="ebt" onclick="draw_it()">Redraw</button>
</p>
<textarea id="positions" rows="3" cols="70">
@@ -401,6 +420,24 @@
:y(a) = &a · (10 - &a) / 10
</textarea>
+<p>Second-Order Finder
+ <button class="ebt" title="Conjunction. You can also write 'and' or '&'."
+ onclick="add_field('second-order', '∧')">∧</button>
+ <button class="ebt" title="Disjunction. You can also write 'or' or '|'."
+ onclick="add_field('second-order', '∨')">∨</button>
+ <button class="ebt" title="Negation. You can also write 'not'."
+ onclick="add_field('second-order', '¬')">¬</button>
+ <button class="ebt" title="Implication. You can also write '->'."
+ onclick="add_field('second-order', '→')">→</button>
+ <button title="Existential Quantifier. You can also write 'ex' or '\E'."
+ class="ebt" onclick="add_field('second-order', '∃')">∃</button>
+ <button title="Universal Quantifier. You can also write 'all' or '\A'."
+ class="ebt" onclick="add_field('second-order', '∀')">∀</button>
+ <button class="ebt" onclick="find_draw_it()">Find</button>
+</p>
+<textarea id="second-order" rows="3" cols="70">
+</textarea>
+
</div>
<div style="position: absolute; top: 4em; right: 0.5em; text-align: left">
@@ -417,7 +454,12 @@
<li><button class="obt" onclick="example_heart()">Heart Drawing</button></li>
</ul>
-<!-- <button onclick="example_3col()">3col</button> -->
+<p>Second-Order Formulas</p>
+<ul style="list-style: square; margin-left: -1.5em">
+<li><button class="obt" onclick="example_2col()">2-coloring</button></li>
+<li><button class="obt" onclick="example_3col()">3-coloring</button></li>
+</ul>
+
</div>
Modified: trunk/Toss/Formula/BoolFormula.ml
===================================================================
--- trunk/Toss/Formula/BoolFormula.ml 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Formula/BoolFormula.ml 2012-07-03 23:55:21 UTC (rev 1741)
@@ -639,6 +639,14 @@
List.for_all (fun x -> List.exists (fun y -> y=x) b) a in
List.filter (fun x -> List.for_all (fun y -> x=y || not(subset y x)) cnf) cnf
+let find_model phi =
+ let arg = flatten (to_nnf ~neg:true phi) in
+ let (sep, aux_phi) = pg_auxcnf_of_bool_formula arg in
+ match Sat.sat (listcnf_of_boolcnf aux_phi) with
+ | None -> None
+ | Some l ->
+ let valid = List.filter (fun v -> v < sep && v > -sep) l in
+ Some (Aux.unique_sorted valid)
let convert ?(disc_vars=[]) phi =
(* input is a Boolean combination; output is a list of list of integers
@@ -900,26 +908,29 @@
| QAll of int list * qbf
(* Print a QBF formula. *)
-let rec qbf_str = function
- | QVar v -> var_str v
- | QNot phi -> "(not " ^ (qbf_str phi) ^ ")"
- | QAnd [] -> "true"
- | QOr [] -> "false"
- | QAnd (qbflist) -> qbf_list_str " and " qbflist
- | QOr (qbflist) -> qbf_list_str " or " qbflist
- | QEx (vars, phi) ->
- "(ex " ^ (String.concat ", " (List.map string_of_int vars)) ^
- " " ^ qbf_str phi ^ ")"
- | QAll (vars, phi) ->
- "(all " ^ (String.concat ", " (List.map string_of_int vars)) ^
- " " ^ qbf_str phi ^ ")"
+let qbf_str ?names phi =
+ let name s = match names with None -> var_str s | Some tbl ->
+ try Hashtbl.find tbl s with Not_found -> var_str s in
+ let rec qbf_str_rec = function
+ | QVar v -> name v
+ | QNot phi -> "(not " ^ (qbf_str_rec phi) ^ ")"
+ | QAnd [] -> "true"
+ | QOr [] -> "false"
+ | QAnd (qbflist) -> qbf_list_str " and " qbflist
+ | QOr (qbflist) -> qbf_list_str " or " qbflist
+ | QEx (vars, phi) ->
+ "(ex " ^ (String.concat ", " (List.map name vars)) ^
+ " " ^ qbf_str_rec phi ^ ")"
+ | QAll (vars, phi) ->
+ "(all " ^ (String.concat ", " (List.map name vars)) ^
+ " " ^ qbf_str_rec phi ^ ")"
+ and qbf_list_str sep = function
+ | [] -> "[]"
+ | [phi] -> qbf_str_rec phi
+ | lst -> "(" ^ (String.concat sep (List.map qbf_str_rec lst)) ^ ")"
+ in qbf_str_rec phi
-and qbf_list_str sep = function
- | [] -> "[]"
- | [phi] -> qbf_str phi
- | lst -> "(" ^ (String.concat sep (List.map qbf_str lst)) ^ ")"
-
(* Read a qdimacs description of a QBF from [in_ch]. *)
let read_qdimacs in_str =
let in_ch = ref in_str in
Modified: trunk/Toss/Formula/BoolFormula.mli
===================================================================
--- trunk/Toss/Formula/BoolFormula.mli 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Formula/BoolFormula.mli 2012-07-03 23:55:21 UTC (rev 1741)
@@ -53,6 +53,10 @@
(** Convert a Boolean formula to NNF and additionally negate if [neg] is set. *)
val to_nnf : ?neg : bool -> bool_formula -> bool_formula
+(** Find a model for a Boolean formula. *)
+val find_model : bool_formula -> int list option
+
+(** Convert a Boolean formula to CNF. If you only want SAT, use find_model. *)
val convert : ?disc_vars: int list -> bool_formula -> int list list
(** Convert an arbitrary formula to CNF via Boolean combinations. *)
@@ -88,7 +92,7 @@
| QAll of int list * qbf
(** Print a QBF formula. *)
-val qbf_str : qbf -> string
+val qbf_str : ?names: (int, string) Hashtbl.t -> qbf -> string
(** Read a qdimacs description of a QBF from a string. *)
val read_qdimacs : string -> qbf
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Solver/Solver.ml 2012-07-03 23:55:21 UTC (rev 1741)
@@ -398,11 +398,23 @@
(* Compute the QBF equivalent to the given SO formula on the given structure. *)
let so_to_qbf struc psi =
- let ids, free_id, elems = Hashtbl.create 7, ref 0, Structure.elements struc in
+ let assoc_or_zero asgn x = try List.assoc x asgn with Not_found -> 0 in
+ let ids, rev_ids, free_id = Hashtbl.create 7, Hashtbl.create 7, ref 0 in
+ let elems = Structure.elements struc in
let get_id x = try Hashtbl.find ids x with Not_found ->
- (Hashtbl.add ids x (!free_id +1); incr free_id; !free_id ) in
- let compute_id var args asgn = get_id (var, args, asgn) in
- let assoc_or_zero asgn x = try List.assoc x asgn with Not_found -> 0 in
+ (Hashtbl.add ids x (!free_id +1);
+ Hashtbl.add rev_ids (!free_id +1) x;
+ incr free_id;
+ !free_id) in
+ let compute_id rel args asgn =
+ let asgnlist = Array.map (assoc_or_zero asgn) args in
+ get_id (rel, asgnlist) in
+ let make_conj qphil =
+ QAnd (List.rev (List.fold_left (fun l f -> match f with
+ QAnd fl -> List.rev_append fl l | _ -> f :: l) [] qphil)) in
+ let make_disj qphil =
+ QOr (List.rev (List.fold_left (fun l f -> match f with
+ QOr fl -> List.rev_append fl l | _ -> f :: l) [] qphil)) in
(* Reduce the Evaluation Problem of SO formulae to QBF *)
let rec so_to_qbf_rec asgn = function
| SO (rel, args) ->
@@ -421,15 +433,13 @@
let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
let dictl = (List.map snd resl) in
(try (List.find (fun x -> x = QOr []) qphil, [])
- with Not_found ->
- (QAnd (List.filter (fun x -> x <> QAnd []) qphil), List.concat dictl)
- )
+ with Not_found -> (make_conj qphil, List.concat dictl) )
| Or phil ->
let resl = (List.map (fun phi -> (so_to_qbf_rec asgn phi)) phil) in
let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
let dictl = (List.map (snd) resl) in
- (try ((List.find (fun x -> x = QAnd []) qphil), []) with Not_found ->
- (QOr (List.filter (fun x -> x <> QOr []) qphil), List.concat dictl)
+ (try (List.find (fun x -> x = QAnd []) qphil, [])
+ with Not_found -> (make_disj qphil, List.concat dictl)
)
| Not phi ->
let (qphi, dict) = so_to_qbf_rec asgn phi in
@@ -442,8 +452,8 @@
let res = List.map (fun x -> so_to_qbf_rec x (Ex (tl, phi))) asgn_list in
let (qphil, dictl) =
((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res) in
- (try (List.find (fun x -> x = QAnd []) qphil, []) with Not_found ->
- (QOr (List.filter (fun x-> x <> QOr []) qphil), List.concat dictl)
+ (try (List.find (fun x -> x = QAnd []) qphil, [])
+ with Not_found ->(make_disj qphil, List.concat dictl)
)
| Ex (var::tl, phi) when is_so var ->
let (qbf_phi, dict_phi) = (so_to_qbf_rec asgn (Ex (tl, phi))) in
@@ -460,10 +470,8 @@
let res = List.map (fun x -> so_to_qbf_rec x (All (tl, phi))) asgn_list in
let (qphil, dictl) =
((Aux.unique_sorted (List.map (fst) res)), List.map (snd) res) in
- (try
- ((List.find (fun x -> x = (QOr [])) qphil), [])
- with Not_found ->
- (QAnd (List.filter (fun x -> x <> (QAnd [])) qphil), List.concat dictl)
+ (try (List.find (fun x -> x = (QOr [])) qphil, [])
+ with Not_found -> (make_conj qphil, List.concat dictl)
)
| All (var::tl, phi) when is_so var ->
let (qbf_phi, dict_phi) = so_to_qbf_rec asgn (All (tl, phi)) in
@@ -475,18 +483,44 @@
else (QAll (rel_qbf_vars, qbf_phi), dict_phi)
| All (var::tl, _) -> (*stub*) failwith "not implemented yet (so_qbf_All)"
| _ -> failwith "not implemented yet (so_qbf_Other)"
- in fst (so_to_qbf_rec [] psi)
+ in (fst (so_to_qbf_rec [] psi), rev_ids)
(* Evaluation with second-order variables. *)
let eval_so struc phi =
- let qbf = so_to_qbf struc phi in
- let bf = (* BoolFormula.sat_of_qbf qbf *) BoolFormula.elim_quant qbf in
- let cnf = BoolFormula.convert bf in
- LOG 1 "QBF %s BF %s CNF %s:" (BoolFormula.qbf_str qbf) (BoolFormula.str bf)
- (Sat.cnf_str cnf);
- if Sat.is_sat cnf then Any else Empty
-
+ let fv = FormulaSubst.free_vars phi in
+ if fv <> [] then failwith "eval_so: free variables not allowed yet" else
+ let qbf, rev_ids = so_to_qbf struc phi in
+ let rec no_ex f = match f with QEx (_, g) -> no_ex g | _ -> f in
+ let bf = BoolFormula.elim_quant (no_ex qbf) in
+ LOG 1 "QBF %s BF %s" (BoolFormula.qbf_str qbf) (BoolFormula.str bf);
+ match BoolFormula.find_model bf with
+ | None -> Empty
+ | Some l ->
+ let mkname (rel,arr) = (String.sub rel 1 (String.length rel - 1)) ^"."^
+ (String.concat "." (Array.to_list (Array.map string_of_int arr))) in
+ let vname i =
+ try let n = mkname (Hashtbl.find rev_ids (abs i)) in
+ if i > 0 then n else "-" ^ n
+ with Not_found -> string_of_int i in
+ LOG 1 "%s" (String.concat ", " (List.map vname l));
+ Any
+
+(* Find assignment for second-order variables and add it to the structure. *)
+let find_so struc phi =
+ let fv = FormulaSubst.free_vars phi in
+ if not (List.for_all is_so fv) then failwith "find_so: non-so free vars" else
+ let qbf, rev_ids = so_to_qbf struc phi in
+ let bf = BoolFormula.elim_quant qbf in
+ LOG 1 "QBF %s BF %s" (BoolFormula.qbf_str qbf) (BoolFormula.str bf);
+ match BoolFormula.find_model bf with
+ | None -> (struc, false)
+ | Some l ->
+ let add_var_rel s i = if i < 0 then s else
+ let (rname, tup) = Hashtbl.find rev_ids i in
+ Structure.add_rel s rname tup in
+ (List.fold_left add_var_rel struc l, true)
+
(* Eval with very basic caching. *)
let eval_m struc phi =
if phi = And [] then Any else (
Modified: trunk/Toss/Solver/Solver.mli
===================================================================
--- trunk/Toss/Solver/Solver.mli 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Solver/Solver.mli 2012-07-03 23:55:21 UTC (rev 1741)
@@ -39,5 +39,9 @@
val eval_counter : int ref
(** Compute the QBF equivalent to the given SO formula on the given structure.*)
-val so_to_qbf : Structure.structure -> Formula.formula -> BoolFormula.qbf
+val so_to_qbf : Structure.structure -> Formula.formula ->
+ BoolFormula.qbf * (int, string * int array) Hashtbl.t
+(** Find assignment for second-order variables and add it to the structure. *)
+val find_so :
+ Structure.structure -> Formula.formula -> Structure.structure * bool
Modified: trunk/Toss/Solver/SolverTest.ml
===================================================================
--- trunk/Toss/Solver/SolverTest.ml 2012-07-02 22:31:54 UTC (rev 1740)
+++ trunk/Toss/Solver/SolverTest.ml 2012-07-03 23:55:21 UTC (rev 1741)
@@ -165,20 +165,41 @@
"{ z->1, z->2, z->3 }";
);
- "convert: second-order to QBF" >::
+ "convert: second-order to QBF and find_so" >::
(fun () ->
let qbf_str_eq struc_s phi_s qbf_s =
let phi, struc = formula_of_string phi_s, struc_of_string struc_s in
LOG 1 "%s" (Formula.str phi);
+ let (qbf_res, rev_ids) = Solver.so_to_qbf struc phi in
+ let name (rel, arr) = (String.sub rel 1 (String.length rel - 1)) ^ "." ^
+ (String.concat "." (Array.to_list (Array.map string_of_int arr))) in
+ let names_tbl = Hashtbl.create (Hashtbl.length rev_ids) in
+ Hashtbl.iter (fun k v -> Hashtbl.add names_tbl k (name v)) rev_ids;
assert_equal ~printer:(fun x -> x) qbf_s
- (BoolFormula.qbf_str (Solver.so_to_qbf struc phi)) in(
+ (BoolFormula.qbf_str ~names:names_tbl qbf_res) in
+
qbf_str_eq "[ a, b | T { a } | ]" "ex |R all x, y (T(x) or |R (x, y))"
- "(ex 3, 4 (3 and 4))";
- qbf_str_eq "[ a, b | T { a } | ]" "all |Q all x, y (T(x) or Q(y) or (x = y))"
- "false";
- qbf_str_eq "[ a, b, c | E { (a,b); (b,c); (c,a) } | ]" ("ex |R, |G all x, y ( (|R(x) or |G(x)) and (" ^ " E(x,y) -> not ( (|R(x) and |R(y)) " ^ " or (|G(x) and |G(y)))))")
- "(ex 1, 5, 7, 9, 13, 17, 21, 23, 25, 27, 29, 33 (ex 2, 6, 8, 10, 14, 18, 22, 24, 26, 28, 30, 34 (((1 or 2) and ((5 or 6) and (not ((5 and 7) or (6 and 8)))) and (9 or 10)) and ((13 or 14) and (17 or 18) and ((21 or 22) and (not ((21 and 23) or (22 and 24))))) and (((25 or 26) and (not ((25 and 27) or (26 and 28)))) and (29 or 30) and (33 or 34)))))";
- );
+ "(ex R.2.1, R.2.2 (R.2.1 and R.2.2))";
+ qbf_str_eq "[ a, b | T { a } | ]"
+ "all |Q all x, y (T(x) or Q(y) or (x = y))" "false";
+ qbf_str_eq "[ a, b, c | E { (a,b); (b,c); (c,a) } | ]"
+ ("ex |R, |G all x, y...
[truncated message content] |
|
From: <luk...@us...> - 2012-07-05 00:25:45
|
Revision: 1742
http://toss.svn.sourceforge.net/toss/?rev=1742&view=rev
Author: lukaszkaiser
Date: 2012-07-05 00:25:38 +0000 (Thu, 05 Jul 2012)
Log Message:
-----------
Work on the structure explorer interface and making stuff tail-recursive in BoolFormula and Solver.
Modified Paths:
--------------
trunk/Toss/Client/Drawing.ml
trunk/Toss/Client/Drawing.mli
trunk/Toss/Client/DrawingTest.ml
trunk/Toss/Client/JsEval.ml
trunk/Toss/Client/Style.css
trunk/Toss/Client/eval.html
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/README
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/SolverTest.ml
trunk/Toss/www/contact.xml
trunk/Toss/www/index.xml
Modified: trunk/Toss/Client/Drawing.ml
===================================================================
--- trunk/Toss/Client/Drawing.ml 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Client/Drawing.ml 2012-07-05 00:25:38 UTC (rev 1742)
@@ -34,16 +34,19 @@
{ x = q.x *. cosa -. q.y *. sina ; y = q.x *. sina +. q.y *. cosa } +: start
(* Colors in RBGA format. *)
-type color = { red: int; blue: int; green: int; alpha: int }
+type color = { red: int; blue: int; green: int; opacity: float }
-let defaultCFill = { red=255 ; green = 228 ; blue = 170 ; alpha = 0 }
-let defaultCStroke = { red=38 ; green = 3 ; blue = 20 ; alpha = 0 }
-let defaultCRed = {red=242 ; green=92 ; blue=5 ; alpha = 0 }
-let defaultCGreen = {red=62 ; green=89 ; blue=24 ; alpha = 0 }
-let defaultCBlue = {red=165 ; green=175 ; blue=170 ; alpha = 0 }
+let defaultCFill = { red=255 ; green = 228 ; blue = 170 ; opacity = 0.5 }
+let defaultCStroke = { red=38 ; green = 3 ; blue = 20 ; opacity = 0.5 }
+let defaultCRed = {red=242 ; green=92 ; blue=5 ; opacity = 1. }
+let defaultCGreen = {red=62 ; green=89 ; blue=24 ; opacity = 1. }
+let defaultCBlue = {red=165 ; green=175 ; blue=170 ; opacity = 1. }
-let color_to_hex c =
- Printf.sprintf "%s%.2x%.2x%.2x" "#" c.red c.green c.blue
+let color_to_str c =
+ let op = string_of_float c.opacity in
+ let l = String.length op - 1 in
+ let op = if op.[l] = '.' then String.sub op 0 l else op in
+ Printf.sprintf "rgba(%i, %i, %i, %s)" c.red c.green c.blue op
(* Various shapes. *)
type shape =
@@ -207,8 +210,8 @@
Aux.concat_map (fun a -> [Circle (pos a.(0), {x=10.; y=10.}, col)]) elems
else if arity = 2 then
let tuples = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- Aux.concat_map (fun a ->
- arrow defaultCStroke (pos_draw a.(0)) (pos_draw a.(1))) tuples
+ let c = if rel.[0] = '|' then defaultCRed else defaultCStroke in
+ Aux.concat_map (fun a -> arrow c (pos_draw a.(0)) (pos_draw a.(1))) tuples
else [] in
elem_drawings @ (Aux.concat_map draw_rel (Structure.rel_signature struc))
@@ -216,7 +219,7 @@
(* Compile the shape to a JavaScript program drawing the shape on 'ctx'. *)
let shape_to_canvas = function
| Circle (p, r, col) ->
- let fill = "ctx.fillStyle = \""^(color_to_hex col)^"\"; ctx.fill();" in
+ let fill = "ctx.fillStyle = \""^(color_to_str col)^"\"; ctx.fill();" in
if r.x = r.y then
let s = Printf.sprintf "ctx.arc(%F,%F,%F,0,2*Math.PI,false); " p.x p.y r.x
in "ctx.beginPath(); "^ s ^ fill ^ " ctx.stroke(); ctx.closePath(); "
@@ -228,7 +231,7 @@
| Line (f, t, col) ->
let fs = Printf.sprintf "ctx.moveTo(%F,%F); " f.x f.y in
let ts = Printf.sprintf "ctx.lineTo(%F,%F); " t.x t.y in
- let stroke= "ctx.strokeStyle = \""^(color_to_hex col)^"\"; ctx.stroke();" in
+ let stroke= "ctx.strokeStyle = \""^(color_to_str col)^"\"; ctx.stroke();" in
"ctx.beginPath(); " ^ fs ^ ts ^ stroke ^ " ctx.closePath(); "
let shapes_to_canvas l =
Modified: trunk/Toss/Client/Drawing.mli
===================================================================
--- trunk/Toss/Client/Drawing.mli 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Client/Drawing.mli 2012-07-05 00:25:38 UTC (rev 1742)
@@ -25,8 +25,15 @@
val rotate : point -> float -> point -> point
(** Colors in RBGA format. *)
-type color = { red: int; blue: int; green: int; alpha: int }
+type color = { red: int; blue: int; green: int; opacity: float }
+(** Default filling color. *)
+val defaultCFill : color
+
+(** Default stroke color. *)
+val defaultCStroke : color
+
+
(** Shapes. *)
type shape =
| Circle of point * point * color (** circle, given middle and radiuses *)
Modified: trunk/Toss/Client/DrawingTest.ml
===================================================================
--- trunk/Toss/Client/DrawingTest.ml 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Client/DrawingTest.ml 2012-07-05 00:25:38 UTC (rev 1742)
@@ -8,6 +8,8 @@
let str p = Printf.sprintf "(%F, %F)" p.x p.y in
assert_equal ~printer:(fun l -> String.concat ", " (List.map str l)) pl ql
+let circ p q = Circle (p, q, defaultCFill)
+
let tests = "Drawing" >::: [
"change coords" >::
(fun () ->
@@ -20,10 +22,10 @@
"crossings" >::
(fun () ->
let z, o, hsq2 = {x=0.;y=0.}, {x=1.;y=1.}, (sqrt 2.) *. 0.5 in
- eq_point_list [o*!hsq2; o *! (-1.*.hsq2)] (crossings z o [Circle (z, o)]);
- eq_point_list [{x=1.;y=0.}] (crossings z {x=1.;y=0.} [Circle (o, o)]);
+ eq_point_list [o*!hsq2; o *! (-1.*.hsq2)] (crossings z o [circ z o]);
+ eq_point_list [{x=1.;y=0.}] (crossings z {x=1.;y=0.} [circ o o]);
eq_point_list [{x = 2. ; y = 0.}; {x = -2. ; y = 0.}]
- (crossings z {x=1.; y=0.} [Circle (z, o *! 2.)]);
+ (crossings z {x=1.; y=0.} [circ z (o *! 2.)]);
);
]
Modified: trunk/Toss/Client/JsEval.ml
===================================================================
--- trunk/Toss/Client/JsEval.ml 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Client/JsEval.ml 2012-07-05 00:25:38 UTC (rev 1742)
@@ -30,11 +30,11 @@
(* Parse a formula. *)
let formula_of_string s = FormulaParser.parse_formula Lexer.lex
- (Lexing.from_string (Aux.normalize_spaces s))
+ (Lexing.from_string (Aux.strip_spaces s))
(* Parse a structure. *)
let structure_of_string s =
- let str = "START " ^ (Aux.normalize_spaces s) in
+ let str = "START " ^ (Aux.strip_spaces s) in
match ArenaParser.parse_game_defs Lexer.lex (Lexing.from_string str) with
| Arena.StartStruc struc -> struc
| _ -> failwith "not a structure"
@@ -42,15 +42,33 @@
(* Drawing the structure. *)
let draw_struc_js so_s struc_s =
- let st, so = structure_of_string (Js.to_string struc_s), Js.to_string so_s in
- let st, so_res = if Aux.strip_spaces so = "" then (st, "none") else
- let so_phi = formula_of_string so in
- let st, res = Solver.find_so st so_phi in
- if res then st, "true" else st, "false" in
- let st_c = Drawing.add_coords 1000. 1000. 50. 50. None None st in
- cur_st := st_c;
- let draw = Drawing.shapes_to_canvas (Drawing.draw_struc st_c) in
- Js.array [|Js.string ("clear_canvas (); " ^ draw) ; Js.string so_res |]
+ let err msg =
+ let js_msg = Js.string ("put_msg('" ^ msg ^ "', 5000);") in
+ Js.array [|js_msg; Js.string "Error"|] in
+ let error_msg where = function
+ | Lexer.Parsing_error m when String.length m > 15 &&
+ String.sub m 0 15 = "File \"\", lines " ->
+ let ms = String.sub m 15 ((String.index m '\n') - 16) in
+ let l, c = String.sub ms 0 (String.index ms '-'), String.index ms ',' in
+ let chars = String.sub ms (c+1) ((String.length ms)-c-1) in
+ let l = string_of_int ((int_of_string l) - 1) in
+ err (where ^ " parsing error in line " ^ l ^ "," ^ chars)
+ | x -> err (where ^ " error:<br />" ^
+ (Aux.str_subst_all "\n" "<br/>" (Printexc.to_string x))) in
+ try
+ let st = structure_of_string (Js.to_string struc_s) in
+ try
+ let so = Js.to_string so_s in
+ let st, so_res = if Aux.strip_spaces so = "" then (st, "No Formula") else
+ let so_phi = formula_of_string so in
+ let st, res = Solver.find_so st so_phi in
+ if res then st, "Formula Satisfied" else st,"Formula Unsatisfiable" in
+ let st_c = Drawing.add_coords 1000. 1000. 50. 50. None None st in
+ cur_st := st_c;
+ let draw = Drawing.shapes_to_canvas (Drawing.draw_struc st_c) in
+ Js.array [|Js.string ("clear_canvas (); " ^ draw) ; Js.string so_res |]
+ with x -> error_msg "Formula" x
+ with x -> error_msg "Structure" x
let _ = set_handle "draw_struc" draw_struc_js
Modified: trunk/Toss/Client/Style.css
===================================================================
--- trunk/Toss/Client/Style.css 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Client/Style.css 2012-07-05 00:25:38 UTC (rev 1742)
@@ -64,7 +64,7 @@
float: right;
}
-.obt, .boldobt, .gamebt, .ebt {
+.obt, .boldobt, .gamebt, .ebt, .ebts {
text-align: left;
border-color: #260314;
border-radius: 4px;
@@ -76,7 +76,7 @@
font-family: Verdana, 'TeXGyreHerosRegular', sans;
}
-.obt:hover, .ebt:hover, .boldobt:hover, .gamebt:hover {
+.obt:hover, .ebt:hover, .ebts:hover, .boldobt:hover, .gamebt:hover {
cursor: pointer;
text-decoration: underline;
}
@@ -86,9 +86,10 @@
font-size: 1em;
}
-.ebt {
+.ebt, .ebts {
/*font-weight: bold;*/
- border-width: 2px;
+ text-align: center;
+ border-width: 1px;
}
.gamebt {
@@ -902,6 +903,7 @@
position: relative;
left: 2em;
top: 5em;
+ width: 30em;
}
#board {
@@ -929,6 +931,7 @@
background-color: #400827;
padding: 1em;
border: 1px solid #260314;
+ z-index: 100;
}
#opening {
@@ -1006,8 +1009,8 @@
}
#canvas {
- width: 28em;
- height: 28em;
+ width: 29em;
+ height: 29em;
border: 2px solid #260314;
}
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Client/eval.html 2012-07-05 00:25:38 UTC (rev 1742)
@@ -53,8 +53,8 @@
var pos = document.getElementById ("positions").value;
var elemsF = document.getElementById ("no-elems-start").value;
var elemsT = document.getElementById ("no-elems-end").value;
- var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with " +
- rels + " with " + pos;
+ var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with \n" +
+ rels + " with \n" + pos;
ASYNCH ("draw_struc", ["", struc], true, function (a) {
var ctx = document.getElementById("canvas").getContext("2d");
eval (a[0])
@@ -67,12 +67,12 @@
var elemsF = document.getElementById ("no-elems-start").value;
var elemsT = document.getElementById ("no-elems-end").value;
var so = document.getElementById ("second-order").value;
- var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with " +
- rels + " with " + pos;
+ var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with \n" +
+ rels + " with \n" + pos;
ASYNCH ("draw_struc", [so, struc], true, function (a) {
var ctx = document.getElementById("canvas").getContext("2d");
eval (a[0]);
- alert (a[1])
+ if (a[1] !== "Error") { put_msg (a[1], 2000) }
})
}
@@ -200,6 +200,14 @@
draw_it ();
}
+function example_matching () {
+ document.getElementById ("second-order").value =
+ "∀ x,y ( |M(x, y) -> (\n" +
+ " ( E(x, y) ∨ E(y, x) ) ∧ ¬∃ z (z≠y ∧ |M(x, z) )\n" +
+ ") ) ∧ ∀ x ∃ y |M(x, y)";
+ find_draw_it ();
+}
+
function example_2col () {
document.getElementById ("second-order").value =
"∀ x,y ( (|R(x) ∨ |G(x)) ∧ ( E(x,y) → " +
@@ -254,7 +262,7 @@
draw_it ();
}
-function save () {
+function save_struc () {
var name = document.getElementById ("struc-name").value;
var elems1 = document.getElementById ("no-elems-start").value;
var elems2 = document.getElementById ("no-elems-end").value;
@@ -264,10 +272,17 @@
localStorage["TRelStrucExplEl2"+name] = elems2;
localStorage["TRelStrucExplRel"+name] = rels;
localStorage["TRelStrucExplPos"+name] = pos;
- list_stored ();
+ list_stored_struc ();
}
-function load (name) {
+function save_so () {
+ var name = document.getElementById ("so-name").value;
+ var phi = document.getElementById ("second-order").value;
+ localStorage["TRelStrucExplSOF"+name] = phi;
+ list_stored_so ();
+}
+
+function load_struc (name) {
document.getElementById ("struc-name").value = name;
document.getElementById ("no-elems-start").value =
localStorage["TRelStrucExplEl1"+name];
@@ -280,7 +295,14 @@
draw_it ();
}
-function list_stored () {
+function load_so (name) {
+ document.getElementById ("so-name").value = name;
+ document.getElementById ("second-order").value =
+ localStorage["TRelStrucExplSOF"+name];
+ find_draw_it ();
+}
+
+function list_stored_struc () {
var saved = document.getElementById("saved-strucs");
while (saved.childNodes.length > 0) { saved.removeChild(saved.firstChild); }
for (var i=0; i < localStorage.length; i++) {
@@ -288,55 +310,109 @@
if (k.substring (0, 16) === "TRelStrucExplEl1") {
var n = k.substring (16, k.length);
var li = document.createElement('li');
- li.innerHTML = '<button class="obt" onclick="load('+ "'"+ n +"'" +')">' +
- n +'</button> (<button class="obt" onclick="del_saved('+ "'"+ n +
+ li.innerHTML ='<button class="obt" onclick="load_struc('+"'"+ n +"'"+')">'
+ + n +'</button> (<button class="obt" onclick="del_struc('+ "'"+ n +
"'" +')" title="Delete this structure.">-</button>)';
saved.appendChild (li);
}
}
}
-function del_saved (name) {
+function list_stored_so () {
+ var saved = document.getElementById("saved-so");
+ while (saved.childNodes.length > 0) { saved.removeChild(saved.firstChild); }
+ for (var i=0; i < localStorage.length; i++) {
+ var k = localStorage.key(i);
+ if (k.substring (0, 16) === "TRelStrucExplSOF") {
+ var n = k.substring (16, k.length);
+ var li = document.createElement('li');
+ li.innerHTML ='<button class="obt" onclick="load_so('+"'"+ n +"'"+')">'
+ + n +'</button> (<button class="obt" onclick="del_so('+ "'"+ n +
+ "'" +')" title="Delete this formula.">-</button>)';
+ saved.appendChild (li);
+ }
+ }
+}
+
+function list_stored () {
+ list_stored_struc ();
+ list_stored_so ();
+}
+
+function del_so (name) {
+ localStorage.removeItem("TRelStrucExplSOF"+name);
+ list_stored_so ();
+}
+
+function del_struc (name) {
localStorage.removeItem("TRelStrucExplEl1"+name);
localStorage.removeItem("TRelStrucExplEl2"+name);
localStorage.removeItem("TRelStrucExplRel"+name);
localStorage.removeItem("TRelStrucExplPos"+name);
- list_stored ();
+ list_stored_struc ();
}
-function toggle_edit () {
+function toggle_edit_view () {
var bt = document.getElementById("editbt");
if (bt.innerHTML == "Edit") {
document.getElementById('edit').style.display = 'block';
- document.getElementById('board-left').style.left = '38em';
- bt.innerHTML = "Hide Edit";
+ document.getElementById('board-left').style.display = 'none';
+ bt.innerHTML = "View";
} else {
document.getElementById('edit').style.display = 'none';
- document.getElementById('board-left').style.left = '2em';
+ document.getElementById('board-left').style.display = 'block';
bt.innerHTML = "Edit";
}
}
-function toggle_view () {
- var bt = document.getElementById("viewbt");
- if (bt.innerHTML == "View") {
- document.getElementById('board-left').style.display = 'block';
- bt.innerHTML = "Hide View";
- } else {
- document.getElementById('board-left').style.display = 'none';
- bt.innerHTML = "View";
- }
-}
-
function adjust_to_width () {
var e = document.getElementById ("edit");
var em_size =
document.defaultView.getComputedStyle(e,null).getPropertyValue('font-size');
var em_size_int = parseInt (em_size.substring (0, em_size.length - 2));
- if (window.innerWidth > 80 * em_size_int) { // enough space for edit
- toggle_edit ()
+ if (window.innerWidth > 80 * em_size_int) { // enough space for view
+ document.getElementById('board-left').style.left = '35em';
+ document.getElementById('board-left').style.display = 'block';
+ document.getElementById('editbt').style.display = 'none';
}
}
+
+function put_msg (content, time) {
+ document.getElementById("working").innerHTML = content;
+ document.getElementById ("working").style.display = "block";
+ setTimeout (function () {
+ document.getElementById ("working").style.display = "none";
+ }, time);
+}
+
+function show_help () {
+ document.getElementById ("working").style.textAlign = "left";
+ document.getElementById ("working").style.fontWeight = "normal";
+ document.getElementById("working").innerHTML = '\
+<b>Welcome to Relational Structures Explorer</b> \
+<p><b>Relational structures</b> consist of a set of <em>elements</em> and \
+of <em>relations</em> defined by <em>formulas</em>.</p> \
+<p><b>Elements</b> are numbered. You can change their range and you can access \
+the number of the element corresponding to a variable <em>x</em> in a formula \
+by writing <em>&x</em> or <em>:nbr(x)</em>.</p> \
+<p><b>Formulas</b> are written in first-order logic. You can use relation \
+symbols, Boolean combinations and quantifiers. Additionally, you can use \
+arithmetic operations (+-*/^) on element numbers and element positions.</p> \
+<p><b>Positions</b> of elements are determined by their <em>x</em> and \
+<em>y</em> coordinates. Define and access them as in <b>:x(a)</b> and \
+<b>:y(a)</b>. You can again use arithmetic operations and also conditionals \
+on formulas, written <b>:(formula)</b>.</p> \
+<p><b>Relation Finder</b>, placed at the bottom, automatically finds relations \
+that satisfy the given property. Use <b>|</b> in front of the relation symbol \
+to be found, as in <b>|R(x)</b>.</p> \
+';
+ document.getElementById ("working").style.display = "block";
+ setTimeout (function () {
+ document.getElementById ("working").style.display = "none";
+ document.getElementById ("working").style.textAlign = "center";
+ document.getElementById ("working").style.fontWeight = "bold";
+ }, 20000);
+}
//-->
</script>
</head>
@@ -353,12 +429,12 @@
<span style="position: relative; left: 2em; top: 0.5em; font-size: 1.2em">
Relational Structures Explorer</span>
<span id="toprighttab" style="display: block;">
- <button class="obt" id="editbt" onclick="toggle_edit()">Edit</button>
- <button class="obt" id="viewbt" onclick="toggle_view()">Hide View</button>
+ <button class="obt" id="editbt" onclick="toggle_edit_view()">View</button>
+ <button class="obt" id="editbt" onclick="show_help()">Help</button>
</span>
</div>
-<div id="board-left">
+<div id="board-left" style="display: none;">
<canvas id="canvas" height="1100" width="1100"
onmouseup="mouseup_handle(event)"
onmousedown="mousedown_handle(event)"
@@ -370,72 +446,118 @@
</canvas>
</div>
-<div id="edit" style="position: absolute; top: 4em; left: 2em; display: none">
+<div id="working" style="display: none; width: 30em;"></div>
+<div id="edit" style="position: absolute; top: 4em; left: 2em;">
+
<p>Name
- <input id="struc-name" type="text" size="20" value="MyStructure1"
- style="width: 10em"></input>
- <button class="ebt" onclick="save()">Save</button>
+ <input id="struc-name" type="text" size="20" value="My Structure 1"
+ style="width: 12em"></input>
+ <span style="position: absolute; right: 2px;">
+ <button class="ebt" style="width: 4em;" title="Save current structure."
+ onclick="save_struc()">Save</button>
+ </span>
</p>
<p>Elements
<input id="no-elems-start" type="text" size="2" value="1"
- style="width: 2em"></input> —
+ style="width: 4em"></input> —
<input id="no-elems-end" type="text" size="4" value="15"
- style="width: 2em"></input>
- <button class="ebt" onclick="add_elem()">+</button>
- <button class="ebt" onclick="del_elem()">-</button>
+ style="width: 4em"></input>
+ <span style="position: absolute; right: 2px;">
+ <button class="ebt" style="width: 2em;" title="Remove last element."
+ onclick="del_elem()">-</button><button title="Add one element."
+ style="width: 2em;" class="ebt" onclick="add_elem()">+</button>
+ </span>
</p>
-<p>Relations
- <button class="ebt" title="Conjunction. You can also write 'and' or '&'."
- onclick="add_field('relations', '∧')">∧</button>
- <button class="ebt" title="Disjunction. You can also write 'or' or '|'."
- onclick="add_field('relations', '∨')">∨</button>
- <button class="ebt" title="Negation. You can also write 'not'."
- onclick="add_field('relations', '¬')">¬</button>
- <button class="ebt" title="Implication. You can also write '->'."
- onclick="add_field('relations', '→')">→</button>
- <button title="Existential Quantifier. You can also write 'ex' or '\E'."
- class="ebt" onclick="add_field('relations', '∃')">∃</button>
- <button title="Universal Quantifier. You can also write 'all' or '\A'."
- class="ebt" onclick="add_field('relations', '∀')">∀</button>
- <button class="ebt" onclick="draw_it()">Redraw</button>
+<p>Relations
+ <span style="position: absolute; right: 2px;">
+ <button class="ebts" title="Not equal. You can also write '<>' or '!='."
+ onclick="add_field('relations', '≠')">≠</button><button
+ class="ebts" title="Less or equal. You can also write '=<'."
+ onclick="add_field('relations', '≤')">≤</button><button
+ class="ebts" title="Conjunction. You can also write 'and' or '&'."
+ onclick="add_field('relations', '∧')">∧</button><button
+ class="ebts" title="Disjunction. You can also write 'or' or '|'."
+ onclick="add_field('relations', '∨')">∨</button><button
+ class="ebts" title="Negation. You can also write 'not'."
+ onclick="add_field('relations', '¬')">¬</button><button
+ class="ebts" title="Implication. You can also write '->'."
+ onclick="add_field('relations', '→')">→</button><button
+ title="Existential Quantifier. You can also write 'ex' or '\E'."
+ class="ebts" onclick="add_field('relations', '∃')">∃</button><button
+ title="Universal Quantifier. You can also write 'all' or '\A'."
+ class="ebts" onclick="add_field('relations', '∀')">∀</button>
+ <button class="ebt" onclick="draw_it()" style="width: 4em;"
+ title="Redraw current structure.">Draw</button>
+ </span>
</p>
-<textarea id="relations" rows="3" cols="70">
+<textarea id="relations" rows="3" cols="60">
E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)
</textarea>
-<p>Positions
- <button class="ebt" onclick="add_field('positions', '+')">+</button>
- <button class="ebt" onclick="add_field('positions', '-')">-</button>
- <button class="ebt" onclick="add_field('positions', '·')">·</button>
- <button class="ebt" onclick="add_field('positions', '/')">/</button>
- <button class="ebt" onclick="add_field('positions', '^')">^</button>
- <button class="ebt" onclick="draw_it()">Redraw</button>
+<p>Positions
+ <span style="position: absolute; right: 2px;">
+ <button class="ebts" title="Not equal. You can also write '<>' or '!='."
+ onclick="add_field('positions', '≠')">≠</button><button
+ class="ebts" title="Less or equal. You can also write '=<'."
+ onclick="add_field('positions', '≤')">≤</button><button
+ class="ebts" title="Conjunction. You can also write 'and' or '&'."
+ onclick="add_field('positions', '∧')">∧</button><button
+ class="ebts" title="Disjunction. You can also write 'or' or '|'."
+ onclick="add_field('positions', '∨')">∨</button><button
+ class="ebts" title="Negation. You can also write 'not'."
+ onclick="add_field('positions', '¬')">¬</button><button
+ class="ebts" title="Implication. You can also write '->'."
+ onclick="add_field('positions', '→')">→</button><button
+ title="Existential Quantifier. You can also write 'ex' or '\E'."
+ class="ebts" onclick="add_field('positions', '∃')">∃</button><button
+ title="Universal Quantifier. You can also write 'all' or '\A'."
+ class="ebts" onclick="add_field('positions', '∀')">∀</button>
+ <button class="ebt" onclick="draw_it()" style="width: 4em;"
+ title="Redraw current structure.">Draw</button>
+ </span>
</p>
-
-<textarea id="positions" rows="3" cols="70">
+<textarea id="positions" rows="3" cols="60">
:x(a) = &a;
:y(a) = &a · (10 - &a) / 10
</textarea>
-<p>Second-Order Finder
- <button class="ebt" title="Conjunction. You can also write 'and' or '&'."
- onclick="add_field('second-order', '∧')">∧</button>
- <button class="ebt" title="Disjunction. You can also write 'or' or '|'."
- onclick="add_field('second-order', '∨')">∨</button>
- <button class="ebt" title="Negation. You can also write 'not'."
- onclick="add_field('second-order', '¬')">¬</button>
- <button class="ebt" title="Implication. You can also write '->'."
- onclick="add_field('second-order', '→')">→</button>
- <button title="Existential Quantifier. You can also write 'ex' or '\E'."
- class="ebt" onclick="add_field('second-order', '∃')">∃</button>
- <button title="Universal Quantifier. You can also write 'all' or '\A'."
- class="ebt" onclick="add_field('second-order', '∀')">∀</button>
- <button class="ebt" onclick="find_draw_it()">Find</button>
+
+<p style="width:100%; border-top: 1px solid; padding-top: 1em;">
+ Formula Name
+ <input id="so-name" type="text" size="20" value="My Formula 1"
+ style="width: 12em"></input>
+ <span style="position: absolute; right: 2px;">
+ <button class="ebt" onclick="save_so()" title="Save current formula."
+ style="width: 4em;">Save</button>
+ </span>
</p>
-<textarea id="second-order" rows="3" cols="70">
+
+<p>Formula
+ <span style="position: absolute; right: 2px;">
+ <button class="ebts" title="Not equal. You can also write '<>' or '!='."
+ onclick="add_field('second-order', '≠')">≠</button><button
+ class="ebts" title="Less or equal. You can also write '=<'."
+ onclick="add_field('second-order', '≤')">≤</button><button
+ class="ebts" title="Conjunction. You can also write 'and' or '&'."
+ onclick="add_field('second-order', '∧')">∧</button><button
+ class="ebts" title="Disjunction. You can also write 'or' or '|'."
+ onclick="add_field('second-order', '∨')">∨</button><button
+ class="ebts" title="Negation. You can also write 'not'."
+ onclick="add_field('second-order', '¬')">¬</button><button
+ class="ebts" title="Implication. You can also write '->'."
+ onclick="add_field('second-order', '→')">→</button><button
+ title="Existential Quantifier. You can also write 'ex' or '\E'."
+ class="ebts" onclick="add_field('second-order', '∃')">∃</button><button
+ title="Universal Quantifier. You can also write 'all' or '\A'."
+ class="ebts" onclick="add_field('second-order', '∀')">∀</button>
+ <button class="ebt" onclick="find_draw_it()" style="width: 4em;"
+ title="Find relations that satisfy the formula.">Find</button>
+ </span>
+</p>
+<textarea id="second-order" rows="3" cols="60">
</textarea>
</div>
@@ -454,10 +576,16 @@
<li><button class="obt" onclick="example_heart()">Heart Drawing</button></li>
</ul>
-<p>Second-Order Formulas</p>
+<p style="border-top: 1px solid; padding-top: 1em">Your Formulas</p>
+<ul id="saved-so" style="list-style: square; margin-left: -1.5em">
+<li>Nothing here yet</li>
+</ul>
+
+<p>Examples</p>
<ul style="list-style: square; margin-left: -1.5em">
<li><button class="obt" onclick="example_2col()">2-coloring</button></li>
<li><button class="obt" onclick="example_3col()">3-coloring</button></li>
+<li><button class="obt" onclick="example_matching()">Matching</button></li>
</ul>
</div>
Modified: trunk/Toss/Formula/BoolFormula.ml
===================================================================
--- trunk/Toss/Formula/BoolFormula.ml 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Formula/BoolFormula.ml 2012-07-05 00:25:38 UTC (rev 1742)
@@ -626,11 +626,11 @@
| _ -> raise (FormulaError "Clauses must not contain non-literals!") in
let list_of_clause = function
| BVar v -> [v]
- | BOr (bflist) -> List.map int_of_literal bflist
+ | BOr (bflist) -> List.rev_map int_of_literal bflist
| _ -> raise (FormulaError "This is not a clause!") in
match phi with
| BVar v -> [[v]]
- | BAnd (bflist) -> List.map list_of_clause bflist
+ | BAnd (bflist) -> List.rev_map list_of_clause bflist
| _ -> raise (FormulaError "This is not a CNF!")
Modified: trunk/Toss/README
===================================================================
--- trunk/Toss/README 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/README 2012-07-05 00:25:38 UTC (rev 1742)
@@ -18,7 +18,8 @@
* AUTHORS
The current version of Toss is developed by
-- Łukasz Kaiser (ka...@li...)
+- Łukasz Kaiser (luk...@gm...)
+- Faried Abu Zaid
- Łukasz Stafiniak
Many other friends helped us with discussion and code at some point.
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-07-03 23:55:21 UTC (rev 1741)
+++ trunk/Toss/Solver/Solver.ml 2012-07-05 00:25:38 UTC (rev 1742)
@@ -429,17 +429,17 @@
(QAnd [], [])
else (QOr [], [])
| And phil ->
- let resl = (List.map (fun phi -> (so_to_qbf_rec asgn phi)) phil) in
- let qphil = (Aux.unique_sorted (List.map (fst) resl)) in
- let dictl = (List.map snd resl) in
+ let resl = (List.rev_map (fun phi -> (so_to_qbf_rec asgn phi)) phil) in
+ let qphil = (Aux.unique_sorted (List.rev_map (fst) resl)) in
+ let dictl = List.fold_left (fun a (_,l) -> List.rev_append l a) [] resl in
(try (List.find (fun x -> x = QOr []) qphil, [])
- with Not_found -> (make_conj qphil, List.concat dictl) )
...
[truncated message content] |
|
From: <luk...@us...> - 2012-07-06 01:06:32
|
Revision: 1743
http://toss.svn.sourceforge.net/toss/?rev=1743&view=rev
Author: lukaszkaiser
Date: 2012-07-06 01:06:25 +0000 (Fri, 06 Jul 2012)
Log Message:
-----------
Interface corrections in structure explorer.
Modified Paths:
--------------
trunk/Toss/Client/Drawing.ml
trunk/Toss/Client/Drawing.mli
trunk/Toss/Client/JsEval.ml
trunk/Toss/Client/Style.css
trunk/Toss/Client/eval.html
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/README
trunk/Toss/www/contact.xml
Modified: trunk/Toss/Client/Drawing.ml
===================================================================
--- trunk/Toss/Client/Drawing.ml 2012-07-05 00:25:38 UTC (rev 1742)
+++ trunk/Toss/Client/Drawing.ml 2012-07-06 01:06:25 UTC (rev 1743)
@@ -42,6 +42,19 @@
let defaultCGreen = {red=62 ; green=89 ; blue=24 ; opacity = 1. }
let defaultCBlue = {red=165 ; green=175 ; blue=170 ; opacity = 1. }
+let palette = Hashtbl.create 7
+
+(* Set a color for a name. *)
+let set_color name color =
+ Hashtbl.add palette name color
+
+(* Get the color. If not set before, it is the default one, depending on
+ whether for stroke or fill, or a default red, if name starts with '|'.*)
+let get_color ?(stroke=false) name =
+ try Hashtbl.find palette name with Not_found ->
+ if String.length name > 0 && name.[0] = '|' then defaultCRed else
+ if stroke then defaultCStroke else defaultCFill
+
let color_to_str c =
let op = string_of_float c.opacity in
let l = String.length op - 1 in
@@ -205,12 +218,11 @@
let draw_rel (rel, arity) =
if arity = 1 then
let elems = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- let col = match rel with | "|R" -> defaultCRed | "|G" -> defaultCGreen
- | "|B" -> defaultCBlue | _ -> defaultCFill in
+ let col = get_color rel in
Aux.concat_map (fun a -> [Circle (pos a.(0), {x=10.; y=10.}, col)]) elems
else if arity = 2 then
let tuples = Structure.Tuples.elements (Structure.rel_graph rel struc) in
- let c = if rel.[0] = '|' then defaultCRed else defaultCStroke in
+ let c = get_color ~stroke:true rel in
Aux.concat_map (fun a -> arrow c (pos_draw a.(0)) (pos_draw a.(1))) tuples
else [] in
elem_drawings @ (Aux.concat_map draw_rel (Structure.rel_signature struc))
Modified: trunk/Toss/Client/Drawing.mli
===================================================================
--- trunk/Toss/Client/Drawing.mli 2012-07-05 00:25:38 UTC (rev 1742)
+++ trunk/Toss/Client/Drawing.mli 2012-07-06 01:06:25 UTC (rev 1743)
@@ -33,7 +33,14 @@
(** Default stroke color. *)
val defaultCStroke : color
+(** Set the color for a name. *)
+val set_color : string -> color -> unit
+(** Get the color. If not set before, it is the default one, depending on
+ whether for stroke or fill, or a default red, if name starts with '|'. *)
+val get_color : ?stroke : bool -> string -> color
+
+
(** Shapes. *)
type shape =
| Circle of point * point * color (** circle, given middle and radiuses *)
Modified: trunk/Toss/Client/JsEval.ml
===================================================================
--- trunk/Toss/Client/JsEval.ml 2012-07-05 00:25:38 UTC (rev 1742)
+++ trunk/Toss/Client/JsEval.ml 2012-07-06 01:06:25 UTC (rev 1743)
@@ -111,3 +111,27 @@
let _ = set_handle "mouseup_handle" mouseup_handle
let _ = set_handle "mousedown_handle" mousedown_handle
let _ = set_handle "mousemove_handle" mousemove_handle
+
+let set_colors colors_str =
+ let defs = Aux.split_charprop (fun c -> c = ';') (Js.to_string colors_str) in
+ let set_color_def rel c =
+ let b = function '0' -> 0 | '1' -> 1 | '2' -> 2 | '3' -> 3 | '4' -> 4
+ | '5' -> 5 | '6' -> 6 | '7' -> 7 | '8' -> 8 | '9' -> 9 | 'a' -> 10
+ | 'A' -> 10 | 'b' -> 11 | 'B' -> 11 | 'c' -> 12 | 'C' -> 12 | 'd' -> 13
+ | 'D' -> 13 | 'e' -> 14 | 'E' -> 14 | 'f' -> 15 | 'F' -> 15 | _ -> -1 in
+ if String.length c <> 7 || c.[0] <> '#' then "Incorrect color: " ^ c else
+ let (r1, r0, g1, g0, b1, b0) =
+ (b c.[1], b c.[2], b c.[3], b c.[4], b c.[5], b c.[6]) in
+ if r0 < 0 || r1 < 0 || g0 < 0 || g1 < 0 || b0 < 0 || b1 < 0 then
+ "Incorrect numbers in color: " ^ c
+ else let col = { Drawing.red = 16*r1+r0 ; Drawing.green = 16*g1+g0 ;
+ Drawing.blue = 16*b1+b0 ; Drawing.opacity = 1. } in
+ Drawing.set_color rel col;
+ "Set " ^ rel ^ " to " ^ c in
+ let parse_def d =
+ match Aux.split_charprop (fun c -> c = ':') d with
+ | [rel; c] -> set_color_def (Aux.strip_spaces rel) (Aux.strip_spaces c)
+ | _ -> "Incorrect color definition: " ^ (Aux.normalize_spaces d) in
+ Js.string (String.concat " <br /> " (List.map parse_def defs))
+
+let _ = set_handle "set_colors" set_colors
Modified: trunk/Toss/Client/Style.css
===================================================================
--- trunk/Toss/Client/Style.css 2012-07-05 00:25:38 UTC (rev 1742)
+++ trunk/Toss/Client/Style.css 2012-07-06 01:06:25 UTC (rev 1743)
@@ -43,7 +43,6 @@
.bt {
border-color: #260314;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 1px;
color: #260314;
background-color: #fff1d4;
@@ -64,11 +63,24 @@
float: right;
}
-.obt, .boldobt, .gamebt, .ebt, .ebts {
+.textar {
+ font-family: Verdana;
+ font-size: 0.9em;
+ width: 33em;
+}
+
+.headerp {
+ width: 100%;
+ border-bottom: 0px solid;
+ padding-top: 0.5em;
+ text-align: center;
+ font-weight: bold;
+}
+
+.obt, .boldobt, .gamebt, .ebt, .ebts, .ebtr, .ebtl {
text-align: left;
border-color: #260314;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 0px;
color: #260314;
background-color: #fff1d4;
@@ -76,7 +88,8 @@
font-family: Verdana, 'TeXGyreHerosRegular', sans;
}
-.obt:hover, .ebt:hover, .ebts:hover, .boldobt:hover, .gamebt:hover {
+.obt:hover, .ebt:hover, .ebts:hover, .ebtr:hover, .ebtl:hover,
+ .boldobt:hover, .gamebt:hover{
cursor: pointer;
text-decoration: underline;
}
@@ -86,12 +99,22 @@
font-size: 1em;
}
-.ebt, .ebts {
+.ebt, .ebts, .ebtr, .ebtl {
/*font-weight: bold;*/
text-align: center;
border-width: 1px;
}
+.ebtr {
+ position: absolute;
+ right: 1px;
+}
+
+.ebtl {
+ position: absolute;
+ left: 1px;
+}
+
.gamebt {
margin-bottom: 1em;
padding-top: 0.5em;
@@ -104,7 +127,6 @@
text-align: left;
border-color: #260314;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 0px;
color: #260314;
background-color: #fff1d4;
@@ -120,7 +142,6 @@
.dbt {
border-color: #fff1d4;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 0px;
color: #fff1d4;
background-color: #400827;
@@ -235,7 +256,6 @@
top: -1em;
background-color: rgba(255, 241, 228, 0.8);
border-radius: 4px;
- -moz-border-radius: 4px;
opacity: 1;
}
@@ -263,7 +283,6 @@
font-size: 0.8em;
border-color: #fff1d4;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 1px;
position: relative;
top: 2px;
@@ -284,9 +303,6 @@
padding-left: 0.2em;
padding-right: 0.2em;
border-radius: 0px;
- -moz-border-radius: 0px;
- /*font-size: 0.9em;
- -moz-border-radius: 6px 6px 0px 0px; */
}
#speed {
@@ -300,8 +316,7 @@
padding: 0px;
margin: 0px;
border-color: #fff1d4;
- /*border-radius: 4px;
- -moz-border-radius: 4px;*/
+ /*border-radius: 4px; */
border-width: 0px;
}
@@ -328,7 +343,6 @@
margin: 0px;
border-color: #fff1d4;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 0px;
}
@@ -349,7 +363,6 @@
.forminput, .hiddenforminput {
border-color: #fff1d4;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 2px;
position: relative;
top: 2px;
@@ -392,7 +405,6 @@
background-color: #ffffff;
border-color: #fff1d4;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 1px;
}
@@ -516,8 +528,6 @@
padding-bottom: 0.2em;
padding-left: 0.2em;
padding-right: 0.2em;
- /*font-size: 0.9em;
- -moz-border-radius: 6px 6px 0px 0px; */
}
#bottom {
@@ -570,9 +580,6 @@
border-color: #fff1d4;
border-style: solid;
border-width: 0px 0px 0px 2px;
- /*border-width: 0px 2px 2px 2px;
- border-radius: 0px 0px 6px 6px;
- -moz-border-radius: 0px 0px 6px 6px;*/
}
#toss-link {
@@ -819,7 +826,6 @@
width: 6em;
border-color: #260314;
border-radius: 4px;
- -moz-border-radius: 4px;
border-width: 1px;
color: #260314;
background-color: #fff1d4;
@@ -899,13 +905,6 @@
padding: 0px;
}
-#board-left {
- position: relative;
- left: 2em;
- top: 5em;
- width: 30em;
-}
-
#board {
padding-top: 1em;
min-width: 10em;
@@ -1009,9 +1008,9 @@
}
#canvas {
- width: 29em;
- height: 29em;
- border: 2px solid #260314;
+ width: 30em;
+ height: 30em;
+ border: 1px solid #260314;
}
/* SVG styling */
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-07-05 00:25:38 UTC (rev 1742)
+++ trunk/Toss/Client/eval.html 2012-07-06 01:06:25 UTC (rev 1743)
@@ -5,6 +5,7 @@
<title>Toss Relational Structures Explorer</title>
<meta name="Description" content="Explore Relational Structures." />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
+ <meta name="viewport" content="initial-scale=0.75" />
<link rel="icon" type="image/vnd.microsoft.icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="Style.css" media="screen" title="Default"/>
<script type="text/javascript">
@@ -46,22 +47,46 @@
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.fillStyle = "#ffe4aa";
+ ctx.strokeStyle = "#260314";
+ ctx.lineWidth = 5;
+ ctx.lineCap = "round";
+ ctx.lineJoin = "round";
}
-function draw_it () {
+function draw_it_msg (msg) {
+ if (msg) {
+ document.getElementById ("working").style.display = 'block';
+ document.getElementById ("working").innerHTML = 'Working...';
+ }
var rels = document.getElementById ("relations").value;
var pos = document.getElementById ("positions").value;
var elemsF = document.getElementById ("no-elems-start").value;
var elemsT = document.getElementById ("no-elems-end").value;
var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with \n" +
rels + " with \n" + pos;
- ASYNCH ("draw_struc", ["", struc], true, function (a) {
- var ctx = document.getElementById("canvas").getContext("2d");
- eval (a[0])
- })
+ if (msg) {
+ ASYNCH ("draw_struc", ["", struc], true, function (a) {
+ document.getElementById ("working").style.display = 'none';
+ var ctx = document.getElementById("canvas").getContext("2d");
+ eval (a[0])
+ toggle_to_show ("view");
+ })
+ } else {
+ ASYNCH ("draw_struc", ["", struc], true, function (a) {
+ var ctx = document.getElementById("canvas").getContext("2d");
+ eval (a[0])
+ })
+ }
}
+function draw_it () {
+ draw_it_msg (true);
+}
+
function find_draw_it () {
+ document.getElementById ("working").style.display = 'block';
+ document.getElementById ("working").innerHTML = 'Working...';
var rels = document.getElementById ("relations").value;
var pos = document.getElementById ("positions").value;
var elemsF = document.getElementById ("no-elems-start").value;
@@ -70,8 +95,10 @@
var struc = "[ " + elemsF + " - " + elemsT + " | | - ] with \n" +
rels + " with \n" + pos;
ASYNCH ("draw_struc", [so, struc], true, function (a) {
+ document.getElementById ("working").style.display = 'none';
var ctx = document.getElementById("canvas").getContext("2d");
eval (a[0]);
+ toggle_to_show ("view");
if (a[1] !== "Error") { put_msg (a[1], 2000) }
})
}
@@ -165,42 +192,59 @@
}
}
-
function handle_elem_click (eid) { console.log (eid); }
+function example_basic () {
+ document.getElementById ("struc-name").value = "Basic";
+ document.getElementById ("relations").value =
+ "E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)";
+ document.getElementById ("positions").value = ":x(a) = &a;\n" +
+ ":y(a) = &a · (10 - &a) / 10";
+ document.getElementById ("no-elems-start").value = "1";
+ document.getElementById ("no-elems-end").value = "15";
+ draw_it_msg (false);
+}
+
function example_primes () {
- document.getElementById ("struc-name").value = "Prime Numbers";
+ document.getElementById ("struc-name").value = "Primes";
document.getElementById ("relations").value =
"P(z) = &z > 1 and ∀ x,y \n (&x · &y = &z → (&x = 1 ∨ &y = 1))";
document.getElementById ("positions").value = ":x(a) = &a; \n:y(a) = 0";
document.getElementById ("no-elems-start").value = "1";
document.getElementById ("no-elems-end").value = "10";
- draw_it ();
+ draw_it_msg (false);
}
function example_tc () {
- document.getElementById ("struc-name").value = "Transitive Closure";
+ document.getElementById ("struc-name").value = "Simple TC";
document.getElementById ("relations").value =
"E(x, y) = &y = &x + 1;\n" +
"S(x, y) = x ≠ y ∧ tc x,y E(x, y)";
document.getElementById("positions").value=":x(a) = 5·&a;\n:y(a) = &a·&a / 2";
document.getElementById ("no-elems-start").value = "1";
document.getElementById("no-elems-end").value = "4";
- draw_it ();
+ draw_it_msg (false);
}
-function example_basic () {
- document.getElementById ("struc-name").value = "Basic Example";
- document.getElementById ("relations").value =
- "E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)";
- document.getElementById ("positions").value = ":x(a) = &a;\n" +
- ":y(a) = &a · (10 - &a) / 10";
+function example_heart () {
+ document.getElementById ("struc-name").value = "Heart";
+ document.getElementById ("relations").value =
+ "E(x, y) = (&y = &x + 1 ∧ &x ≠ 18) ∨ (&x=37 ∧ &y=18)";
+ document.getElementById ("positions").rows = 7;
+ document.getElementById ("positions").value =
+ ":x(a) = :(&a ≤ 18) · (:(&a ≤ 10) · &a - :(&a > 10) · (&a-20))\n" +
+ " - let :b = &a - 18 in :(&a > 18) · (:(:b ≤ 10) · :b - \n " +
+ " :(:b > 10) · (:b - 20) - 2); \n\n" +
+ ":y(a) = :(&a ≤ 18) · (:(&a ≤ 10) ·&a · (10 - &a) / 10 - \n" +
+ " :(&a > 10)·(&a - 10)) + let :b = &a - 18 in :(&a > 18)·( \n" +
+ " :(:b ≤ 10)·:b · (10-:b) / 10 - :(:b > 10)·(:b - 10) )";
document.getElementById ("no-elems-start").value = "1";
- document.getElementById ("no-elems-end").value = "15";
- draw_it ();
+ document.getElementById ("no-elems-end").value = "37";
+ draw_it_msg (false);
}
function example_matching () {
+ document.getElementById ("so-name").value = "Matching";
document.getElementById ("second-order").value =
"∀ x,y ( |M(x, y) -> (\n" +
" ( E(x, y) ∨ E(y, x) ) ∧ ¬∃ z (z≠y ∧ |M(x, z) )\n" +
@@ -209,6 +253,7 @@
}
function example_2col () {
+ document.getElementById ("so-name").value = "2-coloring";
document.getElementById ("second-order").value =
"∀ x,y ( (|R(x) ∨ |G(x)) ∧ ( E(x,y) → " +
"\n ¬( (|R(x) ∧ |R(y)) ∨ (|G(x) ∧ |G(y)) ) ) )";
@@ -216,26 +261,19 @@
}
function example_3col () {
+ document.getElementById ("so-name").value = "3-coloring";
document.getElementById ("second-order").value =
"∀ x,y ( ( |R(x) ∨ |G(x) ∨ |B(x)) ∧ ( E(x,y) → " +
"\n ¬( (|R(x) ∧ |R(y)) ∨ (|G(x) ∧ |G(y)) ∨ (|B(x) ∧ |B(y)) ) ) )";
find_draw_it ();
}
-function example_heart () {
- document.getElementById ("struc-name").value = "Heart Drawing";
- document.getElementById ("relations").value =
- "E(x, y) = (&y = &x + 1 ∧ &x ≠ 18) ∨ (&x=37 ∧ &y=18)";
- document.getElementById ("positions").value =
- ":x(a) = :(&a ≤ 18) · (:(&a ≤ 10) · &a - :(&a > 10) · (&a - 20)) \n" +
- " - let :b = &a - 18 in :(&a > 18) · (:(:b ≤ 10) · :b - \n " +
- " :(:b > 10) · (:b - 20) - 2); \n\n" +
- ":y(a) = :(&a ≤ 18) · (:(&a ≤ 10) ·&a · (10 - &a) / 10 - \n " +
- " :(&a > 10)·(&a - 10)) + let :b = &a - 18 in \n" +
- " :(&a > 18) · (:(:b ≤ 10) ·:b · (10 - :b) / 10 - :(:b > 10)·(:b - 10))";
- document.getElementById ("no-elems-start").value = "1";
- document.getElementById ("no-elems-end").value = "37";
- draw_it ();
+function example_tc_so () {
+ document.getElementById ("so-name").value = "TC";
+ document.getElementById ("second-order").value =
+ "∀ x,y,z ( ( E(x, y) → |Tc(x, y) ) ∧\n" +
+ " ( (|Tc(x, y) ∧ |Tc(y, z)) -> |Tc(x, z) ) )";
+ find_draw_it ();
}
function add_field (field, s) {
@@ -311,8 +349,8 @@
var n = k.substring (16, k.length);
var li = document.createElement('li');
li.innerHTML ='<button class="obt" onclick="load_struc('+"'"+ n +"'"+')">'
- + n +'</button> (<button class="obt" onclick="del_struc('+ "'"+ n +
- "'" +')" title="Delete this structure.">-</button>)';
+ + n +'</button> <button class="ebtr" onclick="del_struc('+ "'"+ n +"'"+
+ ')" style="width: 4em;" title="Delete this structure.">Del</button>';
saved.appendChild (li);
}
}
@@ -327,8 +365,8 @@
var n = k.substring (16, k.length);
var li = document.createElement('li');
li.innerHTML ='<button class="obt" onclick="load_so('+"'"+ n +"'"+')">'
- + n +'</button> (<button class="obt" onclick="del_so('+ "'"+ n +
- "'" +')" title="Delete this formula.">-</button>)';
+ + n +'</button> <button class="ebtr" onclick="del_so('+ "'"+ n +
+ "'" +')" style="width: 4em;" title="Delete this formula.">Del</button>';
saved.appendChild (li);
}
}
@@ -352,28 +390,21 @@
list_stored_struc ();
}
-function toggle_edit_view () {
- var bt = document.getElementById("editbt");
- if (bt.innerHTML == "Edit") {
- document.getElementById('edit').style.display = 'block';
- document.getElementById('board-left').style.display = 'none';
- bt.innerHTML = "View";
- } else {
- document.getElementById('edit').style.display = 'none';
- document.getElementById('board-left').style.display = 'block';
- bt.innerHTML = "Edit";
- }
-}
-
function adjust_to_width () {
var e = document.getElementById ("edit");
var em_size =
document.defaultView.getComputedStyle(e,null).getPropertyValue('font-size');
var em_size_int = parseInt (em_size.substring (0, em_size.length - 2));
- if (window.innerWidth > 80 * em_size_int) { // enough space for view
- document.getElementById('board-left').style.left = '35em';
- document.getElementById('board-left').style.display = 'block';
- document.getElementById('editbt').style.display = 'none';
+ if (window.innerWidth > 80 * em_size_int) { // enough space for left view
+ document.getElementById('div_right_col_full').style.position = 'absolute';
+ document.getElementById('div_right_col_full').style.top = '-1em';
+ document.getElementById('div_right_col_full').style.left = '35em';
+ } else {
+ toggle ("struc");
+ toggle ("formula");
+ toggle ("colors");
+ put_msg ("This page is best viewed on a screen > 80em wide.<br\>" +
+ "It then switches to two-column layout.", 4000)
}
}
@@ -385,39 +416,96 @@
}, time);
}
-function show_help () {
- document.getElementById ("working").style.textAlign = "left";
+function hide_working () {
+ document.getElementById ("working").style.display = 'none';
+ document.getElementById ("working").style.textAlign = "center";
+ document.getElementById ("working").style.fontWeight = "bold";
+}
+
+function toggle (name) {
+ var bt = document.getElementById ("hide_" + name + "_bt");
+ if (bt.innerHTML == "Hide") {
+ bt.innerHTML = "Show";
+ document.getElementById ("div_" + name + "_full").style.display = 'none';
+ } else {
+ bt.innerHTML = "Hide";
+ document.getElementById ("div_" + name + "_full").style.display = 'block';
+ }
+}
+
+function toggle_to_show (name) {
+ var bt = document.getElementById ("hide_" + name + "_bt");
+ if (bt.innerHTML !== "Hide") { toggle (name); }
+}
+
+function show_help (content) {
+ document.getElementById ("working").style.textAlign = "justify";
document.getElementById ("working").style.fontWeight = "normal";
document.getElementById("working").innerHTML = '\
-<b>Welcome to Relational Structures Explorer</b> \
-<p><b>Relational structures</b> consist of a set of <em>elements</em> and \
-of <em>relations</em> defined by <em>formulas</em>.</p> \
-<p><b>Elements</b> are numbered. You can change their range and you can access \
-the number of the element corresponding to a variable <em>x</em> in a formula \
-by writing <em>&x</em> or <em>:nbr(x)</em>.</p> \
-<p><b>Formulas</b> are written in first-order logic. You can use relation \
-symbols, Boolean combinations and quantifiers. Additionally, you can use \
-arithmetic operations (+-*/^) on element numbers and element positions.</p> \
-<p><b>Positions</b> of elements are determined by their <em>x</em> and \
-<em>y</em> coordinates. Define and access them as in <b>:x(a)</b> and \
-<b>:y(a)</b>. You can again use arithmetic operations and also conditionals \
-on formulas, written <b>:(formula)</b>.</p> \
-<p><b>Relation Finder</b>, placed at the bottom, automatically finds relations \
-that satisfy the given property. Use <b>|</b> in front of the relation symbol \
-to be found, as in <b>|R(x)</b>.</p> \
-';
+<b>Relational Structures Explorer Help</b> \
+<button class="obt" style="position: absolute; right: 1em;" onclick="hide_working()">Hide</button> ' + content;
document.getElementById ("working").style.display = "block";
- setTimeout (function () {
- document.getElementById ("working").style.display = "none";
- document.getElementById ("working").style.textAlign = "center";
- document.getElementById ("working").style.fontWeight = "bold";
- }, 20000);
}
+
+function show_help_view () {
+ show_help('\
+<p><b>Structure view</b> shows the elements and relations in the structure.\
+ You can move the elements with your mouse, but old positions will be restored\
+ when the structure is redrawn.</p>\
+ ');
+}
+
+function show_help_saved () {
+ show_help('\
+<p><b>Saved structures and formulas</b> are stored in the browser local \
+ storage. Press the <b>Save</b> button in the respective edit field to save \
+ a structure or a formula, and later the <b>Del</b> button to delete it.</p>\
+ ');
+}
+
+function show_help_struc () {
+ show_help('\
+<p><b>Structure editor</b> allows to edit the relations in the structure and \
+ to set the positions of elements. It uses formulas of extended first-order \
+ logic with counting. Write <b>&a</b> or <b>:nbr(a)</b> to access the number \
+ of the element which is assigned to the variable <b>a</b>, and <b>:x(a)</b> \
+ and <b>:y(a)</b> for the x- and y-coordinate of its position. Look at the \
+ example structures to see more of the syntax we use.</p>\
+ ');
+}
+
+function show_help_formula () {
+ show_help('\
+<p><b>Formula evaluator</b> allows to check formulas and to find relations \
+ defined in second-order logic. To define a new relation, put <b>|</b> in \
+ front of the relation symbol, e.g., write <b>∃ x,y |R(x,y)</b>. The new \
+ relation will be added to the structure (click example formulas to try).</p> \
+ ');
+}
+
+function show_help_colors () {
+ show_help('\
+<p><b>Color selector</b> allows to assign colors to relations, by giving \
+ a list of the form <b>Relation : #xcolor</b> where <b>xcolor</b> must \
+ be 6-characters long and a valid rgb value in hexadecimal.</p> \
+ ');
+}
+
+function select_colors (silent) {
+ var color_defs = document.getElementById('colors').value;
+ if (silent) {
+ ASYNCH ("set_colors", [color_defs], true, function (a) { ; })
+ } else {
+ ASYNCH ("set_colors", [color_defs], true, function (a) {
+ put_msg (a, 5000);
+ })
+ }
+}
//-->
</script>
</head>
-<body onload="init_canvas (); list_stored (); draw_it (); adjust_to_width()">
+<body onload="init_canvas (); select_colors (true) ; list_stored (); draw_it_msg (false); adjust_to_width()">
<div id="main">
<div id="top">
@@ -429,12 +517,26 @@
<span style="position: relative; left: 2em; top: 0.5em; font-size: 1.2em">
Relational Structures Explorer</span>
<span id="toprighttab" style="display: block;">
- <button class="obt" id="editbt" onclick="toggle_edit_view()">View</button>
- <button class="obt" id="editbt" onclick="show_help()">Help</button>
</span>
</div>
-<div id="board-left" style="display: none;">
+
+<div id="working" style="display: none; width: 30em;"></div>
+
+<div id="edit" style="position: relative; top: 2.5em; left: 2em;
+ width: 30em; margin-bottom: 6em;">
+
+<div id="div_right_col_full" style="width: 30em;">
+
+<p class="headerp">
+ <button class="ebtl" style="width: 4em;" title="Show/Hide structure view."
+ id="hide_view_bt" onclick="toggle('view')">Hide</button>
+ View Structure
+ <button class="ebtr" style="width: 4em;" title="Structure viewing help."
+ onclick="show_help_view()">Help</button>
+</p>
+
+<div id="div_view_full" style="width: 30em;">
<canvas id="canvas" height="1100" width="1100"
onmouseup="mouseup_handle(event)"
onmousedown="mousedown_handle(event)"
@@ -446,10 +548,50 @@
</canvas>
</div>
-<div id="working" style="display: none; width: 30em;"></div>
+<p class="headerp">
+ <button class="ebtl" style="width: 4em;" title="Show/Hide color selector."
+ id="hide_colors_bt" onclick="toggle ('colors')">Hide</button>
+ Select Colors
+ <button class="ebtr" style="width: 4em;" title="Color selector help."
+ onclick="show_help_colors()">Help</button>
+</p>
-<div id="edit" style="position: absolute; top: 4em; left: 2em;">
+<div id="div_colors_full">
+<p>Colors
+ <span style="position: absolute; right: 2px;">
+ <button class="ebts" style="background-color: #e5effa;";
+ onclick="add_field('colors', '#e5effa')"> </button><button
+ class="ebts" style="background-color: #a5afaa;";
+ onclick="add_field('colors', '#a5afaa')"> </button><button
+ class="ebts" style="background-color: #93a605;";
+ onclick="add_field('colors', '#93a605')"> </button><button
+ class="ebts" style="background-color: #3e5916;";
+ onclick="add_field('colors', '#3e5916')"> </button><button
+ class="ebts" style="background-color: #f28705;";
+ onclick="add_field('colors', '#f28705')"> </button><button
+ style="background-color: #f25c05;"; class="ebts"
+ onclick="add_field('colors', '#f25c05')"> </button><button
+ style="background-color: #260314;"; class="ebts"
+ onclick="add_field('colors', '#260314')"> </button>
+ <button class="ebt" onclick="select_colors(false)" style="width: 4em;"
+ title="Select these colors.">Select</button>
+ </span>
+</p>
+<textarea id="colors" rows="1" cols="60" class="textar">
+|R : #f25c05 ; |G : #3e5916 ; |B : #a5afaa</textarea>
+</div>
+</div> <!-- end right column -->
+
+<p class="headerp">
+ <button class="ebtl" style="width: 4em;" title="Show/Hide structure editing."
+ id="hide_struc_bt" onclick="toggle('struc')">Hide</button>
+ Edit Structure
+ <button class="ebtr" style="width: 4em;" title="Structure editing help."
+ onclick="show_help_struc()">Help</button>
+</p>
+
+<div id="div_struc_full">
<p>Name
<input id="struc-name" type="text" size="20" value="My Structure 1"
style="width: 12em"></input>
@@ -475,8 +617,6 @@
<span style="position: absolute; right: 2px;">
<button class="ebts" title="Not equal. You can also write '<>' or '!='."
onclick="add_field('relations', '≠')">≠</button><button
- class="ebts" title="Less or equal. You can also write '=<'."
- onclick="add_field('relations', '≤')">≤</button><button
class="ebts" title="Conjunction. You can also write 'and' or '&'."
onclick="add_field('relations', '∧')">∧</button><button
class="ebts" title="Disjunction. You can also write 'or' or '|'."
@@ -493,7 +633,7 @@
title="Redraw current structure.">Draw</button>
</span>
</p>
-<textarea id="relations" rows="3" cols="60">
+<textarea id="relations" rows="3" cols="60" class="textar">
E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)
</textarea>
@@ -501,8 +641,6 @@
<span style="position: absolute; right: 2px;">
<button class="ebts" title="Not equal. You can also write '<>' or '!='."
onclick="add_field('positions', '≠')">≠</button><button
- class="ebts" title="Less or equal. You can also write '=<'."
- onclick="add_field('positions', '≤')">≤</button><button
class="ebts" title="Conjunction. You can also write 'and' or '&'."
onclick="add_field('positions', '∧')">∧</button><button
class="ebts" title="Disjunction. You can also write 'or' or '|'."
@@ -519,14 +657,23 @@
title="Redraw current structure.">Draw</button>
</span>
</p>
-<textarea id="positions" rows="3" cols="60">
+<textarea id="positions" rows="3" cols="60" class="textar">
:x(a) = &a;
:y(a) = &a · (10 - &a) / 10
</textarea>
+</div>
+<p class="headerp">
+ <button class="ebtl" style="width: 4em;" title="Show/Hide formula evaluator."
+ id="hide_formula_bt" onclick="toggle ('formula')">Hide</button>
+ Evaluate Formulas
+ <button class="ebtr" style="width: 4em;" title="Formula evaluator help."
+ onclick="show_help_formula()">Help</button>
+</p>
-<p style="width:100%; border-top: 1px solid; padding-top: 1em;">
- Formula Name
+<div id="div_formula_full">
+<p>
+ Formula Name
<input id="so-name" type="text" size="20" value="My Formula 1"
style="width: 12em"></input>
<span style="position: absolute; right: 2px;">
@@ -539,8 +686,6 @@
<span style="position: absolute; right: 2px;">
<button class="ebts" title="Not equal. You can also write '<>' or '!='."
onclick="add_field('second-order', '≠')">≠</button><button
- class="ebts" title="Less ...
[truncated message content] |
|
From: <luk...@us...> - 2012-07-10 22:44:55
|
Revision: 1744
http://toss.svn.sourceforge.net/toss/?rev=1744&view=rev
Author: lukaszkaiser
Date: 2012-07-10 22:44:46 +0000 (Tue, 10 Jul 2012)
Log Message:
-----------
Optimizing SO-finder and its web interface, larger tests.
Modified Paths:
--------------
trunk/Toss/Arena/Arena.ml
trunk/Toss/Arena/Arena.mli
trunk/Toss/Arena/ArenaParser.mly
trunk/Toss/Arena/ArenaTest.ml
trunk/Toss/Arena/DiscreteRuleParser.mly
trunk/Toss/Client/Drawing.ml
trunk/Toss/Client/Drawing.mli
trunk/Toss/Client/JsEval.ml
trunk/Toss/Client/eval.html
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/Formula/BoolFormula.mli
trunk/Toss/Formula/FormulaParser.mly
trunk/Toss/Formula/Lexer.mll
trunk/Toss/Formula/Sat/Sat.ml
trunk/Toss/Makefile
trunk/Toss/Server/Server.ml
trunk/Toss/Server/Tests.ml
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/Solver.mli
trunk/Toss/Solver/SolverTest.ml
trunk/Toss/Solver/Structure.ml
trunk/Toss/Solver/Structure.mli
trunk/Toss/Solver/StructureParser.mly
trunk/Toss/menhir_conf
trunk/Toss/www/Publications/all.bib
trunk/Toss/www/create.xml
trunk/Toss/www/docs.xml
trunk/Toss/www/index.xml
trunk/Toss/www/play.xml
Added Paths:
-----------
trunk/Toss/www/pub/itrs_qmu.pdf
Modified: trunk/Toss/Arena/Arena.ml
===================================================================
--- trunk/Toss/Arena/Arena.ml 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Arena/Arena.ml 2012-07-10 22:44:46 UTC (rev 1744)
@@ -255,28 +255,7 @@
List.map (fun (lab,_) -> lab.lb_rule) l.(player_no).moves in
List.concat (List.map rules_of_loc (Array.to_list game.graph))
-(* Add a defined relation to a structure. *)
-let add_def_rel_single struc (r_name, vars, def_phi) =
- let def_asg = Solver.M.evaluate struc def_phi in
- match def_asg with
- | AssignmentSet.Empty ->
- Structure.add_rel_name r_name (List.length vars) struc
- | _ ->
- let tuples = AssignmentSet.tuples (Structure.elems struc) vars def_asg in
- Structure.add_rels struc r_name tuples
-let add_def_rels struc rels = List.fold_left add_def_rel_single struc rels
-
-let add_def_fun_single struc (f, v, def_re) =
- LOG 1 "adding fun %s def %s" f (Formula.real_str def_re);
- let elems = Structure.elements struc in
- let asg e = AssignmentSet.FO (v, [(e, AssignmentSet.Any)]) in
- let fval e = Solver.M.get_real_val ~asg:(asg e) def_re struc in
- List.fold_left (fun s e-> Structure.change_fun_int s f e (fval e)) struc elems
-
-let add_def_funs struc funs = List.fold_left add_def_fun_single struc funs
-
-
(* The order of following entries matters: [DefPlayers] adds more
players, with consecutive numbers starting from first available;
later [StartStruc], [CurrentStruc], [StateTime] and [StateLoc] entries
Modified: trunk/Toss/Arena/Arena.mli
===================================================================
--- trunk/Toss/Arena/Arena.mli 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Arena/Arena.mli 2012-07-10 22:44:46 UTC (rev 1744)
@@ -67,13 +67,7 @@
(** Rules with which a player with given number can move. *)
val rules_for_player : int -> game -> string list
-val add_def_rels : Structure.structure ->
- (string * string list * Formula.formula) list -> Structure.structure
-val add_def_funs : Structure.structure ->
- (string * string * Formula.real_expr) list -> Structure.structure
-
-
(** Print a label as a string. *)
val label_str : label -> string
val move_str : (label * int) -> string
Modified: trunk/Toss/Arena/ArenaParser.mly
===================================================================
--- trunk/Toss/Arena/ArenaParser.mly 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Arena/ArenaParser.mly 2012-07-10 22:44:46 UTC (rev 1744)
@@ -38,26 +38,12 @@
"Syntax error in move definition."
}
-real_expr_err:
- | rexp = real_expr { rexp }
- | error
- { Lexer.report_parsing_error $startpos $endpos
- "Syntax error in real expression."
- }
-
-formula_expr_err:
- | phi = formula_expr { phi }
- | error
- { Lexer.report_parsing_error $startpos $endpos
- "Syntax error in formula expression."
- }
-
float_or_int:
| FLOAT { $1 }
| INT { float_of_int $1 }
player_loc_defs:
- | PAYOFF poff = real_expr_err { `Payoff poff }
+ | PAYOFF poff = real_expr { `Payoff poff }
| MOVES moves = separated_list (SEMICOLON, move) { `Moves moves }
| COND hs = separated_list (SEMICOLON, float_or_int) { `Heurs hs }
| error
@@ -90,14 +76,6 @@
"Syntax error in location definition."
}
-rel_def_simple:
- | rel = ID args = delimited (OPEN, separated_list (COMMA, ID), CLOSE)
- EQ body = formula_expr_err { (rel, args, body) }
-
-fun_def_simple:
- | COLON f = ID OPEN v = ID CLOSE EQ body = real_expr
- { (f, v, body) }
-
game_move_timed:
| OPENSQ r = id_int t = FLOAT RARR l = INT EMB
emb = separated_list (COMMA, separated_pair (ID, COLON, id_int)) CLOSESQ
@@ -126,35 +104,21 @@
{ DefLoc l }
| PLAYERS_MOD pnames = separated_list (COMMA, id_int)
{ DefPlayers pnames }
- | SET_CMD r = real_expr_err
+ | SET_CMD r = real_expr
{ DefPattern r }
| REL_MOD rel = ID
arg = delimited (OPEN, separated_list (COMMA, ID), CLOSE)
- body = delimited (OPENCUR, formula_expr_err, CLOSECUR)
+ body = delimited (OPENCUR, formula_expr, CLOSECUR)
{ DefRel (rel, arg, body) }
| REL_MOD rel = ID
arg = delimited (OPEN, separated_list (COMMA, ID), CLOSE)
EQ
- body = formula_expr_err
+ body = formula_expr
{ DefRel (rel, arg, body) }
| START model = struct_expr
{ StartStruc model }
- | START model = struct_expr WITH
- defs = separated_list (SEMICOLON, rel_def_simple)
- { StartStruc (Arena.add_def_rels model defs) }
- | START model = struct_expr WITH
- defs = separated_list (SEMICOLON, rel_def_simple) WITH
- funs = separated_list (SEMICOLON, fun_def_simple)
- { StartStruc (Arena.add_def_funs (Arena.add_def_rels model defs) funs) }
| CURRENT model = struct_expr
{ CurrentStruc model }
- | CURRENT model = struct_expr WITH
- defs = separated_list (SEMICOLON, rel_def_simple)
- { CurrentStruc (Arena.add_def_rels model defs) }
- | CURRENT model = struct_expr WITH
- defs = separated_list (SEMICOLON, rel_def_simple) WITH
- funs = separated_list (SEMICOLON, fun_def_simple)
- { StartStruc (Arena.add_def_funs (Arena.add_def_rels model defs) funs) }
| MOVES moves = separated_list (SEMICOLON, game_move_timed)
{ History (moves) }
| TIME_MOD t = FLOAT
Modified: trunk/Toss/Arena/ArenaTest.ml
===================================================================
--- trunk/Toss/Arena/ArenaTest.ml 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Arena/ArenaTest.ml 2012-07-10 22:44:46 UTC (rev 1744)
@@ -9,31 +9,7 @@
| Arena.StartStruc struc -> struc
| _ -> failwith "GameTreeTest:struc_of_str: not a structure"
-let rel_str rel struc_str =
- let s = struc_of_str struc_str in
- Structure.rel_str s rel (Structure.rel_graph rel s)
-
let tests = "Arena" >::: [
- "structure with rels parsing" >::
- (fun () ->
- let test p s res = assert_equal ~printer:(fun x -> x) res (rel_str p s) in
- test "P" "START [ 1 - 5 | | - ] with P(a) = :nbr(a)= 2" "P (e2)";
- test "P" "START [ 1 - 5 | | - ] with P(a) = :nbr(a)= 2 with :y(a) = 10*&a"
- "P (e2)";
- test "P" ("START [ 1 - 10 | | - ] with P(z) = &z > 1 and " ^
- "all x, y (&x * &y = &z -> (&x = 1 or &y = 1))")
- "P {e2; e3; e5; e7}";
- test "P" ("START [ 1 - 3 | | - ] with E(x, y) = &y = &x + 1; " ^
- "P(x, y) = &x != &y and tc x, y E(x, y)")
- "P {(e1, e2); (e1, e3); (e2, e3)}";
- test "S" ("START [ 1 - 10 | | - ] with P(z) = &z > 1 and " ^
- "all x, y (&x * &y = &z -> (&x = 1 or &y = 1));" ^
- "E(x, y) = P(x) and P(y) and &x < &y and " ^
- " all z (&x < &z and &z < &y -> not P(z));" ^
- "S(x, y) = x != y and tc x, y E(x, y)")
- "S {(e2, e3); (e2, e5); (e2, e7); (e3, e5); (e3, e7); (e5, e7)}";
- );
-
"simple parsing and printing" >::
(fun () ->
let s = "PLAYERS white, black
@@ -120,20 +96,3 @@
"[rule 0. -> 1 emb x: 1]"
);
]
-
-let bigtests = "ArenaBig" >::: [
- "structure with rels: 3 coloring" >::
- (fun () ->
- let test p s res = assert_equal ~printer:(fun x -> x) res (rel_str p s) in
- test "C" ("START [ 1 - 3 | | - ] with E(x, y) = x != y; " ^
- "C(z) = ex R, G, B all x, y ( (x in R or x in G or x in B)"^
- " and ( E(x,y) -> not ( (x in R and y in R) or (x in G and"^
- " y in G) or (x in B and y in B) ) ) )")
- "C {e1; e2; e3}";
- test "C" ("START [ 1 - 4 | | - ] with E(x, y) = x != y; " ^
- "C(z) = ex R, G, B all x, y ( (x in R or x in G or x in B)"^
- " and ( E(x,y) -> not ( (x in R and y in R) or (x in G and"^
- " y in G) or (x in B and y in B) ) ) )")
- "C:1 {}";
- );
-]
Modified: trunk/Toss/Arena/DiscreteRuleParser.mly
===================================================================
--- trunk/Toss/Arena/DiscreteRuleParser.mly 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Arena/DiscreteRuleParser.mly 2012-07-10 22:44:46 UTC (rev 1744)
@@ -67,9 +67,6 @@
DiscreteRule.compile_formula_rule signat defs phi del_part
add_part pre
}
- | MATCH error
- { Lexer.report_parsing_error $startpos $endpos
- "Syntax error after the discrete rewrite rule MATCH keyword" }
parse_discrete_rule:
discrete_rule_expr EOF { $1 };
Modified: trunk/Toss/Client/Drawing.ml
===================================================================
--- trunk/Toss/Client/Drawing.ml 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Client/Drawing.ml 2012-07-10 22:44:46 UTC (rev 1744)
@@ -38,12 +38,15 @@
let defaultCFill = { red=255 ; green = 228 ; blue = 170 ; opacity = 0.5 }
let defaultCStroke = { red=38 ; green = 3 ; blue = 20 ; opacity = 0.5 }
-let defaultCRed = {red=242 ; green=92 ; blue=5 ; opacity = 1. }
+let defaultCRed = {red=232 ; green=42 ; blue=51 ; opacity = 1. }
let defaultCGreen = {red=62 ; green=89 ; blue=24 ; opacity = 1. }
-let defaultCBlue = {red=165 ; green=175 ; blue=170 ; opacity = 1. }
+let defaultCBlue = {red=0 ; green=54 ; blue=76 ; opacity = 1. }
let palette = Hashtbl.create 7
+(* Clear all previous color definitions. *)
+let reset_colors () = Hashtbl.clear palette
+
(* Set a color for a name. *)
let set_color name color =
Hashtbl.add palette name color
@@ -219,7 +222,7 @@
if arity = 1 then
let elems = Structure.Tuples.elements (Structure.rel_graph rel struc) in
let col = get_color rel in
- Aux.concat_map (fun a -> [Circle (pos a.(0), {x=10.; y=10.}, col)]) elems
+ Aux.concat_map (fun a -> [Circle (pos a.(0), {x=5.; y=5.}, col)]) elems
else if arity = 2 then
let tuples = Structure.Tuples.elements (Structure.rel_graph rel struc) in
let c = get_color ~stroke:true rel in
@@ -234,17 +237,19 @@
let fill = "ctx.fillStyle = \""^(color_to_str col)^"\"; ctx.fill();" in
if r.x = r.y then
let s = Printf.sprintf "ctx.arc(%F,%F,%F,0,2*Math.PI,false); " p.x p.y r.x
- in "ctx.beginPath(); "^ s ^ fill ^ " ctx.stroke(); ctx.closePath(); "
+ in ["ctx.beginPath(); "; s; fill; " ctx.stroke(); ctx.closePath(); "]
else
let sc = Printf.sprintf "ctx.scale(%F, %F); " (r.x /.100.) (r.y /.100.) in
let tr = Printf.sprintf "ctx.translate(%F, %F); " p.x p.y in
- "ctx.save(); "^ tr ^sc ^"ctx.beginPath(); ctx.arc(0,0,100,0,2*Math.PI); "^
- fill ^ "ctx.stroke(); ctx.closePath(); ctx.restore(); "
+ ["ctx.save();"; tr;sc; "ctx.beginPath();";"ctx.arc(0,0,100,0,2*Math.PI);";
+ fill; "ctx.stroke(); ctx.closePath(); ctx.restore(); "]
| Line (f, t, col) ->
let fs = Printf.sprintf "ctx.moveTo(%F,%F); " f.x f.y in
let ts = Printf.sprintf "ctx.lineTo(%F,%F); " t.x t.y in
let stroke= "ctx.strokeStyle = \""^(color_to_str col)^"\"; ctx.stroke();" in
- "ctx.beginPath(); " ^ fs ^ ts ^ stroke ^ " ctx.closePath(); "
+ ["ctx.beginPath(); "; fs; ts; stroke; " ctx.closePath(); "]
-let shapes_to_canvas l =
- String.concat " " (List.rev (List.rev_map shape_to_canvas l))
+let shapes_to_canvas ?(attach=[]) l =
+ let shapes = List.fold_left (fun acc shape -> List.rev_append
+ (shape_to_canvas shape) acc) [] l in
+ Array.of_list (attach @ (List.rev shapes))
Modified: trunk/Toss/Client/Drawing.mli
===================================================================
--- trunk/Toss/Client/Drawing.mli 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Client/Drawing.mli 2012-07-10 22:44:46 UTC (rev 1744)
@@ -40,7 +40,10 @@
whether for stroke or fill, or a default red, if name starts with '|'. *)
val get_color : ?stroke : bool -> string -> color
+(** Clear all previous color definitions. *)
+val reset_colors : unit -> unit
+
(** Shapes. *)
type shape =
| Circle of point * point * color (** circle, given middle and radiuses *)
@@ -93,4 +96,4 @@
(** Compile the shapes to a JavaScript program drawing the shape on 'ctx'.
With [result] in JS do: var ctx = canvas.getContext("2d"); eval (result). *)
-val shapes_to_canvas : shape list -> string
+val shapes_to_canvas : ?attach: string list -> shape list -> string array
Modified: trunk/Toss/Client/JsEval.ml
===================================================================
--- trunk/Toss/Client/JsEval.ml 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Client/JsEval.ml 2012-07-10 22:44:46 UTC (rev 1744)
@@ -27,46 +27,55 @@
(* --- Main part: communication with JS and evaluation --- *)
let cur_st = ref (Drawing.empty_struc_coords ())
+let cur_parsed_string = ref ""
(* Parse a formula. *)
let formula_of_string s = FormulaParser.parse_formula Lexer.lex
(Lexing.from_string (Aux.strip_spaces s))
(* Parse a structure. *)
-let structure_of_string s =
- let str = "START " ^ (Aux.strip_spaces s) in
- match ArenaParser.parse_game_defs Lexer.lex (Lexing.from_string str) with
- | Arena.StartStruc struc -> struc
- | _ -> failwith "not a structure"
+let structure_of_string s = StructureParser.parse_structure
+ Lexer.lex (Lexing.from_string (Aux.strip_spaces s))
-
(* Drawing the structure. *)
let draw_struc_js so_s struc_s =
let err msg =
let js_msg = Js.string ("put_msg('" ^ msg ^ "', 5000);") in
- Js.array [|js_msg; Js.string "Error"|] in
+ Js.array [|Js.string "Error"; js_msg|] in
let error_msg where = function
| Lexer.Parsing_error m when String.length m > 15 &&
String.sub m 0 15 = "File \"\", lines " ->
let ms = String.sub m 15 ((String.index m '\n') - 16) in
let l, c = String.sub ms 0 (String.index ms '-'), String.index ms ',' in
let chars = String.sub ms (c+1) ((String.length ms)-c-1) in
- let l = string_of_int ((int_of_string l) - 1) in
+ let l = if where = "Formula" then l else
+ string_of_int ((int_of_string l) - 1) in
err (where ^ " parsing error in line " ^ l ^ "," ^ chars)
| x -> err (where ^ " error:<br />" ^
(Aux.str_subst_all "\n" "<br/>" (Printexc.to_string x))) in
try
- let st = structure_of_string (Js.to_string struc_s) in
+ let in_string = Js.to_string struc_s in
+ let t = AuxIO.gettimeofday () in
+ let st = if !cur_parsed_string = in_string then !cur_st.Drawing.struc else
+ (let s = structure_of_string in_string in
+ LOG 0 "PUT#Structure constructed at %.3fs" (AuxIO.gettimeofday() -. t);
+ s) in
try
let so = Js.to_string so_s in
let st, so_res = if Aux.strip_spaces so = "" then (st, "No Formula") else
let so_phi = formula_of_string so in
- let st, res = Solver.find_so st so_phi in
+ let st, res = Solver.find_so ~logtime:t ~logprefix:"PUT#" st so_phi in
if res then st, "Formula Satisfied" else st,"Formula Unsatisfiable" in
- let st_c = Drawing.add_coords 1000. 1000. 50. 50. None None st in
+ let st_c = Drawing.add_coords 500. 500. 25. 25. None None st in
cur_st := st_c;
- let draw = Drawing.shapes_to_canvas (Drawing.draw_struc st_c) in
- Js.array [|Js.string ("clear_canvas (); " ^ draw) ; Js.string so_res |]
+ if so_res = "No Formula" then cur_parsed_string := in_string else
+ cur_parsed_string := "";
+ let shapes = Drawing.draw_struc st_c in
+ LOG 0 "PUT#Shapes constructed at %.3fs" (AuxIO.gettimeofday() -. t);
+ let draw = Drawing.shapes_to_canvas ~attach:[so_res; "clear_canvas();"]
+ shapes in
+ LOG 0 "PUT#Canvas commands issued at %.3fs" (AuxIO.gettimeofday() -. t);
+ Js.array (Array.map Js.string draw);
with x -> error_msg "Formula" x
with x -> error_msg "Structure" x
@@ -93,7 +102,7 @@
let mousemove_handle x y i =
match elem_moving i with
- | None -> Js.string ""
+ | None -> Js.array [|Js.string ""|]
| Some e ->
let (x,y), st = (Js.to_float x, Js.to_float y), !cur_st.Drawing.struc in
let p = Drawing.change_coords !cur_st.Drawing.coordC
@@ -101,8 +110,9 @@
let st = Structure.change_fun_int st "x" e p.Drawing.x in
let st = Structure.change_fun_int st "y" e (-1. *. p.Drawing.y) in
cur_st := {!cur_st with Drawing.struc = st };
- let s = Drawing.shapes_to_canvas (Drawing.draw_struc !cur_st) in
- Js.string ("clear_canvas(); " ^ s)
+ let s = Drawing.shapes_to_canvas ~attach:["clear_canvas(); "]
+ (Drawing.draw_struc !cur_st) in
+ Js.array (Array.map Js.string s)
let mouseup_handle x y i =
stop_moving i;
@@ -132,6 +142,7 @@
match Aux.split_charprop (fun c -> c = ':') d with
| [rel; c] -> set_color_def (Aux.strip_spaces rel) (Aux.strip_spaces c)
| _ -> "Incorrect color definition: " ^ (Aux.normalize_spaces d) in
+ Drawing.reset_colors ();
Js.string (String.concat " <br /> " (List.map parse_def defs))
let _ = set_handle "set_colors" set_colors
Modified: trunk/Toss/Client/eval.html
===================================================================
--- trunk/Toss/Client/eval.html 2012-07-06 01:06:25 UTC (rev 1743)
+++ trunk/Toss/Client/eval.html 2012-07-10 22:44:46 UTC (rev 1744)
@@ -13,16 +13,35 @@
var worker = new Worker ("JsEval.js");
var worker_handler = new Object ();
-worker.onmessage = function (m) {
+var killBT = '<button class="obt" style="position: ' +
+ 'absolute; right: 1em; font-weight: bold;" ' +
+ 'onclick="restart_worker()">Kill</button> ';
+
+function init_worker () {
+ worker.onmessage = function (m) {
if (typeof m.data == 'string') {
console.log("" + m.data);
+ if (m.data.substr (m.data.indexOf(']')+2, 4) === "PUT#") {
+ var cont = m.data.substring (m.data.indexOf(']')+6, m.data.length);
+ document.getElementById("working").innerHTML = cont + "... " + killBT;
+ }
} else {
//console.log ("[ASYNCH] back from " + m.data.fname);
var handler = worker_handler[m.data.fname];
handler (m.data.result);
}
+ }
+ select_colors (true);
}
+function restart_worker () {
+ worker.terminate ();
+ worker = new Worker ("JsEval.js");
+ worker_handler = new Object ();
+ init_worker ();
+ put_msg ("Killed", 2000);
+}
+
function ASYNCH (action_name, action_args, should_log, cont) {
worker_handler[action_name] = cont;
worker.postMessage ({fname: action_name, args: action_args});
@@ -38,7 +57,7 @@
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#ffe4aa";
ctx.strokeStyle = "#260314";
- ctx.lineWidth = 5;
+ ctx.lineWidth = 2;
ctx.lineCap = "round";
ctx.lineJoin = "round";
}
@@ -49,7 +68,7 @@
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#ffe4aa";
ctx.strokeStyle = "#260314";
- ctx.lineWidth = 5;
+ ctx.lineWidth = 2;
ctx.lineCap = "round";
ctx.lineJoin = "round";
}
@@ -57,7 +76,7 @@
function draw_it_msg (msg) {
if (msg) {
document.getElementById ("working").style.display = 'block';
- document.getElementById ("working").innerHTML = 'Working...';
+ document.getElementById ("working").innerHTML = 'Working... ' + killBT;
}
var rels = document.getElementById ("relations").value;
var pos = document.getElementById ("positions").value;
@@ -69,13 +88,13 @@
ASYNCH ("draw_struc", ["", struc], true, function (a) {
document.getElementById ("working").style.display = 'none';
var ctx = document.getElementById("canvas").getContext("2d");
- eval (a[0])
+ for (var i = 1; i < a.length; i++) { eval (a[i]); }
toggle_to_show ("view");
})
} else {
ASYNCH ("draw_struc", ["", struc], true, function (a) {
var ctx = document.getElementById("canvas").getContext("2d");
- eval (a[0])
+ for (var i = 1; i < a.length; i++) { eval (a[i]); }
})
}
}
@@ -86,7 +105,7 @@
function find_draw_it () {
document.getElementById ("working").style.display = 'block';
- document.getElementById ("working").innerHTML = 'Working...';
+ document.getElementById ("working").innerHTML = 'Working... ' + killBT;
var rels = document.getElementById ("relations").value;
var pos = document.getElementById ("positions").value;
var elemsF = document.getElementById ("no-elems-start").value;
@@ -97,9 +116,9 @@
ASYNCH ("draw_struc", [so, struc], true, function (a) {
document.getElementById ("working").style.display = 'none';
var ctx = document.getElementById("canvas").getContext("2d");
- eval (a[0]);
+ for (var i = 1; i < a.length; i++) { eval (a[i]); }
toggle_to_show ("view");
- if (a[1] !== "Error") { put_msg (a[1], 2000) }
+ if (a[0] !== "Error") { put_msg (a[0], 2000) }
})
}
@@ -170,9 +189,9 @@
ALLOW_MOUSE_MOVE = false;
setTimeout (function () { ALLOW_MOUSE_MOVE = true; }, 100);
var pos = canvasCoords (e.pageX, e.pageY);
- ASYNCH ("mousemove_handle", [pos.x, pos.y, 0], false, function (s) {
+ ASYNCH ("mousemove_handle", [pos.x, pos.y, 0], false, function (a) {
var ctx = document.getElementById("canvas").getContext("2d");
- eval (s);
+ for (var i = 0; i < a.length; i++) { eval (a[i]); }
})
}
}
@@ -184,9 +203,9 @@
setTimeout (function () { ALLOW_MOUSE_MOVE = true; }, 100);
for (var i = 0; i < e.targetTouches.length; i++) {
var p = canvasCoords (e.targetTouches[i].pageX, e.targetTouches[i].pageY);
- ASYNCH ("mousemove_handle", [p.x, p.y, i], false, function (s) {
+ ASYNCH ("mousemove_handle", [p.x, p.y, i], false, function (a) {
var ctx = document.getElementById("canvas").getContext("2d");
- eval (s);
+ for (var i = 0; i < a.length; i++) { eval (a[i]); }
})
}
}
@@ -195,16 +214,30 @@
function handle_elem_click (eid) { console.log (eid); }
function example_basic () {
- document.getElementById ("struc-name").value = "Basic";
+ document.getElementById ("struc-name").value = "Cycle";
document.getElementById ("relations").value =
- "E(x, y) = (&y = &x + 1) ∨ (&x=15 ∧ &y=1)";
+ "E(x, y) = (&y = &x + 1) ∨ (&x=10 ∧ &y=0)";
document.getElementById ("positions").value = ":x(a) = &a;\n" +
":y(a) = &a · (10 - &a) / 10";
- document.getElementById ("no-elems-start").value = "1";
- document.getElementById ("no-elems-end").value = "15";
+ document.getElementById ("no-elems-start").value = "0";
+ document.getElementById ("no-elems-end").value = "10";
draw_it_msg (false);
}
+function example_3x3 () {
+ document.getElementById ("struc-name").value = "3x3 grid";
+ document.getElementById ("relations").value =
+ "C(x, y) = (&y = &x+1) ∧ ¬∃z &x=3*&z + 2;\n" +
+ "R(x, y) = &y = &x+3";
+ document.getElementById ("positions").value =
+ ":x(a) = (&a - :(∃z &a=3*&z + 1) - :(∃z &a=3*&z + 2)*2)*2;\n" +
+ ":y(a) = (:(∃z &a=3*&z + 2)*3 - :(∃z &a=3*&z)*3)*2";
+ document.getElementById ("no-elems-start").value = "0";
+ document.getElementById ("no-elems-end").value = "8";
+ draw_it_msg (false);
+}
+
+
function example_primes () {
document.getElementById ("struc-name").value = "Primes";
document.getElementById ("relations").value =
@@ -215,6 +248,28 @@
draw_it_msg (false);
}
+function example_3dnp_struc () {
+ document.getElementById ("struc-name").value = "Triangles";
+ document.getElementById ("relations").value =
+ "E(x, y) = &y=&x+1 ∨ &y=&x+2 ∨ &x=&y+1 ∨ &x=&y+2";
+ document.getElementById ("positions").value = ":x(a) = &a*2;\n" +
+ ":y(a) = :(∃z &a=3*&z + 2)*9";
+ document.getElementById ("no-elems-start").value = "0";
+ document.getElementById ("no-elems-end").value = "9";
+ draw_it_msg (false);
+}
+
+function example_3col_struc () {
+ document.getElementById ("struc-name").value = "Full 3-partite graph";
+ document.getElementById ("relations").value =
+ "E(x, y) = ¬∃ z (&x=&y+3*&z ∨ &y=&x+3*&z)";
+ document.getElementById ("positions").value = ":x(a) = &a;\n" +
+ ":y(a) = :(∃z &a=3*&z + 1)*5 - :(∃z &a=3*&z + 2)*5";
+ document.getElementById ("no-elems-start").value = "0";
+ document.getElementById ("no-elems-end").value = "18";
+ draw_it_msg (false);
+}
+
function example_tc () {
document.getElementById ("struc-name").value = "Simple TC";
document.getElementById ("relations").value =
@@ -227,7 +282,7 @@
}
function example_heart () {
- document.getElementById ("struc-name").value = "Heart";
+ document.getElementById ("struc-name").value = "Heart drawing";
document.getElementById ("relations").value =
"E(x, y) = (&y = &x + 1 ∧ &x ≠ 18) ∨ (&x=37 ∧ &y=18)";
document.getElementById ("positions").rows = 7;
@@ -243,11 +298,26 @@
draw_it_msg (false);
}
+
+function example_diag () {
+ document.getElementById ("so-name").value = "Diagonal";
+ document.getElementById ("second-order").value =
+ "∀ x,y ( |Diag(x,y) <-> ∃ u (R(x,u) ∧ C(u, y)) )"
+ find_draw_it ();
+}
+
+function example_last_row () {
+ document.getElementById ("so-name").value = "Last row";
+ document.getElementById ("second-order").value =
+ "∀ x (|LastRow(x) <-> ∀ y ¬ C(x, y))";
+ find_draw_it ();
+}
+
function example_matching () {
document.getElementById ("so-name").value = "Matching";
document.getElementById ("second-order").value =
"∀ x,y ( |M(x, y) -> (\n" +
- " ( E(x, y) ∨ E(y, x) ) ∧ ¬∃ z (z≠y ∧ |M(x, z) )\n" +
+ " ( E(x, y) ∨ E(y, x) ) ∧ ¬∃ z (z≠y ∧ (|M(x, z) ∨ |M(z, x)))\n" +
") ) ∧ ∀ x ∃ y |M(x, y)";
find_draw_it ();
}
@@ -268,11 +338,16 @@
find_draw_it ();
}
-function example_tc_so () {
- document.getElementById ("so-name").value = "TC";
+function example_3dnp () {
+ document.getElementById ("so-name").value = "3-DNP";
+ document.getElementById ("second-order").rows = 6;
document.getElementById ("second-order").value =
- "∀ x,y,z ( ( E(x, y) → |Tc(x, y) ) ∧\n" +
- " ( (|Tc(x, y) ∧ |Tc(y, z)) -> |Tc(x, z) ) )";
+ "∀ x ∃ y,u,v (((|R(x) → ¬(|G(x) ∨ |B(x))) ∧\n" +
+ " (|G(x) → ¬(|R(x) ∨ |B(x))) ∧\n" +
+ " (|B(x) → ¬(|R(x) ∨ |G(x)))) ∧\n" +
+ " (|R(x) ∨ (|R(y) ∧ E(x,y))) ∧\n" +
+ " (|G(x) ∨ (|G(u) ∧ E(x,u))) ∧\n" +
+ " (|B(x) ∨ (|B(v) ∧ E(x,v))))";
find_draw_it ();
}
@@ -311,6 +386,7 @@
localStorage["TRelStrucExplRel"+name] = rels;
localStorage["TRelStrucExplPos"+name] = pos;
list_stored_struc ();
+ put_msg ("Structure Saved", 1000);
}
function save_so () {
@@ -318,6 +394,7 @@
var phi = document.getElementById ("second-order").value;
localStorage["TRelStrucExplSOF"+name] = phi;
list_stored_so ();
+ put_msg ("Formula Saved", 1000);
}
function load_struc (name) {
@@ -350,7 +427,7 @@
var li = document.createElement('li');
li.innerHTML ='<button class="obt" onclick="load_struc('+"'"+ n +"'"+')">'
+ n +'</button> <button class="ebtr" onclick="del_struc('+ "'"+ n +"'"+
- ')" style="width: 4em;" title="Delete this structure.">Del</button>';
+ ')" style="width: 2em;" title="Delete this structure.">×</button>';
saved.appendChild (li);
}
}
@@ -365,8 +442,8 @@
var n = k.substring (16, k.length);
var li = document.createElement('li');
li.innerHTML ='<button class="obt" onclick="load_so('+"'"+ n +"'"+')">'
- + n +'</button> <button class="ebtr" onclick="del_so('+ "'"+ n +
- "'" +')" style="width: 4em;" title="Delete this formula.">Del</button>';
+ + n +'</button> <button class="ebtr" onclick="del_so('+ "'"+ n +"'" +
+ ')" style="width: 2em;" title="Delete this formula.">×</button>';
saved.appendChild (li);
}
}
@@ -424,18 +501,18 @@
function toggle (name) {
var bt = document.getElementById ("hide_" + name + "_bt");
- if (bt.innerHTML == "Hide") {
- bt.innerHTML = "Show";
+ if (bt.innerHTML == "«") {
+ bt.innerHTML = "»";
document.getElementById ("div_" + name + "_full").style.display = 'none';
} else {
- bt.innerHTML = "Hide";
+ bt.innerHTML = "«";
document.getElementById ("div_" + name + "_full").style.display = 'block';
}
}
function toggle_to_show (name) {
var bt = document.getElementById ("hide_" + name + "_bt");
- if (bt.innerHTML !== "Hide") { toggle (name); }
+ if (bt.innerHTML !== "«") { toggle (name); }
}
function show_help (content) {
@@ -443,7 +520,8 @@
document.getElementById ("working").style.fontWeight = "normal";
document.getElementById("working").innerHTML = '\
<b>Relational Structures Explorer Help</b> \
-<button class="obt" style="position: absolute; right: 1em;" onclick="hide_working()">Hide</button> ' + content;
+<button class="obt" style="position: absolute; right: 1em; font-weight: bold;"\
+ onclick="hide_working()">×</button> ' + content;
document.getElementById ("working").style.display = "block";
}
@@ -458,8 +536,9 @@
function show_help_saved () {
show_help('\
<p><b>Saved structures and formulas</b> are stored in the browser local \
- storage. Press the <b>Save</b> button in the respective edit field to save \
- a structure or a formula, and later the <b>Del</b> button to delete it.</p>\
+ storage. Press the <b>⇩</b> button in the respect...
[truncated message content] |
|
From: <luk...@us...> - 2012-07-15 20:43:25
|
Revision: 1745
http://toss.svn.sourceforge.net/toss/?rev=1745&view=rev
Author: lukstafi
Date: 2012-07-15 20:43:16 +0000 (Sun, 15 Jul 2012)
Log Message:
-----------
Hierarchical terms: modified specification. Changed representation of terms. New Speagram step 3: iterated substitution based algorithms: MGU, ISA-matching, greatest lower bound and lowest upper bound unification; untested.
Modified Paths:
--------------
trunk/Toss/Formula/Aux.ml
trunk/Toss/Formula/Aux.mli
trunk/Toss/Formula/AuxTest.ml
trunk/Toss/Term/BuiltinLang.ml
trunk/Toss/Term/Coding.ml
trunk/Toss/Term/CodingTest.ml
trunk/Toss/Term/ParseArc.ml
trunk/Toss/Term/ParseArc.mli
trunk/Toss/Term/ParseArcTest.ml
trunk/Toss/Term/Rewriting.ml
trunk/Toss/Term/RewritingTest.ml
trunk/Toss/Term/SyntaxDef.ml
trunk/Toss/Term/SyntaxDefTest.ml
trunk/Toss/Term/TRS.ml
trunk/Toss/Term/TRSTest.ml
trunk/Toss/Term/Term.ml
trunk/Toss/Term/Term.mli
trunk/Toss/Term/TermTest.ml
Modified: trunk/Toss/Formula/Aux.ml
===================================================================
--- trunk/Toss/Formula/Aux.ml 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Formula/Aux.ml 2012-07-15 20:43:16 UTC (rev 1745)
@@ -368,6 +368,13 @@
let new_accu = try f accu a with Not_found -> accu in
fold_left_try f new_accu l
+let array_foldi_left f x a =
+ let r = ref x in
+ for i = 0 to Array.length a - 1 do
+ r := f i !r (Array.unsafe_get a i)
+ done;
+ !r
+
let rec power ?(timeout = fun () -> false) dom img =
List.fold_left (fun sbs v ->
concat_map (fun e -> List.rev (List.rev_map (fun sb ->
@@ -473,6 +480,25 @@
| [] -> acc in
idemp [] (List.sort (fun x y -> - (cmp x y)) l)
+(* Operations for imperatively manipulating the graph for {!topol_sort}. *)
+type 'a topol_sort_ops = {
+ rem_edge : 'a -> 'a -> unit; (* [rem_edge a b] removes a->b. *)
+ iter_outgoing : ('a -> unit) -> 'a -> unit;
+ no_outgoing : 'a -> bool
+}
+
+let topol_sort ops l =
+ let top = ref (List.filter (fun e -> ops.no_outgoing e) l) in
+ let res = ref [] in
+ while !top <> [] do
+ let n = List.hd !top in
+ top := List.tl !top; res := n:: !res;
+ ops.iter_outgoing (fun m ->
+ ops.rem_edge n m; if ops.no_outgoing m then res := m:: !res) n;
+ done;
+ if List.for_all ops.no_outgoing l then List.rev !res
+ else raise Not_found
+
let all_subsets ?max_size set =
let size = match max_size with Some i -> i | None -> List.length set in
[] :: (unique_sorted (List.map unique_sorted (all_ntuples set size)))
@@ -573,11 +599,33 @@
if i = len1 then acc else
fl2_rec (f acc a1.(i) a2.(i)) (i+1) in
fl2_rec start 0
-
+let array_fold_map2 f x a1 a2 =
+ let l1 = Array.length a1 and l2 = Array.length a2 in
+ if l1 <> l2 then raise (Invalid_argument "Aux.array_fold_map2");
+ if l1 = 0 then x, [||] else begin
+ let x0, v0 = f x (Array.unsafe_get a1 0) (Array.unsafe_get a2 0) in
+ let rx = ref x0 in
+ let ra = Array.create l1 v0 in
+ for i = 1 to Array.length ra - 1 do
+ let xi, vi = f !rx (Array.unsafe_get a1 i) (Array.unsafe_get a2 i) in
+ rx := xi; Array.unsafe_set ra i vi
+ done;
+ !rx, ra
+ end
+
+
let array_combine a b =
array_map2 (fun x y->x,y) a b
+let array_exists p a =
+ let res = ref false in
+ let i = ref 0 in
+ while !i < Array.length a && not !res do
+ res := p (Array.unsafe_get a !i);
+ incr i
+ done; !res
+
let array_existsi p a =
let res = ref false in
let i = ref 0 in
Modified: trunk/Toss/Formula/Aux.mli
===================================================================
--- trunk/Toss/Formula/Aux.mli 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Formula/Aux.mli 2012-07-15 20:43:16 UTC (rev 1745)
@@ -161,6 +161,9 @@
[Not_found]. *)
val fold_left_try : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
+(** As {!Array.fold_left}, but with the element position passed. *)
+val array_foldi_left : (int -> 'a -> 'b -> 'a) -> 'a -> 'b array -> 'a
+
(** [power dom img] generates all functions with domain [dom] and
image [img], as graphs. Tail recursive. *)
val power : ?timeout:(unit -> bool) -> 'a list -> 'b list -> ('a * 'b) list list
@@ -212,6 +215,22 @@
[add_to_maximal cmp l1 l2] computes [maximal cmp (l1 @ l2)]. *)
val add_to_maximal : ('a -> 'a -> bool) -> 'a list -> 'a list -> 'a list
+(** Operations for imperatively manipulating the graph for {!topol_sort}. *)
+type 'a topol_sort_ops = {
+ rem_edge : 'a -> 'a -> unit; (** [rem_edge a b] removes [a->b]. *)
+ iter_outgoing : ('a -> unit) -> 'a -> unit;
+ no_outgoing : 'a -> bool
+}
+
+(** Topogical sort of [l] where [cmp a b = true] means that there is
+ an arrow from [a] to [b]. Elements without incoming edges are first
+ and elements without outgoing edges are last. Returns [None] /
+ raises [Not_found] if a cycle is detected.
+
+ Implementation:
+ http://en.wikipedia.org/wiki/Topological_sort#Algorithms *)
+val topol_sort : 'a topol_sort_ops -> 'a list -> 'a list
+
(** Return the list of structurally unique elements, in order sorted
by {!Pervasives.compare}. Not tail-recursive. *)
val unique_sorted : ?cmp: ('a -> 'a -> int) -> 'a list -> 'a list
@@ -259,10 +278,15 @@
val array_fold_left2 :
('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
+(** Fold-left and map on two arrays. *)
+val array_fold_map2 :
+ ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b array -> 'c array -> 'a * 'd array
+
(** Zip two arrays into an array of pairs. Raises [Invalid_argument
"Aux.array_map2"] if the arrays are of different lengths. *)
val array_combine : 'a array -> 'b array -> ('a * 'b) array
+val array_exists : ('a -> bool) -> 'a array -> bool
val array_existsi : (int -> 'a -> bool) -> 'a array -> bool
val array_mem : 'a -> 'a array -> bool
@@ -330,7 +354,7 @@
(** Iterate a function [n] times: [f^n(x)]. *)
val fold_n : ('a -> 'a) -> 'a -> int -> 'a
-(** Returns a string proloning [s] and not appearing in [names]. If
+(** Returns a string prolonging [s] and not appearing in [names]. If
[truncate] is true, remove numbers from the end of [s]. *)
val not_conflicting_name : ?truncate:bool -> Strings.t -> string -> string
Modified: trunk/Toss/Formula/AuxTest.ml
===================================================================
--- trunk/Toss/Formula/AuxTest.ml 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Formula/AuxTest.ml 2012-07-15 20:43:16 UTC (rev 1745)
@@ -231,6 +231,10 @@
["a1";"c2"; "b1"; "a3"; "c7"]);
);
+ "topol_sort" >::
+ (fun () -> ()
+ );
+
"unique, unique_soted, not_unique, take_n" >::
(fun () ->
assert_equal ~printer:(String.concat "; ")
@@ -405,6 +409,17 @@
[|"a";"c";"b"|] [|"e"; "d"|]);
);
+ "array_fold_map2" >::
+ (fun () ->
+ let printer (v,a) =
+ string_of_int v^", [|"^String.concat "; " (Array.to_list a)^"|]" in
+ let sum acc i j = acc+i*j, string_of_int i^string_of_int j in
+ assert_equal ~printer (5, [|"11";"22";"30"|])
+ (Aux.array_fold_map2 sum 0 [|1;2;3|] [|1;2;0|]);
+ assert_equal ~printer (0, [||])
+ (Aux.array_fold_map2 sum 0 [||] [||]);
+ );
+
"partition_choice, partition_map" >::
(fun () ->
assert_equal ~printer:(fun (x,y)->
Modified: trunk/Toss/Term/BuiltinLang.ml
===================================================================
--- trunk/Toss/Term/BuiltinLang.ml 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Term/BuiltinLang.ml 2012-07-15 20:43:16 UTC (rev 1745)
@@ -29,12 +29,12 @@
let list_sd = SDtype [Tp term_type_tp; Str "list"]
let list_name = name_of_sd list_sd
-let list_tp t = Term (list_name, toplevel_type, [|t|])
-let list_tp_a = list_tp (Var ("a", 0, top_type_term, [||]))
+let list_tp t = Term (list_name, [||], [|t|])
+let list_tp_a = list_tp (TVar "a")
let list_nil_sd = SDfun ([Str "["; Str "]"], list_tp_a)
let list_nil_name = name_of_sd list_nil_sd
-let list_cons_sd = SDfun ([Tp (Var ("a",0,top_type_term,[||]));
+let list_cons_sd = SDfun ([Tp (TVar "a");
Str ","; Tp list_tp_a],
list_tp_a)
let list_cons_name = name_of_sd list_cons_sd
@@ -150,8 +150,8 @@
let input_rewrite_rule_name = name_of_sd input_rewrite_rule_sd
let input_rewrite_rule_tp = type_of_sd input_rewrite_rule_sd
-let let_be_sd = SDfun ([Str "let"; Tp (Var ("a_1",0,top_type_term,[||]));
- Str "be"; Tp (Var ("a_1",0,top_type_term,[||]))],
+let let_be_sd = SDfun ([Str "let"; Tp (TVar "a_1");
+ Str "be"; Tp (TVar "a_1")],
input_rewrite_rule_tp)
let let_be_name = name_of_sd let_be_sd
@@ -164,8 +164,8 @@
let let_major_be_sd =
SDfun ([Str "let"; Str "major";
- Tp (Var ("a_1",0,top_type_term,[||])); Str "be";
- Tp (Var ("a_1",0,top_type_term,[||]))],
+ Tp (TVar "a_1"); Str "be";
+ Tp (TVar "a_1")],
priority_input_rewrite_rule_tp)
let let_major_be_name = name_of_sd let_major_be_sd
@@ -191,47 +191,47 @@
let exception_cl_sd = SDtype [Tp term_type_tp; Str "exception"]
let exception_cl_name = name_of_sd exception_cl_sd
-let exception_cl_tp t = Term (exception_cl_name, toplevel_type, [|t|])
+let exception_cl_tp t = Term (exception_cl_name, [||], [|t|])
let exception_sd =
- SDfun ([Str "!"; Str "!"; Tp (Var ("a",0,top_type_term,[||]));
+ SDfun ([Str "!"; Str "!"; Tp (TVar "a");
Str "!";Str "!";],
- exception_cl_tp (Var ("other_than_a!",0,top_type_term,[||])))
+ exception_cl_tp (TVar "other_than_a!"))
let exception_name = name_of_sd exception_sd
let exn_ok_sd =
- SDfun ([Str "+"; Str "+"; Tp (Var ("a",0,top_type_term,[||]));
+ SDfun ([Str "+"; Str "+"; Tp (TVar "a");
Str "+";Str "+";],
- exception_cl_tp (Var ("a",0,top_type_term,[||]))) (* Here it should be a! *)
+ exception_cl_tp (TVar "a")) (* Here it should be a! *)
let exn_ok_name = name_of_sd exception_sd
(* --- Special functions recognized during Normalisation --- *)
let brackets_sd = SDfun ([Str "(";
- Tp (Var ("b",0,top_type_term,[||])); Str ")"],
- Var ("b",0,top_type_term,[||]))
+ Tp (TVar "b"); Str ")"],
+ TVar "b")
let brackets_name = name_of_sd brackets_sd
-let verbatim_sd = SDfun ([Str "<"; Str "|"; Tp (Var ("b",0,top_type_term,[||]));
- Str "|"; Str ">"], Var ("b",0,top_type_term,[||]))
+let verbatim_sd = SDfun ([Str "<"; Str "|"; Tp (TVar "b");
+ Str "|"; Str ">"], TVar "b")
let verbatim_name = name_of_sd verbatim_sd
let if_then_else_sd = SDfun ([Str "if"; Tp boolean_tp; Str "then";
- Tp (Var ("a",0,top_type_term,[||])); Str "else";
- Tp (Var ("a",0,top_type_term,[||]))], Var ("a",0,top_type_term,[||]))
+ Tp (TVar "a"); Str "else";
+ Tp (TVar "a")], TVar "a")
let if_then_else_name = name_of_sd if_then_else_sd
-let eq_bool_sd = SDfun ([Tp (Var ("a",0,top_type_term,[||])); Str "=";
- Tp (Var ("a",0,top_type_term,[||]))], boolean_tp)
+let eq_bool_sd = SDfun ([Tp (TVar "a"); Str "=";
+ Tp (TVar "a")], boolean_tp)
let eq_bool_name = name_of_sd eq_bool_sd
(* --- Syntax Definitions for special meta-functions --- *)
-let code_as_term_sd = SDfun ([Str "code"; Tp (Var ("a",0,top_type_term,[||]));
+let code_as_term_sd = SDfun ([Str "code"; Tp (TVar "a");
Str "as"; Str "term"], term_tp)
let code_as_term_name = name_of_sd code_as_term_sd
@@ -287,13 +287,13 @@
let set_command_tp = type_of_sd set_command_sd
let set_prop_sd = SDfun ([Str "set"; Tp (string_tp); Str "of";
- Tp (Var ("a",0,top_type_term,[||])); Str "to";
- Tp (Var ("b",0,top_type_term,[||]))], set_command_tp)
+ Tp (TVar "a"); Str "to";
+ Tp (TVar "b")], set_command_tp)
let set_prop_name = name_of_sd set_prop_sd
let preprocess_sd = SDfun ([Str "#"; Str "#"; Str "#";
- Tp (Var ("p",0,top_type_term,[||]))], Var ("p",0,top_type_term,[||]))
+ Tp (TVar "p")], TVar "p")
let preprocess_name = name_of_sd preprocess_sd
Modified: trunk/Toss/Term/Coding.ml
===================================================================
--- trunk/Toss/Term/Coding.ml 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Term/Coding.ml 2012-07-15 20:43:16 UTC (rev 1745)
@@ -95,34 +95,32 @@
| Term (n, _, [||]) when n = boolean_false_name -> false
| _ -> raise (DECODE "bool")
-
+(* FIXME: remainder of the old Speagram distinction between types and terms *)
let rec code_term_type = function
- | Var (name, 0, tp, [||]) when tp = top_type_term ->
+ | TVar name ->
Term (term_type_var_name, [|term_type_tp|], [|code_string name|])
- | Var _ -> failwith "code_term_type: non-type variable"
- | Term (name, tp, arr) when name = Term.fun_type_name && tp = toplevel_type->
+ | SVar _ -> failwith "code_term_type: sharing variable"
+ | Term (name, [||], arr) when name = Term.fun_type_name ->
let l = Array.length arr in
let (args_types, return_type) = (Array.sub arr 0 (l-1), arr.(l-1)) in
Term (term_type_fun_name, [|term_type_tp|], [|
code_list [|list_tp term_type_tp|] code_term_type (to_list args_types);
code_term_type return_type|])
- | Term (name, tp, args) when tp = toplevel_type ->
+ | Term (name, [||], args) ->
Term (term_type_cons_name, [|term_type_tp|], [|
code_string name;
code_list [|list_tp term_type_tp|] code_term_type (to_list args)|])
- | Term (name, _, _) when name = top_type_name -> failwith
- "code_term_type: coding top term (the type of a type) not supported"
| Term (name, _, _) -> failwith
- ("code_term_type: non-type term at symbol " ^ name)
+ ("code_term_type: non-toplevel-type term at symbol " ^ name)
let rec decode_term_type = function
| Term (s, _, [|coded_name|]) when s = term_type_var_name ->
- Var (decode_string coded_name, 0, top_type_term, [||])
+ TVar (decode_string coded_name)
| Term (s, _, [|coded_1; coded_2|]) when s = term_type_fun_name ->
- Term (Term.fun_type_name, toplevel_type, of_list (
+ Term (Term.fun_type_name, [||], of_list (
(decode_list decode_term_type coded_1) @ [decode_term_type coded_2]))
| Term (s, _, [|coded_1; coded_2|]) when s = term_type_cons_name ->
- Term (decode_string coded_1, toplevel_type,
+ Term (decode_string coded_1, [||],
of_list (decode_list decode_term_type coded_2))
| _ -> raise (DECODE "term_type")
@@ -132,7 +130,9 @@
let rec code_term = function
- | Var (name, deg, var_type, args) ->
+ | TVar name ->
+ Term (term_type_var_name, [|term_tp|], [|code_string name|])
+ | SVar (name, deg, var_type, args) ->
Term (term_var_cons_name, [|term_tp|],
[|code_string name;
code_term_type var_type;
@@ -146,8 +146,10 @@
let rec code_term_incr_vars = function
- | Var (name, deg, var_type, args) ->
- Var (name, deg+1, var_type, map code_term_incr_vars args)
+ | TVar name ->
+ Term (term_type_var_name, [|term_tp|], [|code_string name|])
+ | SVar (name, deg, var_type, args) ->
+ SVar (name, deg+1, var_type, map code_term_incr_vars args)
| Term (name, types, args) ->
Term (term_term_cons_name, [|term_tp|],
[|code_string name;
@@ -156,9 +158,12 @@
let rec decode_term = function
+ | Term (s, _, [|coded_name|])
+ when s = term_type_var_name ->
+ TVar (decode_string coded_name)
| Term (s, _, [|coded_name; coded_type; coded_deg; coded_args|])
when s = term_var_cons_name ->
- Var (decode_string coded_name,
+ SVar (decode_string coded_name,
bits_to_int (decode_list decode_bit coded_deg),
decode_term_type coded_type,
of_list (decode_list decode_term coded_args))
@@ -226,9 +231,9 @@
let code_type_definition (name, arity) =
let rec var = function
| 0 -> []
- | i -> Var ("a_" ^ (string_of_int i), 0, top_type_term, [||]) :: (var (i-1)) in
+ | i -> TVar ("a_" ^ string_of_int i) :: (var (i-1)) in
Term (type_of_name, [|type_definition_tp|],
- [|code_term_type (Term (name, toplevel_type, of_list (var arity)))|])
+ [|code_term_type (Term (name, [||], of_list (var arity)))|])
let decode_type_definition = function
@@ -296,36 +301,17 @@
(* --- Term matching and substitutions --- *)
-(* Including supertypes.
-let rec matches dict = function
- | (Term (n1, t1, a1), Term (n2, t2, a2))
- when n1=n2 && (length t1 = length t2) && (length a1 = length a2)->
- Aux.array_for_all2 (fun u v -> matches dict (u, v)) t1 t2 &&
- Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, d1, t1, a1), Var (n2, d2, t2, a2))
- when n1 = n2 && d1 = d2 && length a1 = length a2 ->
- matches dict (t1, t2) &&
- Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, d1, t1, [||]), te) ->
- (try
- let arg = List.assoc n1 (!dict) in
- let coded_arg = fn_apply d1 code_term arg in
- te = coded_arg
- with Not_found ->
- let decoded_te = fn_apply d1 decode_term te in
- (dict := (n1, decoded_te) :: (!dict); true)
- )
- | _ -> false
-*)
+(* FIXME: these functions should are obsoleted by the Term module. *)
+
(* Ignoring supertypes. *)
let rec matches dict = function
| (Term (n1, _, a1), Term (n2, _, a2))
when n1=n2 && (length a1 = length a2)->
Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, d1, _, a1), Var (n2, d2, _, a2))
+ | (SVar (n1, d1, _, a1), SVar (n2, d2, _, a2))
when n1 = n2 && d1 = d2 && length a1 = length a2 ->
Aux.array_for_all2 (fun u v -> matches dict (u, v)) a1 a2
- | (Var (n1, d1, t1, [||]), te) ->
+ | (SVar (n1, d1, t1, [||]), te) ->
(try
let arg = List.assoc n1 (!dict) in
let coded_arg = fn_apply d1 code_term arg in
@@ -339,45 +325,47 @@
(* Application of term substitutions (only flat functional
substitutes). Ignoring supertypes. *)
let rec apply_s substs = function
- | Var (n, d, _, [||]) as t ->
+ | SVar (n, d, _, [||]) as t ->
(* FIXME: why we don't apply substitutions recursively, as below? *)
(try (fn_apply d code_term (List.assoc n substs)) with Not_found -> t)
| Term (n, tp, a) -> Term (n, tp, map (apply_s substs) a)
- | Var (n, deg, t, a) ->
+ | TVar _ as ty -> ty
+ | SVar (n, deg, t, a) ->
try (
let raw_result =
match (List.assoc n substs) with
| Term (name, tps, [||]) ->
Term (name, tps, map (apply_s substs) a)
- | Var (name, d, ty, [||]) ->
- Var (name, d, ty, map (apply_s substs) a)
+ | SVar (name, d, ty, [||]) ->
+ SVar (name, d, ty, map (apply_s substs) a)
| _ -> failwith "functional substitution of non-flat term" in
fn_apply deg code_term raw_result
)
- with Not_found -> Var (n, deg, t, map (apply_s substs) a)
+ with Not_found -> SVar (n, deg, t, map (apply_s substs) a)
(* Application of term substitutions (only flat functional
substitutes). Including supertypes. *)
let rec apply_st substs = function
- | Var (n, d, t, [||]) ->
+ | SVar (n, d, t, [||]) ->
(* FIXME: why we don't apply substitutions recursively, as below? *)
(try (fn_apply d code_term (List.assoc n substs))
- with Not_found -> Var (n, d, apply_st substs t, [||]))
+ with Not_found -> SVar (n, d, apply_st substs t, [||]))
| Term (n, tp, a) ->
Term (n, map (apply_st substs) tp, map (apply_st substs) a)
- | Var (n, deg, t, a) ->
+ | TVar _ as ty -> ty
+ | SVar (n, deg, t, a) ->
try (
let raw_result =
match (List.assoc n substs) with
| Term (name, tps, [||]) ->
Term (name, map (apply_st substs) tps, map (apply_st substs) a)
- | Var (name, d, ty, [||]) ->
- Var (name, d, apply_st substs ty, map (apply_st substs) a)
+ | SVar (name, d, ty, [||]) ->
+ SVar (name, d, apply_st substs ty, map (apply_st substs) a)
| _ -> failwith "functional substitution of non-flat term" in
fn_apply deg code_term raw_result
)
with Not_found ->
- Var (n, deg, apply_st substs t, map (apply_st substs) a)
+ SVar (n, deg, apply_st substs t, map (apply_st substs) a)
(* --- Nice Term display based on Syntax Definitions --- *)
@@ -393,7 +381,8 @@
| Term (n, _, a) ->
let args = List.map display_term (Array.to_list a) in
display_sd (split_sdef_name n) args
- | Var (n, _, _, a) ->
+ | TVar _ -> failwith "display_term: type variable"
+ | SVar (n, _, _, a) ->
let args = List.map display_term (Array.to_list a) in
display_sd (split_sdef_name n) args
@@ -407,7 +396,8 @@
| Term (n, _, a) ->
let args = List.map display_term_bracketed (Array.to_list a) in
display_sd_bracketed (split_sdef_name n) args
- | Var (n, _, _, a) ->
+ | TVar _ -> failwith "display_term: type variable"
+ | SVar (n, _, _, a) ->
let args = List.map display_term_bracketed (Array.to_list a) in
display_sd_bracketed (split_sdef_name n) args
@@ -415,9 +405,9 @@
(* --- Display terms and types as XML --- *)
let rec display_type_xml = function
- | Var (n, 0, top_type_term, [||]) ->
+ | TVar n ->
"<type_var>" ^ (make_xml_compatible n) ^ "</type_var>"
- | Var _ -> failwith "display_type_xml: non-type variable"
+ | SVar _ -> failwith "display_type_xml: sharing variable"
| Term (n, _, a) ->
"<type class=\"" ^ (make_xml_compatible n) ^ "\">\n" ^
(String.concat "\n" (List.map display_type_xml (to_list a))) ^
@@ -434,7 +424,8 @@
"<term class=\"" ^ (make_xml_compatible n) ^ "\">\n" ^
(String.concat "\n" (List.map display_term_xml (to_list a))) ^
"\n</term>"
- | Var (n, deg, ty, a) ->
+ | TVar _ -> failwith "display_term_xml: type variable"
+ | SVar (n, deg, ty, a) ->
"<term-variable class=\"" ^ (make_xml_compatible n) ^
"\" deg=\"" ^ (string_of_int deg) ^ "\">" ^
(String.concat "" (List.map display_term_xml (to_list a))) ^
@@ -464,13 +455,14 @@
| _ when is_some (decode_term_opt term) ->
(match (decode_term_opt term) with None -> ""
| Some te -> "@T " ^ (term_to_string te))
- | Var (v, d, t, [||]) ->
+ | TVar _ as ty -> type_to_string ty
+ | SVar (v, d, t, [||]) ->
(try
"@V [" ^ v ^ " @: " ^ (type_to_string t) ^
" @: "^ string_of_int (d) ^ " ]"
with exn -> Printf.printf "Nontype: %s\n%!"(term_to_string t);
raise exn)
- | Var (v, d, t, a) ->
+ | SVar (v, d, t, a) ->
(try
"@V [" ^ v ^ " @: " ^ (type_to_string t) ^
" @: "^ string_of_int (d) ^ " ] (" ^
@@ -502,9 +494,10 @@
(match parse_term_list rest with
| (l, (Delim "]") :: cont) ->
let tp = match l with
- | [] -> top_type_term
- | Var (_, _, tp, _)::_ -> tp
- | Term (_, tps, _)::_ -> tps.(0) in
+ | [] -> TVar "a"
+ | SVar (_, _, ty, _)::_ -> ty
+ | TVar _ as ty::_ -> ty
+ | Term (_, tys, _)::_ -> tys.(0) in
code_list [|list_tp tp|] (fun x -> x) l, cont
| _ -> failwith "parse_term: list not closed"
)
@@ -518,7 +511,7 @@
(match parse_type rest with
| (ty, (Delim "@:") :: (Text deg) :: (Delim "]") :: cont) ->
let (l, c) = parse_bracketed_list cont in
- (Var (v, int_of_string (deg), ty, of_list l), c)
+ (SVar (v, int_of_string deg, ty, of_list l), c)
| _ -> failwith "parse_term: var not closed"
)
| (Text n) :: Delim "[" :: Delim "@:" :: rest ->
@@ -575,29 +568,29 @@
(* --- Rules for special built-in functions --- *)
let brackets_rules =
- [(Term (brackets_name, [|Var ("b",0,top_type_term,[||])|], [|Var ("x", 0, Var("a",0,top_type_term,[||]),[||])|]),
- Var ("x", 0, Var ("a",0,top_type_term,[||]), [||]))]
+ [(Term (brackets_name, [|TVar "b"|], [|SVar ("x", 0, TVar "a",[||])|]),
+ SVar ("x", 0, TVar "a", [||]))]
let verbatim_rules =
- [(Term (verbatim_name, [|Var ("b",0,top_type_term,[||])|], [|Var ("x",0,Var ("a",0,top_type_term,[||]),[||])|]),
- Var ("x", 0, Var ("a",0,top_type_term,[||]), [||]))]
+ [(Term (verbatim_name, [|TVar "b"|], [|SVar ("x",0,TVar "a",[||])|]),
+ SVar ("x", 0, TVar "a", [||]))]
let if_then_else_rules = [
- (Term (if_then_else_name, [|Var ("a",0,top_type_term,[||])|],
+ (Term (if_then_else_name, [|TVar "a"|],
[|code_bool true;
- Var ("x",0,Var ("a",0,top_type_term,[||]),[||]);
- Var ("y",0,Var ("a",0,top_type_term,[||]),[||])|]),
- Var ("x",0,Var ("a",0,top_type_term,[||]),[||]));
- (Term (if_then_else_name, [|Var ("a",0,top_type_term,[||])|],
+ SVar ("x",0,TVar "a",[||]);
+ SVar ("y",0,TVar "a",[||])|]),
+ SVar ("x",0,TVar "a",[||]));
+ (Term (if_then_else_name, [|TVar "a"|],
[|code_bool false;
- Var ("x",0,Var ("a",0,top_type_term,[||]),[||]);
- Var ("y",0,Var ("a",0,top_type_term,[||]),[||])|]),
- Var ("y",0,Var ("a",0,top_type_term,[||]),[||]))]
+ SVar ("x",0,TVar "a",[||]);
+ SVar ("y",0,TVar "a",[||])|]),
+ SVar ("y",0,TVar "a",[||]))]
-let varx_te = Var ("x", 0, Var ("p",0,top_type_term,[||]), [||])
-let preprocess_rules = [(Term (preprocess_name, [|Var ("q",0,top_type_term,[||])|], [|varx_te|]), varx_te)]
+let varx_te = SVar ("x", 0, TVar "p", [||])
+let preprocess_rules = [(Term (preprocess_name, [|TVar "q"|], [|varx_te|]), varx_te)]
let string_quote_rules =
- [(Term (string_quote_name, [|string_tp|], [|Var ("s", 0, string_tp, [||])|]),
- Var ("s", 0, string_tp, [||]))]
+ [(Term (string_quote_name, [|string_tp|], [|SVar ("s", 0, string_tp, [||])|]),
+ SVar ("s", 0, string_tp, [||]))]
let additional_xslt_rules =
[(Term (additional_xslt_name, [|string_tp|], [||]), code_string " ")]
Modified: trunk/Toss/Term/CodingTest.ml
===================================================================
--- trunk/Toss/Term/CodingTest.ml 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Term/CodingTest.ml 2012-07-15 20:43:16 UTC (rev 1745)
@@ -8,10 +8,10 @@
let test_code_decode_tt tt =
let tt1 = decode_term_type (code_term_type tt) in
assert_equal ~printer:(fun x -> type_to_string x) tt tt1 in
- let tt1 = Term ("ala", toplevel_type, [||]) in
- let tt2 = Term ("bolek", toplevel_type, [|tt1; tt1|]) in
- let tt3 = Term (Term.fun_type_name, toplevel_type, [|tt1; tt2; tt1|]) in
- let tt4 = Var ("zmienna",0,top_type_term,[||]) in
+ let tt1 = Term ("ala", [||], [||]) in
+ let tt2 = Term ("bolek", [||], [|tt1; tt1|]) in
+ let tt3 = Term (Term.fun_type_name, [||], [|tt1; tt2; tt1|]) in
+ let tt4 = TVar "zmienna" in
test_code_decode_tt tt1;
test_code_decode_tt tt2;
test_code_decode_tt tt3;
@@ -23,11 +23,11 @@
let test_code_decode_te te =
let te1 = decode_term (code_term te) in
assert_equal ~printer:(fun x -> term_to_string x) te te1 in
- let ty = Term ("text", toplevel_type, [||]) in
+ let ty = Term ("text", [||], [||]) in
let term1 = Term ("ala", [|ty|], [||]) in
let term2 = Term ("bolek", [|ty|], [|term1|]) in
let term3 = Term ("cynik", [|ty|], [|term1; term2|]) in
- let term4 = Var ("zmienna", 0, Var ("a1",0,top_type_term,[||]), [| |]) in
+ let term4 = SVar ("zmienna", 0, TVar "a1", [| |]) in
test_code_decode_te term1;
test_code_decode_te term2;
test_code_decode_te term3;
@@ -53,10 +53,10 @@
let sd1 = decode_syntax_definition (code_syntax_definition sd) in
assert_equal ~printer:(fun x -> "syntax definition test") sd sd1 in
let se1 = SyntaxDef.Str "napisek" in
- let se2 = SyntaxDef.Tp (Var ("eee",0,top_type_term,[||])) in
+ let se2 = SyntaxDef.Tp (TVar "eee") in
let sd1 = SyntaxDef.SDtype [se1; se2] in
- let sd2 = SyntaxDef.SDfun ([se2; se1; se1], Term ("aaa", toplevel_type, [||])) in
- let sd3 = SyntaxDef.SDvar ([se2;se2;se1;se1], Term("qza", toplevel_type, [||])) in
+ let sd2 = SyntaxDef.SDfun ([se2; se1; se1], Term ("aaa", [||], [||])) in
+ let sd3 = SyntaxDef.SDvar ([se2;se2;se1;se1], Term("qza", [||], [||])) in
test_code_decode_sd sd1;
test_code_decode_sd sd2;
test_code_decode_sd sd3;
Modified: trunk/Toss/Term/ParseArc.ml
===================================================================
--- trunk/Toss/Term/ParseArc.ml 2012-07-10 22:44:46 UTC (rev 1744)
+++ trunk/Toss/Term/ParseArc.ml 2012-07-15 20:43:16 UTC (rev 1745)
@@ -11,8 +11,8 @@
[term] does not have [substitution] applied. *)
type parser_elem =
| Token of string
- | PTerm of term * substitution * int (* From [parsed_elems], [cstrn]
- and [endpos] of {!parser_arc}. *)
+ | PTerm of term * substs * int (* From [parsed_elems], [cstrn]
+ and [endpos] of {!parser_arc}. *)
(* Print a parser elem. *)
let elem_str = function
@@ -33,11 +33,13 @@
spos : int; (* Start position of the arc. *)
endpos : int; (* The current end position of the
arc. FIXME: unnecessary? *)
- cstrn : substitution; (* Constraint for the arc. *)
+ cstrn : substs; (* Constraint for the arc. *)
}
(* --- Extending and closing arcs --- *)
+let debug = ref false
+
(* This function takes a parser element and an arc and extends the arc
if the next free position in the arc matches the given
element. Maching means equality for tokens and inference constraint
@@ -76,13 +78,30 @@
precheck_eq ty pty;*)
(* Combine the constraints so far, and extend them to cover
the new parsed element. *)
- let cstrn = combine_mgu_sb t_cstrn arc.cstrn in
+ (*if !debug && arc.sd_n = "Fif_\?_then_\?_else_\?" then Printf.printf
+ "extend_arc: sd_n=%s; #parsed=%d\nty=%s; pty=%s\nt=%s\nt_cstrn=%s\narc.cstrn=%s\n%!"
+ arc.sd_n (List.length arc.parsed_elems)
+ (type_to_string ty) (type_to_string pty)
+ (Cod...
[truncated message content] |
|
From: <luk...@us...> - 2012-07-17 11:31:12
|
Revision: 1746
http://toss.svn.sourceforge.net/toss/?rev=1746&view=rev
Author: lukstafi
Date: 2012-07-17 11:31:00 +0000 (Tue, 17 Jul 2012)
Log Message:
-----------
Topological sorting. Term parsing moved to iterated substitutions.
Modified Paths:
--------------
trunk/Toss/Formula/Aux.ml
trunk/Toss/Formula/Aux.mli
trunk/Toss/Term/Makefile
trunk/Toss/Term/ParseArc.ml
trunk/Toss/Term/ParseArc.mli
trunk/Toss/Term/ParseArcTest.ml
trunk/Toss/Term/Term.ml
trunk/Toss/Term/Term.mli
Modified: trunk/Toss/Formula/Aux.ml
===================================================================
--- trunk/Toss/Formula/Aux.ml 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Formula/Aux.ml 2012-07-17 11:31:00 UTC (rev 1746)
@@ -484,20 +484,30 @@
type 'a topol_sort_ops = {
rem_edge : 'a -> 'a -> unit; (* [rem_edge a b] removes a->b. *)
iter_outgoing : ('a -> unit) -> 'a -> unit;
- no_outgoing : 'a -> bool
+ no_incoming : 'a -> bool;
+ node_to_string : 'a -> string;
}
let topol_sort ops l =
- let top = ref (List.filter (fun e -> ops.no_outgoing e) l) in
+ let top = ref (List.filter (fun e -> ops.no_incoming e) l) in
+ (*Printf.printf "topol_sort: top=%s\n%!"
+ (String.concat ", " (List.map (fun n -> ops.node_to_string n) !top));*)
let res = ref [] in
while !top <> [] do
let n = List.hd !top in
top := List.tl !top; res := n:: !res;
ops.iter_outgoing (fun m ->
- ops.rem_edge n m; if ops.no_outgoing m then res := m:: !res) n;
+ ops.rem_edge n m; if ops.no_incoming m then top := m:: !top) n;
done;
- if List.for_all ops.no_outgoing l then List.rev !res
- else raise Not_found
+ (* FIXME *)
+ if List.for_all ops.no_incoming l then List.rev !res
+ else (*
+ Printf.printf "topol_sort: cycle\n%!";
+ List.iter (fun n -> ops.iter_outgoing (fun m ->
+ Printf.printf "%s->%s; " (ops.node_to_string n) (ops.node_to_string m)
+ ) n) l;
+ Printf.printf "\n%!";*)
+ raise Not_found
let all_subsets ?max_size set =
let size = match max_size with Some i -> i | None -> List.length set in
Modified: trunk/Toss/Formula/Aux.mli
===================================================================
--- trunk/Toss/Formula/Aux.mli 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Formula/Aux.mli 2012-07-17 11:31:00 UTC (rev 1746)
@@ -219,7 +219,8 @@
type 'a topol_sort_ops = {
rem_edge : 'a -> 'a -> unit; (** [rem_edge a b] removes [a->b]. *)
iter_outgoing : ('a -> unit) -> 'a -> unit;
- no_outgoing : 'a -> bool
+ no_incoming : 'a -> bool;
+ node_to_string : 'a -> string;
}
(** Topogical sort of [l] where [cmp a b = true] means that there is
Modified: trunk/Toss/Term/Makefile
===================================================================
--- trunk/Toss/Term/Makefile 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Term/Makefile 2012-07-17 11:31:00 UTC (rev 1746)
@@ -1,6 +1,6 @@
all: allparsed
-MKPARSED = ../TRSTest.native -v -l "../Term/lib"
+MKPARSED = OCAMLRUNPARAM=b; export OCAMLRUNPARAM; ../TRSTest.native -v -l "../Term/lib"
coreparsed:
make -C .. ./Term/TRSTest.native
Modified: trunk/Toss/Term/ParseArc.ml
===================================================================
--- trunk/Toss/Term/ParseArc.ml 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Term/ParseArc.ml 2012-07-17 11:31:00 UTC (rev 1746)
@@ -11,8 +11,8 @@
[term] does not have [substitution] applied. *)
type parser_elem =
| Token of string
- | PTerm of term * substs * int (* From [parsed_elems], [cstrn]
- and [endpos] of {!parser_arc}. *)
+ | PTerm of term * isubsts * int (* From [parsed_elems], [cstrn]
+ and [endpos] of {!parser_arc}. *)
(* Print a parser elem. *)
let elem_str = function
@@ -33,7 +33,7 @@
spos : int; (* Start position of the arc. *)
endpos : int; (* The current end position of the
arc. FIXME: unnecessary? *)
- cstrn : substs; (* Constraint for the arc. *)
+ cstrn : isubsts; (* Constraint for the arc. *)
}
(* --- Extending and closing arcs --- *)
@@ -71,35 +71,27 @@
(* For now (first-order mgu) we assume single type. *)
let pty = type_of t in
try
- (* Purely an optimization step. *)
- precheck_eq ty pty;
- (*let ty = Term.apply_sb arc.cstrn ty in
- let pty = Term.apply_sb t_cstrn pty in
- precheck_eq ty pty;*)
(* Combine the constraints so far, and extend them to cover
the new parsed element. *)
- (*if !debug && arc.sd_n = "Fif_\?_then_\?_else_\?" then Printf.printf
+ (*if !debug then Printf.printf
"extend_arc: sd_n=%s; #parsed=%d\nty=%s; pty=%s\nt=%s\nt_cstrn=%s\narc.cstrn=%s\n%!"
arc.sd_n (List.length arc.parsed_elems)
- (type_to_string ty) (type_to_string pty)
- (Coding.term_to_string t) (substs_str t_cstrn) (substs_str arc.cstrn)
- ;*)
- let cstrn' = combine_mgu_sbs t_cstrn arc.cstrn in
- (*if !debug && arc.sd_n = "Fif_\?_then_\?_else_\?" then Printf.printf
- "S(ty)=%s; S(pty)=%s\ncstrn'=%s\n%!"
- (type_to_string (apply_sbs cstrn' ty))
- (type_to_string (apply_sbs cstrn' pty))
- (substs_str cstrn');*)
+ (term_str ty) (term_str pty)
+ (term_str t)
+ (isubsts_str t_cstrn) (isubsts_str arc.cstrn);*)
+ let cstrn' = aux_mgu_i_cont global_decls t_cstrn arc.cstrn in
+ (*if !debug then Printf.printf
+ "cstrn'=%s\n%!" (isubsts_str cstrn');*)
let cstrn =
- mgu cstrn' [apply_sbs cstrn' pty, apply_sbs cstrn' ty] in
- (*if !debug && arc.sd_n = "Fif_\?_then_\?_else_\?" then Printf.printf
+ aux_mgu_i global_decls cstrn' pty ty in
+ (*if !debug then Printf.printf
"cstrn=%s\n%!"
- (substs_str cstrn);*)
+ (isubsts_str cstrn);*)
Some
{arc with rem_elems; parsed_elems = elem::arc.parsed_elems;
endpos = t_endpos; cstrn}
with UNIFY ->
- (*if !debug && arc.sd_n = "Fif_\?_then_\?_else_\?" then Printf.printf
+ (*if !debug then Printf.printf
"NO UNIFY\n%!";*)
None
@@ -158,7 +150,7 @@
rem_elems = elems;
parsed_elems = [];
endpos = spos;
- cstrn = empty_sbs;
+ cstrn = empty_isbs;
}
(* TODO: clean-up the description.
@@ -284,11 +276,12 @@
(* --- Final parsing --- *)
let parse_with_sdefs sdefs str =
(*Printf.printf "\nparse_with_sdefs: str=%s\n%!" str;
- if str = "if is digit string from c_a :: [] then added ending cl_a else false"
- then debug := true;*)
+ if str = "Let map f_1 {} | {} to x :: xs with first argument v_a be
+ (f_1 v_a | x) :: map f_1 {} | {} to xs with first argument v_a"
+ then (debug := true; Term.debug := true);*)
let type_of_pe = function Token _ -> None
| PTerm (te, cstrn, _) ->
- let result = apply_sbs cstrn te in
- Some result in
+ try Some (apply_isbs cstrn te)
+ with UNIFY -> None in
let elems = parse sdefs (split_input_string str) in
Aux.map_some type_of_pe elems
Modified: trunk/Toss/Term/ParseArc.mli
===================================================================
--- trunk/Toss/Term/ParseArc.mli 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Term/ParseArc.mli 2012-07-17 11:31:00 UTC (rev 1746)
@@ -9,8 +9,8 @@
have [substitution] applied. *)
type parser_elem =
| Token of string
- | PTerm of term * substs * int (** From [parsed_elems], [cstrn]
- and [endpos] of {!parser_arc}. *)
+ | PTerm of term * isubsts * int (** From [parsed_elems], [cstrn]
+ and [endpos] of {!parser_arc}. *)
(** Print a parser elem. *)
val elem_str : parser_elem -> string
@@ -29,7 +29,7 @@
rev. order (all will be arguments). *)
spos : int; (** Start position of the arc. *)
endpos : int; (** The current end position of the arc. *)
- cstrn : substs; (** Constraint for the arc. *)
+ cstrn : isubsts; (** Constraint for the arc. *)
}
Modified: trunk/Toss/Term/ParseArcTest.ml
===================================================================
--- trunk/Toss/Term/ParseArcTest.ml 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Term/ParseArcTest.ml 2012-07-17 11:31:00 UTC (rev 1746)
@@ -37,12 +37,30 @@
let cons_closed = fst (Aux.find_some close_arc cons_arc) in
elem_eq "Te @L[@V [Vx @: @? a @: 0 ]]" cons_closed;
+ (* With iterated substitutions, occurs/cyclicity check is only performed
+ when the substitution is applied, which only happens when
+ parser element is converted to standard term in [parse_with_sdefs].
+
let cons_bad_arc = extend_arc_list var_closed cons_part2_arc in
let cons_bad_closed = Aux.map_some close_arc cons_bad_arc in
- assert_equal ~printer:(fun x -> "empty list test") [] cons_bad_closed;
+ assert_equal ~printer:(fun l ->
+ "["^String.concat"; "(List.map (fun (e,_)->elem_str e) l)^"]")
+ [not empty] cons_bad_closed;
+
+ Instead, we check non-polymorphic case: *)
+
+ let cst_arc = extend_arc_list (Token "true") arcs in
+ let cst_closed = fst (Aux.find_some close_arc cst_arc) in
+ let cons_part1_arc = extend_arc_list cst_closed arcs in
+ let cons_part2_arc = extend_arc_list (Token ",") cons_part1_arc in
+ let cons_bad_arc = extend_arc_list cst_closed cons_part2_arc in
+ let cons_bad_closed = Aux.map_some close_arc cons_bad_arc in
+ assert_equal ~printer:(fun l ->
+ "["^String.concat"; "(List.map (fun (e,_)->elem_str e) l)^"]")
+ [] cons_bad_closed;
);
- "parse" >::
+ "parse_with_sdefs" >::
(fun () ->
let type_decls_list = [
(list_cons_name, Term (Term.fun_type_name, [||],
@@ -57,16 +75,16 @@
let sdefs_basic = [list_cons_sd; list_nil_sd;
boolean_true_sd; boolean_false_sd; var_x_a_sd] in
let sdefs = List.map (fun sd -> (name_of_sd sd, sd)) sdefs_basic in
- let parse_test res l =
- let ls = String.concat ", " (List.map elem_str (parse sdefs l)) in
+ let parse_test res s =
+ let ls = String.concat ", "
+ (List.map term_str (parse_with_sdefs sdefs s)) in
assert_equal ~printer:(fun x -> x) res ls in
- parse_test "Te @V [Vx @: @? a @: 0 ]" ["x"];
- parse_test "Te @L[@V [Vx @: @? a @: 0 ]]"
- ["x"; ","; "["; "]"];
- parse_test "" ["x"; ","; "x"];
+ parse_test "Vx[0:?a]" "x";
+ parse_test "F\\?_\\cm_\\?[:T\\?_list(?a._.7)](Vx[0:?a._.7], F\\ls_\\rs[:T\\?_list(?a._.7)])" "x , [ ]";
+ parse_test "" "x , x";
parse_test
- ("Te @L[@V [Vx @: @? a @: 0 ], @V [Vx @: @? a @: 0 ]]")
- ["x"; ","; "x"; ","; "["; "]"];
+ "F\\?_\\cm_\\?[:T\\?_list(?a._.40)](Vx[0:?a._.40], F\\?_\\cm_\\?[:T\\?_list(?a._.40)](Vx[0:?a._.40], F\\ls_\\rs[:T\\?_list(?a._.40)]))"
+ "x , x , [ ]";
);
Modified: trunk/Toss/Term/Term.ml
===================================================================
--- trunk/Toss/Term/Term.ml 2012-07-15 20:43:16 UTC (rev 1745)
+++ trunk/Toss/Term/Term.ml 2012-07-17 11:31:00 UTC (rev 1746)
@@ -243,6 +243,25 @@
which is a distinctive kind of toplevel types. *)
let fun_type_name = "fffuuunnntyppe"
+(* Concise readable form. *)
+let rec term_str term =
+ let term_array_str ta =
+ String.concat ", " (to_list (map term_str ta)) in
+ match term with
+ | TVar n -> "?"^n
+ | SVar (v, d, t, [||]) ->
+ v ^ "[" ^ string_of_int d ^ ":" ^ term_str t ^ "]"
+ | SVar (v, d, t, a) ->
+ v ^ "[" ^ string_of_int d ^ ":" ^ term_str t ^ "](" ^
+ term_array_str a ^ ")"
+ | Term (n, [||], [||]) -> n
+ | Term (n, [||], a) ->
+ n ^ "(" ^ term_array_str a ^ ")"
+ | Term (n, t, [||]) ->
+ n ^ "[:" ^ term_array_str t ^ "]"
+ | Term (n, t, a) ->
+ n ^ "[:" ^ term_array_str t ^ "](" ^ term_array_str a ^ ")"
+
(* Suffix variables to rename them. *)
let rec suffix i = function
| Term (n, t, a) -> Term (n, map (fun t -> suffix i t) t,
@@ -307,10 +326,12 @@
type optimize = {
mutable no_glb_type_of_var : bool;
mutable no_isa_match_type_of_var : bool;
+ mutable no_mgu_type_of_var : bool;
}
let optimize = {
no_glb_type_of_var = false;
no_isa_match_type_of_var = false;
+ no_mgu_type_of_var = false;
}
@@ -780,7 +801,26 @@
type iterated_subst = (string * term) list
type iter_s_subst = iterated_subst
type iter_t_subst = iterated_subst
+type isubsts = iter_s_subst * iter_t_subst
+let empty_t_isb = empty_sb
+let empty_s_isb = empty_sb
+let empty_isbs = empty_s_isb, empty_t_isb
+
+let subst_str subst = String.concat ", "
+ (List.map (fun (s, t) -> s ^ " <- " ^ (term_str t)) subst)
+
+let s_subst_str = subst_str
+let t_subst_str = subst_str
+
+let substs_str (s_sb, t_sb) =
+ (* "S:"^ *)s_subst_str s_sb ^ (if s_sb <> [] && t_sb <> [] then "; " else "")
+ ^ (* "T:"^ *)t_subst_str t_sb
+
+let isubsts_str = substs_str
+
+let debug = ref false
+
let rec merge_isbs op acc = function
| [], isb | isb, [] -> (* with optimization *)
(match acc with
@@ -790,8 +830,11 @@
| [p3; p2; p1] -> p1::p2::p3::isb
| _ -> List.rev (List.rev_append isb acc))
| ((v1, t1 as p1)::isb1' as isb1), ((v2, t2 as p2)::isb2' as isb2) ->
- if v1 < v2 then merge_isbs op (p1::acc) (isb1', isb2)
- else if v1 = v2 then merge_isbs op ((v1, op t1 t2)::acc) (isb1', isb2')
+ let vcmp = String.compare v1 v2 in
+ if vcmp < 0 (* v1 < v2 *)
+ then merge_isbs op (p1::acc) (isb1', isb2)
+ else if vcmp = 0 (* v1 = v2 *)
+ then merge_isbs op ((v1, op t1 t2)::acc) (isb1', isb2')
else merge_isbs op (p2::acc) (isb1, isb2')
(** [subst_t_pos p subt t] places [subt] at supertype position [p] in [t]. *)
@@ -839,23 +882,47 @@
let rec glb decls t1 t2 =
match t1, t2 with
| _ when t1 == t2 -> ([], []), t1
+ | SVar (v1, _, ty1, [||]), SVar (v2, _, ty2, [||]) ->
+ let vcmp = String.compare v1 v2 in
+ if vcmp = 0 then ([], []), t1
+ else
+ let v, var, ty, te =
+ if vcmp < 0 then v1, t1, ty1, t2 else v2, t2, ty2, t1 in
+ if optimize.no_glb_type_of_var
+ then ([v, te], []), var
+ else aux_glb decls ([v, te], []) ty te
+
+ | TVar v1, TVar v2 ->
+ let vcmp = String.compare v1 v2 in
+ if vcmp = 0 then ([], []), t1
+ else
+ let v, var, te = if vcmp < 0 then v1, t1, t2 else v2, t2, t1 in
+ ([], [v, te]), var
+
| (SVar (v, _, ty, [||]) as var, te | te, (SVar (v, _, ty, [||]) as var)) ->
if optimize.no_glb_type_of_var
then ([v, te], []), var
else aux_glb decls ([v, te], []) ty te
| (SVar (v, d, ty, ste1), (Term (c, sty, ste2) as te)
- | (Term (c, sty, ste2) as te), SVar (v, d, ty, ste1)) ->
+ | (Term (c, sty, ste2) as te), SVar (v, d, ty, ste1))
+ when Array.length ste1 = Array.length ste2 ->
let isbs, glste =
Aux.array_fold_map2 (aux_glb decls) ([v,te],[]) ste1 ste2 in
(* TODO: ignoring the var type *)
isbs, SVar (v, d, ty, glste)
+ | (SVar _, Term _ | Term _, SVar _) (* when arity mismatch *) ->
+ raise UNIFY
- | (SVar (v, d, ty, ste1), (SVar (_, _, ty2, ste2) as te)) ->
+ | (SVar (v, d, ty, ste1), (SVar (_, _, ty2, ste2) as te))
+ when Array.length ste1 = Array.length ste2 ->
+ (* TODO: ignoring v1 = v2, v1 > v2 *)
let isbs, glste =
Aux.array_fold_map2 (aux_glb decls) ([v,te],[]) ste1 ste2 in
(* TODO: ignoring the var type *)
isbs, SVar (v, d, ty, glste)
+ | SVar _, SVar _ (* when arity mismatch *) ->
+ raise UNIFY
| (TVar v as var, te | te, (TVar v as var)) ->
([], [v, te]), var
@@ -876,11 +943,15 @@
let isbs, glte = glb decls t1 (get_t_pos p t2) in
isbs, subst_t_pos p glte t2
| GLB_equal ->
- let isbs, glsty =
- Aux.array_fold_map2 (aux_glb decls) ([], []) sty1 sty2 in
- let isbs, glste =
- Aux.array_fold_map2 (aux_glb decls) isbs ste1 ste2 in
- isbs, Term (c1, glsty, glste)
+ if Array.length sty1 = Array.length sty2 &&
+ Array.length ste1 = Array.length ste2
+ then
+ let isbs, glsty =
+ Aux.array_fold_map2 (aux_glb decls) ([], []) sty1 sty2 in
+ let isbs, glste =
+ Aux.array_fold_map2 (aux_glb decls) isbs ste1 ste2 in
+ isbs, Term (c1, glsty, glste)
+ else raise UNIFY (* arity mismatch *)
| GLB_disjoint -> raise UNIFY
(** Least Upper Bound Unification w.r.t. the ISA relation. Returns
@@ -891,6 +962,23 @@
and lub decls t1 t2 =
match t1, t2 with
| _ when t1 == t2 -> ([], []), t1
+ | SVar (v1, _, ty1, [||]), SVar (v2, _, ty2, [||]) ->
+ let vcmp = String.compare v1 v2 in
+ if vcmp = 0 then ([], []), t1
+ else
+ let v, var, ty, te =
+ if vcmp < 0 then v1, t1, ty1, t2 else v2, t2, ty2, t1 in
+ if optimize.no_glb_type_of_var
+ then ([v, te], []), var
+ else aux_glb decls ([v, te], []) ty te
+
+ | TVar v1, TVar v2 ->
+ let vcmp = String.compare v1 v2 in
+ if vcmp = 0 then ([], []), t1
+ else
+ let v, var, te = if vcmp < 0 then v1, t1, t2 else v2, t2, t1 in
+ ([], [v, te]), var
+
| (SVar (v, _, ty, [||]) as var, te | te, (SVar (v, _, ty, [||]) as var)) ->
if optimize.no_glb_type_of_var
then ([v, te], []), var
@@ -898,19 +986,25 @@
else aux_glb decls ([v, te], []) ty te
| (SVar (v, d, ty, ste1), (Term (c, sty, ste2) as te)
- | (Term (c, sty, ste2) as te), SVar (v, d, ty, ste1)) ->
+ | (Term (c, sty, ste2) as te), SVar (v, d, ty, ste1))
+ when Array.length ste1 = Array.length ste2 ->
(* TODO: not sure whether GLB or LUB *)
let isbs, glste =
Aux.array_fold_map2 (aux_glb decls) ([v,te],[]) ste1 ste2 in
(* TODO: ignoring the var type *)
isbs, SVar (v, d, ty, glste)
+ | (SVar _, Term _ | Term _, SVar _) (* when arity mismatch *) ->
+ raise UNIFY
- | (SVar (v, d, ty, ste1), (SVar (_, _, ty2, ste2) as te)) ->
+ | (SVar (v, d, ty, ste1), (SVar (_, _, ty2, ste2) as te))
+ when Array.length ste1 = Array.length ste2 ->
(* TODO: not sure whether GLB or LUB *)
let isbs, glste =
Aux.array_fold_map2 (aux_glb decls) ([v,te],[]) ste1 ste2 in
(* TODO: ignoring the var type *)
isbs, SVar (v, d, ty, glste)
+ | SVar _, SVar _ (* when arity mismatch *) ->
+ raise UNIFY
| (TVar v as var, te | te, (TVar v as var)) ->
([], [v, te]), var
@@ -927,11 +1021,15 @@
| LUB_greater p ->
lub decls t1 (get_t_pos p t2)
| LUB_equal ->
- let isbs, lusty =
- Aux.array_fold_map2 (aux_lub decls) ([], []) sty1 sty2 in
- let isbs, luste =
- Aux.array_fold_map2 (aux_lub decls) isbs ste1 ste2 in
- isbs, Term (c1, lusty, luste)
+ if Array.length sty1 = Array.length sty2 &&
+ Array.length ste1 = Array.length ste2
+ then
+ let isbs, lusty =
+ Aux.array_fold_map2 (aux_lub decls) ([], []) sty1 sty2 in
+ let isbs, luste =
+ Aux.array_fold_map2 (aux_lub decls) isbs ste1 ste2 in
+ isbs, Term (c1, lusty, luste)
+ else raise UNIFY (* arity mismatch *)
| LUB_unconnected -> raise UNIFY
and aux_glb decls isbs t1 t2 =
@@ -980,19 +1078,28 @@
and isa_match decls pa te =
match pa, te with
| _ when pa == te -> [], []
+ | SVar (v1, _, _, _), SVar (v2, _, _, _) when v1 = v2 ->
+ ([], [])
+ | TVar v1, TVar v2 when v1 = v2 ->
+ ([], [])
+
| SVar (v, _, ty, [||]), te ->
if optimize.no_isa_match_type_of_var
then [v, te], []
else aux_match decls ([v, te], []) ty te
- | SVar (v, _, ty, ste1), (Term (c, sty, ste2) as te) ->
- (* TODO: ignoring variable type *)
- (* TODO: ignoring arity mismatch *)
+ | SVar (v, _, ty, ste1), (Term (c, sty, ste2) as te)
+ when Array.length ste1 = Array.length ste2 ->
+ (* TODO: ignoring variable type -- should first try to match
+ the proper level in the other term *)
Aux.array_fold_left2 (aux_match decls) ([v,te],[]) ste1 ste2
+ | SVar _, Term _ (* when arity mismatch *) -> raise UNIFY
- | SVar (v, _, ty, ste1), (SVar (_, _, ty2, ste2) as te) ->
+ | SVar (v, _, ty, ste1), (SVar (_, _, ty2, ste2) as te)
+ when Array.length ste1 = Array.length ste2 ->
(* TODO: ignoring variable type *)
Aux.array_fold_left2 (aux_match decls) ([v,te],[]) ste1 ste2
+ | SVar _, SVar _ (* when arity mismatch *) -> raise UNIFY
| SVar _, TVar _ -> raise UNIFY
@@ -1009,10 +1116,13 @@
| GLB_greater p ->
isa_match decls pa (get_t_pos p te)
| GLB_equal ->
- let isbs =
- Aux.array_fold_left2 (aux_match decls) ([], []) sty1 sty2 in
- Aux.array_fold_left2 (aux_match decls) isbs ste1 ste2
-
+ if Array.length sty1 = Array.length sty2 &&
+ Array.length ste1 = Array.length ste2
+ then
+ let isbs =
+ Aux.array_fold_left2 (aux_match decls) ([], []) sty1 sty2 in
+ Aux.array_fold_left2 (aux_match decls) isbs ste1 ste2
+ else raise UNIFY
| GLB_glb _ | GLB_smaller _ | GLB_disjoint -> raise UNIFY
and aux_match decls isbs pa te =
@@ -1035,41 +1145,73 @@
and mgu_iter decls t1 t2 =
match t1, t2 with
| _ when t1 == t2 -> [], []
+ | SVar (v1, _, ty1, [||]), SVar (v2, _, ty2, [||]) ->
+ let vcmp = String.compare v1 v2 in
+ if vcmp = 0 then ([], [])
+ else
+ let v, var, ty, te =
+ if vcmp < 0 then v1, t1, ty1, t2 else v2, t2, ty2, t1 in
+ if optimize.no_glb_type_of_var
+ then ([v, te], [])
+ else aux_match decls ([v, te], []) ty te
+
+ | TVar v1, TVar v2 ->
+ let vcmp = String.compare v1 v2 in
+ if vcmp = 0 then ([], [])
+ else
+ let v, var, te = if vcmp < 0 then v1, t1, t2 else v2, t2, t1 in
+ ([], [v, te])
+
| (SVar (v, _, ty, [||]), te | te, SVar (v, _, ty, [||])) ->
- aux_match decls ([v, te], []) ty te
+ if optimize.no_mgu_type_of_var
+ then [v, te], []
+ else aux_match decls ([v, te], []) ty te
| (SVar (v, _, ty, ste1), (Term (c, _, ste2) as te)
- | (Term (c, _, ste2) as te), SVar (v, _, ty, ste1)) ->
- Aux.array_fold_left2 (aux_mgu decls)
+ | (Term (c, _, ste2) as te), SVar (v, _, ty, ste1))
+ when Array.length ste1 = Array.length ste2 ->
+ Aux.array_fold_left2 (aux_mgu_i decls)
(aux_match decls ([v, te], []) ty te)
ste1 ste2
+ | (SVar _, Term _ | Term _, SVar _) -> raise UNIFY
- | (SVar (v, _, ty, ste1), (SVar (_, _, ty2, ste2) as te)) ->
- (* TODO: ignoring variable types *)
- Aux.array_fold_left2 (aux_mgu decls)
+ | (SVar (v, _, ty, ste1), (SVar (_, _, ty2, ste2) as te))
+ when Array.length ste1 = Array.length ste2 ->
+ (* TODO: ignoring variable types, and v1=v2, v1>v2 *)
+ Aux.array_fold_left2 (aux_mgu_i decls)
([v, te], []) ste1 ste2
+ | SVar _, SVar _ -> raise UNIFY
| (TVar v, te | te, TVar v) -> [], [v, te]
- | Term (c1, sty1, ste1), Term (c2, sty2, ste2) when c1 = c2 ->
+ | Term (c1, sty1, ste1), Term (c2, sty2, ste2)
+ when c1 = c2 && Array.length sty1 = Array.length sty2
+ && Array.length ste1 = Array.length ste2 ->
let isbs =
- Aux.array_fold_left2 (aux_mgu decls) ([], []) sty1 sty2 in
- Aux.array_fold_left2 (aux_mgu decls) isbs ste1 ste2
+ Aux.array_fold_left2 (aux_mgu_i decls) ([], []) sty1 sty2 in
+ Aux.array_fold_left2 (aux_mgu_i decls) isbs ste1 ste2
- | Term (c1, _, _), Term (c2, _, _) (* when c1 <> c2 *) ->
+ | Term (c1, _, _), Term (c2, _, _)(* when c1 <> c2 or arity mismatch *) ->
raise UNIFY
-and aux_mgu decls isbs t1 t2 =
+and aux_mgu_i decls isbs t1 t2 =
let isbs' = mgu_iter decls t1 t2 in
- aux_mgu_cont decls isbs isbs'
+ aux_mgu_i_cont decls isbs isbs'
-and aux_mgu_cont decls (s_isb, t_isb) (s_isb', t_isb') =
+and aux_mgu_i_cont decls (s_isb, t_isb) (s_isb', t_isb') =
+ (*if !debug then Printf.printf "aux_mgu_i_cont: isbs=%s\nisbs'=%s\n%!"
+ (isubsts_str (s_isb, t_isb))
+ (isubsts_str (s_isb', t_isb'));*)
let s_isb, more_isbs1 =
mgu_combine_isbs decls s_isb s_isb' in
let t_isb, more_isbs2 =
mgu_combine_isbs decls t_isb t_isb' in
- List.fold_left (aux_mgu_cont decls)
- (List.fold_left (aux_mgu_cont decls) (s_isb, t_isb) more_isbs1)
+ (*if !debug then Printf.printf "aux_mgu_i_cont: combined=%s\nmore_isbs=%s\n%!"
+ (isubsts_str (s_isb, t_isb))
+ (String.concat " / "
+ (List.map isubsts_str (more_isbs1 @ more_isbs2)));*)
+ List.fold_left (aux_mgu_i_cont decls)
+ (List.fold_left (aux_mgu_i_cont decls) (s_isb, t_isb) more_isbs1)
more_isbs2
@@ -1078,8 +1220,10 @@
let result = merge_isbs
(fun t1 t2 -> let isb = mgu_iter decls t1 t2 in
if isb <> ([],[]) then more_isbs := isb:: !more_isbs;
- (* no change since it's an iterated substitution *)
- t1)
+ (* no change since it's an iterated substitution
+ t2 not to fall into a loop with cyclic substs --
+ because isb2 comes from mgu_iter so it's smaller *)
+ t2)
[] (isb1, isb2) in
result, !more_isbs
@@ -1125,12 +1269,10 @@
(* TODO: come up with better function names... *)
let appl_s_sb sb t = (* None = no change *)
match app_s_sb sb t with None -> t | Some t -> t
-let appl_t_sb sb t =
- match app_s_sb sb t with None -> t | Some t -> t
let rec app_t_sb sb t =
let app_tuple a =
- let a' = Array.map (app_s_sb sb) a in
+ let a' = Array.map (app_t_sb sb) a in
if Aux.array_for_all (function None -> true | Some _ -> false) a'
then None
else
@@ -1139,11 +1281,18 @@
match t with
| TVar n ->
(try Some (List.assoc n sb) with Not_found -> None)
- | SVar _ -> None
+ | SVar (_,_,(Term (_, [||], [||]) (* TODO: optimization, test *)
+ | Term (_, [|Term (_, [||], [||])|], [||])),[||]) -> None
| (Term (_, [||], [||]) (* TODO: optimization, test *)
| Term (_, [|Term (_, [||], [||])|], [||])
| Term (_, [|Term (_, [||], [||])|],
[|Term (_, [||], [||])|])) -> None
+ | SVar (n, d, t, a) ->
+ (match app_t_sb sb t, app_tuple a with
+ | None, None -> None
+ | None, Some a -> Some (SVar (n, d, t, a))
+ | Some t, None -> Some (SVar (n, d, t, a))
+ | Some t, Some a -> Some (SVar (n, d, t, a)))
| Term (n, t, a) ->
(match app_tuple t, app_tuple a with
| None, None -> None
@@ -1151,17 +1300,23 @@
| Some t, None -> Some (Term (n, t, a))
| Some t, Some a -> Some (Term (n, t, a)))
-type topsort_elem = {
- e_assoc : string * term;
- e_outgoing : (string, topsort_elem) Hashtbl.t;
+let appl_t_sb sb t =
+ match app_t_sb sb t with None -> t | Some t -> t
+
+type topsort_node = {
+ n_assoc : string * term;
+ n_outgoing : (string, topsort_node) Hashtbl.t;
+ n_incoming : (string, topsort_node) Hashtbl.t;
}
let topsort_ops = {
Aux.rem_edge = (fun n m ->
- Hashtbl.remove n.e_outgoing (fst m.e_assoc));
+ Hashtbl.remove m.n_incoming (fst n.n_assoc);
+ Hashtbl.remove n.n_outgoing (fst m.n_assoc));
iter_outgoing = (fun f n ->
- Hashtbl.iter (fun _ -> f) n.e_outgoing);
- no_outgoing = (fun n -> Hashtbl.length n.e_outgoing = 0)
+ Hashtbl.iter (fun _ -> f) n.n_outgoing);
+ no_incoming = (fun n -> Hashtbl.length n.n_incoming = 0);
+ node_to_string = (fun n -> fst n.n_assoc);
}
(** Apply an iterated substitution -- "unpack" all the variables. We
@@ -1174,34 +1329,54 @@
to be fixed once explicit sharing gets introduced -- although
then the need for [apply_isbs] will be smaller. *)
let apply_isbs (s_isb, t_isb) t =
+ (*if !debug then Printf.printf "apply_isbs: initial isbs = %s\n%!"
+ (isubsts_str (s_isb,t_isb));*)
let s_nodes = List.map
(fun (v,_ as p) ->
- v, {e_assoc = p; e_outgoing = Hashtbl.create 2}) s_isb in
+ v, {n_assoc = p; n_outgoing = Hashtbl.create 2;
+ n_incoming = Hashtbl.create 2}) s_isb in
let t_nodes = List.map
(fun (v,_ as p) ->
- v, {e_assoc = p; e_outgoing = Hashtbl.create 2}) t_isb in
- let s_outgoing (_,{e_assoc=v,t; e_outgoing=vs}) =
+ v, {n_assoc = p; n_outgoing = Hashtbl.create 2;
+ n_incoming = Hashtbl.create 2}) t_isb in
+ (* The incoming edges are the variables in the substituted term. *)
+ let add_edges nodes get_in (_,({n_assoc=v1,t; n_incoming=in_vs} as n1)) =
List.iter
- (fun v -> Hashtbl.add vs v (List.assoc v s_nodes))
- (s_vars_in_term [] t) in
- let t_outgoing (_,{e_assoc=v,t; e_outgoing=vs}) =
- List.iter
- (fun v -> Hashtbl.add vs v (List.assoc v t_nodes))
- (t_vars_in_term [] t) in
- List.iter s_outgoing s_nodes;
- List.iter t_outgoing t_nodes;
- let s_isb = List.map (fun n->n.e_assoc)
- (Aux.topol_sort topsort_ops (List.map snd s_nodes)) in
- let t_isb = List.map (fun n->n.e_assoc)
- (Aux.topol_sort topsort_ops (List.map snd t_nodes)) in
+ (fun v2 ->
+ try
+ let n2 = List.assoc v2 nodes in
+ Hashtbl.add n2.n_outgoing v1 n1;
+ Hashtbl.add in_vs v2 n2
+ with Not_found -> ())
+ (get_in t) in
+ List.iter (add_edges s_nodes (s_vars_in_term [])) s_nodes;
+ List.iter (add_edges t_nodes (t_vars_in_term [])) t_nodes;
+ let s_isb =
+ try
+ List.map (fun n->n.n_assoc)
+ (Aux.topol_sort topsort_ops (List.map snd s_nodes))
+ with Not_found ->
+ failwith "apply_isbs: cyclic terms ...
[truncated message content] |
|
From: <luk...@us...> - 2012-07-18 15:33:32
|
Revision: 1748
http://toss.svn.sourceforge.net/toss/?rev=1748&view=rev
Author: lukaszkaiser
Date: 2012-07-18 15:33:21 +0000 (Wed, 18 Jul 2012)
Log Message:
-----------
Testing TC - bug found and removed.
Modified Paths:
--------------
trunk/Toss/Formula/BoolFormula.ml
trunk/Toss/Formula/BoolFormula.mli
trunk/Toss/Solver/Solver.ml
trunk/Toss/Solver/SolverTest.ml
Modified: trunk/Toss/Formula/BoolFormula.ml
===================================================================
--- trunk/Toss/Formula/BoolFormula.ml 2012-07-18 13:38:17 UTC (rev 1747)
+++ trunk/Toss/Formula/BoolFormula.ml 2012-07-18 15:33:21 UTC (rev 1748)
@@ -40,20 +40,23 @@
let var_str = string_of_int
(** Print a Boolean formula as a string. *)
-let rec str = function
- | BVar v -> var_str v
- | BNot phi -> "(not " ^ (str phi) ^ ")"
- | BAnd [] -> "true"
- | BOr [] -> "false"
- | BAnd (bflist) -> bf_list_str " and " bflist
- | BOr (bflist) -> bf_list_str " or " bflist
+let rec str ?names bf =
+ let name s = match names with None -> var_str s | Some tbl ->
+ try Hashtbl.find tbl s with Not_found -> var_str s in
+ let rec str_rec = function
+ | BVar v -> if v < 0 then "-" ^ (name (-v)) else name v
+ | BNot phi -> "(not " ^ (str_rec phi) ^ ")"
+ | BAnd [] -> "true"
+ | BOr [] -> "false"
+ | BAnd (bflist) -> bf_list_str " and " bflist
+ | BOr (bflist) -> bf_list_str " or " bflist
+ and bf_list_str sep = function
+ | [] -> "[]"
+ | [phi] -> str_rec phi
+ | lst -> "(" ^ (String.concat sep (List.map str_rec lst)) ^ ")" in
+ str_rec bf
-and bf_list_str sep = function
- | [] -> "[]"
- | [phi] -> str phi
- | lst -> "(" ^ (String.concat sep (List.map str lst)) ^ ")"
-
(* ------------------------ ORDER ON FORMULAS ------------------------------- *)
(** Compare two variables. We assume that FO < MSO < Real. *)
@@ -961,7 +964,7 @@
let name s = match names with None -> var_str s | Some tbl ->
try Hashtbl.find tbl s with Not_found -> var_str s in
let rec qbf_str_rec = function
- | QVar v -> name v
+ | QVar v -> if v < 0 then "-" ^ (name (-v)) else name v
| QNot phi -> "(not " ^ (qbf_str_rec phi) ^ ")"
| QAnd [] -> "true"
| QOr [] -> "false"
Modified: trunk/Toss/Formula/BoolFormula.mli
===================================================================
--- trunk/Toss/Formula/BoolFormula.mli 2012-07-18 13:38:17 UTC (rev 1747)
+++ trunk/Toss/Formula/BoolFormula.mli 2012-07-18 15:33:21 UTC (rev 1748)
@@ -17,7 +17,7 @@
val var_str : int -> string
(** Print a formula as a string. *)
-val str : bool_formula -> string
+val str : ?names: (int, string) Hashtbl.t -> bool_formula -> string
(** Helper function to flatten multiple or's and and's. *)
val flatten_sort : bool_formula -> bool_formula
Modified: trunk/Toss/Solver/Solver.ml
===================================================================
--- trunk/Toss/Solver/Solver.ml 2012-07-18 13:38:17 UTC (rev 1747)
+++ trunk/Toss/Solver/Solver.ml 2012-07-18 15:33:21 UTC (rev 1748)
@@ -554,7 +554,7 @@
let qbf, rev_ids = so_to_qbf struc psi in
(match logtime with None -> () | Some t ->
LOG 0 "%sQBF constructed at %.3fs" logprefix (AuxIO.gettimeofday ()-.t));
- let bf = BoolFormula.sat_of_qbf (*elim_quant*) qbf in
+ let bf = BoolFormula.elim_quant qbf in
(match logtime with None -> () | Some t ->
LOG 0 "%sBF constructed at %.3fs" logprefix (AuxIO.gettimeofday () -. t));
match BoolFormula.find_model ?logtime ~logprefix bf with
Modified: trunk/Toss/Solver/SolverTest.ml
===================================================================
--- trunk/Toss/Solver/SolverTest.ml 2012-07-18 13:38:17 UTC (rev 1747)
+++ trunk/Toss/Solver/SolverTest.ml 2012-07-18 15:33:21 UTC (rev 1748)
@@ -198,8 +198,11 @@
(String.concat "." (Array.to_list (Array.map string_of_int arr))) in
let names_tbl = Hashtbl.create (Hashtbl.length rev_ids) in
Hashtbl.iter (fun k v -> Hashtbl.add names_tbl k (name v)) rev_ids;
- assert_equal ~printer:(fun x -> x) qbf_s
- (BoolFormula.qbf_str ~names:names_tbl qbf_res) in
+ let qbf_res_s = BoolFormula.qbf_str ~names:names_tbl qbf_res in
+ LOG 1 "QBF %s BF %s" qbf_res_s (
+ let bf = BoolFormula.simplify (BoolFormula.sat_of_qbf qbf_res) in
+ (BoolFormula.str ~names:names_tbl bf) );
+ assert_equal ~printer:(fun x -> x) qbf_s qbf_res_s in
qbf_str_eq "[ a, b | T { a } | ]" "ex |R all x, y (T(x) or |R (x, y))"
"(ex R.2.2, R.2.1, R.1.2, R.1.1 (R.2.1 and R.2.2))";
@@ -229,8 +232,8 @@
"(|A(x) | (|A(y) & E(x,y))) & (|B(x) | (|B(u)&E(x,u))) &" ^
" (|C(x)|(|C(v) & E(x,v))))") in
let yd = "(&x2=&x1+1 | &x2=&x1+2 | &x1=&x2+1 | &x1=&x2+2)" in ();
-(* find_so_test dnp3 ("[ 0 - 4 | | - ] with E(x1, x2) = " ^ yd)
- "|C {e1; e3}; |B {e0; e4}; |A (e2)"; *)
+ find_so_test dnp3 ("[ 0 - 4 | | - ] with E(x1, x2) = " ^ yd)
+ "|C {e1; e3}; |B {e0; e4}; |A (e2)";
let nd = yd ^ "& ((~(&x1=1) & ~(&x2=1)) | (&x1=1 & &x2=3))" in
find_so_test dnp3 ("[ 0 - 4 | | - ] with E(x1, x2) = " ^ nd) "UNSAT";
@@ -246,8 +249,10 @@
"( (|Tc(x, y) ∧ |Tc(y, z)) -> |Tc(x, z) ) ) ) ∧ " ^
"( ∀ |T ( (∀ x,y,z ( ( E(x, y) → |T(x, y) ) ∧ " ^
"( (|T(x, y) ∧ |T(y, z)) -> |T(x, z) ) ) ) → " ^
- "(∀ x, y (|T(x, y) → |Tc(x, y) )) ))" in
- find_so_test tc2phi "[ c | E { (a, b) } | ]" "|Tc?";
+ "(∀ x, y (|Tc(x, y) → |T(x, y) )) ))" in
+ find_so_test tc2phi "[ | E { (a, b); (c, d) } | ]" "|Tc {(a, b); (c, d)}";
+ find_so_test tc2phi "[ | E { (a, b); (b, c) } | ]"
+ "|Tc {(a, b); (a, c); (b, c)}";
);
"eval: second-order" >::
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|