09.07.2015 Views

FaCiLe - La Recherche - ENAC

FaCiLe - La Recherche - ENAC

FaCiLe - La Recherche - ENAC

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintes<strong>FaCiLe</strong> : librairie de contraintes pour un langage fonctionnel typéPascal Brisset<strong>La</strong>boratoire d’Optimisation Globale<strong>ENAC</strong> / CENA21 mars 2002P. Brisset 1


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesPlan1 Choix 22 Fonctionnalités de <strong>FaCiLe</strong> 83 Mise en œuvre 294 Invariants 375 Benchmarks 426 TODO 43P. Brisset 2


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesChoix1 ChoixQuoi : une librairie documentée en Objective CamlQui : Nicolas Barnier, Pascal BrissetPour qui : ceux qui ne supportent plus C++ ou PrologPourquoi : parce que Choco n’existait pas encore :-)P. Brisset 3


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesChoixwww.choco-constraints.net :<strong>FaCiLe</strong> est petite : moins de 5000 lignes<strong>FaCiLe</strong> est extensible : briques de bases, fonctorisation<strong>FaCiLe</strong> est efficace : presque<strong>FaCiLe</strong> est simple : comme son nom l’indique<strong>FaCiLe</strong> est gratuite : licence LGPLP. Brisset 4


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesChoix1.1 <strong>La</strong>ngageÉviter la « yet another language » approcheObjective Caml (caml.org) :langage fonctionnel fortement typé (pas de surcharge) ;compilateur natif ;porté sur de nombreuses plateformes ;licence à la LGPL ;efficace : www.bagley.org/~doug/shootoutP. Brisset 5


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesChoix1.2 InspirationsMALI, Machine Adaptée aux <strong>La</strong>ngages Indéterministes (Irisa, Rennes)ECLiPSe (ECRC, IC-Parc)ILOG SolverP. Brisset 6


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesChoix1.3 Licence LGPLUtilisable pour la recherche, l’enseignement et dans les applicationsindustrielles.Documentée extensivementDistribuée sous forme source ou paquetagePlatesformes : toutes celles supportées par OCaml (Linux, UNIXes,MacOS, Windows... / x86, Alpha, PPC, HPPA, IA64...)P. Brisset 7


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>2 Fonctionnalités de <strong>FaCiLe</strong>2.1 Un aperçuL’inévitable exemple : séquence magiquelet xs = Fd.array n 0 (n-1)let is_equal_to i x = fd2e x =~~ i2e iArray.iteri(fun i xi ->let cardi = Arith.sum (Array.map (is_equal_to i) xs) inCstr.post (fd2e xi =~ cardi))xsGoals.solve (Goals.Array.forall Goals.indomain xs)P. Brisset 8


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Légendelet xs = Fd.array n 0 (n-1)mot-clés et librairie standard d’OCaml en courriervaleurs prédéfinies de <strong>FaCiLe</strong> en grasvaleurs préfixées par le nom du module de définition (e.g. Fd)pas de parenthèses autour des arguments en MLIci, construction (et non déclaration) d’un tableau de variables de domainesintervalles.P. Brisset 9


£§¦¥£¨¢§¦¥£¨¢£©§§¦£¤¥£¨¢££¡¢¤£¤£¥¤£¥§¦¥£¨¢§¦ £¨¢¤£§¦ £¨¢¤£§¦¥£¨¢¦¢ £<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Typage fortfd2e x =~~ i2e iVariable vers expression fd2e :Constante vers expression i2e :Contrainte d’égalité =~ :Contrainte réifiée =~~ :Pas d’erreur à l’exécution ;pas d’ambiguïtés à la différence d’une solution avec surcharge.P. Brisset 10


¤©©¡¤¦§££ ¤¥¡¤¢¡¤¦¦¤¢¨¤¡¤¦¦¤¢¤¦¦¤¦§¢¨¤<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>ItérateursLibrairie standard d’OCaml :Array.map :<strong>FaCiLe</strong> :Goals.Array.forall :Itération conjonctive d’un but sur un tableau.Le langage nous offre la quantification et les agrégats :ClôtureFonctionnelles¤pas de syntaxe supplémentairelangage de modélisation¥¤¤ £ £¥¤Profil d’un programme utilisant <strong>FaCiLe</strong>P. Brisset 11


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>1. Création de domaine : Domain.create2. Création de variable : Fd.create, Fd.interval3. Création d’expressions : +~, Arith.sum4. Création de contraintes :


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Exécution d’un programme utilisant <strong>FaCiLe</strong>1. Toplevel :apprentissage (enseignement)mise au pointgénération de la documentation2. Compilation bytecode :rapidité de compilationmise au point : exécution pas à pas avec repriseportabilité3. Compilation native-code :efficacitéP. Brisset 13


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>2.2 Un tour completVariables :– domaine entier,– domaine ensembliste (à la Conjunto),– intervalle flottant ;Contraintes :– arithmétiques, ensemblistes,– réifiées, globales,– utilisateurs ;Buts (recherche en profondeur d’abord) :– et, ou, itérateurs,– branch & bound,– utilisateurs.P. Brisset 14


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>2.2.1 DomainesDomaines :entiers : liste d’intervalles ;ensemble d’entiers : intervalle de domaines d’entiers.Représentation fonctionnelle :pas de modification en place ;partage possible.P. Brisset 15


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>2.2.2 VariablesUne variable est soit :instanciée : une valeur (entier, ensemble, intervalle, ...)inconnue : un domaine et des événements attachés (ensembles decontraintes)Pour la gestion mémoire, il est essentiel que ces deux cas soient exclusifs.C’est le pattern-matching qui permet de faire le test :match Fd.value variable withVal x -> ...| Unk attr -> ...Quatre événements associés : instantiation, modification, min, maxP. Brisset 16


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>2.2.3 ContraintesFonction appelée lorsqu’un événement est schéduléUne contrainte peut-être :– postée– réveillée (propagation)– testée– niée– ...PrioritésConstraint store (non racine d’accès, pointeurs faibles)P. Brisset 17


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Contraintes arithmétiquesÉgalité et inégalité d’expressions :variableconstantesomme, produitvaleur absolueexponentiationdivision entière, moduloLes expressions sont systématiquement normalisées : factorisation,ordonnancement des sous-expressions, ...Les expressions booléennes (valeurs 0 ou 1) sont détectées et traitéesspécialement.P. Brisset 18


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Expressions et contraintes ensemblistes (Conjunto)cardinalunion, intersectionsous-ensemble, appartientinférieurtous-disjoints (globale)au-plus-un-en-commun (globale)...P. Brisset 19


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Contraintes réifiées<strong>La</strong> plupart des contraintes peuvent êtres réifiées en variables booléennes.let c = fd2e x =~ i2e 1729 inlet b = Reify.boolean c inCstr.post (fd2e y =~ i2e 42 *~ fd2e b)Indirectement, opérateurs sur les contraintes :(||~~) : Cstr.t -> Cstr.t -> Cstr.tP. Brisset 20


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Contraintes globalesFdArray.get, FdArray.min, FdArray.maxAlldiff : « tous différents » (algo de bin-matching)Gcc : « cardinalité » [Régin, 96]Sort : « tri » [Colmerauer, 97]P. Brisset 21


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Contrainte utilisateurlet different x y =let update _ =match (Fd.value x, Fd.value y) with(Val a, Val b) -> a b || Stak.fail "different"| (Val a, Unk attr_y) -> remove_value y attr_y a; true| (Unk attr_x, Val b) -> remove_value x attr_x b; true| _ -> falseand delay ct =Var.delay [Var.Attr.on_subst] x ct;Var.delay [Var.Attr.on_subst] y ctinCstr.create update delayP. Brisset 22


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>2.2.4 <strong>La</strong>ngage de butsUn but est une clôture évaluée paresseusement par un interpréteurGoals.solve. Le type correspondant est abstrait dans le module Goals.Conjonction et disjonction<strong>La</strong> boucle d’énumération disjonctive des valeurs d’une variable se définit :let enum x = (Goals.indomain x &&~ Goals.fail) ||~ Goals.successP. Brisset 23


£ ¤¤ ¨¡¡¤¡¡¦§ ¦ §¢£¥¤¢¢£¥¤¢<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Itérateurs À chaque structure de données est associée un itérateur.<strong>FaCiLe</strong> fournit les itérateurs compatibles avec le contrôle des buts :Goals.Array.forall :D’où grâce à l’application partielle :let labeling_array = Goals.Array.forall Goals.indomainlet labeling_matrix = Goals.Array.forall labeling_arrayP. Brisset 24


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>Optimisation par branch & bound<strong>Recherche</strong> avec contrainte dynamique sur une variable de coût. Deuxmodes :redémarrage à la racine à chaque solution ;continuation à chaque solution.P. Brisset 25


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>0-100-80-50-50-55Premiere solution Restart ContinueP. Brisset 26


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>But utilisateur1. Butification d’une fonction basique :Goals.atomic (fun () -> print_string "Hello World")2. But composé, éventuellement récursif :let rec iter_disj fgoal list =Goals.create(function[] -> Goals.fail| x::xs -> fgoal x ||~ iter_disj fgoal xs)list3. Cas particulier des but récursifs à argument constantlet repeat = Goals.create_rec (fun self -> Goals.success ||~ self)P. Brisset 27


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesFonctionnalités de <strong>FaCiLe</strong>À la PrologSuppression non-déterministe de l’élément d’une listedelete([X | Xs], X, Xs).delete([X | Xs], Y, [X | Ys]) :- delete(Xs, Y, Ys).avec <strong>FaCiLe</strong> :let rec delete l cont =Goals.create(function[] -> Goals.fail| x :: xs ->cont x xs ||~ delete xs (fun y ys -> cont y (x :: ys)))lP. Brisset 28


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvre3 Mise en œuvreMoins de 5000 lignes d’OCamlHiérarchie d’une douzaine de modules1600 lignes de signatures (interfaces) documentéesEncapsulation permettant de séparer signature interne (développeur) etexterne (utilisateur)P. Brisset 29


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvreDomainInteger finite domainsStackTrail, levels, backtrack, cutBacktrackable referencesArchitectureof <strong>FaCiLe</strong>VarAttributed variableRefine, susbtituteAttached constraintsCstrConstraints, eventsCreation, scheduling, wakingGoalsCreation, OR/AND controlIterators<strong>La</strong>belling, optimizationReifyReificationOperators on constraintsFdArrayArray of variablesIndexation, min, maxArithArithmetic expressionsGccGlobal cardinality constraintAlldiffAll different constraintSortingSorting constraintP. Brisset 30


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvre3.1 PileContinuation d’échec pour le retour-arrière :structurée en niveaux ;un niveau contient– une continuation de succès,– une traînée ;les éléments de la traînée sont des clôtures.Opérations :sauvegarde ;retour-arrière ;coupure.Le module fournit aussi un type de base : la référence backtrackableP. Brisset 31


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvrefailuretrail fun () -x.domain := old_domainx = 0||˜x¡0 &&˜ indomain xP. Brisset 32


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvre3.2 ContrainteUne collection de fonctions :delay : attachement à des événements après postupdate : propagations après réveilcheck (optionnel) : vérification (Oui, Non, NeSaitPas)not (optionnel) : négationfprint (optionnel) : affichageParamétrage du réveil :priorité associée à la contrainteidentification associée à l’événement (e.g. indice de la variableconcernée)P. Brisset 33


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvreExemple : contrainte sur un tableau de variableslet c = fun tab ->let n = Array.length tab inlet update i = if i < n then ... else ...and delay ct =List.iteri(fun i tabi ->Var.delay [Var.Attr.on_subst] tabi ~waking_id:i ct;Var.delay [Var.Attr.on_refine] tabi ~waking_id:(i+n) ct)tabinCstr.create ~priority:later ~nb_wakings:(2*n) update delayP. Brisset 34


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvreGestion des réveils :trois piles (trois priorités)à tout instant, un seul réveil possible par contrainte et par identificateurmarquage des contraintes résoluesLes contraintes actives sont stockées (utile pour détecter le floundering).<strong>La</strong> pile et le constraint store constituent un état global.P. Brisset 35


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvre3.3 <strong>Recherche</strong>Continuation de succès : une liste de clôturesContinuation d’échec : la pileL’échec est contrôlé avec le mécanisme natif d’exception.Sont associés au retour-arrière :un événement (utile pour le branch&bound) ;une fonction utilisateur (pouvant lever une exception).P. Brisset 36


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesMise en œuvre3.4 Variables : fonctorisationDOMAINmin, max,mem, remove...ATTRIBUTEmin, max,event, id...BASICVARmin, max,refine, array,subst, delay...includevalues, iter...VARBASICVARIntDomainIntAttrBasicIntVarIntVarSetDomainMakeAttrfunctorSetAttrMakeVarfunctorSetVarFloatDomainP. Brisset 37


£¢est une variable et£¡¤¡£¢¥¦¥§¨<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesInvariants4 InvariantsÀ la Localizer [Van Hentenryck 97] : maintenance d’équationsfonctionnelles pour la recherche localeoùvariables.¤un expression faisant intervenir d’autresUne modification deoü doit entrainer une mise à jour de¥£P. Brisset 38


¤en©©©££££¡¤¤¡¡¡¡¢£ £¡¢£ £¥¦§¨£¨¡©©¡£¡£¡<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesInvariantsLes équations doivent être maintenues efficacement :Pour la modification d’unen, recalcul :(sauf ancienne valeur à,)¤en © P. Brisset 39


¢£ ¤£¥¦¤¡¢¢¡£¡¢¤¡¡¢¢¤¢¥¢¢¥¡<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesInvariants4.1 Références invariantes dans <strong>FaCiLe</strong>Opérations de base : création, modification, accèsOpérateurs prédéfinis :– somme, produit– indexation, argmin dans un tableauEncapsulation de fonction quelconqueLiaison avec les variables à domaine : Inv.Fd.min, Inv.SetFd.max, ...P. Brisset 40


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesInvariants4.2 Utilisation des références invariantes<strong>Recherche</strong> locale pureMaintien de critère de choix pour la rechercheHybridation : à creuser...P. Brisset 41


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesInvariants4.3 Implémentation des références invariantesUne référence invariante :– une référence backtrackable– un événement activé lors d’une modificationNB : une référence invariante ne stocke pas d’« ancienne » valeurUne équation invariante :– une contrainte ... jamais résolueMécanisme précis de réveil ¤précision de la mise à jourLiaison avec les variables à domaines :– foncteur applicable à un module de variablesP. Brisset 42


¡<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesBenchmarks5 BenchmarksTemps en secondes sur Ultra Sparc pour <strong>FaCiLe</strong>, Ilog Solver 4.3 et ECLiPSe 5.2.Magic 100 200 400 8000.25 0.05 1.5 1.0 0.15 6.1 4.9 0.48 26 21 2Queens 16 32 64 1280.03 0.03 10 0.07 0.040.06 ¡¡0.26 1.2 0.2Golomb 6 7 8 90.04 0.04 0.18 0.33 0.11 1.2 3.3 0.75 11 30 7.0 99Golf 8-4-9 5-3-4 5-3-6 5-3-7gcc 2.0 0.7 5.3 370 100 373 1660 400 2146 243 62 521sort 2.1 – 9.5 380 – 14800 1740 – 11250 250 – 575sets 1.6 1.1 22 390 96 2215 3000 380 26093 380 240 4380P. Brisset 43


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesTODO6 TODORelease (ensembles, invariants, ...)Contraintes globales : edge-finding, ...<strong>Recherche</strong> : LDS, ...Compilation d’OPL vers <strong>FaCiLe</strong>Hybridation avec recherche locale (invariants)Programmation par intervalles pour les flottantsPublicitéP. Brisset 44


<strong>FaCiLe</strong> librairie fonctionnelle de programmation par contraintesTODOhttp://www.recherche.enac.fr/opti/facileP. Brisset 45

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!