3

I'm trying to write an assertion that a certain sequence of integers contains at least 2 occurrences of some integer (say 8). Here is what I wrote:

(declare-const s (Seq Int))
(assert (seq.in.re s
    (re.++
        re.all
        (re.++
            (seq.to.re (seq.unit 8))
            (re.++
                re.all
                (re.++
                    (seq.to.re (seq.unit 8))
                    re.all))))))

When I tried to run it I get the following error:

(error "line 11 column 11: Sort of function 're.++' does not match the declared type. Given domain: (RegEx (Seq Int)) (RegEx String) ")

So I guess re.all is defined only for strings? Is there any way to create a regular expression for all integers?

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87

1 Answers1

1

SMTLib type-system is rather weak, and it gets confused when it sees re.all as it cannot distinguish between a string regexp and a regexp over some other sequence. And thus you're getting a type-error.

This is anticipated in the SMTLib standard actually, see Section 3.6.4 of http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2017-07-18.pdf

The solution (as described in the standard) is to use an as clause to give an explicit type, like this:

(define-fun allInt () (RegEx (Seq Int)) (as re.all (RegEx (Seq Int))))

(declare-const s (Seq Int))
(assert (seq.in.re s
    (re.++
        allInt
        (re.++
            (seq.to.re (seq.unit 8))
            (re.++
                allInt
                (re.++
                    (seq.to.re (seq.unit 8))
                    allInt))))))

This is a common gotcha for people who expect the system to figure out from context what the actual type should be. But to keep the system simple, designers went for a very simple type system: Each term should be typeable on its own, without any contextual information. In rare cases where this is not possible (such as your use case), they provided the as syntax as a means of being explicit about typing.

alias
  • 28,120
  • 2
  • 23
  • 40