10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-11-14 18:13:40 +01:00
QCaml/Utils/Zkey.ml

210 lines
6.2 KiB
OCaml
Raw Normal View History

2018-02-19 16:01:13 +01:00
open Powers
2018-02-14 20:00:12 +01:00
(** Key for hastables that contain tuples of integers encoded in small integers *)
2018-01-19 20:20:19 +01:00
type kind_array =
2018-01-17 18:19:38 +01:00
| Kind_3
| Kind_6
| Kind_12
2018-01-19 18:18:11 +01:00
| Kind_9
2018-01-17 18:19:38 +01:00
2018-02-14 19:23:23 +01:00
type t =
{
left : int ;
right : int ;
}
let of_int right =
{ left = 0 ; right }
2018-01-22 23:19:24 +01:00
2018-02-14 19:23:23 +01:00
let (<|) { left ; right } x =
{ left=right ; right=x }
2018-01-22 23:19:24 +01:00
2018-02-14 19:23:23 +01:00
let (<<) { left ; right } x =
{ left ; right = (right lsl 10) lor x }
let (<+) { left ; right } x =
{ left ; right = (right lsl 15) lor x }
2018-01-22 23:19:24 +01:00
2018-01-17 18:19:38 +01:00
2018-01-19 20:20:19 +01:00
(** Build a Zkey from an array or 1, 2, 3, 4, 6, 9, or 12 integers *)
2018-01-17 18:19:38 +01:00
let of_int_array ~kind a =
2018-02-14 19:23:23 +01:00
2018-01-17 18:19:38 +01:00
match kind with
2018-02-14 19:23:23 +01:00
| Kind_3 -> of_int a.(0) <+ a.(1) <+ a.(2)
| Kind_6 -> of_int a.(0) << a.(1) << a.(2) << a.(3) << a.(4) << a.(5)
| Kind_12 ->
of_int a.(0) << a.(1) << a.(2) << a.(3) << a.(4) << a.(5)
<| a.(6) << a.(7) << a.(8) << a.(9) << a.(10) << a.(11)
2018-01-19 18:18:11 +01:00
| Kind_9 ->
2018-02-14 19:23:23 +01:00
of_int a.(0) << a.(1) << a.(2) << a.(3) << a.(4) << a.(5)
<| a.(6) << a.(7) << a.(8)
2018-01-17 18:19:38 +01:00
2018-01-19 20:20:19 +01:00
type kind =
2018-02-19 16:01:13 +01:00
| Three of Powers.t
| Six of (Powers.t * Powers.t)
| Nine of (Powers.t * Powers.t * Powers.t)
| Twelve of (Powers.t * Powers.t * Powers.t * Powers.t)
let of_powers a =
2018-01-19 20:20:19 +01:00
match a with
2018-02-19 16:01:13 +01:00
| Three { x=a ; y=b ; z=c ; _ } -> of_int a <+ b <+ c
| Six ({ x=a ; y=b ; z=c },{ x=d ; y=e ; z=f }) ->
2018-02-14 19:23:23 +01:00
of_int a << b << c << d << e << f
2018-02-19 16:01:13 +01:00
| Twelve ({ x=a ; y=b ; z=c },{ x=d ; y=e ; z=f },{ x=g ; y=h ; z=i },{ x=j ; y=k ; z=l }) ->
2018-02-14 19:23:23 +01:00
of_int a << b << c << d << e << f
<| g << h << i << j << k << l
2018-02-19 16:01:13 +01:00
| Nine ({ x=a ; y=b ; z=c },{ x=d ; y=e ; z=f },{ x=g ; y=h ; z=i }) ->
2018-02-14 19:23:23 +01:00
of_int a << b << c << d << e << f
<| g << h << i
2018-01-19 20:20:19 +01:00
2018-02-14 19:23:23 +01:00
let mask10 = 0x3ff
and mask15 = 0x7fff
2018-01-19 20:20:19 +01:00
2018-01-17 18:19:38 +01:00
(** Transform the Zkey into an int array *)
2018-02-14 19:23:23 +01:00
let to_int_array ~kind { left ; right } =
2018-01-17 18:19:38 +01:00
match kind with
2018-02-14 19:23:23 +01:00
| Kind_3 -> [|
mask15 land (right lsr 30) ;
mask15 land (right lsr 15) ;
mask15 land right
|]
| Kind_6 -> [|
mask10 land (right lsr 50) ;
mask10 land (right lsr 40) ;
mask10 land (right lsr 30) ;
mask10 land (right lsr 20) ;
mask10 land (right lsr 10) ;
mask10 land right
|]
| Kind_12 -> [|
mask10 land (left lsr 50) ;
mask10 land (left lsr 40) ;
mask10 land (left lsr 30) ;
mask10 land (left lsr 20) ;
mask10 land (left lsr 10) ;
mask10 land left ;
mask10 land (right lsr 50) ;
mask10 land (right lsr 40) ;
mask10 land (right lsr 30) ;
mask10 land (right lsr 20) ;
mask10 land (right lsr 10) ;
mask10 land right
|]
| Kind_9 -> [|
mask10 land (left lsr 20) ;
mask10 land (left lsr 10) ;
mask10 land left ;
mask10 land (right lsr 50) ;
mask10 land (right lsr 40) ;
mask10 land (right lsr 30) ;
mask10 land (right lsr 20) ;
mask10 land (right lsr 10) ;
mask10 land right
|]
2018-01-19 20:20:19 +01:00
2018-01-17 18:19:38 +01:00
2018-01-22 23:19:24 +01:00
(** Transform the Zkey into an int tuple *)
2018-02-19 16:01:13 +01:00
let to_powers ~kind { left ; right } =
2018-01-19 20:20:19 +01:00
match kind with
2018-02-19 16:01:13 +01:00
| Kind_3 -> Three (Powers.of_int_tuple (
2018-02-14 19:23:23 +01:00
mask15 land (right lsr 30) ,
mask15 land (right lsr 15) ,
mask15 land right
2018-02-19 16:01:13 +01:00
))
2018-02-14 19:23:23 +01:00
2018-02-19 16:01:13 +01:00
| Kind_6 -> Six (Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (right lsr 50) ,
mask10 land (right lsr 40) ,
mask10 land (right lsr 30)),
2018-02-19 16:01:13 +01:00
Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (right lsr 20) ,
mask10 land (right lsr 10) ,
mask10 land right )
)
2018-02-19 16:01:13 +01:00
| Kind_12 -> Twelve (Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (left lsr 50) ,
mask10 land (left lsr 40) ,
mask10 land (left lsr 30)),
2018-02-19 16:01:13 +01:00
Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (left lsr 20) ,
mask10 land (left lsr 10) ,
mask10 land left ) ,
2018-02-19 16:01:13 +01:00
Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (right lsr 50) ,
mask10 land (right lsr 40) ,
mask10 land (right lsr 30)),
2018-02-19 16:01:13 +01:00
Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (right lsr 20) ,
mask10 land (right lsr 10) ,
mask10 land right )
)
2018-02-19 16:01:13 +01:00
| Kind_9 -> Nine (Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (left lsr 20) ,
mask10 land (left lsr 10) ,
mask10 land left ) ,
2018-02-19 16:01:13 +01:00
Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (right lsr 50) ,
mask10 land (right lsr 40) ,
mask10 land (right lsr 30)),
2018-02-19 16:01:13 +01:00
Powers.of_int_tuple
2018-02-14 19:23:23 +01:00
( mask10 land (right lsr 20) ,
mask10 land (right lsr 10) ,
mask10 land right )
)
let hash = Hashtbl.hash
let equal
{ right = r1 ; left = l1 }
{ right = r2 ; left = l2 } =
r1 = r2 && l1 = l2
let cmp
{ right = r1 ; left = l1 }
{ right = r2 ; left = l2 } =
if r1 < r2 then -1
else if r1 > r2 then 1
else if l1 < l2 then -1
else if l1 > l2 then 1
else 0
let to_string ~kind { left ; right } =
"< " ^ string_of_int left ^ string_of_int right ^ " | " ^ (
to_int_array kind { left ; right }
2018-01-22 23:19:24 +01:00
|> Array.map string_of_int
|> Array.to_list
|> String.concat ", "
) ^ " >"
2018-02-14 20:00:12 +01:00
(*
2018-01-17 18:19:38 +01:00
let debug () =
and k3 = of_int_array Kind_3 [| 1 ; 2 ; 3 |]
and k6 = of_int_array Kind_6 [| 1 ; 2 ; 3; 4 ; 5; 6|]
and k12 = of_int_array Kind_12 [| 1 ; 2 ; 3; 4 ; 5; 6 ; 7 ; 8 ; 9 ; 10 ; 11; 12|]
in
print_endline @@ to_string Kind_3 k3 ;
print_endline @@ to_string Kind_6 k6 ;
print_endline @@ to_string Kind_12 k12
2018-02-14 19:23:23 +01:00
(*
< 65538 | 1, 2 >
< 1050627 | 1, 2, 3 >
< 281483566841860 | 1, 2, 3, 4 >
< 1128102155523078 | 1, 2, 3, 4, 5, 6 >
< 20809811751934310026571282435288076 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 >
*)
2018-01-17 18:19:38 +01:00
let () = debug ()
2018-02-14 20:00:12 +01:00
*)