File: strat.ml

package info (click to toggle)
ocamlgraph 2.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,624 kB
  • sloc: ml: 19,995; xml: 151; makefile: 14; sh: 1
file content (133 lines) | stat: -rw-r--r-- 4,184 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
(**************************************************************************)
(*                                                                        *)
(*  Ocamlgraph: a generic graph library for OCaml                         *)
(*  Copyright (C) 2004-2007                                               *)
(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)
(*                                                                        *)
(*  This software is free software; you can redistribute it and/or        *)
(*  modify it under the terms of the GNU Library General Public           *)
(*  License version 2, with the special exception on linking              *)
(*  described in file LICENSE.                                            *)
(*                                                                        *)
(*  This software is distributed in the hope that it will be useful,      *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)
(*                                                                        *)
(**************************************************************************)

(* $Id:$ *)

open Graph


module V = struct
  type t = bool * int
  let compare = compare
  let hash = Hashtbl.hash
  let equal = (=)
end


module G = Persistent.Digraph.Concrete(V)


module P = struct
  type vertex = V.t
  type t = vertex * (vertex list) * (vertex -> bool)

  let get_initial (i, _, _) = i
  let is_final (_, f, _) v = List.mem v f

  let turn (_, _, f) v = f v
end


module S = struct
  type vertex = V.t
  type t = vertex -> vertex

  let empty =
    fun _ -> raise (Invalid_argument "Strategy definition")

  let next f v = f v

  let add s v v' =
    fun e -> if V.equal e v then v' else next s e
end


module A = Strat.Algo(G)(P)(S);;


(* Match game : n matches in line, two players. Each player takes
   one, two or three matches in order. The player who takes the
   last match loses. *)


(* States are given by the remaining number of matches
   and the player whose turn it is to play.
   Edges are the possible moves. *)
let rec trans_aux g (j, n) =
  if n = 0 then g
  else
    if n = 1 then
      let g = G.add_edge g (j, n) (not j, n - 1) in
	(if j then trans_aux g (not j, n) else trans_aux g (not j, n - 1))
    else
      if n = 2 then
	let g = G.add_edge g (j, n) (not j, n - 1) in
	let g = G.add_edge g (j, n) (not j, n - 2) in 
	  (if j then trans_aux g (not j, n) else trans_aux g (not j, n - 1))
      else
	let g = G.add_edge g (j, n) (not j, n - 1) in
	let g = G.add_edge g (j, n) (not j, n - 2) in
	let g = G.add_edge g (j, n) (not j, n - 3) in
	  (if j then trans_aux g (not j, n) else trans_aux g (not j, n - 1));;
let trans n = trans_aux G.empty (true, n);;
let p n = ((true, n), [(true, 0)], fun (b, _) -> b);;


(* ex n = ((true, _), _) if there is a winning strategy for the
   first player to play. In this case, it provides
   a strategy. *)
let ex n =
  let t = trans n in
    (A.strategyA t (p n), t);;

let n1 = 15;;
let n2 = 13;;

let ex1 = ex n1;;
let ex2 = ex n2;;


(* Printing on the standard out channel ;
   simply uncomment to see the results. *)

let couple_of_strat g s =
  let f v l =
    try
      let v' = S.next s v in (v, v') :: l
    with Invalid_argument _ -> l
  in
    G.fold_vertex f g [];;

let string_of_couple ((_, i1), (_, i2)) =
  "(" ^ (string_of_int i1) ^ ", " ^ (string_of_int i2) ^ ") ";;

let rec string_of_couple_list l = match l with
    [] -> ""
  | e :: l' -> (string_of_couple e) ^ (string_of_couple_list l');;

print_newline();;
print_string ("For " ^ (string_of_int n1) ^ " matches, is there a winning strategy for the first player ?");;
print_newline();;
print_string (string_of_bool (fst (fst ex1)));;
print_string " --- ";;
print_string (string_of_couple_list (couple_of_strat (snd ex1) (snd (fst ex1))));;
print_newline();; print_newline();;
print_string ("For " ^ (string_of_int n2) ^ " matches, is there a winning strategy for the first player ?");;
print_newline();;
print_string (string_of_bool (fst (fst ex2)));;
print_newline();; print_newline();;