1%---------------------------------------------------------------------- 2% BEGIN LICENSE BLOCK 3% Version: CMPL 1.1 4% 5% The contents of this file are subject to the Cisco-style Mozilla Public 6% License Version 1.1 (the "License"); you may not use this file except 7% in compliance with the License. You may obtain a copy of the License 8% at www.eclipse-clp.org/license. 9% 10% Software distributed under the License is distributed on an "AS IS" 11% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 12% the License for the specific language governing rights and limitations 13% under the License. 14% 15% The Original Code is The Zinc Modelling Interface for ECLiPSe 16% The Initial Developer of the Original Code is Joachim Schimpf 17% Portions created by the Initial Developer are 18% Copyright (C) 2007 Cisco Systems, Inc. All Rights Reserved. 19% 20% Contributor(s): Joachim Schimpf 21% 22% END LICENSE BLOCK 23%---------------------------------------------------------------------- 24 25:- module(fzn_eplex). 26 27:- comment(categories, ["Interfacing","Constraints"]). 28:- comment(summary, "Mapping from FlatZinc to lib(eplex)"). 29:- comment(author, "Joachim Schimpf, supported by Cisco Systems and NICTA Victoria"). 30:- comment(copyright, "Cisco Systems Inc, licensed under CMPL"). 31:- comment(date, "$Date: 2009/07/16 09:11:24 $"). 32:- comment(see_also, [library(flatzinc),library(eplex)]). 33:- comment(desc, html(" 34This module defines a mapping from FlatZinc operations to lib(eplex) 35and is intended to be used in conjunction with lib(flatzinc). 36</P><P> 37TODO: Add a mapping for sets as array of booleans. 38Add an appropriate globals.mzn. 39<P> 40")). 41 42 43% Lazy person's way of exporting (almost) all locally defined predicates: 44:- local initialization( 45 ( 46 current_module_predicate(local, Pred), 47 get_flag(Pred, auxiliary, off), 48 nonmember(Pred, [eplex_opt/3, vector_sum/3]), 49 export(Pred), 50 fail 51 ; 52 true 53 )). 54 55:- lib(eplex). % the actual solver library 56 57:- import 58 fzn_write/2, 59 fzn_error/2 60 from flatzinc. 61 62 63% Declarations ----------------------------------------------- 64 65% Single variable declarations 66bool_declare(X) :- X $:: 0..1, integers(X). 67int_declare(X) :- integers(X). 68float_declare(X) :- reals([X]). 69int_declare(X, Min, Max) :- X $:: Min..Max, integers(X). 70float_declare(X, Min, Max) :- X $:: Min..Max. 71 72% Variable array declarations 73% Unfortunately not all primitives can handle arrays 74bool_declare_array(Xs) :- ( foreacharg(X,Xs) do X $:: 0..1, integers(X) ). 75int_declare_array(Xs) :- ( foreacharg(X,Xs) do integers(X) ). 76float_declare_array(Xs) :- ( foreacharg(X,Xs) do reals(X) ). 77int_declare_array(Xs, Min, Max) :- 78 ( foreacharg(X,Xs), param(Min,Max) do X $:: Min..Max, integers(X) ). 79float_declare_array(Xs, Min, Max) :- 80 ( foreacharg(X,Xs), param(Min,Max) do X $:: Min..Max ). 81 82 83% Comparisons ----------------------------------------------- 84 85% int_??(var int, var int) 86int_eq(X, Y) :- X $= Y. 87int_le(X, Y) :- X $=< Y. 88int_ge(X, Y) :- X $>= Y. 89 90% float_??(var float, var float) 91float_eq(X, Y) :- X $= Y. 92float_le(X, Y) :- X $=< Y. 93float_ge(X, Y) :- X $>= Y. 94 95% bool_??(var bool, var bool) 96bool_eq(X, Y) :- X $= Y. 97bool_le(X, Y) :- X $=< Y. 98bool_ge(X, Y) :- X $>= Y. 99 100 101% int_lin_??(array[int] of int, array[int] of var int, int) 102int_lin_eq(Cs, Xs, Rhs) :- vector_sum(Cs, Xs, CXs), sum(CXs) $= Rhs. 103int_lin_le(Cs, Xs, Rhs) :- vector_sum(Cs, Xs, CXs), sum(CXs) $=< Rhs. 104int_lin_ge(Cs, Xs, Rhs) :- vector_sum(Cs, Xs, CXs), sum(CXs) $>= Rhs. 105 106% float_lin_??(array[int] of float, array[int] of var float, float) 107float_lin_eq(Cs, Xs, Rhs) :- vector_sum(Cs, Xs, CXs), sum(CXs) $= Rhs. 108float_lin_le(Cs, Xs, Rhs) :- vector_sum(Cs, Xs, CXs), sum(CXs) $=< Rhs. 109float_lin_ge(Cs, Xs, Rhs) :- vector_sum(Cs, Xs, CXs), sum(CXs) $>= Rhs. 110 111 vector_sum(Cs, Xs, CXs) :- 112 arity(Cs, N), 113 ( arity(Xs, N) -> 114 ( for(I,1,N), foreach(C*X,CXs), param(Cs,Xs) do 115 arg(I, Cs, C), arg(I, Xs, X) 116 ) 117 ; 118 fzn_error("Mismatched vector product %w %w", [Cs, Xs]) 119 ). 120 121 122% Arithmetic operations ----------------------------------------------- 123 124% int_???(var int, var int, var int) 125int_negate(X, Z) :- Z $= -X. 126int_plus(X, Y, Z) :- Z $= X+Y. 127int_minus(X, Y, Z) :- Z $= X-Y. 128 129% float_???(var float, var float, var float) 130float_negate(X, Z) :- Z $= -X. 131float_plus(X, Y, Z) :- Z $= X+Y. 132float_minus(X, Y, Z) :- Z $= X-Y. 133 134 135% Logical operations ----------------------------------------------- 136 137 138% Set operations ----------------------------------------------- 139 140 141% Array operations ----------------------------------------------- 142 143 144% Coercion operations ----------------------------------------------- 145 146int2float(I, F) :- ( var(I) -> F=I ; F is float(I) ). 147bool2int(X, X). 148 149 150% FZN data <-> ECLiPSe data ----------------------------------------------- 151 152bool_fzn_to_solver(false, 0). 153bool_fzn_to_solver(true, 1). 154 155bool_solver_to_fzn(0, false). 156bool_solver_to_fzn(1, true). 157 158% model floats are just solver floats 159float_fzn_to_solver(X, X) :- float(X). 160 161float_solver_to_fzn(X, X) :- real(X). 162 163% Set constants are ordered lists (pars only) 164set_fzn_to_solver(List, Set) :- 165 sort(List, Set). 166 167set_solver_to_fzn(List, List) :- is_list(List). 168 169% Set constants are ordered lists (pars only) 170range_fzn_to_solver(Min, Max, Set) :- 171 ( for(I,Min,Max), foreach(I,Set) do true ). 172 173 174% Search ----------------------------------------------- 175 176satisfy(Anns) :- 177 eplex_opt(min(0), Anns, _Cost). 178 179minimize(Expr, Anns, Cost) :- 180 eplex_opt(min(Expr), Anns, Cost). 181 182maximize(Expr, Anns, Cost) :- 183 eplex_opt(max(Expr), Anns, Cost). 184 185 eplex_opt(Obj, _Anns, Cost) :- 186 eplex_solver_setup(Obj), 187 eplex_solve(Cost), 188 eplex_get(vars, Vars), 189 eplex_get(typed_solution, Vals), 190 eplex_cleanup, 191 Vars=Vals. 192 193