Solucion con 1 restriccion de igualdad declare %Declara una referencia o un procedimiento
proc {Money Root} %Procedimiento: Difinicion o llamado, declara las variables necesarias.
S E N D M O R Y %variables necesaria para la solucion del problema
in %Conectar con variable "root", afirmar restricciones, definir ramificacion
Root = sol(s:S e:E n:N d:D m:M o:O r:R y:Y) %Root: Argumento para las soluciones del problema a resolver Root ::: 0#9 %Root: Los campos de root son enteros en el dominio: {0,1,2,3,4,5,6,7,8,9}
S \=: E E \=: N N \=: D D\=: M M \=: O O \=: R R \=: Y %Tosas las variables tienen que ser diferentes
S \=:N E \=: D N \=: M D \=:O M \=: R O \=:Y S \=: D E \=: M N \=: O D \=: R M \=: Y S \=: M E \=:O N \=: R D \=: Y
S \=: O E \=: R N \=: Y S \=: R E \=: Y
S \=: Y
S \=: 0 %Los valores de las varibles S y M son diferentes de cero
M \=: 0
1000*S + 100*E + 10*N + D %Estas instrucciones seguientes son los digitos de las letras que satisfacen la ecuacion Send+More=Money
{FD.distribute naive Root} %define la distribucion
end
{ExploreAll Money} %Z={SearchOne Money}
%{Browse Z}
declare %Declara una referencia o un procedimiento
proc {Money Root} %Procedimiento: Definición o llamado, declara las variables necesarias.
S E N D M O R %variables necesaria para la solución del problema
in
Root = sol(s:S e:E n:N d:D m:M o:O r:R y:Y) %Root: Argumento para las soluciones del problema a resolver
Root ::: 0#9 %Root: Los campos de root son enteros en el dominio: {0,1,2,3,4,5,6,7,8,9}
{FD.distinct Root} % Estrategia de búsqueda
S \=: 0 %Los valores de las variables S y M son diferentes de cero M \=: 0
1000*S + 100*E + 10*N + D % Estas instrucciones siguientes son los dígitos de las letras que satisfacen la ecuación Send+More=Money
+ 1000*M + 100*O + 10*R + E =: 10000*M + 1000*O + 100*N + 10*E + Y
{FD.distribute ff Root} %Estrategia de búsqueda
end %Fin del programa, por ultimo calculara y mostrara la lista de todas las soluciones {exploreAll Money} %Llamado a la función principal Money de proc
____________________________________________________________________________________________________________________________
declare %Declara una referencia o un procedimiento
proc {Money2 Root} %Procedimiento: Definición o llamado, declara las variables necesarias.
S E N D M O R Y C1 C2 C3 C4 Carry %variables necesaria para la solución del problema c1, c2..c4 son las variables de los acarreos
in %Conectar con variable "root", afirmar restricciones, definir ramificación
Root = sol(s:S e:E n:N d:D m:M o:O r:R y:Y) % root es el que recibe las soluciones del problema a resolver, además es un disco que tiene campo para cada letra.
Carry = sol2(c1:C1 c2:C2 c3:C3 c4:C4)
Root ::: 0#9 %Root: Los campos de root son enteros en el dominio: {0,1,2,3,4,5,6,7,8,9} Carry ::: 0#1 %dominio de los acarreos
{FD.distinct Root} % Estrategia de búsqueda
S \=: 0 %Los valores de las variables S y M son diferentes de cero M \=: 0
D + E =: 10*C1 + Y % Estas instrucciones siguientes son los dígitos de las letras que satisfacen la ecuación Send+More=Money
C1 + N + R =: 10*C2 + E C2 + E + O =: 10*C3 + N C3 + S + M =: 10*C4 + O C4 =: M
{FD.distribute ff Root} %Estrategia de búsqueda
End %Fin del programa, por ultimo calculara y mostrara la lista de todas las soluciones %{Browse {SearchAll Money2}
____________________________________________________________________________________________________________________________ declare %Declara una referencia o un procedimiento
proc {Money3 Root} %Procedimiento: Definición o llamado, declara las variables necesarias.
S E N D M O R Y C1 C2 C3 C4 Carry %variables necesaria para la solución del problema c1, c2..c4 son las variables de los acarreos
in %Conectar con variable "root", afirmar restricciones, definir ramificación
Root = sol(s:S e:E n:N d:D m:M o:O r:R y:Y) % root es el que recibe las soluciones del problema a resolver, además es un disco que tiene campo para cada letra.
Carry = sol2(c1:C1 c2:C2 c3:C3 c4:C4)
Root ::: 0#9 %Root: Los campos de root son enteros en el dominio: {0,1,2,3,4,5,6,7,8,9}
Carry ::: 0#1 %dominio de los acarreos
S \=: E E \=: N N \=: D D \=: M M \=: O O \=: R R \=: Y %Tosas las variables tienen que ser diferentes
S \=: N E \=: D N \=: M D \=: O M \=: R O \=: Y S \=: D E \=: M N \=: O D \=: R M \=: Y
S \=: M E \=: O N \=: R D \=: Y S \=: O E \=: R N \=: Y
S \=: R E \=: Y S \=: Y
S \=: 0 %Los valores de las variables S y M son diferentes de cero M \=: 0
D + E =: 10*C1 + Y % Estas instrucciones siguientes son los dígitos de las letras que satisfacen la ecuación Send+More=Money
C1 + N + R =: 10*C2 + E C2 + E + O =: 10*C3 + N C3 + S + M =: 10*C4 + O C4 =: M
{FD.distribute ff Root} %Estrategia de busqueda
{ExploreOne Money3} %Llamado a la función principal Money de proc
____________________________________________________________________________________________________________________________
%%%%%%%%%%%%%% Solucion con 28 variables %%%%%%%%%%%%%%%%%%%%%%%%
% programa principal donde se ejecutan las instrucciones
6.declare
% procedimiento definicion o llamado declara las variables necesarias
proc {Money5 Root}
S E N D M O R Y C1 C2 C3 C4 Carry NRoot
Z
% conectar las variables y afirma las restricciones
In% root es el que recibe las soluciones del problema a resolver, además es un
disco que tiene campo para cada letra.
Root = sol(S E N D M O R Y) % 1 Carry = sol2(c1:C1 c2:C2 c3:C3 c4:C4) NRoot = {Width Root}
% dominio de las valores que que pueden tomar las variables(0,9)
Root ::: 0#9 Carry ::: 0#1
%funcion que recibe 3 parametros
{MakeTuple z NRoot-1 Z}
{For 1 NRoot-1 1 proc{$ I}
end }
{For 1 NRoot-1 1 proc {$ I}
{For I+1 NRoot 1 proc {$ J}
Root.I - Root.J =<: 10 - 11*Z.I.(J-I) Root.J - Root.I =<: 11*Z.I.(J-I) - 1 end
} end }
S \=: 0 % 4 M \=: 0
D + E =: 10*C1 + Y C1 + N + R =: 10*C2 + E C2 + E + O =: 10*C3 + N C3 + S + M =: 10*C4 + O C4 =: M
% controla la distribución de las soluciones
{FD.distribute ff Root}
%finaliza funcion
end
{ExploreOne Money5}
%% New Primitives
% programa principal donde se ejecutan las instrucciones
% procedimiento definicion o llamado declara las variables necesarias
proc {Money6 Root}S E N D M O R Y
% conectar las variables y afirma las restricciones
In% root es el que recibe las soluciones del problema a resolver, además es un
disco que tiene campo para cada letra.
Root = sol(s:S e:E n:N d:D m:M o:O r:R y:Y) {FD.dom 0#9 Root}
{FD.distinct Root} {FD.sum [S] '\\=:' 0} {FD.sum [M] '\\=:' 0} {FD.sumC
[1000 100 10 1 1000 100 10 1 ~10000 ~1000 ~100 ~10 ~1] [ S E N D M O R E M O N E Y] '=:'
0}
% controla la distribución de las soluciones
{FD.distribute ff Root} end
{ExploreAll Money6}
%%
%% Example: Queens %%
% programa principal donde se ejecutan las instrucciones
Declare
% procedimiento definicion o llamado declara las variables necesarias
proc {$ Row}
% Creando registros de tamaño N L1N ={MakeTuple c N}
%LM1N={MakeTuple c N}
% conectar las variables y afirma las restricciones
in%% Row = queens(n1:N1 n2:N2 n3:N3 ...) %% Row ::: 1#N
{FD.tuple queens N 1#N Row}
% controla la distribución de las soluciones
{FD.distinct Row}
{For 1 N-1 1 proc {$ I} {For I+1 N 1 proc{$ J}
Row.I - Row.J \=: I - J Row.I - Row.J \=: J - I end
} end }
{FD.distribute naive Row} end
end
{ExploreAll {Queens 8}}
%%
%% Example: Zebra Puzzle %%
Declare
% procedimiento definicion o llamado declara las variables necesarias
proc {Zebra Nb}
Groups = [ [english spanish japanese italian norwegian] [red green white yellow blue]
[painter sculptor diplomat violinist doctor] [dog snails fox horse zebra]
[tea coffee milk juice water] ]
Properties = {FoldR Groups Append nil}
proc {Partition Group}
{FD.distinct {Map Group fun {$ P} Nb.P end}} end
proc {Adjacent X Y}
{FD.distance X Y '=:' 1} end
in
%% Nb maps all properties to house numbers
{FD.record number Properties 1#5 Nb} {ForAll Groups Partition}
Nb.english =: Nb.red Nb.spanish =: Nb.dog Nb.japanese =: Nb.painter Nb.italian =: Nb.tea Nb.norwegian =: 1 Nb.green =: Nb.coffee Nb.green >: Nb.white Nb.sculptor =: Nb.snails Nb.diplomat =: Nb.yellow Nb.milk =: 3
{Adjacent Nb.norwegian Nb.blue} Nb.violinist =: Nb.juice
Nb.zebra =: Nb.white
% controla la distribución de las soluciones
{FD.distribute split Nb} end
{ExploreOne Zebra}
declare
fun {Knapsack Problem}
NumProducts = {Length Problem.values} DatosFuentes = Problem.knaspack in
proc {$ Sol}
sol(maxvalues: MaxValues = {FD.decl}
products: Products = {FD.list NumProducts 0#FD.sup})= Sol
in
% {FD.tuple product NumProducts 0#1 Products}
MaxValues = {FD.sumC Problem.values Products '=:'}
{ForAll {Arity DatosFuentes} proc {$ I}
Datos = DatosFuentes.I in
{FD.sumC Datos.obj Products '=<:' Datos.v} end}
{FD.distribute naive Products} end
end
Problem =
problem(knaspack: datos( r(v: 5 obj: [2 3 1 4]) ) values: [5 7 5 11])
{ExploreAll {Knapsack Problem}}
%% Example: Changing Money
declare
fun {ChangeMoney BillsAndCoins Amount}
Available = {Record.map BillsAndCoins fun {$ A#_} A end} Denomination = {Record.map BillsAndCoins fun {$ _#D} D end} NbDenoms = {Width Denomination}
in
proc {$ Change}
{FD.tuple change NbDenoms 0#Amount Change} {For 1 NbDenoms 1
proc {$ I} Change.I =<: Available.I end
}
{FD.sumC Denomination Change '=:' Amount}
{FD.distribute generic(order:naive value:max) Change} end
end
BillsAndCoins = bac(10#50 10#20 10#1)
{ExploreAll {ChangeMoney BillsAndCoins 60}}
{Browse {SearchOne {ChangeMoney BillsAndCoins 142}}}
{Browse {Length {SearchAll {ChangeMoney BillsAndCoins 142}}}}
%% Example: Coloring a Map
declare
fun {MapColoring Data}
Countries = {Map Data fun {$ C#_} C end} in
proc {$ Color}
NbColors = {FD.decl} in
{FD.distribute naive [NbColors]} %% Color: Countries --> 1#NbColors
{FD.record color Countries 1#NbColors Color} {ForAll Data
proc {$ A#Bs}
{FD.distribute ff Color} end
end
Data = [ austria # [italy switzerland germany]
belgium # [france netherlands germany luxemburg] france # [spain luxemburg italy]
germany # [france luxemburg netherlands] italy # nil
luxemburg # nil netherlands # nil portugal # nil
spain # [portugal]
switzerland # [italy france germany austria] ]
{ExploreOne {MapColoring Data}}
%% Example: Magic Squares
declare
fun {MagicSquare N} NN = N*N
L1N = {List.number 1 N 1} % [1 2 3 ... N] in
proc {$ Square} fun {Field I J}
Square.((I-1)*N + J) end
proc {Assert F}
% {F 1} + {F 2} + ... + {F N} =: Sum {FD.sum {Map L1N F} '=:' Sum}
end
Sum = {FD.decl} in
{FD.tuple square NN 1#NN Square} {FD.distinct Square}
%% Diagonals
{For 1 N 1
proc {$ I} {Assert fun {$ J} {Field I J} end} end} %% Rows
{For 1 N 1
proc {$ J} {Assert fun {$ I} {Field I J} end} end} %% Eliminate symmetries
{Field 1 1} <: {Field N N} {Field N 1} <: {Field 1 N} {Field 1 1} <: {Field N 1}
%% Redundant: sum of all fields = (number rows) * Sum NN*(NN+1) div 2 =: N*Sum
%%
{FD.distribute split Square} % {FD.distribute ff Square} end
end
{ExploreOne {MagicSquare 5}}
declare
proc {Crossword Z}
Hoses1 Laser1 Sails1 Sheet1 Steer1 Heel4 Hike4 Keel4 Knot4 Line4 Aft7 Ale7 Eel7 Lee7 Tie7 Hoses8 Laser8 Sails8 Sheet8 Steer8 Hoses2 Laser2 Sails2 Sheet2 Steer2 Hoses3 Laser3 Sails3 Sheet3 Steer3 Heel5 Hike5 Keel5 Knot5 Line5 Aft6 Ale6 Eel6 Lee6 Tie6 K
in
Z = sol1(hoses1:Hoses1 laser1:Laser1 sails1:Sails1 sheet1:Sheet1 steer1:Steer1 heel4:Heel4 hike4:Hike4
keel4:Keel4 knot4:Knot4 line4:Line4 aft7:Aft7 ale7:Ale7 eel7:Eel7 lee7:Lee7 tie7:Tie7 hoses8:Hoses8 laser8:Laser8 sails8:Sails8 sheet8:Sheet8 steer8:Steer8 hoses2:Hoses2 laser2:Laser2 sails2:Sails2 sheet2:Sheet2 steer2:Steer2 hoses3:Hoses3 laser3:Laser3 sails3:Sails3 sheet3:Sheet3 steer3:Steer3 heel5:Heel5 hike5:Hike5 keel5:Keel5
knot5:Knot5 line5:Line5 aft6:Aft6 ale6:Ale6 eel6:Eel6 lee6:Lee6 tie6:Tie6)
Z ::: 0#1
Z.aft7 + Z.ale7 + Z.eel7 + Z.lee7 + Z.tie7 =: 1 Z.hoses8 + Z.laser8 + Z.sails8 + Z.sheet8 + Z.steer8 =: 1 Z.hoses2 + Z.laser2 + Z.sails2 + Z.sheet2 + Z.steer2 =: 1 Z.hoses3 + Z.laser3 + Z.sails3 + Z.sheet3 + Z.steer3 =: 1 Z.heel5 + Z.hike5 + Z.keel5 + Z.knot5 + Z.line5 =: 1 Z.aft6 + Z.ale6 + Z.eel6 + Z.lee6 + Z.tie6 =: 1
thread
{FD.reified.sumC [Z.hoses1] [Z.sails2] '=:' 2} + {FD.reified.sumC [Z.hoses1] [Z.sheet2] '=:' 2} + {FD.reified.sumC [Z.hoses1] [Z.steer2] '=:' 2 } + {FD.reified.sumC [Z.laser1] [Z.sails2] '=:' 2 } + {FD.reified.sumC [Z.laser1] [Z.sheet2] '=:' 2 } + {FD.reified.sumC [Z.laser1] [Z.steer2] '=:' 2 } =<: 1
{FD.reified.sumC [Z.hoses1] [Z.sails3] '=:' 2} + {FD.reified.sumC [Z.hoses1] [Z.sheet3] '=:' 2} + {FD.reified.sumC [Z.hoses1] [Z.steer3] '=:' 2 } + {FD.reified.sumC [Z.sails1] [Z.sheet3] '=:' 2 } + {FD.reified.sumC [Z.sails1] [Z.steer3] '=:' 2 } =<:1
{FD.reified.sumC [Z.heel4] [Z.sails2] '=:' 2} + {FD.reified.sumC [Z.hike4] [Z.sheet2] '=:' 2} +
{FD.reified.sumC [Z.keel4] [Z.steer2] '=:' 2 } + {FD.reified.sumC [Z.knot4] [Z.sheet2] '=:' 2 } + {FD.reified.sumC [Z.line4] [Z.steer2] '=:' 2 } =<:1
{FD.reified.sumC [Z.heel4] [Z.heel5] '=:' 2} + {FD.reified.sumC [Z.hike4] [Z.hike5] '=:' 2} +{FD.reified.sumC [Z.keel4] [Z.keel5] '=:' 2 } + {FD.reified.sumC [Z.knot4] [Z.knot5] '=:' 2 } + {FD.reified.sumC [Z.line4]
[Z.line5] '=:' 2 } =<:1
end
{FD.distribute split Z} end
%{SearchOne Crossword} {ExploreOne Crossword}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% programa principal donde se ejecutan las instrucciones
declare
% función Golomb
% procedimiento definicion o llamado declara las variables necesarias
proc{$ X}
NumMark = Problem Z
% conectar las variables y afirma las restricciones
in
{FD.tuple x NumMark 0#FD.sup X}
{For 1 NumMark-1 1 proc{$ I}
X.I <: X.(I+1) end
}
{FD.tuple z NumMark*NumMark 1#FD.sup Z}
{FD.distinct Z}
{For 1 NumMark - 1 1 proc {$ I}
{For I+1 NumMark 1 proc {$ J}
Z.(I*(NumMark-1)+J) =: X.J - X.I
end } end
}
% controla la distribución de las soluciones
end