From 1de7267256498e9a901129440d33e869bc970635 Mon Sep 17 00:00:00 2001 From: Jean-Guillaume Fages Date: Fri, 4 Aug 2023 23:55:40 +0200 Subject: [PATCH] pow and square refactoring the constraint logic should be in the constraint factory only --- .../constraints/IIntConstraintFactory.java | 20 +++++++++++++++++++ .../discrete/arithmetic/BiArExpression.java | 14 ++----------- .../discrete/arithmetic/UnArExpression.java | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/solver/src/main/java/org/chocosolver/solver/constraints/IIntConstraintFactory.java b/solver/src/main/java/org/chocosolver/solver/constraints/IIntConstraintFactory.java index fc844e9b25..249422c8f2 100644 --- a/solver/src/main/java/org/chocosolver/solver/constraints/IIntConstraintFactory.java +++ b/solver/src/main/java/org/chocosolver/solver/constraints/IIntConstraintFactory.java @@ -546,6 +546,9 @@ default Constraint pow(IntVar base, int exponent, IntVar result) { b = mm.get(C - mid); return ref().times(a, b, Y); /*/ + if (exponent == 2) { + return square(result, base); + } if ((exponent % 2) == 0) { return new Constraint(ConstraintsName.POWER, new PropPowEven(result, base, exponent)); } else { @@ -555,6 +558,23 @@ default Constraint pow(IntVar base, int exponent, IntVar result) { } } + default Constraint pow(IntVar base, IntVar exponent, IntVar result) { + if (exponent.isInstantiated()) { + return pow(base, exponent.getValue(), result); + } + // table decomposition todo as intension constraint + Tuples tuples = new Tuples(true); + for (int val1 : base) { + for (int val2 : exponent) { + int res = (int) Math.pow(val1, val2); + if (result.contains(res)) { + tuples.add(val1, val2, res); + } + } + } + return base.getModel().table(new IntVar[]{base, exponent, result}, tuples); + } + //################################################################################################################## //TERNARIES ######################################################################################################## //################################################################################################################## diff --git a/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/BiArExpression.java b/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/BiArExpression.java index 0e5b121e7e..f72cd84590 100644 --- a/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/BiArExpression.java +++ b/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/BiArExpression.java @@ -10,7 +10,6 @@ package org.chocosolver.solver.expression.discrete.arithmetic; import org.chocosolver.solver.Model; -import org.chocosolver.solver.constraints.extension.Tuples; import org.chocosolver.solver.variables.IntVar; import org.chocosolver.util.tools.VariableUtils; @@ -106,19 +105,10 @@ public IntVar intVar() { me = model.intVar(model.generateName("mod_exp_"), bounds[0], bounds[1]); model.mod(v1, v2, me).post(); break; - case POW: // todo as intension constraint + case POW: bounds = VariableUtils.boundsForPow(v1, v2); me = model.intVar(model.generateName("pow_exp_"), bounds[0], bounds[1]); - Tuples tuples = new Tuples(true); - for(int val1 : v1){ - for(int val2 : v2){ - int res = (int)Math.pow(val1, val2); - if(me.contains(res)) { - tuples.add(val1, val2, res); - } - } - } - model.table(new IntVar[]{v1, v2, me}, tuples).post(); + model.pow(v1, v2, me).post(); break; case MIN: bounds = VariableUtils.boundsForMinimum(v1, v2); diff --git a/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/UnArExpression.java b/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/UnArExpression.java index 8390431fa2..c3644aebdd 100644 --- a/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/UnArExpression.java +++ b/solver/src/main/java/org/chocosolver/solver/expression/discrete/arithmetic/UnArExpression.java @@ -90,7 +90,7 @@ public IntVar intVar() { case SQR: int[] bounds = VariableUtils.boundsForMultiplication(v, v); me = model.intVar(model.generateName("sqr_exp_"), bounds[0], bounds[1]); - model.times(v, v, me).post(); + model.square(me, v).post(); break; default: throw new UnsupportedOperationException("Unary arithmetic expressions does not support "+op.name());