1 year ago

#363577

test-img

user4676310

Satisfiability check of first order logic formula is "unknown" in Z3py

I'm trying to implement satisfiability checking of a regular expression by converting it into a first-order logic formula based on the following excerpt from Rex: Symbolic Regular Expression Explorer

enter image description here

The problem seems to be that the circular reference(?) of Acc1 in the last axiom makes it so that Z3 is not capable of terminating and returns with "unknown" after a considerable amount of time. This seems weird to me, since if I understand correctly the second arguments of Acc0 and Acc1 are used to guarantee termination by decreasing until reaching a value of 0.

In my case to avoid naming conflicts the goal string is named w instead of s.

Note: Z3 also fails to return "sat" when a satisfying value (eg. "cc") is asserted to w.

Edit: After realizing the need for patterns (underlined parts in the screenshot) I've added them. Sadly Z3 still times out trying to solve this problem. I've looked into strategies but haven't found any that seems to help. It would be great if there was a way to eliminate the quantified formulas with the help of pattern matching.

enter image description here

from z3 import *;

def hd(x):
    return SubString(x, 0, 1)

def tl(x):
    return SubString(x,1,Length(x)-1)

def phi(x):
    return And(
        x >= StringVal('a'),
        x <= StringVal('z')
    )

solver = Solver()

solver.set()

Number = Datatype('Number')
Number.declare('nil') # 0
Number.declare('s', ('prev', Number)) # 1 = s(0), 2 = s(s(0))...
Number = Number.create()
nil = Number.nil
s = Number.s

x = String('x')
y = Const('y', Number)
w = String('w')

Acc0 = Function('Acc0', StringSort(), Number, BoolSort()) # String X Number -> Bool
Acc1 = Function('Acc1', StringSort(), Number, BoolSort()) # String X Number -> Bool

ax0_0 = ForAll( x, Acc0(x,nil) == False , patterns=[Acc0(x,nil)]) # For all(x: Acc0(x, 0) -> False
ax0_1 = ForAll( [x, y], Acc0(x, s(y)) == # For all(x,(y: Acc0(x, s(y)) <=>
    And(    
        Not(x == StringVal('')),               #(x != '' AND
        phi(hd(x)), # 'a' <= head(x) <= 'z' AND
        Acc1(tl(x),y)   # Acc1( tail(x),(y)
    ),
    patterns=[Acc0(x, s(y))]
)

ax1_0 = ForAll( x, Acc1(x,nil) == (x == StringVal('')), patterns=[Acc1(x,nil)]) # For all(x: Acc1(x, 0) <=>(x == ''
ax1_1 = ForAll( [x, y], Acc1(x, s(y)) == # For all(x,(y: Acc1(x, s(y)) <=>
    Or(
        And(                           # (
            Not(x == StringVal('')),   #(x != '' AND
            phi(hd(x)), # 'a' <= head(x) <= 'z' AND
            Acc1(tl(x),y)  # Acc1(tail(x),(y)
        ),                             # )
        x == StringVal('')            # OR(x == ''
    ),
    patterns=[Acc1(x, s(y))]
)

solver.add(
    Acc0(w, s(s(nil))),
    ax1_1,
    ax1_0,
    ax0_1,
    ax0_0
)

print(solver.check())

python

z3

smt

z3py

0 Answers

Your Answer

Accepted video resources