type vecteur = int;;
type matrice = int list;;

(* Zolie fonction d'affichage (h=nombre de lignes) *)
(* L'algorithme est moche, mais y a pas trop d'autre solution que de arrayiser la liste, c'est stoqué dans le mauvais sens *)
let nthOfBinarint i n = if ((0b1 lsl n) land i)=0 then "0" else "1";;
let print_matrice h (matl:matrice) :unit =
	let mat = Array.of_list matl in
	let l = Array.length mat in
	print_string "┌";
	for i=0 to (l-1) do
		print_string (nthOfBinarint mat.(i) 0)
	done;
	print_endline "┐";
	for j=1 to (h-2) do
	print_string "│";
	for i=0 to (l-1) do
		print_string (nthOfBinarint mat.(i) j)
	done;
	print_endline "│";
	done;
	print_string "└";
	for i=0 to (l-1) do
		print_string (nthOfBinarint mat.(i) (h-1))
	done;
	print_endline "┘";;
let print_vecteur h x = print_matrice h [x];;

(* Effectue le produit matriciel 'matrice' . 'vecteur' *)
let produit (matrice:matrice) (vecteur:vecteur) :vecteur =
	let rec auxiliaire resultat_partiel masque = function
		| [] -> resultat_partiel
		| colonne :: reste ->
			let resultat =
				if masque mod 2 = 1
				then (lxor) colonne resultat_partiel
				else resultat_partiel
			in auxiliaire resultat (masque / 2) reste
	in auxiliaire 0 vecteur matrice
;;

(* Ne calcul papy *)
let deux_puissance = (lsl) 1;;


(* Construit la matrice identité de taille d.d *)
let identite d =
	let rec sub acc = function
		| p  when p >= 0 -> sub ((deux_puissance p) :: acc) (p-1)
		| _ -> acc
	in sub [] (d-1)
;;


(* Change l'état du 'i'-eme bit *)
let changer_bit i = (lxor) (deux_puissance i);;






(* Vérifie que 'y' respecte toutes les contraintes de 'cs' *)
(* Est-ce que pour tout P dans cs, P(cs) ? *)
let respecter y cs =
	let ny = (lnot) y in
	List.fold_right (fun c b -> b && (land) c ny > 0) cs true
;;

