[Toss-devel-svn] SF.net SVN: toss:[1542] trunk/Toss
Status: Beta
Brought to you by:
lukaszkaiser
|
From: <luk...@us...> - 2011-08-18 09:30:32
|
Revision: 1542
http://toss.svn.sourceforge.net/toss/?rev=1542&view=rev
Author: lukstafi
Date: 2011-08-18 09:30:20 +0000 (Thu, 18 Aug 2011)
Log Message:
-----------
GDL translation: reverting to saturation-based solver for aggregate playout; optimized saturation (better data structures, matching instead of unification).
Modified Paths:
--------------
trunk/Toss/Formula/Aux.ml
trunk/Toss/Formula/Aux.mli
trunk/Toss/GGP/GDL.ml
trunk/Toss/GGP/GDL.mli
trunk/Toss/GGP/GDLTest.ml
trunk/Toss/GGP/TranslateGame.ml
trunk/Toss/GGP/TranslateGameTest.ml
Modified: trunk/Toss/Formula/Aux.ml
===================================================================
--- trunk/Toss/Formula/Aux.ml 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/Formula/Aux.ml 2011-08-18 09:30:20 UTC (rev 1542)
@@ -81,6 +81,10 @@
[] -> tl
| a::l -> let r = f a in r :: map_prepend tl f l
+let rec map_rev_prepend tl f = function
+ [] -> tl
+ | a::l -> let r = f a in map_rev_prepend (r::tl) f l
+
let map_some f l =
let rec maps_f accu = function
| [] -> accu
Modified: trunk/Toss/Formula/Aux.mli
===================================================================
--- trunk/Toss/Formula/Aux.mli 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/Formula/Aux.mli 2011-08-18 09:30:20 UTC (rev 1542)
@@ -54,7 +54,11 @@
(** Map a second list and prepend the result to the first list, by
single traversal. Not tail-recursive. *)
val map_prepend : 'a list -> ('b -> 'a) -> 'b list -> 'a list
+(** Map a second list and prepend the result to the first list, in
+ reverse order. Tail-recursive. *)
+val map_rev_prepend : 'a list -> ('b -> 'a) -> 'b list -> 'a list
+
(** Map a list filtering out some elements. *)
val map_some : ('a -> 'b option) -> 'a list -> 'b list
Modified: trunk/Toss/GGP/GDL.ml
===================================================================
--- trunk/Toss/GGP/GDL.ml 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/GGP/GDL.ml 2011-08-18 09:30:20 UTC (rev 1542)
@@ -258,7 +258,25 @@
(List.map (subst_one sb1) terms2)
| _ -> raise Not_found
+(* Yet another variant, for fast saturation. *)
+let rec match_nonvar sb terms1 terms2 =
+ match terms1, terms2 with
+ | [], [] -> sb
+ | Const a::terms1, Const b::terms2 when a=b ->
+ match_nonvar sb terms1 terms2
+ | Func (f,args1)::terms1, Func (g,args2)::terms2 when f=g ->
+ match_nonvar sb (Array.to_list args1 @ terms1)
+ (Array.to_list args2 @ terms2)
+ | _::terms1, Var _::terms2 ->
+ match_nonvar sb terms1 terms2
+ | Var x::terms1, c::terms2 ->
+ let sb1 = x, c in
+ match_nonvar (sb1::List.map (fun (x,t)->x, subst_one sb1 t) sb)
+ (List.map (subst_one sb1) terms1)
+ (List.map (subst_one sb1) terms2)
+ | _ -> raise Not_found
+
let unify_args ?(sb=[]) args1 args2 =
unify sb (Array.to_list args1) (Array.to_list args2)
@@ -289,6 +307,10 @@
try ignore (unify [] [term1] [term2]); true
with Not_found -> false
+let try_match_nonvar terms1 terms2 =
+ try ignore (match_nonvar [] terms1 terms2); true
+ with Not_found -> false
+
let unify_rels ?sb (rel1, args1) (rel2, args2) =
if rel1 = rel2 then unify_args ?sb args1 args2
else raise Not_found
@@ -387,35 +409,79 @@
rel ^"(" ^ String.concat ", " args ^")"
-(* TODO: optimize by using rel-indexing (also in [aggregate_playout]).
- TODO: optimize by using constant-time append data structure. *)
-(* Variables still left after saturation have universal interpretation! *)
-let saturate base rules =
+(** {4 Saturation-based solver.} *)
- let instantiate_one (tot_base : rel_atom list)
- (cur_base : rel_atom list) irules =
- Aux.concat_map (function
- | head, [], neg_body ->
- if List.mem head tot_base then []
- else if List.exists (fun (rel,args as neg_atom) ->
+module Tuples = Set.Make(struct
+ type t = term array
+ let compare = Pervasives.compare
+end)
+type graph = Tuples.t Aux.StrMap.t
+
+let add_tuples nvs vs =
+ List.fold_left (fun vs nv -> Tuples.add nv vs) vs nvs
+let tuples_of_list nvs =
+ add_tuples nvs Tuples.empty
+
+let merge_graphs graph1 graph2 =
+ Aux.StrMap.fold
+ (fun rel tups1 graph ->
+ let tups2 =
+ try Aux.StrMap.find rel graph2 with Not_found -> Tuples.empty in
+ Aux.StrMap.add rel (Tuples.union tups1 tups2) graph)
+ graph1 graph2
+
+let build_graph atoms =
+ List.fold_left
+ (fun graph (rel,tups) ->
+ Aux.StrMap.add rel (tuples_of_list tups) graph)
+ Aux.StrMap.empty (Aux.collect atoms)
+
+let graph_to_atoms graph =
+ List.rev
+ (Aux.StrMap.fold (fun rel tups atoms ->
+ Aux.map_rev_prepend atoms (fun tup -> rel, tup)
+ (Tuples.elements tups)) graph [])
+
+let graph_mem rel tup graph =
+ try
+ Tuples.mem tup (Aux.StrMap.find rel graph)
+ with Not_found -> false
+
+let instantiate_one tot_base cur_base irules =
+ Aux.concat_map (function
+ | (hrel, hargs as head), [], neg_body ->
+ if (try Tuples.mem hargs (Aux.StrMap.find hrel tot_base)
+ with Not_found -> false)
+ then []
+ else if List.exists (fun (rel,args) ->
+ let rel_tups =
+ try Aux.StrMap.find rel tot_base with Not_found -> Tuples.empty in
+ Tuples.mem args rel_tups ||
rel = "distinct" && Aux.not_unique (Array.to_list args) ||
- (* faster option: *)
- (* List.mem neg_atom tot_base *)
- (* accurate option: *)
- List.exists (rels_unify neg_atom) tot_base
- ) neg_body then []
- else [Aux.Left head]
- | head, cond1::body, neg_body ->
- Aux.map_try (fun fact ->
+ let neg_tup = Array.to_list args in
+ Tuples.exists
+ (fun tup -> try_match_nonvar neg_tup (Array.to_list tup))
+ rel_tups
+ ) neg_body then []
+ else [Aux.Left head]
+ | (hrel, hargs as head), (rel,args as pos_atom)::body, neg_body ->
+ if (try Tuples.mem hargs (Aux.StrMap.find hrel tot_base)
+ with Not_found -> false)
+ then []
+ else
+ let pos_tup = Array.to_list args in
+ let cur_tups =
+ try Tuples.elements (Aux.StrMap.find rel cur_base)
+ with Not_found -> [] in
+ Aux.map_try
+ (fun rel_tup ->
(* {{{ log entry *)
-
if !debug_level > 5 then (
- Printf.printf "instantiate_one: trying to unify %s and %s\n%!"
- (rel_atom_str fact) (rel_atom_str cond1)
+ Printf.printf "instantiate_one: trying to match %s and %s\n%!"
+ (rel_atom_str (rel, rel_tup)) (rel_atom_str pos_atom)
);
-
(* }}} *)
- let sb = unify_rels fact cond1 in
+ let sb = match_nonvar [] pos_tup (Array.to_list rel_tup) in
(* {{{ log entry *)
if !debug_level > 5 then (
Printf.printf "instantiate_one: succeeded with %s\n%!"
@@ -425,21 +491,26 @@
let irule =
subst_rel sb head,
subst_rels sb body, subst_rels sb neg_body in
- Aux.Right irule
- ) cur_base) irules in
+ Aux.Right irule)
+ cur_tups)
+ irules
+(* TODO: optimize by using rel-indexing (also in [aggregate_playout]). *)
+(* Variables still left after saturation have universal interpretation! *)
+let saturate base rules =
+
let rec inst_stratum old_base old_irules cur_base cur_irules =
(* {{{ log entry *)
if !debug_level > 4 then (
- Printf.printf "inst_stratum: old_base = %s; cur_base = %s\n%!"
- (rel_atoms_str old_base) (rel_atoms_str cur_base);
+ (*Printf.printf "inst_stratum: old_base = %s; cur_base = %s\n%!"
+ (rel_atoms_str old_base) (rel_atoms_str cur_base);*)
Printf.printf
"inst_stratum: #old_irules = %d, #cur_irules = %d\n%!"
(List.length old_irules) (List.length cur_irules)
);
(* }}} *)
- let base = Aux.unique_sorted (cur_base @ old_base)
- and irules = Aux.unique_sorted (cur_irules @ old_irules) in
+ let base = merge_graphs cur_base old_base
+ and irules = Aux.sorted_merge cur_irules old_irules in
let new_base1, new_irules1 =
Aux.partition_choice (instantiate_one base cur_base cur_irules) in
(* {{{ log entry *)
@@ -464,24 +535,24 @@
(rel_atoms_str new_base3)
);
(* }}} *)
- let new_base = Aux.unique_sorted (new_base1 @ new_base2 @ new_base3)
+ let new_base = build_graph
+ (new_base1 @ new_base2 @ new_base3)
and new_irules = Aux.unique_sorted
(new_irules1 @ new_irules2 @ new_irules3) in
- let new_base =
- List.filter (fun f->not (List.mem f base)) new_base in
- let new_irules =
- List.filter (fun f->not (List.mem f irules)) new_irules in
- if new_base = [] && new_irules = []
+ (* [new_base] is already disjoint from [base] *)
+ let new_irules = Aux.sorted_diff new_irules irules in
+ if Aux.StrMap.is_empty new_base && new_irules = []
then base
else inst_stratum base irules new_base new_irules in
let rec instantiate base = function
| [] -> base
| stratum::strata ->
- instantiate (inst_stratum [] [] base stratum) strata in
+ instantiate (inst_stratum Aux.StrMap.empty [] base stratum) strata in
- instantiate base
- (List.map rules_of_defs (stratify [] (defs_of_rules rules)))
+ instantiate (*build_graph*) base
+ (List.map (Aux.unique_sorted -| rules_of_defs)
+ (stratify [] (defs_of_rules rules)))
@@ -872,35 +943,34 @@
(* [~aggregate:true] performs an aggregate ply, [~aggregate:false]
performs a random ply. *)
let ply_satur ~aggregate players static current rules =
- let base =
- Aux.map_prepend static (fun term -> "true", [|term|]) current in
- let base = saturate (base @ static) rules in
+ let base = Aux.StrMap.add "true" current
+ (*tuples_of_list (List.map (fun term -> [|term|]) current)*) static in
+ let base = saturate base rules in
(* {{{ log entry *)
if !debug_level > 4 then (
Printf.printf "GDL.ply: updated base -- %s\n%!"
- (rel_atoms_str base)
+ (rel_atoms_str (graph_to_atoms base))
);
(* }}} *)
- let does = Aux.map_some (fun (rel, args) ->
- if rel = "legal" then Some ("does", args) else None) base in
+ let does = Tuples.elements (Aux.StrMap.find "legal" base) in
let does =
if aggregate then does
else
List.map (Aux.random_elem -| snd)
- (Aux.collect (List.map (fun (_,args as atom) ->
- args.(0), atom) does)) in
+ (Aux.collect (List.map (fun args ->
+ args.(0), args) does)) in
if (* no move *)
Aux.array_existsi (fun _ player ->
List.for_all (function
- |_, [|Var _; _ |] -> false
- | _, [|actor; _ |] -> player <> actor | _ -> true)
+ | [|Var _; _ |] -> false
+ | [|actor; _ |] -> player <> actor | _ -> true)
does) players
then (
(* {{{ log entry *)
if !debug_level > 0 then (
let players_nomove =
Aux.array_find_all (fun player ->
- List.for_all (function _, [|actor; _|] -> player <> actor
+ List.for_all (function [|actor; _|] -> player <> actor
| _ -> true)
does) players in
Printf.printf
@@ -910,16 +980,11 @@
(* }}} *)
raise Playout_over)
else
- let step = saturate (does @ base) rules in
- let step_state = Aux.map_some
- (function ("next", [|arg|]) -> Some arg
- | _ -> None) step in
+ let step = saturate
+ (Aux.StrMap.add "does" (tuples_of_list does) base) rules in
+ let step_state = Aux.StrMap.find "next" step in
if !playout_fixpoint && (* fixpoint reached *)
- List.for_all (function
- | Func (_,[|arg|]) when
- Aux.array_existsi (fun _ player -> arg=player) players -> true
- | term -> List.mem term current
- ) step_state
+ Tuples.subset step_state current
then (
(* {{{ log entry *)
if !debug_level > 0 then (
@@ -928,7 +993,8 @@
(* }}} *)
raise Playout_over)
else if not aggregate && (* terminal position reached *)
- List.mem_assoc "terminal" step
+ (try not (Tuples.is_empty (Aux.StrMap.find "terminal" step))
+ with Not_found -> false)
then (
(* {{{ log entry *)
if !debug_level > 0 then (
@@ -937,8 +1003,11 @@
(* }}} *)
raise Playout_over)
else
- List.map snd does, step_state
+ does, step_state
+let state_of_tups ts =
+ List.map (fun s->s.(0)) (Tuples.elements ts)
+
(* Besides the playout, also return the separation of rules
into static and dynamic. Note that the list of playout states is
one longer than that of playout actions.
@@ -967,7 +1036,7 @@
["init"; "does"; "true"; "next"; "terminal"; "goal"] in
let static_rules, dynamic_rules = List.partition
(fun ((rel,_),_,_) -> List.mem rel static_rels) rules in
- let static_base = saturate [] static_rules in
+ let static_base = saturate Aux.StrMap.empty static_rules in
let state_rules =
List.map (function
| ("legal", [|player; _|] as head), body, neg_body ->
@@ -987,30 +1056,33 @@
(* {{{ log entry *)
if !debug_level > 0 then (
Printf.printf "playout: state %s\n%!"
- (String.concat " " (List.map term_str next))
+ (String.concat " "
+ (List.map term_str (state_of_tups next)))
);
(* }}} *)
let next =
- if aggregate then state @ next else next in
+ if aggregate then (Tuples.union state next) else next in
if step < horizon then
loop (actions::actions_accu) (state::state_accu) (step+1) next
else
+ let states = List.rev (next::state::state_accu) in
List.rev (actions::actions_accu),
- List.rev (next::state::state_accu)
+ List.map (fun ts->state_of_tups ts) states
with Playout_over ->
- List.rev actions_accu, List.rev (state::state_accu)) in
+ List.rev actions_accu,
+ List.map (fun ts->state_of_tups ts)
+ (List.rev (state::state_accu))) in
(* FIXME: this is identity, right? remove *)
let init_base = saturate static_base state_rules in
- let init_state =
- Aux.map_some (function ("init", [|arg|]) -> Some arg
- | _ -> None) init_base in
+ let init_state = Aux.StrMap.find "init" init_base in
(* {{{ log entry *)
if !debug_level > 0 then (
Printf.printf "playout: init %s\n%!"
- (String.concat " " (List.map term_str init_state))
+ (String.concat " "
+ (List.map term_str (state_of_tups init_state)))
);
(* }}} *)
- static_rules, dynamic_rules, static_base, init_state,
+ static_rules, dynamic_rules, static_base, (state_of_tups init_state),
loop [] [] 0 init_state
Modified: trunk/Toss/GGP/GDL.mli
===================================================================
--- trunk/Toss/GGP/GDL.mli 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/GGP/GDL.mli 2011-08-18 09:30:20 UTC (rev 1542)
@@ -76,9 +76,12 @@
val subst_clause : substitution -> clause -> clause
val subst_consts_clause : substitution -> clause -> clause
+module Tuples : Set.S with type elt = term array
+type graph = Tuples.t Aux.StrMap.t
+val graph_mem : string -> term array -> graph -> bool
+val graph_to_atoms : graph -> rel_atom list
(** Saturation currently exposed for testing purposes. *)
-val saturate :
- rel_atom list -> gdl_rule list -> rel_atom list
+val saturate : graph -> gdl_rule list -> graph
(** {3 Continuation-based Prolog interpreter} *)
@@ -175,7 +178,7 @@
val playout_satur :
aggregate:bool -> term array -> int -> gdl_rule list ->
gdl_rule list * gdl_rule list *
- rel_atom list * term list *
+ graph * term list *
(term array list list * term list list)
val playout_prolog :
Modified: trunk/Toss/GGP/GDLTest.ml
===================================================================
--- trunk/Toss/GGP/GDLTest.ml 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/GGP/GDLTest.ml 2011-08-18 09:30:20 UTC (rev 1542)
@@ -57,24 +57,24 @@
(beta rock)
(theta scisors) (gamma scisors)" in
(* GDL.debug_level := 3; *)
- let res = GDL.saturate []
+ let res = GDL.saturate Aux.StrMap.empty
(Aux.concat_map GDL.rules_of_clause descr) in
assert_equal ~printer:(fun x->x) ~msg:"simple stratified"
"(alpha paper) (alpha rock) (beta paper) (beta rock) (beta scisors) (gamma paper) (gamma scisors) (theta scisors) (zeta rock)"
(String.concat " "
- (List.map GDL.rel_atom_str res));
+ (List.map GDL.rel_atom_str (GDL.graph_to_atoms res)));
let descr = parse_game_descr
"
(<= (two-of-three ?X ?Y) (a ?X) (a ?Y) (distinct ?X ?Y))
(a 1) (a 2) (a 3)" in
(* GDL.debug_level := 3; *)
- let res = GDL.saturate []
+ let res = GDL.saturate Aux.StrMap.empty
(Aux.concat_map GDL.rules_of_clause descr) in
assert_equal ~printer:(fun x->x) ~msg:"simple distinct"
"(a 1) (a 2) (a 3) (two-of-three 1 2) (two-of-three 1 3) (two-of-three 2 1) (two-of-three 2 3) (two-of-three 3 1) (two-of-three 3 2)"
(String.concat " "
- (List.map GDL.rel_atom_str res));
+ (List.map GDL.rel_atom_str (graph_to_atoms res)));
);
"saturate recursive" >::
@@ -96,12 +96,12 @@
(succ 4 5) (succ 5 6) (succ 6 7) (succ 7 8)
" in
(* GDL.debug_level := 3; *)
- let res = GDL.saturate []
+ let res = GDL.saturate Aux.StrMap.empty
(Aux.concat_map GDL.rules_of_clause descr) in
assert_equal ~printer:(fun x->x) ~msg:"simple stratified"
"(lte 0 0) (lte 0 1) (lte 0 2) (lte 0 3) (lte 0 4) (lte 0 5) (lte 0 6) (lte 0 7) (lte 0 8) (lte 1 1) (lte 1 2) (lte 1 3) (lte 1 4) (lte 1 5) (lte 1 6) (lte 1 7) (lte 1 8) (lte 2 2) (lte 2 3) (lte 2 4) (lte 2 5) (lte 2 6) (lte 2 7) (lte 2 8) (lte 3 3) (lte 3 4) (lte 3 5) (lte 3 6) (lte 3 7) (lte 3 8) (lte 4 4) (lte 4 5) (lte 4 6) (lte 4 7) (lte 4 8) (lte 5 5) (lte 5 6) (lte 5 7) (lte 5 8) (lte 6 6) (lte 6 7) (lte 6 8) (lte 7 7) (lte 7 8) (lte 8 8) (number 0) (number 1) (number 2) (number 3) (number 4) (number 5) (number 6) (number 7) (number 8) (succ 0 1) (succ 1 2) (succ 2 3) (succ 3 4) (succ 4 5) (succ 5 6) (succ 6 7) (succ 7 8)"
(String.concat " "
- (List.map GDL.rel_atom_str res));
+ (List.map GDL.rel_atom_str (GDL.graph_to_atoms res)));
);
"run_prolog" >::
Modified: trunk/Toss/GGP/TranslateGame.ml
===================================================================
--- trunk/Toss/GGP/TranslateGame.ml 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/GGP/TranslateGame.ml 2011-08-18 09:30:20 UTC (rev 1542)
@@ -250,14 +250,18 @@
) clauses in
let players = Array.of_list players in
let rules = Aux.concat_map rules_of_clause clauses in
- (*
+ (* Turns out the saturation-based solver is sometimes far better for
+ performing aggregate playout, which is very much
+ saturation-like. *)
let static_rel_defs, nonstatic_rel_defs,
static_base, init_state, (agg_actions, agg_states) =
playout_satur ~aggregate:true players !playout_horizon rules in
- *)
+ (* *)
+ (*
let program = preprocess_program clauses in
let agg_actions, agg_states =
playout_prolog ~aggregate:true players !playout_horizon program in
+ *)
let init_state = List.hd agg_states in
let static_rels, nonstatic_rels =
static_rels (defs_of_rules rules) in
@@ -345,8 +349,8 @@
Aux.fold_left_try (fun struc etup ->
let tup = Array.of_list (List.map2 at_path etup ptup) in
if rel = "EQ_" && arity = 2 && tup.(0) = tup.(1) ||
- (* List.mem (rel, tup) static_base *)
- rel <> "EQ_" && run_prolog_check_atom (rel, tup) program
+ rel <> "EQ_" && graph_mem rel tup static_base
+ (* rel <> "EQ_" && run_prolog_check_atom (rel, tup) program *)
then (
stable_rels := Aux.Strings.add fact_rel !stable_rels;
Structure.add_rel_named_elems struc fact_rel
Modified: trunk/Toss/GGP/TranslateGameTest.ml
===================================================================
--- trunk/Toss/GGP/TranslateGameTest.ml 2011-08-16 14:49:54 UTC (rev 1541)
+++ trunk/Toss/GGP/TranslateGameTest.ml 2011-08-18 09:30:20 UTC (rev 1542)
@@ -172,7 +172,7 @@
"control__blank_", "control_MV1"]
~loc1_noop:"noop" ~loc1_move:"(mark f g)"
);
-(*
+
"breakthrough" >::
(fun () ->
game_test_case ~game_name:"breakthrough" ~player:"white"
@@ -211,11 +211,11 @@
"control__blank_", "control_MV1"]
~loc1_noop:"noop" ~loc1_move:"(mark f g)"
);
-*)
+
]
let a () =
- (* GDL.debug_level := 4; *)
+ GDL.debug_level := 4;
TranslateGame.debug_level := 4;
GameSimpl.debug_level := 4;
DiscreteRule.debug_level := 4;
@@ -223,18 +223,20 @@
let a () =
- game_test_case ~game_name:"tictactoe" ~player:"xplayer"
+ game_test_case ~game_name:"breakthrough" ~player:"white"
~own_plnum:0 ~opponent_plnum:1
- ~loc0_rule_name:"mark_x6_y_noop"
+ ~loc0_rule_name:"move_x239_y257_x238_y256_0"
~loc0_emb:[
- "cell_x6_y__BLANK_", "cell_2_2__BLANK_";
- "control__BLANK_", "control__BLANK_"]
- ~loc0_move:"(mark 2 2)" ~loc0_noop:"noop"
- ~loc1:1 ~loc1_rule_name:"noop_mark_x7_y0"
+ "cellholds_x239_y257__blank_", "cellholds_2_2_MV1";
+ "cellholds_x238_y256__blank_", "cellholds_1_3_MV1";
+ "control__blank_", "control_MV1"]
+ ~loc0_move:"(move 2 2 1 3)" ~loc0_noop:"noop" ~loc1:1
+ ~loc1_rule_name:"move_x467_y497_x466_y496_1"
~loc1_emb:[
- "cell_x7_y0__BLANK_", "cell_1_1__BLANK_";
- "control__BLANK_", "control__BLANK_"]
- ~loc1_noop:"noop" ~loc1_move:"(mark 1 1)"
+ "cellholds_x467_y497__blank_", "cellholds_7_7_MV1";
+ "cellholds_x466_y496__blank_", "cellholds_6_6_MV1";
+ "control__blank_", "control_MV1"]
+ ~loc1_noop:"noop" ~loc1_move:"(move 7 7 6 6)"
let a () =
@@ -270,9 +272,9 @@
TranslateGame.generate_test_case := None
let a () =
- regenerate ~debug:false ~game_name:"tictactoe" ~player:"xplayer";
+ (* regenerate ~debug:false ~game_name:"tictactoe" ~player:"xplayer"; *)
(* regenerate ~debug:false ~game_name:"connect5" ~player:"x"; *)
- (* regenerate ~debug:true ~game_name:"breakthrough" ~player:"white"; *)
+ regenerate ~debug:true ~game_name:"breakthrough" ~player:"white";
(* regenerate ~debug:true ~game_name:"pawn_whopping" ~player:"x"; *)
(* regen_with_debug ~game_name:"connect4" ~player:"white"; *)
(* failwith "generated"; *)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|