Próbuję użyć Z3 do uzasadnienia podłańcuchów i napotkałem pewne nieintuicyjne zachowanie. Z3 zwraca 'sat', gdy zostanie poproszony o ustalenie, czy "xy" pojawia się w ciągu "xy", ale zwraca "nieznany", gdy pytanie "x" jest w "x", lub "x" w "xy".Czy Z3 może być używany do wnioskowania o podciągach?
mam skomentował poniższy kod, żeby zilustrować ten problem:
(set-logic AUFLIA)
(declare-sort Char 0)
;characters to build strings are _x_ and _y_
(declare-fun _x_() Char)
(declare-fun _y_() Char)
(assert (distinct _x_ _y_))
;string literals
(declare-fun findMeX() (Array Int Char))
(declare-fun findMeXY() (Array Int Char))
(declare-fun x() (Array Int Char))
(declare-fun xy() (Array Int Char))
(declare-fun length ((Array Int Char)) Int)
;set findMeX = 'x'
(assert (= (select findMeX 0) _x_))
(assert (= (length findMeX) 1))
;set findMeXY = 'xy'
(assert (= (select findMeXY 0) _x_))
(assert (= (select findMeXY 1) _y_))
(assert (= (length findMeXY) 2))
;set x = 'x'
(assert (= (select x 0) _x_))
(assert (= (length x) 1))
;set xy = 'xy'
(assert (= (select xy 0) _x_))
(assert (= (select xy 1) _y_))
(assert (= (length xy) 2))
teraz, że problem jest skonfigurowana, staramy się znaleźć podciągi:
;search for findMeX='x' in x='x'
(push 1)
(assert
(exists
((offset Int))
(and
(<= offset (- (length x) (length findMeX)))
(>= offset 0)
(forall
((index Int))
(=>
(and
(< index (length findMeX))
(>= index 0))
(=
(select x (+ index offset))
(select findMeX index)))))))
(check-sat) ;'sat' expected, 'unknown' returned
(pop 1)
Gdybyśmy zamiast szukać findMeXY
w xy
, solver zwraca 'sat', zgodnie z oczekiwaniami. Wydaje się, że ponieważ solver może obsłużyć to zapytanie dla "xy", powinno być w stanie obsłużyć to dla "x". Ponadto, wyszukując findMeX='x'
w 'xy='xy'
, zwraca "nieznany".
Czy ktoś może zaproponować wyjaśnienie, a może alternatywny model wyrażania tego problemu w rozwiązaniu SMT?
Starałem się odtworzyć problem opisałeś bez powodzenia. Z której wersji Z3 korzystasz? Próbowałem używać Z3 2.19 (Windows i Linux) i Z3 3.0 (dostępny na stronie internetowej SMT-COMP) i wszystkie zostały zwrócone dla powyższego zapytania. Dzięki, Leo. –
Dzięki za komentarz, Leo, i uświadomiłaś mi, że zostawiłem coś poza pytaniem. Wygląda na to, że zachowanie, którego doświadczam, występuje tylko wtedy, gdy ostateczne asercje i check-sat pojawiają się pomiędzy poleceniami "push" i "pop", których używałem do wypróbowania różnych eksperymentów w ramach tego samego zestawu asercji. Odpowiednio zmodyfikowałem pytanie, ale teraz wydaje się, że problem dotyczy scopingu. Jeśli 'push' i' pop' są pominięte, to masz rację, 'sat' jest zwracany we wszystkich przypadkach. – Katie
Może być szukasz tego: https://www.cs.purdue.edu/homes/zheng16/str/ – user