Il suffit de vérifier que
Et on est ramené à échanger dans toutes les variables le Noir et le Blanc.
Par contre, le type tableau est ici plus simple : il suffit de parcourir
le tableau et d'intervertir les -1 et les -2, alors qu'on est obligé,
avec les references, de conserver une liste des variables
déjà rencontrées pour éviter de boucler en parcourant
l'arbre qui représente l'image. Cette technique est en fait à la
base de la plupart des routines écrites, avec de petites variantes.
C'est ici qu'appara^t l'intérêt du type Fantome, qui permet
d'instancier une image dont on ne conna^t pas encore les fils mais dont on
veut avoir une référence (c'est également ici qu'apparait
la nécessité des mutables.) On définit donc une
référence sur un Fantome, et ensuite seulement on affecte à
cette référence un Node avec la liste de ses fils.
let inverse im=
let deja_vues = ref [] in
let rec inverse_aux = function
(Color Blanc) -> ref (Color Noir)
| (Color Noir)->ref (Color Blanc)
| noeud -> try assq noeud !deja_vues
with Not_found -> let h = ref Fantome
in deja_vues := (neud, h)::(!deja_vues);
h := Node(map inverse_aux (fils i));
h
in !(inverse_aux im);;
Comme l'algorithme consiste à parcourir le graphe, il est en , et a
été implémenté en
Finalement, la routine d'inversion a été généralisée, puisqu'elle prend comme argument une fonction color image pour modifier chaque occurrence de Blanc ou Noir par l'image qui lui est associée.