xcsp3team / pycsp3

A Python Library for modeling combinatorial constrained problems
https://www.pycsp.org
MIT License
61 stars 9 forks source link

Strange xml generation for an intension constraint with distance expression #48

Closed wjsuijlenh closed 3 months ago

wjsuijlenh commented 3 months ago

Dear PyCSP3 developers,

I came across a strange XML generation behaviour regarding an intension expression of the form z == abs(x[y] - x[i]) for i in range(n), where x, y, z are variables and n is a constant. The generated expression in XML becomes eq(z,abs(neg(sub(aux_gb[0],%0)))).

I did not expect to see a neg in here.

If I swap the places places of x[y] and x[i], I get eq(z,dist(aux_gb[0], %0)) , which is perfect!

My guess is that you intended that the first case also had a similar conversion.

Here is a small self-contained Python code that demonstrates the behaviour

import pycsp3
from pycsp3 import *

n = 2
m = 3
x = VarArray(size = n, dom = range(m))
y = Var(dom = range(m))
z = Var(dom = range(m))
i = Var(dom = range(n))

satisfy(
  (y == abs(x[j] - x[i]) for j in range(n)),
  (z == abs(x[i] - x[j]) for j in range(n))
)

On today's master (9af123e1) this generates the following XML

<instance format="XCSP3" type="CSP">
  <variables>
    <array id="x" size="[2]"> 0..2 </array>
    <var id="y"> 0..2 </var>
    <var id="z"> 0..2 </var>
    <var id="i"> 0 1 </var>
    <array id="aux_gb" note="aux_gb[i] is the ith auxiliary variable having been automatically introduced" size="[1]"> 0..2 </array>
  </variables>
  <constraints>
    <group>
      <intension> eq(y,abs(neg(sub(aux_gb[0],%0)))) </intension>
      <args> x[0] </args>
      <args> x[1] </args>
    </group>
    <group>
      <intension> eq(z,dist(aux_gb[0],%0)) </intension>
      <args> x[0] </args>
      <args> x[1] </args>
    </group>
    <element>
      <list> x[0] x[1] </list>
      <index> i </index>
      <value> aux_gb[0] </value>
    </element>
  </constraints>
</instance>

To summarize, I would have expected that in the XML above, the first generated intension constraint would

  1. not contain a neg operation
  2. be similar to the second generated intension expression
xcsp3team commented 3 months ago

I didn't attempt to fix the problem at the source of the process generating the expression. I now impose some reasonable rules simplifying expressions, as e.g., abs(neg(.)) => abs(.) I have pushed the code, and now, regarding your example, you should get the same expressions. (we plan to make an update on Pypi by the end of August)

best.

wjsuijlenh commented 3 months ago

Nice! Thanks. I tried this morning's master branch (67ff8626) and it works now as expected.