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.