type t = { bitstring : Z.t ; phase : Phase.t ; } let of_list l = let rec aux accu nperm = function | [] -> { bitstring = accu; phase = Phase.of_nperm nperm; } | i :: rest -> let i = pred i in let x = Z.(shift_left one i) in let accu = Z.logor accu x in let nperm = let mask = Z.(x-one) in let r = Z.logand accu mask in if r = Z.zero then nperm else nperm + (Z.popcount r) in aux accu nperm rest in List.rev l |> aux Z.zero 0 (* TODO Phase *) let rec to_list spindet = let rec aux accu z = if z <> Z.zero then let element = (Z.(trailing_zeros z)+1) in aux (element::accu) Z.(z land (pred z)) else List.rev accu in aux [] spindet let pp_bitstring ppf bs = String.init (Z.numbits bs) (fun i -> if (Z.testbit bs i) then '+' else '-') |> Format.fprintf ppf "@[%s@]" let pp_spindet ppf s = Format.fprintf ppf "@[%a %a@]" Phase.pp_phase s.phase pp_bitstring s.bitstring let test_case () = let test_creation () = let l_a = [ 1 ; 2 ; 3 ; 5 ] in let det = of_list l_a in Alcotest.(check (list int )) "bitstring" (to_list det.bitstring) l_a; Alcotest.(check bool) "phase" (det.phase = Phase.Pos) true; let l_b = [ 1 ; 3 ; 2 ; 5 ] in let det = of_list l_b in Alcotest.(check (list int )) "bitstring" (to_list det.bitstring) l_a; Alcotest.(check bool) "phase" (det.phase = Phase.Neg) true; in [ "Creation", `Quick, test_creation; ]