Voir le fichier install dans le répertoire source.
pour windows : voir le fichier install.win dans le répertoire source.
Moca est un générateur de fonctions de construction pour des types de données caml avec invariants.
Moca permet la définition et le traitement automatique d'invariants complexes des structures de données. de surcroît, moca est capable de générer des fonctions de constructions qui produisent des valeurs maximalement partagées.
Un type de données relationnel est un type de données concrets qui déclare des invariants ou des relations qui sont vérifiés par ses constructeurs. pour chaque définition de type relationnel, moca compile un ensemble de fonctions de construction qui implémente les relations déclarées.
Moca admet deux espèces de relations:
Les relations algébriques sont primitives en moca et leur traitement est donc correct (sauf erreur à signaler d'urgence). au contraire, les règles de réécriture générales sont sous la responsabilité pleine et entière du programmeur; en conséquence les propriétés attendues des règles doivent être soigneusement étudiées (ou mieux prouvées) avant la compilation (en particulier la terminaison, la complétude et la confluence du système de réécriture engendré).
Les invariants algébriques sont spécifiés à l'aide de mot-clés dénotant des théories équationnelles comme la commutativité et l'associativité. les fonctions de constructions générées par moca permettent alors de représenter chaque classe d'équivalence par une unique valeur, son représentant canonique.
Le compilateur mocac lit un
fichier .mlm
(ou .mlms
) et
produit un module objective caml (fichier d'interface + fichier
d'implementation).
Un fichier .mlm(s)
est semblable à un fichier
d'interface .mli
habituel: il doit définir un type
(privé), avec la possibilité supplémentaire de déclarer les relations
algébriques qui sont vérifiées par les constructeurs.
Mocac génère alors les fonctions de constructions pour les
constructeurs, de telle sorte que les relations sont effectivement vérifiées
pour toutes les valeurs du type défini.
Les définitions de type de moca ont la même syntaxe que
celles d'objective caml avec des annotations supplémentaires pour les relations
algébriques associées aux constructeurs définis dans le type. ces annotations
apparaissent entre les mots clés begin
et end
.
Pour obtenir un partage maximal des données construites par les fonctions de
construction, il suffit d'utiliser l'option spéciale --sharing
du
compilateur mocac.
Cette option est automatiquement utilisé lorsqu'un
fichier .mlms
est donné en argument.
Il suffit d'appeler mocac avec pour argument votre fichier
.mlm(s)
.
Sous windows : appeler sh mocac avec pour argument votre
fichier .mlm(s)
.
Voici une définition pour un type de données qui représente les valeurs d'un
groupe additif. le groupe comporte une opération binaire add
, un
élément neutre zero
, un opérateur unaire pour l'opposé
opp
, et un générateur one
:
type t = private | zero | one | opp of t | add of t * t begin associative commutative neutral (zero) opposite (opp) end ;;
Les propriétés algébriques des opérateurs du groupe sont ici portées par
l'opération binaire add
. les mots clés associative
,
commutative
, neutral
et opposite
sont
spécifiques à moca et confèrent les propriétés habituelles
correspondantes au constructeur add
.
Si l'on suppose que ce code est dans le fichier group.mlm
,
alors la commande mocac group.mlm
génère le module
group
sous la forme des deux fichiers group.mli
et
group.ml
.
Le fichier d'interface group.mli
déclare le type privé
t
qui est le support des valeurs du groupe et déclare la signature
des fonctions de construction associées aux constructeurs:
type t = private | zero | one | opp of t | add of t * t ;; val add : t * t -> t;; val one : t;; val opp : t -> t;; val zero : t;;
Le fichier d'implémentation group.ml
définit le type
t
et les fonctions de construction correspondantes. son contenu
est équivalent à:
type t = | zero | one | opp of t | add of t * t ;; let rec add z = match z with | (zero, y) -> y | (x, zero) -> x | (add (x, y), z) -> add (x, add (y, z)) | (opp x, y) -> insert_inv_add x y | (x, opp y) -> insert_inv_add y x | (x, y) -> insert_inv_add (opp x) y and delete_add x u = match u with | add (y, _) when x < y -> raise not_found | add (y, t) when x = y -> t | add (y, t) -> add (y, delete_add x t) | _ when u = x -> zero | _ -> raise not_found and insert_inv_add x u = try delete_add x u with | not_found -> insert_add (opp x) u and insert_add x u = match u with | add (y, _) when x < y -> add (x, u) | add (y, t) -> add (y, insert_add x t) | _ when x > u -> add (u, x) | _ -> add (x, u) and one = one and opp x = match x with | zero -> zero | opp x -> x | add (x, y) -> add (opp x, opp y) | _ -> opp x and zero = zero;;
Les valeurs du type t
sont maintenant toutes correctement
normalisées selon les règles des groupes (autrement dit, il n'existe pas de
valeur du type t
qui ne soit normalisée). par exemple:
# add (one, add (zero, opp one));; - : t = zero
Le répertoire examples
de la distribution contient de nombreux
autres exemples de structures de données traitées par moca.
Moca étend la syntaxe des définitions de type de caml de la manière suivante:
constr-decl | ::= | constr-name [ annotation ] |
| | constr-name of typeexpr [ annotation ] |
annotation | ::= | begin { relation }+ end |
side | ::= | left |
| | right |
invopp | ::= | inverse |
| | opposite |
rpo_status | ::= | lex |
| | mul |
completion_hint | ::= | precedence int |
| | status rpo_status |
relation | ::= | commutative [ ( comp ) ] |
| | associative | |
| | involutive | |
| | idempotent [side] | |
| | nilpotent [side] | |
| | neutral [side] ( constr-name ) | |
| | absorbent [side] ( constr-name ) | |
| | absorbing [side] ( constr-name ) | |
| | distributive [invopp] [side] ( constr-name [,constr-name] ) | |
| | rule pattern -> pattern |
Nous donnons la théorie équationnelle qui correspond à chaque mot-clé et les propriétés des représentants des classes d'équivalence générés par moca.
(pervasives.compare)
.
c
est commutative
(comp)
,c (x, y) = c (y, x)
et, pour chaque valeur filtrant
c (x, y)
, comp x y < 0
.
comp
est l'identifiant d'une fonction de
comparaison donnée par l'utilisateur.
c
est associative,c (c (x, y), z) = c (x, c (y, z))
et aucune valeur n'est
filtrée par c (c (x, y), z)
.c
est involutive,c (c (x)) = x
et aucune valeur n'est filtrée par c
(c (x))
.idempotent left
et idempotent
right
.c
est idempotent
left,c (x, c (x, y)) = c (x, y)
et aucune valeur n'est
filtrée par c (x, c (x, y))
.c
est idempotent
right,c (c (x, y), y) = c (x, y)
et aucune valeur n'est
filtrée par c (c (x, y), y)
.c
est idempotent
,c (c (x)) = x
et aucune valeur n'est filtrée par c
(c (x))
.(d)
neutral left (d)
et neutral right
(d)
.c
est neutral left
(d)
,c (d, x) = x
et aucune valeur n'est filtrée par c
(d, x)
.c
est neutral right
(d)
,c (x, d) = x
et aucune valeur n'est filtrée par c
(x, d)
.nilpotent left (a)
et nilpotent
right (a)
.c
est nilpotent
left(a)
,c (x, c (x, y)) = a
et aucune valeur n'est
filtrée par c (x, c (x, y))
.c
est nilpotent
right(a)
,c (c (x, y), y) = a
et aucune valeur n'est
filtrée par c (c (x, y), y)
.(i, e)
(i, e)
et inverse right
(i, e)
.c
est inverse left
(i, e)
,c (i (x), x) = e
et aucune valeur n'est filtrée par
c (i (x), x)
.c
est inverse right
(i, e)
,c (x, i (x)) = e
et aucune valeur n'est filtrée par
c (x, i (x))
.c
est
neutral [side] (e)
,inverse [side'] (i)
est
équivalent à inverse [side'](i, e)
.c
est
inverse [side](i, e)
et absorbent
[side'](a)
,c
lève l'exception Failure "Division by Absorbent"
quand un
des arguments est a
.(d, e)
distributive left(d, e)
et
distributive right(d, e)
.(d)
distributive (d, d)
.c
est distributive left
(d, e)
,c (d (x, y), z) = e (c (x, z), c (y, z))
et aucune
valeur n'est filtrée par c (d (x, y), z)
.c
est
distributive right
(d)
,c (z, d (x, y)) = e (c (z, x), c (z, y))
et aucune
valeur n'est filtrée par c (z, d (x, y))
.c
est
distributive inverse left
(d, e)
,
c (d (x, y), z) = e (c (y, z), c (x, z))
et aucune
valeur n'est filtrée par c (d (x, y), z)
.(a)
absorbent left(a)
et absorbent
right(a)
.c
est absorbent left
(a)
,c (a, x) = a
et aucune valeur n'est filtrée par c
(a, x)
.c
est absorbent right
(a)
,c (x, a) = a
et aucune valeur n'est filtrée par c
(x, a)
.(d)
absorbing left(d)
et absorbing
right(d)
.c
est absorbing left
(d)
,c (d (x, y), y) = y
et aucune valeur n'est filtrée par
c (d (x, y), y)
.c
est absorbing right
(d)
,c (x, d (x, y)) = x
et aucune valeur n'est filtrée par
c (x, d (x, y))
.c
est
rule l -> r
,
c (l) = r
et aucune valeur n'est filtrée par c
(l)
.r
sont remplacés par des appels aux
fonctions de construction correspondantes, et les simplifications induites par
ces annotations sont appliquées autant que possible et en priorité. en présence
d'une telle annotation, le code généré n'est plus garanti correct
ni même convergent.Lors de l'utilisation de la complétion (expérimentale) dans Moca , certains paramètres peuvent être spécifiés dans le code source par les mots-clés suivants:
c
a status s
,
c
aura le
status s
,
c'est-à-dire lexicographique (lex) ou
multi-ensemble (mul), pour l'ordre RPO
lors de la complétion.
c
a precedence i
,
i
dans l'ordre sur
les entiers qui induira l'ordre de précédence sur les symboles.
On the implementation of
construction functions for non-free concrete data types,
F. Blanqui, T. Hardin and P. Weis, ESOP'07.
Télécharger: [ps],
[pdf],
[dvi].
Cliquez ici pour voir les transparents des présentations sur Moca.
Moca est développé actuellement dans le cadre de l'arc quotient. Pour plus d'information, voir le site de l'ARC ici.
Si vous voulez contacter les implémenteurs, écrivez à Pierre Weis ou Frédéric Blanqui.
Fichier créé le 11 avril 2005.
Dernière modification le
mercredi 13 février 2008.
Copyright
© 2005 - 2008 INRIA, tous droits réservés.