• Aucun résultat trouvé

Dans cette section, nous montrons comment la chaîne de compilation XCSP3 (i.e., le format XCSP3 et son

écosystème, incluant les API JvCSP3 et PyCSP3 avec

leurs compilateurs) est connectée aux chaînes de com- pilation développées par la communauté PPC. Nous comparons tout d’abord XCSP3 à FlatZinc, et discu-

tons ensuite de MiniZinc [?] et Conjure [?].

3.1 FlatZinc

Avant de discuter des similarités et différences entre les chaînes XCSP3 et MiniZinc, focalisons nous tout

d’abord sur FlatZinc en considérant à nouveau le pro- blème 007 de CSPLib [?]. Un modèle (mzn), proposé par H. Kjellerstrand, est décrit par la figure 4. Ce modèle est équivalent à celui décrit en section2.1.

Lorsqu’il est compilé (libminizinc-2.2.3), avec n = 4, on obtient le fichier (fzn) FlatZinc donné par la figure 5.

Il est assez évident que FlatZinc n’est pas conçu pour être manipulé directement (ni même lu) par un humain, mais plutôt traité par des outils et solveurs. On peut également remarquer qu’une partie de la struc- ture est décomposée car des variables auxiliaires sont introduites et une analyse est nécessaire (avec éventuel- lement des annotations) pour reconstruire une expres- sion telle que diffs[k] = abs(x[k +1]−x[k]) pour tout

k. Par ailleurs, la compilation en MiniZinc est toujours

ajustée à un solveur cible (ceci est discuté plus loin). Cela signifie qu’il n’est pas prévu qu’un fichier FlatZinc généré soit lu par des solveurs différents. Pour faire une comparaison entre deux solveurs, la plupart du temps, il est nécessaire de partir de deux fichiers : le fichier mzn et le fichier dzn. En comparaison, avec XCSP3,

un seul fichier est nécessaire, et même si cela peut paraître assez mineur au premier regard, c’est assez pratique (et moins sujet à une erreur de manipulation). Pour finir, les fichiers XCSP3 sont généralement assez

compacts. Par exemple, les fichiers XCSP3 et FlatZinc

générés pour All-Interval avec n = 1000 ont comme taille respective 36Kb et 422Kb.

include " globals .mzn"; int: n;

array [1.. n] of var 1..n: x;

array [1..n -1] of var 1..n -1: diffs ; constraint all_different ( diffs ) /\ all_different (x) /\ forall (k in 1..n -1) ( diffs [k] = abs(x[k+1] - x[k]) ) /\ % symmetry breaking x[1] < x[n -1] /\ diffs [1] < diffs [2] ;

Figure 4 – Le fichier MiniZincBacp.mzn

3.2 MiniZinc et Conjure

MiniZinc et Conjure [?] sont deux chaînes de com- pilation populaires, visant à ajuster les modèles aux exigences des solveurs cibles. En MiniZinc, lorsqu’on interface un solveur spécifique à FlatZinc, il est possible de spécifier comment les contraintes (globales) doivent être considérées (reformulées), de manière à générer un fichier FlatZinc adéquat au solveur. Il est également pos- sible d’utiliser un outil (appelé globalizer) pour refor- muler automatiquement certaines parties des modèles. Un autre atout de MiniZinc est l’intégration possible de solveurs MIP (Mixed Integer Programming).

Conjure est un outil PPC qui peut automatique- ment lire des spécifications de problème abstraites données dans le langage Essence [?] et générer des modèles concrets dans le langage de modélisation Es- sence’ [?]. Ensuite, l’assistant de modélisation Savile Row [?] est capable de traduire les modèles Essen- ce’ sous des formes appropriées aux solveurs cibles (y compris, SAT). Savile Row applique automatiquement un certain nombre de techniques sophistiquées, telles que la ’common sub-expression elimination’ (CSE), qui remplace par des variables les expressions similaires trouvées dans les expressions.

Tandis que MiniZinc et Conjure se focalisent tous les deux à l’ajustement de compilation, le principal objectif de XCSP3 est d’être capable de représenter

des instances de problèmes sous une forme compacte, lisible et structurée, les rendant aussi proches que pos- sible des modèles originaux. Lorsque la compilation est lancée depuis PyCSP3, aucune reformulation ou

predicate all_different_int ( array [int] of var int: x); array [1..2] of int: X_INTRODUCED_7_ = [1 , -1];

var 1..4: X_INTRODUCED_0_ ; var 1..4: X_INTRODUCED_1_ ; var 1..4: X_INTRODUCED_2_ ; var 1..4: X_INTRODUCED_3_ ;

var -3..3: X_INTRODUCED_8_ :: var_is_introduced :: is_defined_var ; var 1..3: X_INTRODUCED_9_ :: var_is_introduced :: is_defined_var ; var -3..3: X_INTRODUCED_10_ :: var_is_introduced :: is_defined_var ; var 1..3: X_INTRODUCED_11_ :: var_is_introduced :: is_defined_var ; var -3..3: X_INTRODUCED_12_ :: var_is_introduced :: is_defined_var ; var 1..3: X_INTRODUCED_13_ :: var_is_introduced :: is_defined_var ; array [1..4] of var int: x:: output_array ([1..4]) =

[ X_INTRODUCED_0_ , X_INTRODUCED_1_ , X_INTRODUCED_2_ , X_INTRODUCED_3_ ]; array [1..3] of var int: diffs :: output_array ([1..3]) = [ X_INTRODUCED_9_ ,

X_INTRODUCED_11_ , X_INTRODUCED_13_ ]; constraint all_different_int ( diffs ); constraint all_different_int (x);

constraint int_abs ( X_INTRODUCED_8_ , X_INTRODUCED_9_ ):: defines_var ( X_INTRODUCED_9_ );

constraint int_abs ( X_INTRODUCED_10_ , X_INTRODUCED_11_ ):: defines_var ( X_INTRODUCED_11_ );

constraint int_abs ( X_INTRODUCED_12_ , X_INTRODUCED_13_ ):: defines_var ( X_INTRODUCED_13_ );

constraint int_lin_le ( X_INTRODUCED_7_ ,[ X_INTRODUCED_0_ , X_INTRODUCED_2_ ],-1); constraint int_lin_le ( X_INTRODUCED_7_ ,[ X_INTRODUCED_9_ , X_INTRODUCED_11_ ],-1); constraint int_lin_eq ([1 , -1 , -1] ,[ X_INTRODUCED_1_ , X_INTRODUCED_0_ , X_INTRODUCED_8_

] ,0)

:: defines_var ( X_INTRODUCED_8_ );

constraint int_lin_eq ([1 , -1 , -1] ,[ X_INTRODUCED_2_ , X_INTRODUCED_1_ , X_INTRODUCED_10_ ] ,0)

:: defines_var ( X_INTRODUCED_10_ );

constraint int_lin_eq ([1 , -1 , -1] ,[ X_INTRODUCED_3_ , X_INTRODUCED_2_ , X_INTRODUCED_12_ ] ,0)

:: defines_var ( X_INTRODUCED_12_ ); solve satisfy ;

Figure 5 – Le fichier FlatZincBacp.fzn transformation n’est appliquées. Il s’agit d’une forme

de compilation ’haute fidélité’. D’un côté, le principal avantage de la compilation ajustée est d’ajuster les modèles aux solveurs, tout en prêtant garde à l’effica- cité. De l’autre, le principal avantage de la compilation ’haute fidélité’ est de pouvoir tester la robustesse des sol-

veurs (une sorte de défi IA), tout en gardant les choses simples du point de vue de l’utilisateur. Il est à noter qu’on pourrait envisager pour des tâches spécifiques de construire des outils indépendants permettant de reformuler des instances XCSP3, avant ou au moment

du parsing, mais ceci n’est pas l’une de nos priorités. Pour conclure cette partie, nous tenons à souligner qu’il est facile d’éditer les fichiers XCSP3 pour tester

par exemple des modifications mineures. Par exemple, on peut facilement tester (lorsqu’on cherche à corriger un bug) si ajouter ou supprimer un tuple dans la liste

des supports (ou conflits) d’une contrainte table mo- difie le comportement du solveur. Également, on peut facilement éditer l’automate définissant une contrainte regular car son expression en XCSP3 est tout à fait

naturelle et lisible. Une alternative est de modifier le modèle et de relancer la compilation : cela est vrai pour les approches ajustées et haute-fidélité. Cepen- dant, l’utilisateur doit être très rigoureux, en s’assurant de récupérer le bon modèle original, le bon fichier de données, et avec les approches ajustées, éventuellement les bons fichiers de configuration (pour les contraintes globales) et les bonnes options de compilation. De plus, pour MiniZinc et Conjure, il est nécessaire de relancer la compilation pour chaque solveur devant être testé sur l’instance modifiée.

PyCSP3: modéliser des problèmes combinatoires sous contraintes en Python

4 Conclusion

À l’heure d’écrire cet article, environ 80 problèmes ont été modélisés avec PyCSP3. Les modèles sont en

règle générale (légèrement) plus compacts que ceux, équivalents, écrits en JvCSP3. Dans un futur proche,

nous prévoyons quelques extensions à ce travail, comme par exemple, offrir à l’utilisateur la possibilité d’écrire des contraintes en intention sous forme naturelle (infixe) comme « x = y + z ».

Remerciements

Ce travail a obtenu le soutien du projet CPER DATA de la région “Hauts-de-France”.

Références

[1] O. Akgun, A. Frisch, I. Gent, B. Hussain, C. Jefferson, L. Kotthoff, I. Miguel et P. Nightingale : Automated symmetry breaking and model selection in Conjure. In Proceedings of

CP’13, pages 107–116, 2013.

[2] C. Bessiere, P. Meseguer, E.C. Freuder et J. Larrosa : On Forward Checking for non-binary constraint satisfaction. Artificial Intelligence, 141: 205–224, 2002.

[3] F. Boussemart, C. Lecoutre et G. Aude- mard C. Piette : XCSP3 : an integrated for- mat for benchmarking combinatorial constrained problems. CoRR, abs/1611.03398, 2016.

[4] A. Frisch, M. Grum, C. Jefferson, B. Mar- tinez Hernandez et I. Miguel : The design of ESSENCE : A constraint language for speci- fying combinatorial problems. In Proceedings of

IJCAI’07, pages 80–87, 2007.

[5] E. Hebrard, E. O’Mahony et B. O’Sullivan : Constraint programming and combinatorial op- timisation in Numberjack. In Proceedings of

CPAIOR’10, pages 181–185, 2010.

[6] B. Hnich, Z. Kiziltan et T. Walsh : CSPLib Pro- blem 030 : Balanced academic curriculum problem.

http://www.csplib.org/Problems/prob030.

[7] H. Hoos : CSPLib Problem 007 : All-interval series. http://www.csplib.org/Problems/

prob007.

[8] C. Jefferson, I. Miguel, B. Hnich, T. Walsh et I. Gent : CSPLib : A problem library for constraints. http://www.csplib.org, 1999.

[9] C. Lecoutre : MCSP3 : Easy mo-

deling for everybody. Rapport technique, CRIL, 2018. https://github.com/xcsp3team/

XCSP3-Java-Tools/tree/master/doc.

[10] N. Nethercote, P. Stuckey, R. Becket, S. Brand, G. Duck et G. Tack : MiniZinc : Towards a standard CP modelling language. In

Proceedings of CP’07, pages 529–543, 2007.

[11] P. Nightingale, O. Akgün, I. Gent, C. Jeffer- son, I. Miguel et P. Spracklen : Automatically improving constraint models in Savile Row. Arti-

ficial Intelligence, 251:35–61, 2017.

[12] P. Nightingale et A. Rendl : Essence’ descrip- tion. Rapport technique arXiv :1601.02865, CoRR, 2016.

Actes JFPC 2019

Outline

Documents relatifs