chess960 in OCaml — Generating Valid Positions

let genpositions () =
  uniq (
    sort compare (
      filter (conjunction [valid_king; valid_bishops])
		    (permutations [R;N;B;Q;K;B;N;R])))
# let genpositions () =
  uniq (
    sort compare (
      filter (conjunction [valid_king; valid_bishops])
		    (permutations [R;N;B;Q;K;B;N;R])));;
val genpositions : unit -> piece list list = <fun>

Conjunction of the Two Validity Tests

# conjunction [valid_king; valid_bishops] [R;N;B;Q;K;B;N;R];;
- : bool = true
# conjunction [valid_king; valid_bishops] [R;N;B;Q;B;K;N;R];;
- : bool = false
# conjunction [valid_king; valid_bishops] [R;N;B;Q;B;N;R;K];;
- : bool = false
# 

Filtering Out Invalid Positions

# length perms;;
- : int = 40320
# filter (conjunction [valid_king; valid_bishops]) perms;;
- : piece list list =
[[R; N; B; Q; K; B; N; R]; [N; R; B; Q; K; B; N; R];
 [B; R; N; Q; K; B; N; R]; [B; N; R; Q; K; B; N; R];
 [B; N; Q; R; K; B; N; R]; [B; R; Q; N; K; B; N; R];
 [B; Q; R; N; K; B; N; R]; [B; Q; N; R; K; B; N; R];
 [B; R; Q; K; N; B; N; R]; [B; Q; R; K; N; B; N; R];
 [R; B; Q; K; B; N; N; R]; [R; B; Q; K; B; N; N; R];
 [R; B; Q; K; B; N; R; N]; [N; Q; B; R; K; B; N; R];
 [Q; N; B; R; K; B; N; R]; [R; Q; B; N; K; B; N; R];
 [Q; R; B; N; K; B; N; R]; [R; Q; B; K; N; B; N; R];
 [Q; R; B; K; N; B; N; R]; [Q; B; R; K; B; N; N; R];
 [Q; B; R; K; B; N; N; R]; [Q; B; R; K; B; N; R; N];
 [R; N; Q; K; B; B; N; R]; [N; R; Q; K; B; B; N; R];
 [N; Q; R; K; B; B; N; R]; [R; Q; N; K; B; B; N; R];
 [Q; R; N; K; B; B; N; R]; [Q; N; R; K; B; B; N; R];
 [R; Q; K; N; B; B; N; R]; [Q; R; K; N; B; B; N; R];
 [R; Q; K; B; B; N; N; R]; [Q; R; K; B; B; N; N; R];
 [R; Q; K; B; B; N; N; R]; [Q; ...]; ...]
# length (filter (conjunction [valid_king; valid_bishops]) perms);;
- : int = 7680
# 

Why 7,680 and Not 960?

# let t = Hashtbl.create 8000;;
val t : ('_a, '_b) Hashtbl.t = <abstr>
# iter (fun pos -> Hashtbl.add t pos pos) filtered;;
- : unit = ()
# Hashtbl.find_all t [R; N; B; Q; K; B; N; R];;
- : piece list list =
[[R; N; B; Q; K; B; N; R]; [R; N; B; Q; K; B; N; R];
 [R; N; B; Q; K; B; N; R]; [R; N; B; Q; K; B; N; R];
 [R; N; B; Q; K; B; N; R]; [R; N; B; Q; K; B; N; R];
 [R; N; B; Q; K; B; N; R]; [R; N; B; Q; K; B; N; R]]
# 

Eliminating Duplicates

# length (sort compare (
	    filter (conjunction [valid_king; valid_bishops])
			  (permutations [R;N;B;Q;K;B;N;R])));;
- : int = 7680
# length (uniq (
	    sort compare (
	      filter (conjunction [valid_king; valid_bishops])
			    (permutations [R;N;B;Q;K;B;N;R]))));;
- : int = 960
#