Skip to content

2.8.0: inconsistent behavior of partial functions and undefined values #760

Description

@matsc-at-sics-se

This behavior is consistent with the relational semantics [Section 2.2.7 of the Handbook]: division by zero gets silently treated as falsehood:

$ cat /tmp/foo.mzn
var -1 .. 1: D :: output_var;
var -1 .. 1: Q :: output_var = -1 div D;
$ minizinc -a /tmp/foo.mzn
D = -1;
----------
D = 1;
----------
==========

But if you narrow the domain of D to 0..0, the falsehood is not silent any more:

$ cat /tmp/foo.mzn
var  0 .. 0: D :: output_var;
var -1 .. 1: Q :: output_var = -1 div D;$ minizinc -a /tmp/foo.mzn
$ minizinc -a /tmp/foo.mzn
Warning: undefined result becomes false in Boolean context
  (division by zero)
/tmp/foo.mzn:2.1-28
  in variable declaration for 'Q'
  in binary 'div' operator expression
  in binary 'div' operator expression

Warning: model inconsistency detected
/tmp/foo.mzn:2.1-28
  in variable declaration for 'Q'
  in binary 'div' operator expression

=====UNSATISFIABLE=====

So in the first case it's silent, in the second case it's verbose. This is a bit inconsistent. The verbosity can get in the way. Please provide a way to turn off warnings.

Another odd thing: D and Q were annotated :: output_var but only D was output. Why?

Another example:

$ cat /tmp/foo.mzn 
var bool: P;
var  0 .. 1: D :: output_var;
var -1 .. 1: Q = if P then 1 else -1 div D endif  :: output_var;
output ["P = \(P);\n"];
output ["D = \(D);\n"];
output ["Q = \(Q);\n"];
$ minizinc -a /tmp/foo.mzn
P = true;
D = 0;
Q = 1;
----------
P = false;
D = 1;
Q = -1;
----------
P = true;
D = 1;
Q = 1;
----------
==========

Note the solution with D = 0 for which the constraint Q = if P then 1 else -1 div D endif contains a division by zero. Says Section 2.2.7: any undefinedness “bubbles up” to the closest Boolean context and becomes false there.
Apparently, the if-then-else-endif integer expression does not behave as a partial function in this respect. I did not expect a solution for D = 0.

Another example:

$ cat /tmp/foo.mzn
var -2.. -2 union 1..1: A;
constraint
    (((abs(A) - ((1 div 1) mod 0))=1) <-> false);
$ minizinc -a /tmp/foo.mzn
Error: result of evaluation is undefined: division by zero
/tmp/foo.mzn:3.6-47
  in binary '<->' operator expression
  in binary '=' operator expression
  in binary '-' operator expression
  in binary 'mod' operator expression

I expected the division by zero to bubble up, effectively turning the constraint into false <-> false. I expected to get two solutions but got none.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    resolvedIssue is resolved and the feature or fix will be part of next release

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions