3

How do I add an offset to a value obtained from an IndexOf expression? That is, how do I do this?

> import z3
> s = 'hello'
> t = 'e'
> z3.simplify(z3.IndexOf(s, t, 0) + z3.IntVal(1))
z3.z3types.Z3Exception: Non-sequence passed as a sequence

I want to get the location after than of e.

On the other hand, switching the order works as expected

> z3.simplify(z3.IntVal(1) + z3.IndexOf(s, t, 0))
2
Rahul Gopinath
  • 808
  • 10
  • 24

1 Answers1

4

You found a bug in z3py!

The bug is on this line: https://github.com/Z3Prover/z3/blob/master/src/api/python/z3/z3.py#L10150

which reads:

    return SeqRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)

Instead, it should say:

    return ArithRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)

I've reported this at their bug tracker: https://github.com/Z3Prover/z3/issues/2159

Once you make that change in your local-copy of z3.py, your program should work as is. Or you can wait till they release a fix.

alias
  • 28,120
  • 2
  • 23
  • 40
  • Thank you! Much appreciated. – Rahul Gopinath Feb 27 '19 at 21:28
  • By the way, do you know how to invoke the doctests on z3's python API? I don't see any docs on it. If possible, I want to contribute a fix and a test to make sure this gets fixed fast. – Rahul Gopinath Feb 28 '19 at 13:52
  • I believe they have some sort of a builtbot that runs all the tests upon a commit. I don't know how to run it locally though. See here: https://github.com/Z3Prover/z3test – alias Feb 28 '19 at 15:18