On se donne deux représentations différentes des complexes:
cartesienpolairetype cartesien = {re: float; im: float}
type polaire = {modulus: float; arg: float}
polaire_to_cartesien qui convertit un complexe sous forme polaire vers sa représentation cartésienne.cartesien_to_polaire qui convertit un complexe sous forme cartésienne vers sa représentation polaire. On rappelle l'existence de la fonction atan2 telle que atan2 y x renvoie une mesure de l'angle entre le vecteur directeur de l'axe des abscisses et le vecteur de coordonnées (x, y).complexe qui permet de travailler simultanément sur les deux représentations possibles.conj qui renvoie le conjugué d'un complexe. Le type de la fonction doit donc être complexe -> complexe.add: complexe -> complexe -> complexe qui calcule la somme de deux nombres complexes.mul: complexe -> complexe -> complexe qui calcule le produit de deux nombres complexes.Un tas, aussi appellé file de priorité est une structure de données qui dispose des opérations suivantes:
get_min : renvoie le plus petit élément du tasremove_min : enlève le plus petit élément du tasinsert x : ajoute l'élément x au tas Un tas d'appariement (en anglais pairing heap) est un tas qui admet facilement une implémentation "purement fonctionnelle" (on dira plutôt persistante, au sens où on ne modifie pas de manière visible la structure de données, on en obtient toujours une copie avec la mise à jour effectuée). On supposera dans la suite pour simplifier que les éléments d'un tas sont des entiers (on verra plus tard comment on pourrait généraliser de manière propre à un ensemble ordonné quelconque).
pairing_tree permettant de représenter un arbre d'appariement.pairing_heap.get_min.merge2 : pairing_heap -> pairing_heap -> pairing_heap qui fusionne deux tas.

insert: int -> pairing_heap -> pairing_heap. Pour cela on crée un nouveau tas avec l'élément à insérer et on le fusionne avec le tas passé en paramètre.remove_min: pairing_tree -> pairing_heap n'est définie que sur un tas non vide (donc un arbre). Il suffit de fusionner tous les fils de la racine. On doit donc définir une fonction auxiliaire merge: pairing_tree list -> pairing_heap qui fusionne un nombre arbitraire d'arbres. On procède par récurrence sur le nombre d'arbres en utilisant la fonction merge2 définie précédemment:t1 et t2 et encore une liste tl d'autres arbres, on fusionne d'une part t1 et t2, d'autre part on fusionne tl par récurrence, puis on fusionne ces deux tas fusionnés.from_list qui crée un tas d'appariement à partir d'une listeto_list qui crée la liste (ordonnée) des éléments d'un tas d'appariementheap_sort qui trie une liste par l'algorithme du tri par tas.On représente un monôme par son coefficient (non nul) et son degré. Un polynôme "creux" (avec beaucoup de coefficients à zéro) est représenté succinctement par la liste de ses monômes non nuls triée par degrés décroissants.
type monome = {coeff: float; deg: int}
type polynome = monome list
Remarquez que le type polynome est un alias du type monome list. On verra plus tard comment abstraire et rendre opaque un type tel que polynome pour mieux mettre en avant le fait qu'un polynôme est une liste de monômes qui vérifie certains invariants, et non une liste quelconque de monômes. Mais comme c'était déjà le cas dans l'exercice précédent, toutes les opérations que nous allons définir sur ce type concret devront préserver ces invariants.
degree qui renvoie le degré d'un polynôme.degree? Pouvons-nous y faire quelque chose?++ qui réalise la somme de deux polynômes.~~ qui renvoie l'opposé d'un polynôme. En déduire l'opérateur -- qui réalise la différence de deux polynômes.mult_monome qui réalise le produit d'un monôme et d'un polynôme. En déduire l'opérateur ** qui réalise le produit de deux polynômes.// qui réalise la division euclidienne de deux polynômes.monomes_to_polynome qui prend en argument une liste de monômes sans aucune contrainte et qui renvoie le polynôme qui correspond à leur somme.