Skip to content

Function Recursion - Wrong order of Evaluation #177

Closed
@schutta

Description

@schutta

I have this model test_recursion.mzn, in which the recursive function get_max is defined.

int: n = 3;
set of int: I = 1..n;
array[I] of int: x = [1, 6, 6]; 
array[I] of int: y = [4, 5, 7]; 

function int: get_max(int: xx, int: yy_max, int: i) = 
    if i > n then
        yy_max
    elseif x[i] = xx then
        let {
            int: new_yy_max = max(yy_max, trace("i = \(i)\n", y[i])),
            int: new_i = i + 1,
        } in get_max(xx, new_yy_max, new_i)
    else
        get_max(xx, yy_max, i + 1)
    endif;

set of int: X = { x[i] | i in I };
array[int] of int: dur = [ get_max(s, 1, 1) | s in X ];

solve satisfy;

Using MiniZinc 2.1.5 with this command mzn2fzn test_recursion.mzn aborts with this message

i = 2
i = 3
i = 4
MiniZinc: result of evaluation is undefined: 
  test_recursion.mzn:24:
    with s = 6
  in call 'get_max'
  test_recursion.mzn:7:
  in if-then-else expression
  test_recursion.mzn:20:
  in call 'get_max'
  test_recursion.mzn:7:
  in if-then-else expression
  test_recursion.mzn:14:
  in let expression
  test_recursion.mzn:18:
  in call 'get_max'
  test_recursion.mzn:7:
  in if-then-else expression
  test_recursion.mzn:14:
  in let expression
  test_recursion.mzn:18:
  in call 'get_max'
  test_recursion.mzn:15:
  in call 'max'
  in call 'trace'
  in array access
  array access out of bounds

It seems so, that the compiler internally computes the new index i and then uses it to access the array y leading to an array access error.

BTW: Tested different versions of MiniZinc with the same result except for MiniZinc 1.6 that aborted with a cycle detection error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions