Z3 FiniteDomain doesn't seem to work with implications

128 Views Asked by At

Here's a Z3 program, that creates two variables X and Y which cannot be equal, and have a domain of size 2:

var solver = ctx.MkSolver();

// Section A
var T = ctx.MkFiniteDomainSort("T", 2);
var a = ctx.MkNumeral(0, T);
var b = ctx.MkNumeral(1, T);
var x = ctx.MkConst("x", T);
var y = ctx.MkConst("y", T);

// Section B
//var a = ctx.MkInt(0);
//var b = ctx.MkInt(1);
//var x = ctx.MkIntConst("x");
//var y = ctx.MkIntConst("y");
//solver.Add(ctx.MkLe(a, x), ctx.MkLe(x, b));
//solver.Add(ctx.MkLe(a, y), ctx.MkLe(y, b));

// Section C
//solver.Assert(!ctx.MkEq(x, y));

// Section D
solver.Assert(ctx.MkImplies(ctx.MkEq(x, a), ctx.MkEq(y, b)));
solver.Assert(ctx.MkImplies(ctx.MkEq(x, b), ctx.MkEq(y, a)));
solver.Assert(ctx.MkImplies(ctx.MkEq(y, a), ctx.MkEq(x, b)));
solver.Assert(ctx.MkImplies(ctx.MkEq(y, b), ctx.MkEq(x, a)));

// Section E
//solver.Assert(ctx.MkEq(x, a));

var status = solver.Check();
Console.WriteLine(status);
Console.WriteLine(solver.Model);
Console.WriteLine(solver.Model.Eval(ctx.MkEq(x, a)));
Console.WriteLine(solver.Model.Eval(ctx.MkEq(y, b)));

// Should always be true, but doesn't work when only sections A and D are uncommented?
Console.WriteLine(solver.Model.Eval(ctx.MkImplies(ctx.MkEq(x, a), ctx.MkEq(y, b))));

I get output.

SATISFIABLE
(define-fun y () T
  0)
(define-fun x () T
  0)
true
false
false

This model clearly does not satisfy the constraints. I explicitly evaluate the 1st constraint to double check, and indeed, it's false.

The same problem does not occur if I use integers (section B instead of section A), or I add additional constraints (section C & E).

What am I missing? I'd like to use FiniteDomain as it's more convenient than adding bounds to integers, but it seems it behaves quite differently.

1

There are 1 best solutions below

0
On

This GitHub issue explains that FiniteDomain is only intended for the Datalog engine, and is broken in other uses.

Using enumerations is the correct way to do this in Z3 in other engines.