MiniZinc / libminizinc

The MiniZinc compiler
http://www.minizinc.org
Other
514 stars 80 forks source link

`void MiniZinc::Type::ot(const OptType&): Assertion 'o == OT_PRESENT || !structBT() || typeId() == 0' failed.` #830

Closed LebedevRI closed 1 month ago

LebedevRI commented 2 months ago

This might be a duplicate of https://github.com/MiniZinc/libminizinc/issues/826, i'm not sure.

int: NUM_CONTACTS = 3;
enum CONTACTS = C(1..NUM_CONTACTS);

int: NUM_GRAPH_NODES = NUM_CONTACTS;
int: NUM_GRAPH_EDGES = length(GRAPH_LEAVING_NODE);

enum GRAPH_NODES = GN(CONTACTS);
enum GRAPH_EDGES = _(1..length(j,i in CONTACTS where i > j)(1));

array[GRAPH_EDGES] of tuple(GRAPH_NODES,GRAPH_NODES): GRAPH_NODE_PAIRS = [ (GN(j),GN(i)) | j,i in CONTACTS where i > j ];
array[GRAPH_EDGES] of GRAPH_NODES: GRAPH_LEAVING_NODE  = [ p.1 | p in GRAPH_NODE_PAIRS ];
array[GRAPH_EDGES] of GRAPH_NODES: GRAPH_ENTERING_NODE = [ p.2 | p in GRAPH_NODE_PAIRS ];

function GRAPH_EDGES: getEdgeIndice(GRAPH_NODES: j, GRAPH_NODES: i) =
  let {
    constraint count(e in GRAPH_NODE_PAIRS)((j,i) == e) == 1;
  } in to_enum(GRAPH_EDGES, sum(e in GRAPH_EDGES)(
    if GRAPH_NODE_PAIRS[e] == (j,i) then e else 0 endif
  ));

array[CONTACTS,CONTACTS] of opt GRAPH_EDGES: GRAPH_EDGE_INDEX = array2d(CONTACTS, CONTACTS, 
   [ if(j == i) then <> else getEdgeIndice(to_enum(GRAPH_NODES, min(j,i)), to_enum(GRAPH_NODES, max(j,i))) endif | j in CONTACTS, i in CONTACTS ]);

constraint assert(forall (j,i in CONTACTS where i > j)(
    GRAPH_EDGE_INDEX[j,i] == GRAPH_EDGE_INDEX[i,j]
/\  GRAPH_NODE_PAIRS[GRAPH_EDGE_INDEX[j,i]] == (j,i)    % ?????
), "");
minizinc: ./include/minizinc/type.hh:120: void MiniZinc::Type::ot(const OptType&): Assertion `o == OT_PRESENT || !structBT() || typeId() == 0' failed.
Process finished with non-zero exit code 6.
cyderize commented 2 months ago

This is a separate bug, but will be fixed by 854d2e2e598d6a71eb46a25afadb988eb8800f93 in the next release (which will give a type error instead of crashing/giving a confusing error message).

Currently using an optional index to access an array of tuples/records is not supported (but hopefully we will be able to support this in a future version).

For now, a workaround would be to do this:

constraint assert(forall (j,i in CONTACTS where i > j)(
    GRAPH_EDGE_INDEX[j,i] == GRAPH_EDGE_INDEX[i,j]
/\  GRAPH_LEAVING_NODE[GRAPH_EDGE_INDEX[j,i]] == GN(j)
/\  GRAPH_ENTERING_NODE[GRAPH_EDGE_INDEX[j,i]] == GN(i)
), "");
LebedevRI commented 2 months ago

@cyderize thank you for taking a look!

cyderize commented 1 month ago

I believe this should now be fixed in 2.8.6