Le paramètre de position de l'image est implicite dans l'énoncé, il vaut initiallement (0,0) (en bas et à gauche enfin normalement), et va changer par la suite. On imagine donc écrite une fonction do_vers_arbre img i j k dont la mission est de transformer la sous-image carrée de coté k positionnée dans img en (i,j) en un arbre. L'appel initial est alors :
let image_vers_arbre k img = do_vers_arbre img 0 0 k ;;

Et voici do_vers_arbre :
let rec do_vers_arbre img i j k = if k <= 1 then Feuille img.(i).(j) else let k2 = k/2 in (* Je gagne 8 parenthèses *) let c1 = do_vers_arbre img i (j+k2) k2 and c2 = do_vers_arbre img (i+k2) (j+k2) k2 and c3 = do_vers_arbre img i j k2 and c4 = do_vers_arbre img (i+k2) j k2 in match c1,c2,c3,c4 with | Feuille n1, Feuille n2, Feuille n3, Feuille n4 when n1 = n2 && n2 = n3 && n3 = n4 -> c1 | _,_,_,_ -> Noeud (c1,c2,c3,c4) ;;
On remarque toujours au sujet du filtrage : Sur un autre plan, le paramètre img de do_vers_arbre ne change pas. On aurait donc pu économiser un argument à do_vers_arbre en utilisant une fonction locale :
let image_vers_arbre k img = let rec do_vers_arbre i j k = if k <= 1 then Feuille img.(i).(j) else let k2 = k/2 in let c1 = do_vers_arbre img i (j+k2) k2 ... in do_vers_arbre 0 0 k ;;
C'est affaire de goût et de nombre de paramètres essentiellement. (Noter quand même les aventures du paramètre k dans la version avec fonction locale obtenue par copier-coller, bel exemple d'innocuité de la liaison lexicale).