I think this is something funky to do with matching in Z3. My guess is that the way that Dafny implements the map comprehension somehow makes the value
'''
function method RemoveElementFromMap(m:map<int,int>, x:int) : map<int,int>
{
map i | i in m && i != x :: m[i]
}
method test() {
var m := map[3 := 5, 4 := 6, 1 := 4];
var l := RemoveElementFromMap(m,3);
assert l == map[4:= 6, 1 := 4];
}
'''
http://rise4fun.com/Dafny/lmquH
It is possible my explaination is wrong. We could probably work out the exact reason by looking in detail at what Boogie code is generated by Dafny for this example.
(map i | i in m && i != 3 :: m[i])
unsuitable for use in the SMT solver's e-graph (or perhaps it is suitable, but Dafny does not give an appropriate trigger). And the usual way to fix these kinds of problems is to introduce a function, so that Z3 has something it can use in the e-graph in place of the value map i | i in m && i != 3 :: m[i]
. The following appears to work:'''
function method RemoveElementFromMap(m:map<int,int>, x:int) : map<int,int>
{
map i | i in m && i != x :: m[i]
}
method test() {
var m := map[3 := 5, 4 := 6, 1 := 4];
var l := RemoveElementFromMap(m,3);
assert l == map[4:= 6, 1 := 4];
}
'''
http://rise4fun.com/Dafny/lmquH
It is possible my explaination is wrong. We could probably work out the exact reason by looking in detail at what Boogie code is generated by Dafny for this example.